pupu_pot Posted July 2 Share Posted July 2 (edited) was just wondering if you kind folks would double check my methods below. i have never coded a day in my life before last week, so this was put together with chatGPT along with trial and error. interested to see if you guys have any pointers, or notice anything I have going on here that might be a no-no. i used intelliJ IDEA community version, and right now I created everything under one class, but I think best practice might be to separate out main/mining/crafting classes. I have tested this just for 20 min or so and it seems to work well enough, but I would like to eventually incorporate the following things if the base methods are sound. -simple paint -additional random pauses or other anti-ban methods -GUI so that I can toggle some options upon selecting the script in my osbot selector -figure out how to get custom cursor and logo to work even though I already added them into a resource directory import org.osbot.rs07.api.model.Item; import org.osbot.rs07.api.model.RS2Object; import org.osbot.rs07.script.Script; import org.osbot.rs07.script.ScriptManifest; import org.osbot.rs07.utility.ConditionalSleep; @ScriptManifest(author = "pupupot", info = "Mines Amethyst crystals and crafts dart tips", name = "Amethyst Minecraft", version = 1.2, logo = "") public class AmethystMinecraft extends Script { private final int AMETHYST_X = 3008; private final int[] AMETHYST_Y = {9710, 9711, 9712}; // Y positions of amethyst crystals private final String AMETHYST_CRYSTALS_NAME = "Amethyst crystals"; private final String AMETHYST_NAME = "Amethyst"; private final String CHISEL_NAME = "Chisel"; @Override public void onStart() { log("Script started. Let's get this bag.");} @Override public int onLoop() throws InterruptedException { log("Looking for the purple shit to start mining."); // Check if inventory is full and craft dart tips if needed if (getInventory().isFull() || getEmptySlots() <= 2) { craftDartTips(); return 1000; // Wait for a second before checking again } // Check each Y position for amethyst crystals for (int y : AMETHYST_Y) { RS2Object amethyst = getObjects().closest(obj -> obj != null && obj.getName().equals(AMETHYST_CRYSTALS_NAME) && obj.getX() == AMETHYST_X && obj.getY() == y); if (amethyst != null && amethyst.isVisible()) { log("Found the purple shit at X=" + AMETHYST_X + ", Y=" + y); // Attempt to mine the amethyst if (amethyst.interact("Mine")) { log("Mining amethyst... Getting this money"); // Wait until the amethyst turns into "Empty wall" new ConditionalSleep(240000, 2000) { // 240,000 milliseconds (4 minutes) @Override public boolean condition() throws InterruptedException { return !amethyst.exists() || amethyst.getName().equals("Empty wall"); } }.sleep(); // Check if the amethyst was successfully mined if (!amethyst.exists() || amethyst.getName().equals("Empty wall")) { log("Bag secured at X=" + AMETHYST_X + ", Y=" + y); // Check inventory space and craft dart tips if needed if (getEmptySlots() <= 2) { craftDartTips(); } } else { log("Failed to mine amethyst at X=" + AMETHYST_X + ", Y=" + y); } } else { log("Failed to interact with amethyst at X=" + AMETHYST_X + ", Y=" + y); } // Exit loop once one amethyst is successfully mined break; } } return random(600, 700); // Return a short random delay before the next loop } private int getEmptySlots() { int count = 0; for (Item item : getInventory().getItems()) { if (item == null || item.getId() == -1) { count++; } } return count; } private void craftDartTips() throws InterruptedException { // Check if chisel and amethyst are in inventory if (getInventory().contains(CHISEL_NAME) && getInventory().contains(AMETHYST_NAME)) { log("We got the tools. Let's start the crafting process."); // Use chisel on amethyst if (getInventory().interact("Use", CHISEL_NAME)) { new ConditionalSleep(2000) { @Override public boolean condition() throws InterruptedException { return getInventory().isItemSelected(); } }.sleep(); if (getInventory().interact("Use", AMETHYST_NAME)) { log("Waiting for crafting interface to appear."); // Wait for crafting interface to appear new ConditionalSleep(5000) { @Override public boolean condition() throws InterruptedException { return getWidgets().isVisible(270, 17); // Interface 270, Component 17 is the dart tip selection } }.sleep(); // Select "Make Amethyst dart tip" option (4th option) if (getWidgets().isVisible(270, 17)) { log("Crafting interface visible. Selecting 'Amethyst dart tips' option."); getWidgets().interact(270, 17, "Make"); } else { log("Crafting interface not visible."); } // Wait for crafting to complete new ConditionalSleep(60000) { @Override public boolean condition() throws InterruptedException { return !getInventory().contains(AMETHYST_NAME); } }.sleep(); log("Crafted amethyst dart tips."); } else { log("Failed to use chisel on amethyst."); } } else { log("Failed to select chisel."); } } else { log("Cannot craft amethyst dart tips. Missing required items."); } } @Override public void onExit() { log("Script stopped. Later Nerd."); } } Edited July 2 by pupu_pot Quote Link to comment Share on other sites More sharing options...
Gunman Posted July 2 Share Posted July 2 @pupu_pot API already has a empty slots method getInventory().getEmptySlots(); Use ConditionalSleep2 at least over ConditionalSleep if not a custom sleep class. Empty wall part doesn't actually work I'm pretty sure // Wait until the amethyst turns into "Empty wall" new ConditionalSleep(240000, 2000) { // 240,000 milliseconds (4 minutes) @Override public boolean condition() throws InterruptedException { return !amethyst.exists() || amethyst.getName().equals("Empty wall"); } }.sleep(); Furthermore I recommend not using any AI assistance if you're trying to truly learn coding. If you're just slapping scripts together go for it. 1 Quote Link to comment Share on other sites More sharing options...
pupu_pot Posted July 2 Author Share Posted July 2 18 minutes ago, Gunman said: @pupu_pot API already has a empty slots method getInventory().getEmptySlots(); Use ConditionalSleep2 at least over ConditionalSleep if not a custom sleep class. Empty wall part doesn't actually work I'm pretty sure Furthermore I recommend not using any AI assistance if you're trying to truly learn coding. If you're just slapping scripts together go for it. Thanks for your input Gunman I wanted the crafting action to start whether the inv was full or if there was two or less empty slots, which is why I setup the -2 variable Can you elaborate on the pros and cons of ConditionalSleep2 vs ConditionalSleep vs a custom sleep class? The empty wall part does work, or at least it did when I tested it yesterday And yeah, I do get your point on the AI assistance, I'm definitely not fully understanding the code yet but for my first exposure it's definitely helping a lot. It took a lot of different prompts and trial and error to get to where I'm at, lol Quote Link to comment Share on other sites More sharing options...
Gunman Posted July 2 Share Posted July 2 1 hour ago, pupu_pot said: Can you elaborate on the pros and cons of ConditionalSleep2 vs ConditionalSleep vs a custom sleep class? CS2 is a one liner, functions the same just less code. And the only reason to use a custom sleep class would be to add other functionality like a reset condition. 1 Quote Link to comment Share on other sites More sharing options...
Khaleesi Posted July 2 Share Posted July 2 I did some modifications on some parts and made some things simpler I did not test run it though ^^ import org.osbot.rs07.api.model.RS2Object; import org.osbot.rs07.script.Script; import org.osbot.rs07.script.ScriptManifest; import org.osbot.rs07.utility.ConditionalSleep2; import java.util.Arrays; import java.util.List; @ScriptManifest(author = "pupupot", info = "Mines Amethyst crystals and crafts dart tips", name = "Amethyst Minecraft", version = 1.2, logo = "") public class AmethystMinecraft extends Script { private final int AMETHYST_X = 3008; private final List<Integer> AMETHYST_Y = Arrays.asList(9710, 9711, 9712); // Y positions of amethyst crystals private final String AMETHYST_NAME = "Amethyst"; @Override public void onStart() { log("Script started. Let's get this bag."); } @Override public int onLoop() throws InterruptedException { log("Looking for the purple shit to start mining."); if (getInventory().getEmptySlots() <= 2) { craftDartTips(); return 1000; } RS2Object amethyst = getObjects().closest(obj -> obj != null && obj.getName().equals("Amethyst crystals") && obj.getX() == AMETHYST_X && AMETHYST_Y.contains(obj.getY())); if (amethyst != null) { if (amethyst.interact("Mine")) { log("Mining amethyst... Getting this money"); ConditionalSleep2.sleep(240_000, () -> !amethyst.exists() || amethyst.getName().equals("Empty wall")); } } return random(600, 700); // Return a short random delay before the next loop } private void craftDartTips() throws InterruptedException { // Check if chisel and amethyst are in inventory String CHISEL_NAME = "Chisel"; if (!getInventory().contains(CHISEL_NAME) || !getInventory().contains(AMETHYST_NAME)) { log("Cannot craft amethyst dart tips. Missing required items."); return; } // Try to get Widget by Text or spellname as the ids can change sometimes, don;t know the widget root, but here is an example //getWidgets().getWidgetContainingAction(270, "Make"); if (getWidgets().isVisible(270, 17)) { //Could also press spacebar on keyboard with the Keyboard class if (getWidgets().interact(270, 17, "Make")) { ConditionalSleep2.sleep(60_000, () -> !getInventory().contains(AMETHYST_NAME)); } return; } if (!getInventory().isItemSelected()) { if (getInventory().interact("Use", CHISEL_NAME)) { ConditionalSleep2.sleep(2500, () -> getInventory().isItemSelected()); } } else { if (getInventory().interact("Use", AMETHYST_NAME)) { ConditionalSleep2.sleep(5_000, () -> getWidgets().isVisible(270, 17)); } } } @Override public void onExit() { log("Script stopped. Later Nerd."); } } 1 Quote Link to comment Share on other sites More sharing options...
pupu_pot Posted July 2 Author Share Posted July 2 40 minutes ago, Khaleesi said: I did some modifications on some parts and made some things simpler I did not test run it though ^^ Thanks, I will check it out! Do you guys develop code for a living and this is just a hobby for you? I've always been interested in the behind the scenes of these scripts Quote Link to comment Share on other sites More sharing options...
yfoo Posted July 2 Share Posted July 2 Why did you set only certain amethyst positions to be mine-able? private final List<Integer> AMETHYST_Y = Arrays.asList(9710, 9711, 9712); // Y positions of amethyst crystals Quote Link to comment Share on other sites More sharing options...
pupu_pot Posted July 2 Author Share Posted July 2 20 minutes ago, yfoo said: Why did you set only certain amethyst positions to be mine-able? private final List<Integer> AMETHYST_Y = Arrays.asList(9710, 9711, 9712); // Y positions of amethyst crystals idk, I liked the idea of sticking to that one section as that is what I would do if I were playing myself Quote Link to comment Share on other sites More sharing options...
Fanny Posted July 9 Share Posted July 9 I'm no expert, but I like to code everything thinking in loops instead of sequentially The main reason being; if you need to handle unexpected events, it is more difficult to implement this in sequential code You could still use craftDartTips() call on each loop, but the logic would be less sequential and more reactive to the situation Khal's example is great for example: loop1: is chisel selected? no: use chisel customsleep (till selected) return 0; loop2: is chisel selected? yes: use gem customsleep (till all crafted) return 0; Obviously with all the appropriate logic there too Scenarios: What if the bot misclicks? What if you get a random event that you want to interact with? i.e. Genie What if you are suddenly in combat? In these cases, since the loop will end quickly or immediately, the next loop with handle these scenarios with priority over the task you were performing Not saying those scenarios are relevant to this necessarily, but planning ahead? 1 Quote Link to comment Share on other sites More sharing options...