Jump to content

Explv

Scripter II
  • Posts

    2314
  • Joined

  • Last visited

  • Days Won

    6
  • Feedback

    100%

Everything posted by Explv

  1. Items on the ground are GroundItems not RS2Objects. So to get the bones you need to do: GroundItem bones = getGroundItems().closest("Bones"); To check if your player is attacking something you can do: if(myPlayer().getInteracting() != null) Or this may work too: getCombat().isFighting() Also FYI you don't need a separate variable for each target NPC. You can get the closest out of all of them with one statement: NPC enemy = S.getNpcs().closest("Chicken", "Cow", "Cow calf"); But you may also want to check that those npcs are not under attack themselves, and that they are not dead. Perhaps something like: NPC enemy = getNpcs().closest(new NameFilter<>("Chicken", "Cow", "Cow calf"), npc -> !npc.isUnderAttack() && npc.getHealthPercent() > 0);
  2. I think that your portal area checks should not be inside the bank area check. Perhaps if you cleaned up the script a bit, you could more easily identify the issues: import org.osbot.rs07.api.map.Area; 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; @ScriptManifest(author = "Explv", name = "Wine Drinker", info = "Drinks Wine", logo = "", version = 0.1) public class WineDrinker extends Script { private enum State { BANKING, DRINKING, WALKING_TO_BANK, WALKING_TO_PORTAL, WALKING_TO_COMBAT, TELEPORTING } private final Area portalArea = new Area(0, 0, 0, 0), bankArea = new Area(0, 0, 0, 0), spawnArea = new Area(0, 0, 0, 0), combatArea = new Area(0, 0, 0, 0); @Override public int onLoop() throws InterruptedException { switch (getState()){ case BANKING: bank(); break; case DRINKING: drink(); break; case WALKING_TO_BANK: getWalking().webWalk(bankArea); break; case WALKING_TO_PORTAL: getWalking().webWalk(portalArea); break; case WALKING_TO_COMBAT: getWalking().webWalk(combatArea); break; case TELEPORTING: teleport(); break; } return random(200, 300); } private State getState() { if(!getInventory().contains("Jug of wine")){ return bankArea.contains(myPosition()) ? State.BANKING : State.WALKING_TO_BANK; } if(spawnArea.contains(myPosition())) return State.WALKING_TO_COMBAT; if(combatArea.contains(myPosition())) return State.DRINKING; return portalArea.contains(myPosition()) ? State.TELEPORTING : State.WALKING_TO_PORTAL; } private void teleport(){ if(getObjects().closest("Free-for-all portal").interact("Enter")){ new ConditionalSleep(5000) { @Override public boolean condition() throws InterruptedException { return !portalArea.contains(myPosition()); } }.sleep(); } } private void bank() throws InterruptedException { if(!getBank().isOpen()) { openBank(); } else if(!getInventory().isEmptyExcept("Jug of wine")) { getBank().depositAllExcept("Jug of wine"); } else if(!getInventory().contains("Jug of wine")){ if(getBank().contains("Jug of wine")) getBank().withdrawAll("Jug of wine"); else stop(); } } private void openBank() throws InterruptedException { if(getBank().open()){ new ConditionalSleep(5000) { @Override public boolean condition() throws InterruptedException { return getBank().isOpen(); } }.sleep(); } } private void drink() { if (getSkills().getStatic(Skill.HITPOINTS) - getSkills().getDynamic(Skill.HITPOINTS) > 11) { getInventory().getItem("Jug of wine").interact("Drink"); } } }
  3. Well the only reason that log statement wouldn't work is if your player is not in the area. Feel free to pm me in the chatbox and I can take a look over teamviewer
  4. Try and use a different area, it might be that the one you took from the snippet is incorrect. You can use my map to help you: http://explv.github.io/
  5. He didn't make an instance of Player, he just stored it. That's not the issue
  6. In the future, when posting to the scripting help section, please use the code tags. It is the blue button that looks like: < > Are you sure your player is in one of those areas? What is the code after, that does work?
  7. You are using Intellij Form Designer though right? private JPanel panel; If that JPanel is not bound to the JPanel in Intelij Form Designer, then when you call: add(panel); It will throw a NullPointerException.Here is a graphical example of what I meant in my previous comment. Firs you have to provide a name for the top level JPanel in the .form view: Then in the bound Java class with the same name you do: import javax.swing.*; public class GUI extends JFrame { private JPanel mainPanel; public GUI(){ add(mainPanel); setTitle("Whatever"); setVisible(true); } } This code works perfectly fine.Don't forget you will also need to set a preferred size on your JFrame otherwise it will be very small: import javax.swing.*; import java.awt.*; public class GUI extends JFrame { private JPanel mainPanel; public GUI(){ add(mainPanel); setTitle("Whatever"); setVisible(true); setPreferredSize(new Dimension(400, 400)); } } One more important thing.If you are uploading this script to the SDN, and you are using Intellij Form Designer, you will need to make Intellij compile the .form into Java code in your class. If you don't do this, when you copy over your GUI class file, none of your GUI code will be there, and it will break. To do this you need to go to: File -> Settings -> Editor -> GUI Designer And change the option "Generate GUI into:"'s value to Java source code. And then make the project
  8. Can you post your GUI code?
  9. I need more information about the error, what line number it was thrown on, what threw it etc.
  10. Firstly I am not sure that your script even works? You have created a variable GroundItem arrows; And you set its value to the closest arrows ground item: this.arrows = (GroundItem)this.groundItems.closest(new String[]{"Adamant arrow"}); You only need to use this. to refer to a variable in the current class, if there is another variable in the method with the same name. I am not sure why you are casting to GroundItem here because the method already returns a GroundItem. I am also not sure why you are using a String[] with one value, rather than just using a String. Perhaps you decompiled this from someone else's script? You then only pick up these arrows if there are < 25 of them: if(this.arrows.getAmount() <25 && this.arrows != null ...) Which will also throw a NullPointerException by the way, as you are calling getAmount() before checking if it is null. Finally, you walk to the bank when the amount of arrows on the ground is >= 100: if (this.arrows.getAmount() >= 100) getWalking().webWalk(edgevilleBank); I also don't understand why you are always web walking to the bank. You only need to do that if you are not already in the bank. The web walking may also fail, which will lead to your calls to getBank().open() etc. throwing errors. You are also not sleeping after calling getBank().open or after taking the arrows, which will result in a lot of spam clicking. None of this code makes any sense, and I would be surprised if it has been working at all for you. What you really want to be doing, is checking how many arrows you have in your Inventory. If you have more than 100 arrows in your inventory, the you want to bank. If there are any amount of arrows on the ground, then you want to pick them up. With regards to walking to find arrows, you can just web walk to random positions within the area you created, and stop walking if there are arrows on the ground. I have written an untested example and have added comments to it, to try and show you how this could be done: import org.osbot.rs07.api.map.Area; import org.osbot.rs07.api.map.Position; import org.osbot.rs07.api.map.constants.Banks; import org.osbot.rs07.api.model.GroundItem; import org.osbot.rs07.api.webwalk.INodeRouteFinder; import org.osbot.rs07.event.WebWalkEvent; import org.osbot.rs07.script.Script; import org.osbot.rs07.script.ScriptManifest; import org.osbot.rs07.utility.Condition; import org.osbot.rs07.utility.ConditionalSleep; import java.awt.*; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.URL; import java.net.URLConnection; import java.util.Optional; @ScriptManifest(author = "Explv", name = "Adamant Arrow Wildy Looter", info = "Loots adamant arrows in the Wilderness", version = 0.1, logo = "") public class WildyLooter extends Script { // This is an enum of all the possible states of the script private enum State { FIND_LOOT, LOOTING, BANKING, WALKING_TO_WILDERNESS, WALKING_TO_BANK } private final Area wilderness = new Area(3070, 3527, 3100, 3548); private final int adamantArrowID = 890; private int adamantArrowPrice = -1; private long prevArrowCount; // Stores the amount of arrows in the inventory private long arrowCounter; // Stores the amount of arrows collected private long startTime; /* The INoderouteFinder is what web walking uses to find routes, you need to create one of these to use custom web walking events. Only create this ONCE, it is very expensive to create. */ private INodeRouteFinder routeFinder; @Override public void onStart() { // When the script starts, an instance of INodeRouteFinder is created, for the custom web walk event routeFinder = INodeRouteFinder.createAdvanced(); // When the script starts, set the prevArrowCount to the amount of arrows in the inventory prevArrowCount = getInventory().getAmount("Adamant arrow"); startTime = System.currentTimeMillis(); adamantArrowPrice = getPrice(adamantArrowID); // get the price of adamant arrows } @Override public int onLoop() throws InterruptedException { // This line makes sure that the route finder is created, before we continue with the script if (routeFinder == null) return 100; /* A switch statement, is just like having multiple if else statements, where we are only checking the value on one variable */ switch (getState()) { // get the result of the getState() method case FIND_LOOT: findLoot(); // when the value is FIND_LOOT, call the findLoot() method (random walk) break; case LOOTING: loot(); // when the value is LOOTING, call the loot method (pick up arrows) break; case BANKING: bank(); // when the value is BANKING, perform the banking break; case WALKING_TO_WILDERNESS: // TODO: I'm not sure that web walking to the wilderness will even work, you may need to make a custom method for this getWalking().webWalk(wilderness); break; case WALKING_TO_BANK: getWalking().webWalk(Banks.EDGEVILLE); break; } return random(200, 300); } // This method returns what State the script is in at the current point in time. private State getState() { // If there are at least 100 Adamant arrows in the inventory if (getInventory().getAmount("Adamant arrow") >= 100) { // If we are in the bank, then perform banking, otherwise, walk to the bank return Banks.EDGEVILLE.contains(myPosition()) ? State.BANKING : State.WALKING_TO_BANK; } // We do not have 100 Adamant arrows in the inventory so: // If the player is not in the wilderness, walk there if (!wilderness.contains(myPosition())) return State.WALKING_TO_WILDERNESS; // If there are Adamant arrows on the ground, pick them up if (getGroundItems().closest("Adamant arrow") != null) return State.LOOTING; // There are no Adamant arrows on the ground, so randomly walk until we find some return State.FIND_LOOT; } // This method randomly walks around the wilderness, looking for arrows private void findLoot() { // Here we try and get a Position which is inside the wilderness area, and at least 20 tiles from the player final Optional<Position> randomDestination = wilderness.getPositions().stream().filter(position -> getMap().distance(position) >= 20).findAny(); // If we found a position that is at least 20 tiles away if (randomDestination.isPresent()) { // Create a custom WebWalkEvent, using the routefinder we created, and with the position as its destination final WebWalkEvent webWalkEvent = new WebWalkEvent(routeFinder, randomDestination.get()); // Set the break condition of the event to stop walking when there are Adamant arrows on the ground webWalkEvent.setBreakCondition(new Condition() { @Override public boolean evaluate() { return getGroundItems().closest("Adamant arrow") != null; } }); // Start web walking execute(webWalkEvent); } } // This method picks up Adamant arrows from the ground private void loot() { // Find the closest Adamant arrows final GroundItem adamantArrows = getGroundItems().closest("Adamant arrow"); // If we found some, and we successfully perform the interaction "Take" if (adamantArrows != null && adamantArrows.interact("Take")) { // Sleep for 5 seconds or until the arrows no longer exist (Either we picked them up, or someone else did) new ConditionalSleep(5000) { @Override public boolean condition() throws InterruptedException { return !adamantArrows.exists(); } }.sleep(); updateArrowCount(); // Update the arrow counter } } // This method updates the arrow counter; private void updateArrowCount() { long arrowInvcount = getInventory().getAmount("Adamant arrow"); arrowCounter += (arrowInvcount - prevArrowCount); prevArrowCount = arrowInvcount; } // This method performs the banking private void bank() throws InterruptedException { if (!getBank().isOpen()) openBank(); // If the bank isn't open, open it else if(!getInventory().isEmpty() && getBank().depositAll()){ // Otherwise, the bank is open, so deposit everything prevArrowCount = 0; // Reset inventory arrow amount to 0 (we just deposited them) } } // Custom method for opening the bank (with a sleep to avoid spam clicking) private void openBank() throws InterruptedException { // If we successfully performed the open bank interaction if (getBank().open()){ // Sleep for 5 seconds, or until the bank is open new ConditionalSleep(5000) { @Override public boolean condition() throws InterruptedException { return getBank().isOpen(); } }.sleep(); } } @Override public void onPaint(final Graphics2D g) { Font font1 = new Font("Arial", 0, 12); Color color1 = new Color(255, 255, 255, 255); g.setFont(font1); g.setColor(color1); g.drawString("Runtime: " + formatTime(System.currentTimeMillis() - startTime), 8, 335); g.drawString("Arrows collected: " + arrowCounter, 8, 350); if (adamantArrowPrice > -1) { g.drawString("Arrow price: " + adamantArrowPrice, 8, 370); g.drawString("Profit: " + formatValue(adamantArrowPrice * arrowCounter), 8, 390); } } // Converts ms to a timestamp private String formatTime(long ms){ long s = ms / 1000, m = s / 60, h = m / 60, d = h / 24; s %= 60; m %= 60; h %= 24; return d > 0 ? String.format("%02d:%02d:%02d:%02d", d, h, m, s) : h > 0 ? String.format("%02d:%02d:%02d", h, m, s) : String.format("%02d:%02d", m, s); } // Converts a value to m or k private String formatValue(long v){ return (v > 1_000_000) ? String.format("%.2fm", (double) (v / 1_000_000)) : (v > 1000) ? String.format("%.1fk", (double) (v / 1000)) : v + ""; } // Gets the price of an item from the rsbuddy api private int getPrice(int id){ try { URL url = new URL("http://api.rsbuddy.com/grandExchange?a=guidePrice&i=" + id); URLConnection con = url.openConnection(); con.setUseCaches(true); BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream())); String[] data = br.readLine().replace("{", "").replace("}", "").split(","); return Integer.parseInt(data[0].split(":")[1]); } catch(Exception e){ log(e); } return -1; } @Override public void onExit(){ routeFinder = null; } } An explanation of this: If there are at least 100 Adamant arrows in the inventory: If the player is in the bank: If the bank is not open: Attempt to open it Sleep until it is open Else: Deposit everything Else: Walk to the bank Else if the player is not in the wilderness: Walk there Else if there are any Adamant arrows on the ground: Attempt to take them Sleep until the arrows no longer exist Else: Randomly walk until there are some Adamant arrows on the ground
  11. Yes, things like NullPointerExceptions will cause the script to freeze. Assuming that all your code does is getWorlds().hopToP2PWorld() or some similar method, then it looks like that is an issue with the world hopper, you can post it as a client bug here: http://osbot.org/forum/forum/316-bug-reports/ As a temporary fix you could always write your own world hopper, or try and use this one (until it is fixed): http://osbot.org/forum/topic/73332-quick-hopper/?p=811421
  12. When you create a form in IntelliJ it also creates a binding class. For example if you named your form "GUI" there will also be a Java class called "GUI" that is created. In the form view you will see that the there is a top level container, which is a JPanel. The first thing to do is name this JPanel, you can call it "mainPanel" or something like that. Then make the binding class extend JFrame. JFrame is the main window for a swing GUI. Your GUI class should look something like: public class GUI extends JFrame { JPanel mainPanel; // some other variables } Now, you will need to add the JPanel (mainPanel) that you created in the form view, to this gui: public class GUI extends JFrame { JPanel mainPanel; // some other variables public GUI(){ add(mainPanel); } } Now, in your script when you want to display this GUI you can simply do: @ScriptManifest(...) public class YourScript extends Script { private GUI gui; @Override public void onStart() { gui = new GUI(); gui.setVisible(true); } @Override public int onLoop() throws InterruptedException { return 0; } @Override public void onExit() { if(gui != null) { gui.setVisible(false); gui.dispose(); } } }
  13. You could do it like this, with a relative path: Create a path from the portal to the room e.g. List<Position> path = new ArrayList<>(); path.add(new Position(x, y, z)); path.add(new Position(x, y, z)); And at at the same time that you made this path store the position of the portal e.g. Position portalPos = new Position(0,0,0); Then in your script when you enter the house do something like: Position currentPortalPos = getObjects().closest("portal").getPosition(); int diffX = portalPos.getX() - currentPortalPos.getX(); int diffY = portalPos.getY() - currentPortalPos.getY(); for(int i = 0; i < path.length; i++) { path.set(i, new Position(path.get(i).getX() - diffX, path.get(i).getY() - diffY, path.get(i).getZ()); } And then finally walk the path getWalking().walkPath(path); Either that, or try and walk to the room using an object e.g. getWalking().walk(getObjects().closest("whatever"));
  14. I believe some areas in runescape are dynamic, and so using areas or fixed positions will not help you. You could either construct a relative path to wherever you are trying to walk to, or not use positions / areas at all
  15. I'm not sure what you mean, can you show me your code?
  16. You could so something like: private void clickInSamePlace(final Entity entity){ if(!getMouse().isOnCursor(entity)) entity.hover(); else getMouse().click(false); } Or if you want to control the speed of the clicking, or the above doesn't work you could do: private void clickInSamePlace(final Entity entity) throws InterruptedException { if(!getMouse().isOnCursor(entity)) { entity.hover(); } else { final Point mousePos = getMouse().getPosition(); getBot().getMouseEventHandler().generateBotMouseEvent(BUTTON1, System.currentTimeMillis(), 0, mousePos.x, mousePos.y, 1, false, BUTTON1, true); sleep(500); // amount to sleep between clicks } } Or if you want to click super fast all in the same spot you can do: private void clickInSamePlace(final Entity entity, final int numClicks) { if(!getMouse().isOnCursor(entity)) { entity.hover(); } else { final Point mousePos = getMouse().getPosition(); getBot().getMouseEventHandler().generateBotMouseEvent(BUTTON1, System.currentTimeMillis(), 0, mousePos.x, mousePos.y, numClicks, false, BUTTON1, true); } }
  17. I made that post a little while ago, this should be a bit more readable for you: private void typeStringInstant(final String output){ for(int i = 0; i < output.length(); i ++) { final char c = output.charAt(i); getBot().getKeyEventHandler().generateBotKeyEvent(KEY_TYPED, System.currentTimeMillis(), 0, KeyEvent.getExtendedKeyCodeForChar(c), c); } getBot().getKeyEventHandler().generateBotKeyEvent(KEY_TYPED, System.currentTimeMillis(), 0, VK_ENTER, '\n', KEY_LOCATION_STANDARD); }
  18. You don't need to null check getStore()
  19. Thanks boss, I will make some tutorials in the near future
  20. Please in the future when posting in the scripting help section use the code tags, it is the blue button that looks like < > . With regards to your problem, I feel like you need to structure everything a bit better, adding ConditionalSleeps and more checks. With a better structure it will be easier to debug whatever problem you are having. Perhaps a structure like this would work better for you? (Sorry if there are any syntax errors) private enum State { WALKING_TO_STORE, BUYING, HOPPING } private final Area exampleStore = new Area(0, 0, 0, 0); private boolean shouldHop; @Override public int onLoop() throws InterruptedException { switch(getState()){ case WALKING_TO_STORE: getWalking().webWalk(exampleStore); break; case BUYING: buyItems(); break; case HOPPING: hopWorlds(); break; } return random(200, 300); } private State getState(){ if(!exampleStore.contains(myPosition())) return State.WALKING_TO_STORE; else if(shouldHop) return State.HOPPING; return State.BUYING; } private void buyItems() { if(!getStore().isOpen()) openStore(); else if(getStore().getAmount("Example item") > 0) buyAll("Example item"); else if(getStore().close()) shouldHop = true; } private boolean buyAll(final String itemName){ return getStore().buy(itemName, getStore().getAmount(itemName)); } private boolean openStore() { NPC example = npcs.closest("Example"); if(example != null && example.interact("Trade")) { new ConditionalSleep(5000) { @Override public boolean condition() throws InterruptedException { return getStore().isOpen(); } }.sleep(); return true; } return false; } private void hopWorlds() { if(getWorlds().hopToP2PWorld()) shouldHop = false; } Here is what this code does: While the script is running: If the player is not in the store: walk to the store Else, if the world hop flag has been set to true: Attempt to change worlds If the player has successfully changed worlds: Set the hop flag to false Else, if the store is not open: Attempt to open the store If the interaction was successful: sleep until the store is open Else the store is open, so if the store contains any of the item: Buy all of the item Else the store is open and doesn't contains any of the item so: Attempt to close the store If the interaction was successful: Sleep until the store is closed Set the hop flag to true If the getStore().isOpen() method is the issue, then consider writing your own, for example: private boolean isStoreOpen() { return getWidgets.getWidgetContainingText("some text found on the store interface") != null; }
  21. No you can use Positions. I only suggested that you use an Area so that you can determine if your player is in the kebab store. That Area consists of all the positions in the kebab store, so by calling the contains method with the player's position, you are effectively saying. "If my player is in the kebab store"
  22. Sorry I assumed kebabstore was an Area. If you are using a Position, I recommend you change it to this: private final Area kebabstore = new Area(3271, 3179, 3275, 3183); Also change getWalking().walk(kebabstore); To getWalking().webWalk(kebabstore);
  23. case BUY: if(!kebabstore.contains(myPosition()){ getWalking().walk(kebabstore); } else if(!getDialogues().inDialogue()){ npcs.closest("Karim").interact("Talk-to"); new ConditionalSleep(5000) { @Override public boolean condition() throws InterruptedException { return getDialogues().inDialogue(); } }.sleep(); } else if (dialogues.isPendingContinuation()) { dialogues.clickContinue(); sleep(random(700, 1000)); } else if (dialogues.isPendingOption()) { dialogues.selectOption("Yes please."); sleep(random(700, 1000)); } break; You only need to perform these actions when certain criteria are satisfied. E.g. you only want to walk to the kebab store if you aren't already there. You only want to talk to Karim if you aren't already in a dialogue etc.
  24. Explv

    Players

    Runescape uses non breaking spaces, so you need to replace them: player.getName().replace('\u00A0', ' ');
×
×
  • Create New...