omni4life Posted August 12, 2015 Share Posted August 12, 2015 Hey guys, I'm just toying around with OSBot's API and Java in general trying to get a feel for everything. I don't have a huge amount of experience coding, only in MATLAB. I wrote this script last night with the help of Apaec's tutorial, however, it won't interact with the rocks. It drops perfectly fine, it just won't mine. On the paint, it is almost always on the "dropping" status until I manually override and mine, at which point it changes to "sleeping" as opposed to mining. All in all, I'm very confused and I'd love a second set of eyes to help my chase down my problem Sincerely, -Omni. import org.osbot.rs07.api.model.Entity; import org.osbot.rs07.script.Script; import org.osbot.rs07.script.ScriptManifest; import java.awt.*; import java.util.concurrent.TimeUnit; @ScriptManifest(author = "Omni", info = "Iron Powerminer", name = "Omni Miner", version = 1.0, logo = "") public class OmniMiner extends Script { private int [] targetRock = {13458, 13456}; private int oreMined = 0; private long timeBegan; private long timeRan; // DEBUG STATUS public static String status; // Paint Variables private final Color color1 = new Color(0, 102, 102); private final Color color2 = new Color(0, 0, 0); private final BasicStroke stroke1 = new BasicStroke(1); private final Font font1 = new Font("Arial", 1, 14); private final Font font2 = new Font("Arial", 1, 10); @Override public void onStart() { log("Omni Miner has begun. Please report any bugs to me via the forums"); status = "script starting"; timeBegan = System.currentTimeMillis(); } private enum State { MINE, DROP, SLEEP }; private State getState() { Entity rock = objects.closest(targetRock); // Dropping state if (!myPlayer().isAnimating() && !inventory.isEmptyExcept(1269)) return State.DROP; // Check if mining already if (myPlayer().isAnimating()) return State.SLEEP; // Mining State if (rock != null && !myPlayer().isAnimating()) return State.MINE; return State.SLEEP; } @Override public int onLoop() throws InterruptedException { switch (getState()) { case MINE: Entity rock = objects.closest(targetRock); if (!inventory.isEmpty() && !myPlayer().isAnimating()) { rock.interact("Mine"); status = "Mining"; } break; case DROP: inventory.dropAllExcept(1265, 1269); status = "Dropping"; sleep(random(200,300)); break; case SLEEP: sleep(random(200, 300)); status = "Sleeping"; break; } return random(200, 300); } @Override public void onExit() { log("Thanks for running Omni Miner."); } @Override public void onPaint(Graphics2D g) { timeRan = System.currentTimeMillis() - this.timeBegan; g.setColor(color1); g.fillRect(7, 458, 325, 16); g.setColor(color2); g.setStroke(stroke1); g.drawRect(7, 458, 325, 16); g.setColor(color1); g.fillRect(325, 345, 170, 129); g.setColor(color2); g.drawRect(325, 345, 170, 129); g.setFont(font1); g.drawString("Omni Miner V 1.01" , 329, 362); g.setFont(font2); g.drawString("Time Running: " + ft(timeRan), 329, 375); g.setFont(font2); g.drawString("Experience Gained:", 329, 387); g.setFont(font2); g.drawString("Ores mined: ", 329, 399); g.setFont(font2); g.drawString("Status: " + status, 329, 411); } private String ft(long duration) { String res = ""; long days = TimeUnit.MILLISECONDS.toDays(duration); long hours = TimeUnit.MILLISECONDS.toHours(duration) - TimeUnit.DAYS.toHours(TimeUnit.MILLISECONDS.toDays(duration)); long minutes = TimeUnit.MILLISECONDS.toMinutes(duration) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(duration)); long seconds = TimeUnit.MILLISECONDS.toSeconds(duration) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(duration)); if (days == 0) { res = (hours + ":" + minutes + ":" + seconds); } else { res = (days + ":" + hours + ":" + minutes + ":" + seconds); } return res; } } Quote Link to comment Share on other sites More sharing options...
RickyD Posted August 12, 2015 Share Posted August 12, 2015 (edited) Hey guys, I'm just toying around with OSBot's API and Java in general trying to get a feel for everything. I don't have a huge amount of experience coding, only in MATLAB. I wrote this script last night with the help of Apaec's tutorial, however, it won't interact with the rocks. It drops perfectly fine, it just won't mine. On the paint, it is almost always on the "dropping" status until I manually override and mine, at which point it changes to "sleeping" as opposed to mining. All in all, I'm very confused and I'd love a second set of eyes to help my chase down my problem Sincerely, -Omni. instead of !inventory.isEmptyExcept(1269) use inventory.isFull() And for if (rock != null && !myPlayer().isAnimating()) return State.MINE; return State.SLEEP; You cant return two states at once. Just use MINE in that one Add sleep in case MINE if its spamclicking Edited August 12, 2015 by RickyD Quote Link to comment Share on other sites More sharing options...
omni4life Posted August 12, 2015 Author Share Posted August 12, 2015 instead of !inventory.isEmptyExcept(1269) use inventory.isFull() And for if (rock != null && !myPlayer().isAnimating()) return State.MINE; return State.SLEEP; You cant return two states at once. Just use MINE in that one Add sleep in case MINE if its spamclicking I really appreciate you taking the time to help me. I made the changes you suggested, however, the Mine case still isn't running for whatever reason. I don't suppose you have any other ideas? If not, thanks for all your help anyway. My getState is now: private State getState() { Entity rock = objects.closest(targetRock); // Dropping state if (!myPlayer().isAnimating() && !inventory.isEmptyExcept(1269)) return State.DROP; // Check if mining already if (myPlayer().isAnimating()) return State.SLEEP; // Mining State if (rock != null && !myPlayer().isAnimating()) return State.MINE; else return State.SLEEP; } I put an else return State.Sleep in there because it was throwing me an error telling me it wanted a return null after return State.Mine without it. Quote Link to comment Share on other sites More sharing options...
RickyD Posted August 12, 2015 Share Posted August 12, 2015 (edited) private State getState() { Entity rock = objects.closest(targetRock); // Dropping state if(inventory.isFull()){ return State.DROP; }else{ if(myPlayer().isAnimating()){ return State.SLEEP; }else{ if(rock != null){ return State.MINE; }else{ return State.SLEEP; } } } } Edited August 12, 2015 by RickyD 1 Quote Link to comment Share on other sites More sharing options...
omni4life Posted August 12, 2015 Author Share Posted August 12, 2015 private State getState() { Entity rock = objects.closest(targetRock); // Dropping state if(inventory.isFull()){ return State.DROP; }else{ if(myPlayer().isAnimating()){ return State.SLEEP; }else{ if(rock != null){ return State.MINE; }else{ return State.SLEEP; } } } } That fixed it up perfectly, thank you very much. I'll keep toying around with it to get it perfect but I really appreciate the help Quote Link to comment Share on other sites More sharing options...
RickyD Posted August 12, 2015 Share Posted August 12, 2015 NP Quote Link to comment Share on other sites More sharing options...
Joseph Posted August 12, 2015 Share Posted August 12, 2015 The inventory doesn't always have to be full to drop Quote Link to comment Share on other sites More sharing options...
omni4life Posted August 12, 2015 Author Share Posted August 12, 2015 (edited) The inventory doesn't always have to be full to drop On that note, if I change the dropping method from is.Full to .isEmptyExcept, the script breaks again. It gets stuck in the 'dropping' status and doesn't mine still. Even when I change it to is.Full, it mines a full inventory successfully and drops the full load, but then doesn't resume. Also, one (hopefully) last question for anyone reading: Is there a limit radius command in OSBot? I'm mining in the middle of two rocks and I want it to wait if those two are exhausted until they respawn. Instead, it runs off to a very nearby rock, but it takes longer than waiting. Is there a command similar to "Entity rock = objects.closest" that is sort of a "Entity rock = objects.within2tiles" Do you have any advise about that? I honestly can't see where I've gone wrong. This is my updated code. import org.osbot.rs07.api.model.Entity; import org.osbot.rs07.api.ui.Skill; import org.osbot.rs07.script.Script; import org.osbot.rs07.script.ScriptManifest; import java.awt.*; import java.util.concurrent.TimeUnit; @ScriptManifest(author = "Omni", info = "Iron Powerminer", name = "Omni Miner", version = 1.0, logo = "") public class OmniMiner extends Script { private int [] targetRock = {13710}; private long timeBegan; private long timeRan; private int xpGained; private int xpPerHour; private int currentXP; private int currentLevel; private int beginningXP; private double nextLevelXP; private long timeTNL; private double xpTillNextLevel; private int OreMined = 0; final int[] XP_TABLE = { 0, 0, 83, 174, 276, 388, 512, 650, 801, 969, 1154, 1358, 1584, 1833, 2107, 2411, 2746, 3115, 3523, 3973, 4470, 5018, 5624, 6291, 7028, 7842, 8740, 9730, 10824, 12031, 13363, 14833, 16456, 18247, 20224, 22406, 24815, 27473, 30408, 33648, 37224, 41171, 45529, 50339, 55649, 61512, 67983, 75127, 83014, 91721, 101333, 111945, 123660, 136594, 150872, 166636, 184040, 203254, 224466, 247886, 273742, 302288, 333804, 368599, 407015, 449428, 496254, 547953, 605032, 668051, 737627, 814445, 899257, 992895, 1096278, 1210421, 1336443, 1475581, 1629200, 1798808, 1986068, 2192818, 2421087, 2673114, 2951373, 3258594, 3597792, 3972294, 4385776, 4842295, 5346332, 5902831, 6517253, 7195629, 7944614, 8771558, 9684577, 10692629, 11805606, 13034431, 200000000 }; // DEBUG STATUS public static String status; // Paint Variables private final Color color1 = new Color(0, 102, 102); private final Color color2 = new Color(0, 0, 0); private final BasicStroke stroke1 = new BasicStroke(1); private final Font font1 = new Font("Arial", 1, 14); private final Font font2 = new Font("Arial", 1, 10); @Override public void onStart() { log("Omni Miner has begun. Please report any bugs to me via the forums"); status = "script starting"; timeBegan = System.currentTimeMillis(); beginningXP = skills.getExperience(Skill.MINING); timeTNL = 0; } private enum State { MINE, DROP, SLEEP }; private State getState() { Entity rock = objects.closest(targetRock); // Dropping state if(!inventory.isEmptyExcept(1269)){ return State.DROP; }else{ if(myPlayer().isAnimating()){ return State.SLEEP; }else{ if(rock != null){ return State.MINE; }else{ return State.SLEEP; } } } } @Override public int onLoop() throws InterruptedException { switch (getState()) { case MINE: Entity rock = objects.closest(targetRock); if ((!inventory.isEmpty()) && !myPlayer().isAnimating()) { rock.interact("Mine"); status = "Mining"; sleep(random(4000,4500)); } break; case DROP: inventory.dropAllExcept(1265, 1269); status = "Dropping"; sleep(random(200,300)); break; case SLEEP: sleep(random(200, 300)); status = "Sleeping"; break; } return random(200, 300); } @Override public void onExit() { log("Thanks for running Omni Miner."); } @Override public void onPaint(Graphics2D g) { currentXP = skills.getExperience(Skill.MINING); currentLevel = skills.getStatic(Skill.MINING); xpGained = currentXP - beginningXP; xpPerHour = (int)( xpGained / ((System.currentTimeMillis() - this.timeBegan) / 3600000.0D)); nextLevelXP = XP_TABLE[currentLevel + 1]; xpTillNextLevel = nextLevelXP - currentXP; OreMined = xpGained / 35; if (xpGained >= 1) { timeTNL = (long) ((xpTillNextLevel / xpPerHour) * 3600000); } timeRan = System.currentTimeMillis() - this.timeBegan; g.setColor(color1); g.fillRect(7, 458, 325, 16); g.setColor(color2); g.setStroke(stroke1); g.drawRect(7, 458, 325, 16); g.setColor(color1); g.fillRect(325, 345, 170, 129); g.setColor(color2); g.drawRect(325, 345, 170, 129); g.setFont(font1); g.drawString("Omni Miner V 1.0" , 329, 362); g.setFont(font2); g.drawString("Time Running: " + ft(timeRan), 329, 375); g.setFont(font2); g.drawString("Experience Gained: " + xpGained, 329, 387); g.setFont(font2); g.drawString("TTL: " + ft(timeTNL), 329,399); g.setFont(font2); g.drawString("Ores mined: " + OreMined, 329, 411); g.setFont(font2); g.drawString("Status: " + status, 329, 423); } private String ft(long duration) { String res = ""; long days = TimeUnit.MILLISECONDS.toDays(duration); long hours = TimeUnit.MILLISECONDS.toHours(duration) - TimeUnit.DAYS.toHours(TimeUnit.MILLISECONDS.toDays(duration)); long minutes = TimeUnit.MILLISECONDS.toMinutes(duration) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(duration)); long seconds = TimeUnit.MILLISECONDS.toSeconds(duration) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(duration)); if (days == 0) { res = (hours + ":" + minutes + ":" + seconds); } else { res = (days + ":" + hours + ":" + minutes + ":" + seconds); } return res; } } Edited August 12, 2015 by omni4life Quote Link to comment Share on other sites More sharing options...
fixthissite Posted August 12, 2015 Share Posted August 12, 2015 Rather than manually typing out the experience table, you can use the formula Jagex uses to calculate it dynamically. Here's a little snippit if you want to use it in the future: public static int[] createTable(int level) { int[] table = new int[level]; for(int i=1, b=0; i < level; b += i + 300 * Math.pow(2, i / 7d), table[i] = i == 99? 200000000 : b/4, i++); return table; } 1 Quote Link to comment Share on other sites More sharing options...
omni4life Posted August 12, 2015 Author Share Posted August 12, 2015 (edited) Rather than manually typing out the experience table, you can use the formula Jagex uses to calculate it dynamically. Here's a little snippit if you want to use it in the future: public static int[] createTable(int level) { int[] table = new int[level]; for(int i=1, b=0; i < level; b += i + 300 * Math.pow(2, i / 7d), table[i] = i == 99? 200000000 : b/4, i++); return table; } Thanks heaps, I'll use that to neaten it up . I don't suppose you have any ideas regarding why it isn't executing properly? Sometimes it also gets stuck on 'starting script' status and doesn't proceed until I manually mine an ore at which point, it stops mining and is stuck in the 'dropping' state. The strange thing is, I think it may be tied to my paint. Prior to its addition, it actually all worked okay so perhaps I inadvertently tweaked something. Edited August 12, 2015 by omni4life Quote Link to comment Share on other sites More sharing options...
Merccy Posted August 13, 2015 Share Posted August 13, 2015 private State getState() { Entity rock = objects.closest(targetRock); // Dropping state if(inventory.isFull()){ return State.DROP; }else{ if(myPlayer().isAnimating()){ return State.SLEEP; }else{ if(rock != null){ return State.MINE; }else{ return State.SLEEP; } } } } You could also return State.DROP when there aren't any rocks available. 1 Quote Link to comment Share on other sites More sharing options...
omni4life Posted August 13, 2015 Author Share Posted August 13, 2015 You could also return State.DROP when there aren't any rocks available. I'd actually quite like to implement that, is there a way to limit the Entity = objects.clostest and set it within a limit of two tiles. I found in the API Entity Area(int x1, int y1, int x2, int y2), would I utilise that and set a square that contains the two rocks that I want to target? I'm not totally sure how to utilise it so I'd love any input anyone has. Quote Link to comment Share on other sites More sharing options...
Merccy Posted August 13, 2015 Share Posted August 13, 2015 (edited) I'd actually quite like to implement that, is there a way to limit the Entity = objects.clostest and set it within a limit of two tiles. I found in the API Entity Area(int x1, int y1, int x2, int y2), would I utilise that and set a square that contains the two rocks that I want to target? I'm not totally sure how to utilise it so I'd love any input anyone has. I saw you use object.closest but I think the correct way is to do getObjects().closest. You can also use the Objects object to find the rocks in an area with this. getObjects().closest(new Area(x1, y1, x2, y2), ids); You could also just use .closest like you already do and check if the distance is more than the maximum that you want. Edit: Same for inventory, use getInventory(). I would also recommend to always use brackets with your if statements. private State getState() { Entity rock = objects.closest(targetRock); // Dropping state if (!myPlayer().isAnimating() && !inventory.isEmptyExcept(1269)) { return State.DROP; } // Check if mining already if (myPlayer().isAnimating()) { return State.SLEEP; } // Mining State if (rock != null && !myPlayer().isAnimating()) { return State.MINE; } return State.SLEEP; } Edited August 13, 2015 by Merccy Quote Link to comment Share on other sites More sharing options...
omni4life Posted August 13, 2015 Author Share Posted August 13, 2015 I saw you use object.closest but I think the correct way is to do getObjects().closest. You can also use the Objects object to find the rocks in an area with this. getObjects().closest(new Area(x1, y1, x2, y2), ids);You could also just use .closest like you already do and check if the distance is more than the maximum that you want.Edit: Same for inventory, use getInventory(). I would also recommend to always use brackets with your if statements. private State getState() { Entity rock = objects.closest(targetRock); // Dropping state if (!myPlayer().isAnimating() && !inventory.isEmptyExcept(1269)) { return State.DROP; } // Check if mining already if (myPlayer().isAnimating()) { return State.SLEEP; } // Mining State if (rock != null && !myPlayer().isAnimating()) { return State.MINE; } return State.SLEEP; } I'll definitely toy around with that and your dropping during null ore idea tomorrow when I get home. I really appreciate you and everyone else taking the time to answer simple questions for me, it's hugely helpful in wrapping my head around Java and the api Quote Link to comment Share on other sites More sharing options...
RickyD Posted August 13, 2015 Share Posted August 13, 2015 (edited) I'd actually quite like to implement that, is there a way to limit the Entity = objects.clostest and set it within a limit of two tiles. I found in the API Entity Area(int x1, int y1, int x2, int y2), would I utilise that and set a square that contains the two rocks that I want to target? I'm not totally sure how to utilise it so I'd love any input anyone has. in onLoop you could do something like: Position myPosition = new Position(myPlayer().getPosition()); Area myRadius = new Area(new Position(myPosition.getX()+2, myPosition.getY()+2,0), new Position(myPosition.getX()-2, myPosition.getY()-2,0)); the "myRadius" creates a square radius around you. I'm not sure how a mining script works so you have to figure out where you'd want to logically ask if a there are only null rocks in "myRadius" if(myRadius.contains(NULLROCK.getPosition)){ //all the rocks here are NULL, dropping inventory... } Edited August 13, 2015 by RickyD 1 Quote Link to comment Share on other sites More sharing options...