Jump to content
Frequently Asked Questions
  • Are you not able to open the client? Try following our getting started guide
  • Still not working? Try downloading and running JarFix
  • Help! My bot doesn't do anything! Enable fresh start in client settings and restart the client
  • How to purchase with PayPal/OSRS/Crypto gold? You can purchase vouchers from other users
  • Proper way to model state machines in Java?


    theholynoob

    Recommended Posts

    Hi,

    Working on my first script to automate chinning my pure at MM1 tunnels.

    I'm getting issues and I'm assuming it's due to my poor state management; I've read some posts that reference using an enum struct to manage state but I'm unfamiliar with Java. 

     

    Any tips on how I could improve this code; or what could be causing issues? (Still learning how to properly sleep until the appropriate time in a lot of situations).

    Also is there a slack/discord for other scripters? real time communication would be awesome.

    package main;
    
    import org.dreambot.api.methods.Calculations;
    import org.dreambot.api.methods.map.Area;
    import org.dreambot.api.methods.map.Tile;
    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.interactive.NPC;
    import org.dreambot.api.wrappers.widgets.WidgetChild;
    
    import java.awt.*;
    import java.util.HashMap;
    import java.util.HashSet;
    import java.util.Map;
    
    @ScriptManifest(author = "TheHolyNoob", category = Category.COMBAT, name = "MM1 Trainer_v2", version = 1.0)
    public class main extends AbstractScript {
        public int state;
        public static int minEatHp;
        public static int minDrinkHp;
        public static int refreshRate;
        public static String currentAction;
        public int currentTick;
        public boolean debug;
        public int remainingPots;
        public int remainingFood;
    
        public static final HashMap<Integer, String> STATES = new HashMap<Integer, String>(){{
            put(-2, "Testing");
            put(-1, "House");
            put(0, "Banking");
            put(1, "going to Gnome Stronghold");
            put(2, "going to Glider ....");
            put(3, "Training");
        }};
    
        public static final HashMap<String, Integer> INVENTORY = new HashMap<String, Integer>(){{
            put("Manta Ray", 9);
            put("Prayer potion(4)", 15);
            put("Ranging potion(4)", 2);
            put("Stamina potion(2)", 1);
            put("Teleport to House", 5);
        }};
    
        @Override
        public void onPaint(Graphics g){
            int x = 0;
            int y = 260;
            g.drawString("Current State: " + state + " | " + STATES.get(state), x, y);
            g.drawString("Current Action: " + currentAction, x, y+20);
            g.drawString("Tick: " + currentTick % 2, x, y+40);
            g.setColor(Color.CYAN);
    
            int debug_x_offset = 300;
            if(debug)
                g.drawString("Prayer Pots: " + remainingPots, x+debug_x_offset, y);
            g.drawString("Food: " + remainingFood, x+debug_x_offset, y+20);
        }
    
    
        @Override
        public void onStart() {
            debug = true;
            state = 2;
            minEatHp = 20;
            minDrinkHp = 26;
            currentTick = 0;
            refreshRate = Calculations.random(600, 800);
            currentAction = "Not assigned action....";
    
            super.onStart();
        }
    
        @Override
        public int onLoop() {
            if (state == 0)
                resupply();
    
            if (state == 1)
                if(walkToSpiritTree())
                    if(interactTree())
                        state = 2;
            if (state == 2)
                getToDario();
    
    
            currentTick++;
            return refreshRate;
        }
    
    
        public void getToDario() {
            Area outside = new Area(new Tile(2466, 3491, 0), new Tile(2466, 3491, 0));
            Area inside = new Area(new Tile(2465, 3493, 0), new Tile(2466, 3493, 0));
            currentAction = "to the tree";
    
            while (!outside.contains(getLocalPlayer())) {
                getWalking().walkExact(new Tile(2466, 3491, 0));
                sleep(Calculations.random(700*2, 1100*2));
            }
            sleep(Calculations.random(700*2, 1100*2));
            if (sleepUntil(() -> getLocalPlayer().isStandingStill(), Calculations.random(5000, 8000))) {
                GameObject TreeDoor = getGameObjects().closest(name -> name != null && name.getName().equals("Tree door"));
                TreeDoor.interact("Open");
            }
            if (sleepUntil(() -> inside.contains(getLocalPlayer()), 8000)) {
                GameObject TreeLadder = getGameObjects().closest(name -> name != null &&
                        name.getName().equals("Ladder"));
                TreeLadder.interact("Climb-up");
            }
    
            if (sleepUntil(() -> !getLocalPlayer().isAnimating(), 4000)) {
                Area daera = new Area(new Tile(2484, 3490, 1), new Tile(2480, 3486, 1));
                while (!daera.contains(getLocalPlayer())) {
                    getWalking().walk(daera.getRandomTile());
                }
            }
            if (sleepUntil(() -> getLocalPlayer().isStandingStill(), 10000)) {
                NPC daero = getNpcs().closest(name -> name.getName().equals("Daero"));
                daero.interact("Travel");
            }
    
            if (sleepUntil(() -> !getLocalPlayer().isAnimating(), 12000)) {
                NPC waydar = getNpcs().closest(name -> name.getName().equals("Waydar"));
                waydar.interact("Travel");
            }
    
            if (sleepUntil(() -> !getLocalPlayer().isAnimating(), 12000)) {
                NPC lumdo = getNpcs().closest(name -> name.getName().equals("Lumdo"));
                lumdo.interact("Travel");
            }
            sleep(Calculations.random(6000, 11000));
            state = 3;
        }
    
        public boolean walkToSpiritTree(){
            HashSet<Tile> tiles = new HashSet<>();
            tiles.add(new Tile(3183, 3508, 0));
            tiles.add(new Tile(3184, 3508, 0));
            tiles.add(new Tile(3183, 3507, 0));
            tiles.add(new Tile(3182, 3508, 0));
    
            while (!tiles.contains(getLocalPlayer().getTile())){
                getWalking().walk(new Tile(3183, 3508, 0));
                sleep(Calculations.random(2000, 3000));
            }
            return true;
    
        }
        public boolean interactTree(){
            GameObject SpiritTree = getGameObjects().closest(name -> name != null && name.getName().equals("Spirit tree"));
            currentAction = "Trying to use...." + SpiritTree.getName() + " | " + SpiritTree.getID();
            SpiritTree.interact("Travel");
            sleep(Calculations.random(2000, 3000));
            WidgetChild gnome_stronghold = getWidgets().getWidget(187).getChild(3).getChild(1);
            gnome_stronghold.interact("Continue");
    
            sleep(2000, 3000);
            return true;
        }
        public void resupply(){
            currentAction = "Banking";
    
            Tile closestBankLocation = getBank().getClosestBankLocation().getCenter();
            getWalking().walk(closestBankLocation);
            sleepUntil(() -> getLocalPlayer().isStandingStill(), Calculations.random(8000, 12000));
    
            NPC Banker = getNpcs().closest(npc -> npc != null && npc.hasAction("Bank"));
            Banker.interact("Bank");
    
            if(sleepUntil(() -> getBank().isOpen(), Calculations.random(6000, 8000)));
            getBank().depositAllItems();
    
            if(sleepUntil(() ->!getInventory().isFull(), 7000))
    
                for (Map.Entry itemSet : INVENTORY.entrySet()){
                    String item = (String)itemSet.getKey();
                    Integer amount = (Integer)itemSet.getValue();
                    currentAction = "Withdrawing " + amount + " " + item + "'s";
                    getBank().withdraw(item, amount);
                    sleep(Calculations.random(1500, 3000));
                }
    
            //TODO:
            //  Error handling. Not enough supplies
    
            if (getInventory().isFull())
                getBank().close();
            sleep(900);
            state = 1;
        }
    }

     

    Link to comment
    Share on other sites

    There's an edu channel, but it's more for education, not really for support.

    The "state" system is still basically the same with enums, you're just using enums as your 1, 2, 3, etc, to make it a bit more readable.

    And instead of it being an actual state machine where one state sends you to another, you run a check at the start of your onloop that sets the current state.

    so state = getState();
    where getState() goes through the conditionals to see which state it *should* be in.

    But really, what that method returns is all up to you. You could keep it state machine-esque and only check certain conditions if your current state is X.

     

    Enums are just

    enum State{
    WALKING,FIGHTING,DONATING_MONEY_TO_NEZZ;
    }
    then in your getState()
    return State.DONATING_MONEY_TO_NEZZ;

    Link to comment
    Share on other sites

    Archived

    This topic is now archived and is closed to further replies.

    ×
    ×
    • Create New...

    Important Information

    We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.