Captjayz 0 Posted June 9, 2023 Hello, i am fairly new at scripting, and I have tackled a couple easy projects which were a success (flax picker/banker, PlankMaker at woodcutting guild) so I have now wanted to try and tackle a more difficult project such as Blast Furnace. I have gotten the code so far to do what is required but after a second loop it seems to lose track, I believe its because I have hard coded many things and have not been checking the logic properly within the loop. it got so messy that I pretty much cannot find out what's going wrong where and how to fix it. Here is my notorious code. Keep in mind this script assumes you have ice gloves equipped with open coal bag in inventory and money already deposited in coffer before starting. Any insight or help is appreciated! import org.dreambot.api.methods.container.impl.Inventory; import org.dreambot.api.methods.container.impl.bank.Bank; import org.dreambot.api.methods.dialogues.Dialogues; import org.dreambot.api.methods.input.Keyboard; import org.dreambot.api.methods.interactive.GameObjects; import org.dreambot.api.methods.interactive.Players; import org.dreambot.api.methods.map.Area; import org.dreambot.api.methods.walking.impl.Walking; import org.dreambot.api.script.AbstractScript; import org.dreambot.api.script.Category; import org.dreambot.api.script.ScriptManifest; import org.dreambot.api.wrappers.interactive.GameObject; import org.dreambot.api.wrappers.items.Item; import static org.dreambot.api.methods.hint.HintArrow.getTile; import static org.dreambot.api.methods.interactive.Players.getLocal; import static org.dreambot.api.methods.walking.impl.Walking.walk; @ScriptManifest(category = Category.MINIGAME, name = "Blast Furnace Smelter", description = "Smelts Mithril bars at the Blast Furnace", author = "Capt Jay", version = 1.0) public class Main extends AbstractScript { private final int MITHRIL_ORE_ID = 447; private final int MITHRIL_BAR_ID = 2359; private final int COAL_ID = 453; private final int COAL_BAG_ID = 24480; private final int CONVEYOR_BELT_ID = 9100; private final int Dispenser_ID = 9092; private final int BANK_CHEST_ID = 26707; private final Area Conveyor_Belt_Tile = new Area(1941, 4967, 1940, 4967); private final Area BANK_AREA = new Area(1949, 4957, 1944, 4960); private final Area Dispenser_Area = new Area(1940, 4965, 1938, 4963); private boolean isInBank() { return BANK_AREA.contains(Players.getLocal()); } private boolean hasCoal() { return Inventory.contains(COAL_ID); } private boolean hasMithrilOreFull() { return Inventory.contains(MITHRIL_ORE_ID) && Inventory.get(MITHRIL_ORE_ID).getAmount() == 27; } private boolean FillCoalBag() { Item openCoalBag = Inventory.get(COAL_BAG_ID); return openCoalBag != null && openCoalBag.interact("Fill"); } private boolean EmptyCoalBag() { Item openCoalBag = Inventory.get(COAL_BAG_ID); return openCoalBag != null && openCoalBag.interact("Empty"); } private boolean interactWithConveyorBelt() { GameObject conveyorBelt = GameObjects.closest(CONVEYOR_BELT_ID); return conveyorBelt != null && conveyorBelt.interact("Put-ore-on"); } private boolean interactWithDispenser() { GameObject conveyorBelt = GameObjects.closest(Dispenser_ID); return conveyorBelt != null && conveyorBelt.interact("Take"); } @Override public int onLoop() { //For the Coal and Coal in bag run if (isInBank()) { if (!Bank.isOpen()) { GameObject bankChest = GameObjects.closest(BANK_CHEST_ID); if (bankChest != null && bankChest.interact("Use")) { sleepUntil(Bank::isOpen, 2000, 2000); } if (!hasCoal()) { FillCoalBag(); } if (!hasCoal()) { if (Bank.withdrawAll(COAL_ID)) { sleepUntil(() -> Inventory.contains(COAL_ID), 2000, 2000); } if (hasCoal()) { Bank.close(); sleepUntil(Bank::close, 2000, 2000); } if (Bank.close()) { Walking.walk(Conveyor_Belt_Tile.getRandomTile()); sleepUntil(() -> getTile().equals(Conveyor_Belt_Tile), 2000,2000); interactWithConveyorBelt(); sleepUntil(() -> (!hasCoal()), 4000, 4000); EmptyCoalBag(); sleepUntil(this::hasCoal, 2000, 2000); interactWithConveyorBelt(); sleepUntil(() -> !Inventory.contains(COAL_ID), 2000, 2000); walk(BANK_AREA.getRandomTile()); sleepUntil(() -> BANK_AREA.contains(getLocal()), 2000,2000); } } } } //now for the Mithril Ores and Coal in the Bag Run if (!isInBank()) { walk(BANK_AREA.getRandomTile()); sleepUntil(() -> BANK_AREA.contains(getLocal()), 2000,2000); } if (isInBank()) { if (!Bank.isOpen()) { GameObject bankChest = GameObjects.closest(BANK_CHEST_ID); if (bankChest != null && bankChest.interact("Use")) { sleepUntil(Bank::isOpen, 2000, 2000); } if (!hasMithrilOreFull()) { FillCoalBag(); } if (!hasMithrilOreFull()) { if (Bank.withdrawAll(MITHRIL_ORE_ID)) { sleepUntil(() -> Inventory.contains(MITHRIL_ORE_ID), 2000, 2000); } if (hasMithrilOreFull()) { Bank.close(); sleepUntil(Bank::close, 2000, 2000); } if (Bank.close()) { Walking.walk(Conveyor_Belt_Tile.getRandomTile()); sleepUntil(() -> getTile().equals(Conveyor_Belt_Tile), 2000, 2000); interactWithConveyorBelt(); sleepUntil(() -> !Inventory.contains(MITHRIL_ORE_ID), 4000, 4000); EmptyCoalBag(); sleepUntil(this::hasCoal, 2000, 2000); interactWithConveyorBelt(); sleepUntil(() -> !Inventory.contains(COAL_ID), 2000, 2000); walk(Dispenser_Area.getRandomTile()); sleepUntil(() -> Dispenser_Area.contains(getLocal()), 6000, 6000); interactWithDispenser(); sleepUntil(() -> Dialogues.inDialogue(), 3000, 3000); Dialogues.continueDialogue(); sleep(1000); // Wait for the dialogue to fully appear Keyboard.holdSpace(() -> false, 3000); sleepUntil(() -> Inventory.contains(MITHRIL_BAR_ID), 3000, 3000); if (Inventory.contains(MITHRIL_BAR_ID)) { walk(BANK_AREA.getRandomTile()); sleepUntil(() -> BANK_AREA.contains(getLocal()), 2000, 2000); } if (!Bank.isOpen()) { bankChest = GameObjects.closest(BANK_CHEST_ID); if (bankChest != null && bankChest.interact("Use")) { sleepUntil(Bank::isOpen, 2000, 2000); } if (Bank.isOpen()) { Bank.depositAll(2359); if (!Inventory.contains(MITHRIL_BAR_ID)){ FillCoalBag(); Bank.withdrawAll(MITHRIL_ORE_ID); sleepUntil(() -> Inventory.contains(MITHRIL_ORE_ID), 2000, 2000); if (hasMithrilOreFull()) { Bank.close(); sleepUntil(Bank::close, 2000, 2000); } if (Bank.close()) { Walking.walk(Conveyor_Belt_Tile.getRandomTile()); sleepUntil(() -> getTile().equals(Conveyor_Belt_Tile), 2000, 2000); interactWithConveyorBelt(); sleepUntil(() -> !Inventory.contains(MITHRIL_ORE_ID), 4000, 4000); EmptyCoalBag(); sleepUntil(this::hasCoal, 2000, 2000); interactWithConveyorBelt(); sleepUntil(() -> !Inventory.contains(COAL_ID), 2000, 2000); walk(Dispenser_Area.getRandomTile()); sleepUntil(() -> Dispenser_Area.contains(getLocal()), 6000, 6000); interactWithDispenser(); sleepUntil(() -> Dialogues.inDialogue(), 3000, 3000); Dialogues.continueDialogue(); sleep(1000); // Wait for the dialogue to fully appear Keyboard.holdSpace(() -> false, 3000); sleepUntil(() -> Inventory.contains(MITHRIL_BAR_ID), 3000, 3000); if (Inventory.contains(MITHRIL_BAR_ID)) { walk(BANK_AREA.getRandomTile()); sleepUntil(() -> BANK_AREA.contains(getLocal()), 2000, 2000); } if (!Bank.isOpen()) { bankChest = GameObjects.closest(BANK_CHEST_ID); if (bankChest != null && bankChest.interact("Use")) { sleepUntil(Bank::isOpen, 2000, 2000); } if (Bank.isOpen()) { Bank.depositAll(2359); } } } } } } } } } } return getSleepDelay(); } private int getSleepDelay() { return 200; } }
prechcik 34 Posted June 11, 2023 (edited) Hi! Welcome to Dreambot Scripting! It looks like You are on the right path! I would like to point out few things that could help You get where You want This function private boolean hasMithrilOreFull() { return Inventory.contains(MITHRIL_ORE_ID) && Inventory.get(MITHRIL_ORE_ID).getAmount() == 27; } will always fire false, as You're getting the first item from inventory with ID of mithril ore and getting it's amount - since ore's aren't stacable, it's amount will always be 1. To check how many items You have in Your inventory, You can use Inventory.count(itemName) which will return actual count of items. Second of all, and most importantly - You have to remember how Dreambot Script works in the core. Whenever You launch a script it fires it's methods like onStart(). Then it keeps launching onLoop() method, sleeping for an amount You return in that function. So always plan ahead of how the script should behave, usually from the end to the start. In this case You'll have to separate all the tasks and decide when to fire each one - right now the script will fire everything line by line, no matter what happens. So basically Blast furnace is getting ores from bank, running to conveyor, putting ores in, getting them out of dispenser and repeat. Let me quickly draw a sketch of how it could work public int onLoop() { if (Inventory.contains("Mithril ore")) { GameObject conveyor = GameObjects.closest("Conveyor belt"); // find closest conveyor if (conveyor != null && conveyor.interact("Put-ore-on")) { // if conveyor exists and successfuly interacted Sleep.sleepWhile(() -> Inventory.contains("Mithril ore"), 20 * 1000); // Sleep while has items or 20 seconds GameObject dispenser = GameObjects.closest("Dispenser"); if (dispenser != null && dispenser.interact("Take")) { Sleep.sleepUntil(Inventory.count("Mithril bar") > 26, 20 * 1000); // Sleep until got 27 bars or 20 seconds. } } } else { if (Bank.isOpen()) { if (Inventory.count("Mithril bar") > 0 && Bank.depositAll("Mithril bar")) Sleep.sleep(450, 750); // If has any bars, deposit and sleep for half a second if (Bank.withdrawAll("Mithril ore")) { // If successfuly withdrawn Sleep.sleep(750, 1500); // I always add a small sleep after withdrawing or actions so the script won't run too fast Bank.close(); // Close the bank after finishing } } else { if (Walking.shouldWalk()) Bank.open(); // Walking.shouldWalk to prevent spam clicking } } return Calculations.random(450,750) } This is just simple attempt from the top of my head of how I would implement such script. Of course I didnt add coal bag here and there are still some things missing, but I think this should point You to the correct path! Remember, script is always looped so always check for something first and sleep after that accordingly or return earlier so the script won't fire next lines of code unnecessary. Next things on there I would add Sleep.sleepUntil() functions after interacting to make sure we actually interacted - this function returns true or false depending on the condition You specified, so i.e if (object.interact() && Sleep.sleepUntil(() -> Players.getLocal().isAnimating(), 20 * 1000)) {} This will interact and sleep until player animates. If the player animates before 20 seconds, the function will return true and Your code inside that if condition will fire, otherwise it will return false, and the code inside won't be executed - very helpful to avoid double clicking of items or looping itself. Edited June 11, 2023 by prechcik
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now