JS3 Posted July 6, 2018 Share Posted July 6, 2018 (edited) As the title says, not my first script. BUT I am looking for feedback. Some of the issues I am running into now is when I level up, it will not continue and restart smithing, and sometimes it doesn't click the widget box on the first try, will wait few seconds, then start over again. Please let me know how this looks so far. Thanks Spoiler import org.osbot.rs07.api.map.Area; import org.osbot.rs07.api.model.RS2Object; import org.osbot.rs07.api.ui.RS2Widget; import org.osbot.rs07.api.ui.Skill; import org.osbot.rs07.script.Script; import org.osbot.rs07.script.ScriptManifest; import org.osbot.rs07.utility.ConditionalSleep; import java.awt.*; @ScriptManifest(logo ="", name ="Cannonballer", version =1.0 , info ="Makes cannonballs for ca$h" , author ="J$" ) public class Main extends Script { public final Area bankArea = new Area(3098, 3494, 3095, 3495); public final Area furnaceRoom = new Area(3109, 3498, 3108, 3500); enum State { WALK_TO_FURNACE, WALK_TO_BANK, SMITH_CBALLS, DEPOSIT_CB, WITHDRAW_BARS, IDLE } @Override public void onStart() throws InterruptedException { getExperienceTracker().start(Skill.SMITHING); } @Override public int onLoop() throws InterruptedException { switch (getState()) { case SMITH_CBALLS: log("BEGIN BALLS"); RS2Object furnace = objects.closest("Furnace"); RS2Widget smithFace = getWidgets().get(270, 14, 38); if (furnace != null) { if (!myPlayer().isAnimating()) { if (smithFace != null && smithFace.isVisible()) { smithFace.interact("Make sets:"); getMouse().moveOutsideScreen(); new ConditionalSleep(30000, 5000) { @Override public boolean condition() throws InterruptedException { return getDialogues().isPendingContinuation() || !getInventory().contains("Steel bar"); } }.sleep(); } else { sleep(800); if (!myPlayer().isAnimating()) { furnace.interact(); } } } } break; case WALK_TO_FURNACE: log("On the way.."); if (!furnaceRoom.contains(myPlayer())){ getWalking().webWalk(furnaceRoom); } break; case WALK_TO_BANK: log("Walking to the Bank"); if (!bankArea.contains(myPlayer())){ getWalking().webWalk(bankArea); } break; case DEPOSIT_CB: log("Depositing the Balls"); if (bank.isOpen()) { bank.depositAllExcept("Ammo mould"); } else { RS2Object bankBooth = getObjects().closest("Bank booth"); if (bankBooth != null && bankBooth.interact("Bank")) { new ConditionalSleep(1000){ @Override public boolean condition() { return bank.isOpen(); } }.sleep(); } } break; case WITHDRAW_BARS: log("Pulling out the Bars"); if (bank.isOpen()) { bank.withdraw("Steel bar", 27); } else { RS2Object bankBooth = getObjects().closest("Bank booth"); if (bankBooth != null && bankBooth.interact("Bank")) { new ConditionalSleep(1000){ @Override public boolean condition() { return bank.isOpen(); } }.sleep(); } } break; case IDLE: log("Idle Idle Idle"); getMouse().moveOutsideScreen(); } return 800; } private State getState() { if (getInventory().contains("Steel bar") && !furnaceRoom.contains(myPlayer())) { log("Walking to Furnace"); return State.WALK_TO_FURNACE; } else if (furnaceRoom.contains(myPlayer()) && getInventory().isEmptyExcept("Ammo mould")) { log("Walking to Bank for Bars"); return State.WALK_TO_BANK; } else if (getInventory().isEmptyExcept("Ammo mould") && bankArea.contains(myPlayer())) { log("Pulling out the Bars"); return State.WITHDRAW_BARS; } else if (getInventory().contains("Ammo mould", "Steel bar") && getInventory().isFull()) { log("Starting to make Cannonballs"); return State.SMITH_CBALLS; } else if (getInventory().isEmptyExcept("Ammo mould", "Cannonball") && bankArea.contains(myPlayer())) { log("Banking the Balls"); return State.DEPOSIT_CB; } else if (getInventory().onlyContains("Ammo mould", "Cannonball") && !bankArea.contains(myPlayer())) { log("Walking to Bank to Deposit Balls"); return State.WALK_TO_BANK; } else { log("Idling for now"); return State.IDLE; } } @Override public void onExit() throws InterruptedException { } @Override public void onPaint(Graphics2D gP) { int smithXPtot = getExperienceTracker().getGainedXP(Skill.SMITHING); int smithXPhr = getExperienceTracker().getGainedXPPerHour(Skill.SMITHING); EDIT: I've updated the script a bit to avoid static IDs on the widget and tried cleaning up the SMITH_CBALLS case to interact better. I keep running into issues with animation delay. For example, when I click the furnace, it will sleep, press space, but not go into IDLE everytime. Instead, it seems like the delay is throwing off myPlayer().isAnimating, as it will try to run through and click furnace -> Interact with widget, loops until hitting IDLE. EDIT AGAIN: I have separated the smithing action into 2 cases. I wanted to see if this would fix the re-click on the furnace when the widget is present and if I could get the smithing state to re-engage if cannonballs and steels bars were still in inv. Trying to figure out the issue with the widget and interaction. Now getting this error on the log. [INFO][Bot #1][07/09 10:38:34 PM]: STATE: START_WIDGET [INFO][Bot #1][07/09 10:38:34 PM]: Interacting with Furnace and widget [ERROR][Bot #1][07/09 10:38:34 PM]: Error in script executor! java.lang.NullPointerException [INFO][Bot #1][07/09 10:38:34 PM]: STATE: START_WIDGET [INFO][Bot #1][07/09 10:38:34 PM]: Interacting with Furnace and widget [ERROR][Bot #1][07/09 10:38:34 PM]: Error in script executor! java.lang.NullPointerException [INFO][Bot #1][07/09 10:38:34 PM]: STATE: START_WIDGET [INFO][Bot #1][07/09 10:38:34 PM]: Interacting with Furnace and widget [ERROR][Bot #1][07/09 10:38:34 PM]: Error in script executor! java.lang.NullPointerException Spoiler import org.osbot.rs07.api.map.Area; import org.osbot.rs07.api.model.RS2Object; import org.osbot.rs07.api.ui.RS2Widget; import org.osbot.rs07.api.ui.Skill; import org.osbot.rs07.script.Script; import org.osbot.rs07.script.ScriptManifest; import org.osbot.rs07.utility.ConditionalSleep; import java.awt.*; import java.util.List; @ScriptManifest(logo ="", name ="Cannonballer", version =1.0 , info ="Makes cannonballs for ca$h" , author ="J$" ) public class Main extends Script { public final Area bankArea = new Area(3098, 3494, 3095, 3495); public final Area furnaceRoom = new Area(3109, 3498, 3108, 3500); public long lastAnimation = 0; enum State { WALK_TO_FURNACE, WALK_TO_BANK, SMITH_CBALLS, DEPOSIT_CB, WITHDRAW_BARS, IDLE, START_WIDGET } @Override public void onStart() throws InterruptedException { getExperienceTracker().start(Skill.SMITHING); getSkills().getStatic(Skill.SMITHING); } @Override public int onLoop() throws InterruptedException { switch (getState()) { case START_WIDGET: log("Interacting with Furnace and widget"); RS2Object furnace = objects.closest("Furnace"); RS2Widget smithFace = getWidgets().getWidgetContainingText(270, "How many"); if (smithFace.isVisible() && smithFace.interact()) { sleep(2500); getKeyboard().pressKey(32); } else { if (furnace != null && furnace.interact("Smelt")) { new ConditionalSleep(2000) { @Override public boolean condition() { return smithFace.isVisible() && smithFace.interact(); } }.sleep(); } } break; case SMITH_CBALLS: boolean cBallTotal = getInventory().getAmount("Cannonball") == 108; log("Smithing Cannonballs"); if (myPlayer().isAnimating()) { getMouse().moveOutsideScreen(); new ConditionalSleep(20000, 5000) { @Override public boolean condition() { return cBallTotal || getDialogues().isPendingContinuation(); } }.sleep(); } break; case WALK_TO_FURNACE: log("On the way.."); if (!furnaceRoom.contains(myPlayer())){ getWalking().webWalk(furnaceRoom); } break; case WALK_TO_BANK: log("Walking to the Bank"); if (!bankArea.contains(myPlayer())){ getWalking().webWalk(bankArea); } break; case DEPOSIT_CB: log("Depositing the Balls"); if (bank.isOpen()) { bank.depositAllExcept("Ammo mould"); } else { RS2Object bankBooth = getObjects().closest("Bank booth"); if (bankBooth != null && bankBooth.interact("Bank")) { new ConditionalSleep(1000){ @Override public boolean condition() { return bank.isOpen(); } }.sleep(); } } break; case WITHDRAW_BARS: log("Pulling out the Bars"); if (bank.isOpen()) { bank.withdraw("Steel bar", 27); } else { RS2Object bankBooth = getObjects().closest("Bank booth"); if (bankBooth != null && bankBooth.interact("Bank")) { new ConditionalSleep(1000){ @Override public boolean condition() { return bank.isOpen(); } }.sleep(); } } break; case IDLE: log("Idle Idle Idle"); getMouse().moveOutsideScreen(); } return 700; } private State getState() { if (getInventory().contains("Steel bar") && !furnaceRoom.contains(myPlayer())) { log("STATE: WALK_TO_FURNACE"); return State.WALK_TO_FURNACE; } else if (furnaceRoom.contains(myPlayer()) && getInventory().isEmptyExcept("Ammo mould")) { log("STATE: WALK_TO_BANK"); return State.WALK_TO_BANK; } else if (getInventory().isEmptyExcept("Ammo mould") && bankArea.contains(myPlayer())) { log("STATE: WITHDRAW_BARS"); return State.WITHDRAW_BARS; } else if (getInventory().contains("Ammo mould", "Steel bar") && getInventory().isFull()) { log("STATE: START_WIDGET"); return State.START_WIDGET; } else if (getInventory().isEmptyExcept("Ammo mould", "Cannonball") && bankArea.contains(myPlayer())) { log("STATE: DEPOSIT_CB"); return State.DEPOSIT_CB; } else if (getInventory().onlyContains("Ammo mould", "Cannonball") && !bankArea.contains(myPlayer())) { log("STATE: WALK_TO_BANK"); return State.WALK_TO_BANK; } else if (!myPlayer().isAnimating() && furnaceRoom.contains(myPlayer())) { log("STATE: SMITH_CBALLS"); return State.SMITH_CBALLS; } else log("STATE: IDLE"); return State.IDLE; } @Override public void onExit() throws InterruptedException { } @Override public void onPaint(Graphics2D gP) { int smithXPtot = getExperienceTracker().getGainedXP(Skill.SMITHING); int smithXPhr = getExperienceTracker().getGainedXPPerHour(Skill.SMITHING); int startLvl = getSkills().getDynamic(Skill.SMITHING); long ttl = getExperienceTracker().getTimeToLevel(Skill.SMITHING); int xpTTL = getExperienceTracker().getGainedLevels(Skill.SMITHING); super.onPaint(gP); gP.drawString("Cannonballin by J$", 10, 50); gP.drawString("Smith XP Total: " + smithXPtot, 10, 65); gP.drawString("Smith XP Per Hour: " + smithXPhr, 10, 80); gP.drawString("Smithing level: " + startLvl, 10, 95); gP.drawString("Gained levels: " + xpTTL, 10, 110); } } Last Edit: Finally have worked out all the bugs I was experiencing. Posting the final code here. Thanks to everyone for the help! Spoiler import org.osbot.rs07.api.map.Area; import org.osbot.rs07.api.model.RS2Object; import org.osbot.rs07.api.ui.RS2Widget; import org.osbot.rs07.api.ui.Skill; import org.osbot.rs07.script.Script; import org.osbot.rs07.script.ScriptManifest; import org.osbot.rs07.utility.ConditionalSleep; import java.awt.*; @ScriptManifest(logo ="", name ="Cannonballer", version =1.0 , info ="Makes cannonballs for ca$h" , author ="J$" ) public class Main extends Script { public final Area bankArea = new Area(3098, 3494, 3095, 3495); public final Area furnaceRoom = new Area(3109, 3498, 3108, 3500); private long startTime; private long runTime; enum State { WALK_TO_FURNACE, WALK_TO_BANK, SMITH_CBALLS, DEPOSIT_CB, WITHDRAW_BARS, IDLE, START_WIDGET } @Override public void onStart() throws InterruptedException { getExperienceTracker().start(Skill.SMITHING); getSkills().getStatic(Skill.SMITHING); startTime = System.currentTimeMillis(); } @Override public int onLoop() throws InterruptedException { switch (getState()) { case START_WIDGET: log("Interacting with Furnace and widget"); RS2Object furnace = objects.closest("Furnace"); RS2Widget smithFace = getWidgets().singleFilter(270, w -> w != null && w.isVisible()); if (smithFace != null && smithFace.isVisible()) { getKeyboard().pressKey(32); } else { if (furnace != null && furnace.interact("Smelt")) { new ConditionalSleep(2000) { @Override public boolean condition() { return smithFace.isVisible(); } }.sleep(); } } break; case SMITH_CBALLS: boolean cBallTotal = getInventory().getAmount("Cannonball") == 108; log("Smithing Cannonballs"); getMouse().moveOutsideScreen(); new ConditionalSleep(5000, 2500) { @Override public boolean condition() { return cBallTotal || getDialogues().isPendingContinuation(); } }.sleep(); break; case WALK_TO_FURNACE: log("On the way.."); if (!furnaceRoom.contains(myPlayer())){ getWalking().webWalk(furnaceRoom); } break; case WALK_TO_BANK: log("Walking to the Bank"); if (!bankArea.contains(myPlayer())){ getWalking().webWalk(bankArea); } break; case DEPOSIT_CB: log("Depositing the Balls"); if (bank.isOpen()) { bank.depositAllExcept("Ammo mould"); } else { RS2Object bankBooth = getObjects().closest("Bank booth"); if (bankBooth != null && bankBooth.interact("Bank")) { new ConditionalSleep(1000){ @Override public boolean condition() { return bank.isOpen(); } }.sleep(); } } break; case WITHDRAW_BARS: log("Pulling out the Bars"); if (bank.isOpen()) { bank.withdraw("Steel bar", 27); } else { RS2Object bankBooth = getObjects().closest("Bank booth"); if (bankBooth != null && bankBooth.interact("Bank")) { new ConditionalSleep(1000){ @Override public boolean condition() { return bank.isOpen(); } }.sleep(); } } break; case IDLE: log("Idle Idle Idle"); getMouse().moveOutsideScreen(); } return 1400; } private State getState() { if (getInventory().contains("Steel bar") && !furnaceRoom.contains(myPlayer())) { log("STATE: WALK_TO_FURNACE"); return State.WALK_TO_FURNACE; } else if (furnaceRoom.contains(myPlayer()) && getInventory().isEmptyExcept("Ammo mould")) { log("STATE: WALK_TO_BANK"); return State.WALK_TO_BANK; } else if (getInventory().isEmptyExcept("Ammo mould") && bankArea.contains(myPlayer())) { log("STATE: WITHDRAW_BARS"); return State.WITHDRAW_BARS; } else if (getInventory().contains("Ammo mould", "Steel bar") && getInventory().isFull() && !myPlayer().isAnimating()) { log("STATE: START_WIDGET"); return State.START_WIDGET; } else if (getInventory().isEmptyExcept("Ammo mould", "Cannonball") && bankArea.contains(myPlayer())) { log("STATE: DEPOSIT_CB"); return State.DEPOSIT_CB; } else if (getInventory().onlyContains("Ammo mould", "Cannonball") && !bankArea.contains(myPlayer())) { log("STATE: WALK_TO_BANK"); return State.WALK_TO_BANK; } else if (myPlayer().isAnimating() && furnaceRoom.contains(myPlayer())) { log("STATE: SMITH_CBALLS"); return State.SMITH_CBALLS; } else log("STATE: IDLE"); return State.IDLE; } @Override public void onExit() throws InterruptedException { } public final String formatTime(final long ms) { long s = ms / 1000, m = s / 60, h = m / 60; s %= 60; m %= 60; h %= 24; return String.format("%02d:%02d:%02d", h, m, s); } @Override public void onPaint(Graphics2D gP) { int smithXPtot = getExperienceTracker().getGainedXP(Skill.SMITHING); int smithXPhr = getExperienceTracker().getGainedXPPerHour(Skill.SMITHING); int startLvl = getSkills().getDynamic(Skill.SMITHING); long ttl = getExperienceTracker().getTimeToLevel(Skill.SMITHING); int xpTTL = getExperienceTracker().getGainedLevels(Skill.SMITHING); runTime = System.currentTimeMillis() - this.startTime; super.onPaint(gP); gP.setColor(Color.decode("#FFFFFF")); gP.drawString("Cannonballin by J$", 10, 50); gP.drawString("Time Ran: " + formatTime(runTime), 10, 65); gP.drawString("Smith XP Total: " + smithXPtot, 10, 80); gP.drawString("Smith XP Per Hour: " + smithXPhr, 10, 95); gP.drawString("Smithing level: " + startLvl, 10, 110); gP.drawString("Gained levels: " + xpTTL, 10, 125); } } Edited July 11, 2018 by m3JS Quote Link to comment Share on other sites More sharing options...
ProjectPact Posted July 6, 2018 Share Posted July 6, 2018 I would recommend not using static ID's. By using dynamic ID's instead, you are able to ensure that your script stays functional after a "non-crucial" update, because Jagex likes changing child ID's. RS2Widget smithFace = getWidgets().get(270, 14, 38); 1 Quote Link to comment Share on other sites More sharing options...
JS3 Posted July 6, 2018 Author Share Posted July 6, 2018 2 minutes ago, ProjectPact said: I would recommend not using static ID's. By using dynamic ID's instead, you are able to ensure that your script stays functional after a "non-crucial" update, because Jagex likes changing child ID's. RS2Widget smithFace = getWidgets().get(270, 14, 38); Thanks! When you say dynamic, do you mean straying away from using the IDs like 270,14, etc? For example, use the root ID 270 and then something like containsText("example")? Quote Link to comment Share on other sites More sharing options...
ProjectPact Posted July 6, 2018 Share Posted July 6, 2018 (edited) 7 minutes ago, m3JS said: Thanks! When you say dynamic, do you mean straying away from using the IDs like 270,14, etc? For example, use the root ID 270 and then something like containsText("example")? Exactly, searching for text is one reliable way to do it! You can get even more dynamic than that, but it digs a little deeper than just understanding the fundamentals. Edit: Also, after look at your code more, you have this: smithFace.interact("Make sets:"); You should do: if(smithFace.interact("Make sets:")){ // Code in here } The reason you should do this is because you ONLY want to move the mouse and do the conditional sleep, or anything else you can think of, ONLY if the action was successful. Since it is a boolean, it will return true or false. Edited July 6, 2018 by ProjectPact Quote Link to comment Share on other sites More sharing options...
JS3 Posted July 6, 2018 Author Share Posted July 6, 2018 3 minutes ago, ProjectPact said: Exactly, searching for text is one reliable way to do it! You can get even more dynamic than that, but it digs a little deeper than just understanding the fundamentals. Awesome! I will work on that. Thanks again for your feedback! 1 Quote Link to comment Share on other sites More sharing options...
ProjectPact Posted July 6, 2018 Share Posted July 6, 2018 1 minute ago, m3JS said: Awesome! I will work on that. Thanks again for your feedback! I updated my post again for a little more info that might help Quote Link to comment Share on other sites More sharing options...
JS3 Posted July 6, 2018 Author Share Posted July 6, 2018 54 minutes ago, ProjectPact said: I updated my post again for a little more info that might help I've run into some interesting problems. See below: case SMITH_CBALLS: log("BEGIN BALLS"); RS2Object furnace = objects.closest("Furnace"); RS2Widget smithFace = getWidgets().get(270, 14, 38); if (furnace != null) { if (!myPlayer().isAnimating()) { if (smithFace != null && smithFace.isVisible()) { if (smithFace.interact("Make sets:")) { getMouse().moveOutsideScreen(); new ConditionalSleep(30000, 5000) { @Override public boolean condition() throws InterruptedException { return getDialogues().isPendingContinuation() || !getInventory().contains("Steel bar"); } }.sleep(); } else { sleep(800); if (!myPlayer().isAnimating()) { furnace.interact(); } } } } } break; When adding if(smithFace.interact("Make sets:"), it cannot locate the action to select unless I remove the if statement. On the contrary, when looking for the widget dynamically, it cannot locate the widget when doing RS2Widget smithFace = getWidgets().getWidgetContainingText(240, "How many bars would you like to smith?"); when I run it, I keep getting stuck on BEGIN BALLS and Starting to Make Cannonballs in the logger for either option. For the script to keep running, I default back to original setup. Quote Link to comment Share on other sites More sharing options...
Athylus Posted July 6, 2018 Share Posted July 6, 2018 (edited) For readability you might want to change your main loop. Instead of writing a lot of code under your case <enum>:, call methods. And if possible call other methods inside the methods for readability. It's not such a big issue in this script, mainly because it's 'private'. But it's good to get in the habit of doing that if you want to get better at this. When you start writing bigger scripts such as a farming script, it will be really hard to trace back errors and such. Readability is good practice. Perhaps you can put multiple nested if statements together by using logical operators. About the widget, make sure the text is spelled right. One single letter is an error and the widget will not be found. If you want to test this easily learn to use paint and debug there what you want to test. If widget != null then g.drawString("widget can't be found", 10, 15); Put that in a separate project. It will make your life easier. Good luck! Edited July 6, 2018 by Athylus Quote Link to comment Share on other sites More sharing options...
JS3 Posted July 6, 2018 Author Share Posted July 6, 2018 6 hours ago, Athylus said: For readability you might want to change your main loop. Instead of writing a lot of code under your case <enum>:, call methods. And if possible call other methods inside the methods for readability. It's not such a big issue in this script, mainly because it's 'private'. But it's good to get in the habit of doing that if you want to get better at this. When you start writing bigger scripts such as a farming script, it will be really hard to trace back errors and such. Readability is good practice. Perhaps you can put multiple nested if statements together by using logical operators. About the widget, make sure the text is spelled right. One single letter is an error and the widget will not be found. If you want to test this easily learn to use paint and debug there what you want to test. If widget != null then g.drawString("widget can't be found", 10, 15); Put that in a separate project. It will make your life easier. Good luck! Great feedback and thank you for the suggestions! My goal is to create bigger and more complex scripts but to also put forth my efforts back to the community. I have tried to go back to not using States and enums as I am fairly new to Java and don't understand fully why to use enums over not using them. I think I need to go back and do some basic Java to better understand everything. I used the tutorials @Chris made and scanned through a lot of snippets and other forum posts. As for the widget, I was thinking about that this morning, I am gonna do some separate tests off script to practice. 1 Quote Link to comment Share on other sites More sharing options...
JS3 Posted July 7, 2018 Author Share Posted July 7, 2018 On 7/5/2018 at 9:13 PM, ProjectPact said: I updated my post again for a little more info that might help I've run into some interesting problems. See below: case SMITH_CBALLS: log("BEGIN BALLS"); RS2Object furnace = objects.closest("Furnace"); RS2Widget smithFace = getWidgets().get(270, 14, 38); if (furnace != null) { if (!myPlayer().isAnimating()) { if (smithFace != null && smithFace.isVisible()) { if (smithFace.interact("Make sets:")) { getMouse().moveOutsideScreen(); new ConditionalSleep(30000, 5000) { @Override public boolean condition() throws InterruptedException { return getDialogues().isPendingContinuation() || !getInventory().contains("Steel bar"); } }.sleep(); } else { sleep(800); if (!myPlayer().isAnimating()) { furnace.interact(); } } } } } break; When adding if(smithFace.interact("Make sets:"), it cannot locate the action to select unless I remove the if statement. On the contrary, when looking for the widget dynamically, it cannot locate the widget when doing RS2Widget smithFace = getWidgets().getWidgetContainingText(240, "How many bars would you like to smith?"); when I run it, I keep getting stuck on BEGIN BALLS and Starting to Make Cannonballs in the logger for either option. For the script to keep running, I default back to original setup. Update: I have updated OP but since then have improved the smithing state. See Below case SMITH_CBALLS: log("BEGIN BALLS"); boolean cBallTotal = getInventory().getAmount("Cannonball") == 108; RS2Object furnace = objects.closest("Furnace"); RS2Widget smithFace = getWidgets().getWidgetContainingText(270, "How many"); if (furnace != null && furnace.interact("Smelt")) { sleep(3000); if (smithFace != null) { getKeyboard().pressKey(32); } new ConditionalSleep(25000, 5000){ @Override public boolean condition(){ getMouse().moveOutsideScreen(); return cBallTotal || getDialogues().isPendingContinuation(); } }.sleep(); } break; I have not had any issues with clicking timing or getting stuck. Quote Link to comment Share on other sites More sharing options...
Alek Posted July 8, 2018 Share Posted July 8, 2018 Finally a decent script 1 Quote Link to comment Share on other sites More sharing options...
progamerz Posted July 8, 2018 Share Posted July 8, 2018 8 hours ago, m3JS said: I've run into some interesting problems. See below: case SMITH_CBALLS: log("BEGIN BALLS"); RS2Object furnace = objects.closest("Furnace"); RS2Widget smithFace = getWidgets().get(270, 14, 38); if (furnace != null) { if (!myPlayer().isAnimating()) { if (smithFace != null && smithFace.isVisible()) { if (smithFace.interact("Make sets:")) { getMouse().moveOutsideScreen(); new ConditionalSleep(30000, 5000) { @Override public boolean condition() throws InterruptedException { return getDialogues().isPendingContinuation() || !getInventory().contains("Steel bar"); } }.sleep(); } else { sleep(800); if (!myPlayer().isAnimating()) { furnace.interact(); } } } } } break; When adding if(smithFace.interact("Make sets:"), it cannot locate the action to select unless I remove the if statement. On the contrary, when looking for the widget dynamically, it cannot locate the widget when doing RS2Widget smithFace = getWidgets().getWidgetContainingText(240, "How many bars would you like to smith?"); when I run it, I keep getting stuck on BEGIN BALLS and Starting to Make Cannonballs in the logger for either option. For the script to keep running, I default back to original setup. Update: I have updated OP but since then have improved the smithing state. See Below case SMITH_CBALLS: log("BEGIN BALLS"); boolean cBallTotal = getInventory().getAmount("Cannonball") == 108; RS2Object furnace = objects.closest("Furnace"); RS2Widget smithFace = getWidgets().getWidgetContainingText(270, "How many"); if (furnace != null && furnace.interact("Smelt")) { sleep(3000); if (smithFace != null) { getKeyboard().pressKey(32); } new ConditionalSleep(25000, 5000){ @Override public boolean condition(){ getMouse().moveOutsideScreen(); return cBallTotal || getDialogues().isPendingContinuation(); } }.sleep(); } break; I have not had any issues with clicking timing or getting stuck. log("BEGIN BALLS"); RS2Object furnace = objects.closest("Furnace"); RS2Widget smithFace = getWidgets().getWidgetContainingText(270, "How many"); if (furnace != null && furnace.interact("Smelt")) { sleep(2000); if (!myPlayer().isAnimating() && smithFace != null) { getKeyboard().pressKey(32); new ConditionalSleep(30000, 5000) { @Override public boolean condition() throws InterruptedException { getMouse().moveOutsideScreen(); return getDialogues().isPendingContinuation() || !getInventory().contains("Steel bar") || !myPlayer().isAnimating(); } }.sleep(); } } break; Instead of this, what u can do, ur logic is a bit off here, if some1 or u started script with smith interface open, it would interact for no reason again with furnace, u can try using what i posted below, to fix this issue. if smithface is not null and is visible interact smith face or whatever else if furnace is not null and interact with furnace, sleep until widget x is not null and widget x is visible Quote Link to comment Share on other sites More sharing options...
JS3 Posted July 9, 2018 Author Share Posted July 9, 2018 (edited) On 7/8/2018 at 1:10 AM, progamerz said: log("BEGIN BALLS"); RS2Object furnace = objects.closest("Furnace"); RS2Widget smithFace = getWidgets().getWidgetContainingText(270, "How many"); if (furnace != null && furnace.interact("Smelt")) { sleep(2000); if (!myPlayer().isAnimating() && smithFace != null) { getKeyboard().pressKey(32); new ConditionalSleep(30000, 5000) { @Override public boolean condition() throws InterruptedException { getMouse().moveOutsideScreen(); return getDialogues().isPendingContinuation() || !getInventory().contains("Steel bar") || !myPlayer().isAnimating(); } }.sleep(); } } break; Instead of this, what u can do, ur logic is a bit off here, if some1 or u started script with smith interface open, it would interact for no reason again with furnace, u can try using what i posted below, to fix this issue. if smithface is not null and is visible interact smith face or whatever else if furnace is not null and interact with furnace, sleep until widget x is not null and widget x is visible Is that something I can add to the conditional sleep? Can I do if and else statements within there? One thing I was also considering was breaking up the Smithing case into 2 parts. First being interaction with the furnace and opening the widget. Then once that completes, have it complete the action and sleep until cannonball amount was met or pendingcontinuation or player is not animating. I've noticed with any changes I apply, I have a problem on the initial widget interaction, it will click furnace, see the widget, loop then click furnace again and finally interact. Other problem is, if I have cannonballs and steel bars in my inv, and it hits the Idle state, it will not come out of Idle to re-engage with the furnace/widget. Also, @progamerz I hit you up on discord if you can help. Thank you! Edited July 9, 2018 by m3JS Quote Link to comment Share on other sites More sharing options...
JS3 Posted July 10, 2018 Author Share Posted July 10, 2018 Updated OP and made changes to script based on previous recommendations and also attempting to improve overall! Quote Link to comment Share on other sites More sharing options...
progamerz Posted July 10, 2018 Share Posted July 10, 2018 On 7/6/2018 at 6:33 AM, m3JS said: if (smithFace.isVisible() && smithFace.interact()) { sleep(2500); getKeyboard().pressKey(32); } add a smithface not null, i am on phone can't write much atm.. Quote Link to comment Share on other sites More sharing options...