Jump to content
Parabot - Bot for Ikov, DreamScape, SoulPlay, RuneWild, and more
fryslan

[Parabot] Scripting Tutorial - Part 4 [Basic Woodcutter Task Framework]

Recommended Posts

Parabot Scripting Tutorial - Part 4 Basic Woodcutter Task FrameWork

Requirements:
    - IDEA (Intellij, Eclipse, Netbeans,.....), I'll be using Intellij. https://www.parabot.org/community/topic/14781-parabot-scripting-tutorial-part-1-setting-up-intellij/
    - Framework Knowledge. https://www.parabot.org/community/topic/14782-parabot-scripting-tutorial-part-2-frameworks/
    - Basic Java Knowlegde.

Introduction
In the last Tutorial https://www.parabot.org/community/topic/14784-parabot-scripting-tutorial-part-3-basic-woodcutter-looptask-framework/ I promised to explain how the task 
framework works so here it is.

Before starting the script you have to provide an list of strategy Objects to the bot, once that is done and the script is started it will loop through the strategies from top to bottom once it reaches and strategy from wicht the activate method matches the current state of the game it will run the execute method.
when the bot is finished doing that it will restart looping through the list.
%7Boption%7Dhttp://i.imgur.com/YDl9Y2Q.png

^thanks to JKetelaar

Script Structure
1.1 As introduced in the last tutorial for this Script i made an Script Structure aswell and you might see its slightly different from the previous one.

/*
  * Class Chop
  *     Check if we have Space for Logs
  *     Check if we aren't Chopping
  *     Check if a tree is around
  *         ^ true -> Chop tree
  *
  * Class Drop
  *     Check if we don't have Space for Logs
  *         ^ true -> Drop the Logs
 */

Task Framework

2.1 If you have Paid attention in the second Tutorial you know the basic Task skeleton, this is where we're going to start off.

package task_woodcutter;

import org.parabot.environment.scripts.Category;
import org.parabot.environment.scripts.Script;
import org.parabot.environment.scripts.ScriptManifest;
import org.parabot.environment.scripts.framework.Strategy;

import java.util.ArrayList;

/**
 * User: Fryslan
 */
@ScriptManifest(
        author = "Fryslan", //Your Name.
        name = "Basic Woodcutter", //Name of your Script.
        category = Category.WOODCUTTING, //Category Object depending on the purpose of your script.
        version = 1.0, //version of your Script.
        description = "Chops Trees and Drops the Logs.", //Description of what your Script does.
        servers = {"Ikov", "PKHonor"}) //Name(s) of the Server('s) this script can be used on.

public class WoodCutter extends Script {

    //List To Store the Strategies
    private ArrayList<Strategy> strategies;

    /*
      * Class Chop
      *     Check if we have Space for Logs
      *     Check if we aren't Chopping
      *     Check if a tree is around
      *         ^ true -> Chop tree
      *
      * Class Drop
      *     Check if we don't have Space for Logs
      *         ^ true -> Drop the Logs
     */

    @Override
    public boolean onExecute() {
        //Create an new List for storing the Strategies.
        strategies = new ArrayList<>();


        //Add the Strategies to the Bot
        provide(strategies);
        return true;
    }

    @Override
    public void onFinish() {
        System.out.println("Script Stopped");
    }
}

2.2 In the Script Structure you might have noticed we are using 2 different classes a Chop class and a Drop class, this works the same way as the Test class we made in the 2nd Tutorial.
So lets start off with the Chop class, you can see I added the Chop class to the strategies list and that will be automaticly followed by creating the Chop class.
I decided to create and private class so everything will be on one page for larger scripts I suggest to create an seperate class for it so you can have everything ordened neatly.

package task_woodcutter;

import org.parabot.environment.scripts.Category;
import org.parabot.environment.scripts.Script;
import org.parabot.environment.scripts.ScriptManifest;
import org.parabot.environment.scripts.framework.Strategy;

import java.util.ArrayList;

/**
 * User: Fryslan
 */
@ScriptManifest(
        author = "Fryslan", //Your Name.
        name = "Basic Woodcutter", //Name of your Script.
        category = Category.WOODCUTTING, //Category Object depending on the purpose of your script.
        version = 1.0, //version of your Script.
        description = "Chops Trees and Drops the Logs.", //Description of what your Script does.
        servers = {"Ikov", "PKHonor"}) //Name(s) of the Server('s) this script can be used on.

public class WoodCutter extends Script {

    //List To Store the Strategies
    private ArrayList<Strategy> strategies;

    /*
      * Class Chop
      *     Check if we have Space for Logs
      *     Check if we aren't Chopping
      *     Check if a tree is around
      *         ^ true -> Chop tree
      *
      * Class Drop
      *     Check if we don't have Space for Logs
      *         ^ true -> Drop the Logs
     */

    @Override
    public boolean onExecute() {
        //Create an new List for storing the Strategies.
        strategies = new ArrayList<>();

        //Create and Add the Chop class.
        strategies.add(new Chop());

        //Add the Strategies to the Bot
        provide(strategies);
        return true;
    }

    @Override
    public void onFinish() {
        System.out.println("Script Stopped");
    }

    private class Chop implements Strategy {
        @Override
        public boolean activate() {
            return false;
        }

        @Override
        public void execute() {

        }
    }
}

2.3 now we have created the Chop class its time to add the checks, how this works is we add the Checks to the activate method and when they all match the execture method gets activated:

 * Class Chop
      *     Check if we have Space for Logs
      *     Check if we aren't Chopping
      *     Check if a tree is around
      *         ^ true -> Chop tree
      *

2.4 As noted in the Script Structure we have to check for Inventory space, if we are chopping and if there is a tree around when this all is the case then we can chop a tree so lets first add the checks.

package task_woodcutter;

import org.parabot.environment.scripts.Category;
import org.parabot.environment.scripts.Script;
import org.parabot.environment.scripts.ScriptManifest;
import org.parabot.environment.scripts.framework.Strategy;
import org.rev317.min.api.methods.Inventory;
import org.rev317.min.api.methods.Players;
import org.rev317.min.api.methods.SceneObjects;
import org.rev317.min.api.wrappers.SceneObject;

import java.util.ArrayList;

/**
 * User: Fryslan
 */
@ScriptManifest(
        author = "Fryslan", //Your Name.
        name = "Basic Woodcutter", //Name of your Script.
        category = Category.WOODCUTTING, //Category Object depending on the purpose of your script.
        version = 1.0, //version of your Script.
        description = "Chops Trees and Drops the Logs.", //Description of what your Script does.
        servers = {"Ikov", "PKHonor"}) //Name(s) of the Server('s) this script can be used on.

public class WoodCutter extends Script {

    //List To Store the Strategies
    private ArrayList<Strategy> strategies;
    private final int[] TREE_IDS = {1276, 1278}; //These are normal Tree ID's.

    /*
      * Class Chop
      *     Check if we have Space for Logs
      *     Check if we aren't Chopping
      *     Check if a tree is around
      *         ^ true -> Chop tree
      *
      * Class Drop
      *     Check if we don't have Space for Logs
      *         ^ true -> Drop the Logs
     */

    @Override
    public boolean onExecute() {
        //Create an new List for storing the Strategies.
        strategies = new ArrayList<>();

        //Create and Add the Chop class.
        strategies.add(new Chop());

        //Add the Strategies to the Bot
        provide(strategies);
        return true;
    }

    @Override
    public void onFinish() {
        System.out.println("Script Stopped");
    }

    private class Chop implements Strategy {

        SceneObject tree;

        @Override
        public boolean activate() {
            tree = tree();
            return !Inventory.isFull() && Players.getMyPlayer().getAnimation() == -1 && tree != null;
        }

        @Override
        public void execute() {

        }
    }

    /**
     * Gets the nearest tree by de given ID's.
     * @return nearest tree by de given ID's.
     */
    private SceneObject tree(){
        //Loop through all loaded Objects and return the once that match the TREE_IDS.
        for(SceneObject tree : SceneObjects.getNearest(TREE_IDS)){
            //Check if the Object is around.
            if(tree != null){
                //Return the Tree Object.
                return tree;
            }
        }
        //Return null when no Object is Found.
        return null;
    }
}

2.5 You can see I added a little more than only the checks I also added an Local variable tree I did this becouse we need to use tree more than once and this prevents us from having to load all objects everytime we need to use the tree.I also added the tree() method to get the nearest tree this is all the same as we did in the previous tutorial.

 /**
     * Gets the nearest tree by de given ID's.
     * @return nearest tree by de given ID's.
     */
    private SceneObject tree(){
        //Loop through all loaded Objects and return the once that match the TREE_IDS.
        for(SceneObject tree : SceneObjects.getNearest(TREE_IDS)){
            //Check if the Object is around.
            if(tree != null){
                //Return the Tree Object.
                return tree;
            }
        }
        //Return null when no Object is Found.
        return null;
    }

2.6 Now its time for some action, we checked properly if we can chop the tree so now lets do this.
As you can see I added a Dynamic sleep after we are interacting with the tree this means the script will wait for your player to chop the tree.

package task_woodcutter;

import org.parabot.environment.api.utils.Time;
import org.parabot.environment.scripts.Category;
import org.parabot.environment.scripts.Script;
import org.parabot.environment.scripts.ScriptManifest;
import org.parabot.environment.scripts.framework.SleepCondition;
import org.parabot.environment.scripts.framework.Strategy;
import org.rev317.min.api.methods.Inventory;
import org.rev317.min.api.methods.Players;
import org.rev317.min.api.methods.SceneObjects;
import org.rev317.min.api.wrappers.SceneObject;

import java.util.ArrayList;

/**
 * User: Fryslan
 */
@ScriptManifest(
        author = "Fryslan", //Your Name.
        name = "Basic Woodcutter", //Name of your Script.
        category = Category.WOODCUTTING, //Category Object depending on the purpose of your script.
        version = 1.0, //version of your Script.
        description = "Chops Trees and Drops the Logs.", //Description of what your Script does.
        servers = {"Ikov", "PKHonor"}) //Name(s) of the Server('s) this script can be used on.

public class WoodCutter extends Script {

    //List To Store the Strategies
    private ArrayList<Strategy> strategies;
    private final int[] TREE_IDS = {1276, 1278}; //These are normal Tree ID's.

    /*
      * Class Chop
      *     Check if we have Space for Logs
      *     Check if we aren't Chopping
      *     Check if a tree is around
      *         ^ true -> Chop tree
      *
      * Class Drop
      *     Check if we don't have Space for Logs
      *         ^ true -> Drop the Logs
     */

    @Override
    public boolean onExecute() {
        //Create an new List for storing the Strategies.
        strategies = new ArrayList<>();

        //Create and Add the Chop class.
        strategies.add(new Chop());

        //Add the Strategies to the Bot
        provide(strategies);
        return true;
    }

    @Override
    public void onFinish() {
        System.out.println("Script Stopped");
    }

    private class Chop implements Strategy {

        SceneObject tree; // local variable to store the tree.

        @Override
        public boolean activate() {
            tree = tree(); // set the local Variable
            //Check if we need to chop the tree
            return !Inventory.isFull() && Players.getMyPlayer().getAnimation() == -1 && tree != null;
        }

        @Override
        public void execute() {
            //Chop the tree
            tree.interact(SceneObjects.Option.CHOP_DOWN);
            //Wait for the Player to chop the Tree
            Time.sleep(new SleepCondition() {
                @Override
                public boolean isValid() {
                    return Players.getMyPlayer().getAnimation() == -1;
                }
            }, 3000);
        }
    }

    /**
     * Gets the nearest tree by de given ID's.
     * @return nearest tree by de given ID's.
     */
    private SceneObject tree(){
        //Loop through all loaded Objects and return the once that match the TREE_IDS.
        for(SceneObject tree : SceneObjects.getNearest(TREE_IDS)){
            //Check if the Object is around.
            if(tree != null){
                //Return the Tree Object.
                return tree;
            }
        }
        //Return null when no Object is Found.
        return null;
    }
}

2.7 The last thing we have to do is handle the logs when our Inventory is full.
To do this we first have to create an new class like we did with the Chop class.
Lets call this one Drop.

package task_woodcutter;

import org.parabot.environment.api.utils.Time;
import org.parabot.environment.scripts.Category;
import org.parabot.environment.scripts.Script;
import org.parabot.environment.scripts.ScriptManifest;
import org.parabot.environment.scripts.framework.SleepCondition;
import org.parabot.environment.scripts.framework.Strategy;
import org.rev317.min.api.methods.Inventory;
import org.rev317.min.api.methods.Players;
import org.rev317.min.api.methods.SceneObjects;
import org.rev317.min.api.wrappers.SceneObject;

import java.util.ArrayList;

/**
 * User: Fryslan
 */
@ScriptManifest(
        author = "Fryslan", //Your Name.
        name = "Basic Woodcutter", //Name of your Script.
        category = Category.WOODCUTTING, //Category Object depending on the purpose of your script.
        version = 1.0, //version of your Script.
        description = "Chops Trees and Drops the Logs.", //Description of what your Script does.
        servers = {"Ikov", "PKHonor"}) //Name(s) of the Server('s) this script can be used on.

public class WoodCutter extends Script {

    //List To Store the Strategies
    private ArrayList<Strategy> strategies;
    private final int[] TREE_IDS = {1276, 1278}; //These are normal Tree ID's.

    /*
      * Class Chop
      *     Check if we have Space for Logs
      *     Check if we aren't Chopping
      *     Check if a tree is around
      *         ^ true -> Chop tree
      *
      * Class Drop
      *     Check if we don't have Space for Logs
      *         ^ true -> Drop the Logs
     */

    @Override
    public boolean onExecute() {
        //Create an new List for storing the Strategies.
        strategies = new ArrayList<>();

        //Create and Add the Chop class.
        strategies.add(new Chop());
        
        //Create and Add the Drop class
        strategies.add(new Drop());

        //Add the Strategies to the Bot
        provide(strategies);
        return true;
    }

    @Override
    public void onFinish() {
        System.out.println("Script Stopped");
    }

    private class Chop implements Strategy {

        SceneObject tree; // local variable to store the tree.

        @Override
        public boolean activate() {
            tree = tree(); // set the local Variable
            //Check if we need to chop the tree
            return !Inventory.isFull() && Players.getMyPlayer().getAnimation() == -1 && tree != null;
        }

        @Override
        public void execute() {
            //Chop the tree
            tree.interact(SceneObjects.Option.CHOP_DOWN);
            //Wait for the Player to chop the Tree
            Time.sleep(new SleepCondition() {
                @Override
                public boolean isValid() {
                    return Players.getMyPlayer().getAnimation() == -1;
                }
            }, 3000);
        }
    }

    /**
     * Gets the nearest tree by de given ID's.
     * @return nearest tree by de given ID's.
     */
    private SceneObject tree(){
        //Loop through all loaded Objects and return the once that match the TREE_IDS.
        for(SceneObject tree : SceneObjects.getNearest(TREE_IDS)){
            //Check if the Object is around.
            if(tree != null){
                //Return the Tree Object.
                return tree;
            }
        }
        //Return null when no Object is Found.
        return null;
    }

    private class Drop implements Strategy {
        @Override
        public boolean activate() {
            return false;
        }

        @Override
        public void execute() {

        }
    }
}

2.8 Now lets add checks to the Drop class using the Activate method.

 * Class Drop
      *     Check if we don't have Space for Logs
      *         ^ true -> Drop the Logs

As you can see we only have to check if we have no more space for logs

package task_woodcutter;

import org.parabot.environment.api.utils.Time;
import org.parabot.environment.scripts.Category;
import org.parabot.environment.scripts.Script;
import org.parabot.environment.scripts.ScriptManifest;
import org.parabot.environment.scripts.framework.SleepCondition;
import org.parabot.environment.scripts.framework.Strategy;
import org.rev317.min.api.methods.Inventory;
import org.rev317.min.api.methods.Players;
import org.rev317.min.api.methods.SceneObjects;
import org.rev317.min.api.wrappers.SceneObject;

import java.util.ArrayList;

/**
 * User: Fryslan
 */
@ScriptManifest(
        author = "Fryslan", //Your Name.
        name = "Basic Woodcutter", //Name of your Script.
        category = Category.WOODCUTTING, //Category Object depending on the purpose of your script.
        version = 1.0, //version of your Script.
        description = "Chops Trees and Drops the Logs.", //Description of what your Script does.
        servers = {"Ikov", "PKHonor"}) //Name(s) of the Server('s) this script can be used on.

public class WoodCutter extends Script {

    //List To Store the Strategies
    private ArrayList<Strategy> strategies;
    private final int[] TREE_IDS = {1276, 1278}; //These are normal Tree ID's.

    /*
      * Class Chop
      *     Check if we have Space for Logs
      *     Check if we aren't Chopping
      *     Check if a tree is around
      *         ^ true -> Chop tree
      *
      * Class Drop
      *     Check if we don't have Space for Logs
      *         ^ true -> Drop the Logs
     */

    @Override
    public boolean onExecute() {
        //Create an new List for storing the Strategies.
        strategies = new ArrayList<>();

        //Create and Add the Chop class.
        strategies.add(new Chop());

        //Create and Add the Drop class
        strategies.add(new Drop());

        //Add the Strategies to the Bot
        provide(strategies);
        return true;
    }

    @Override
    public void onFinish() {
        System.out.println("Script Stopped");
    }

    private class Chop implements Strategy {

        SceneObject tree; // local variable to store the tree.

        @Override
        public boolean activate() {
            tree = tree(); // set the local Variable
            //Check if we need to chop the tree
            return !Inventory.isFull() && Players.getMyPlayer().getAnimation() == -1 && tree != null;
        }

        @Override
        public void execute() {
            //Chop the tree
            tree.interact(SceneObjects.Option.CHOP_DOWN);
            //Wait for the Player to chop the Tree
            Time.sleep(new SleepCondition() {
                @Override
                public boolean isValid() {
                    return Players.getMyPlayer().getAnimation() == -1;
                }
            }, 3000);
        }
    }

    /**
     * Gets the nearest tree by de given ID's.
     * @return nearest tree by de given ID's.
     */
    private SceneObject tree(){
        //Loop through all loaded Objects and return the once that match the TREE_IDS.
        for(SceneObject tree : SceneObjects.getNearest(TREE_IDS)){
            //Check if the Object is around.
            if(tree != null){
                //Return the Tree Object.
                return tree;
            }
        }
        //Return null when no Object is Found.
        return null;
    }

    private class Drop implements Strategy {
        @Override
        public boolean activate() {
            return Inventory.isFull();
        }

        @Override
        public void execute() {

        }
    }
}

2.9 Since we did check if we need to drop the logs now lets finialiy drop them.
The way it did it is loop through all the item in you inventory if it matches the id of log, drop it.

package task_woodcutter;

import org.parabot.environment.api.utils.Time;
import org.parabot.environment.scripts.Category;
import org.parabot.environment.scripts.Script;
import org.parabot.environment.scripts.ScriptManifest;
import org.parabot.environment.scripts.framework.SleepCondition;
import org.parabot.environment.scripts.framework.Strategy;
import org.rev317.min.api.methods.Inventory;
import org.rev317.min.api.methods.Players;
import org.rev317.min.api.methods.SceneObjects;
import org.rev317.min.api.wrappers.Item;
import org.rev317.min.api.wrappers.SceneObject;

import java.util.ArrayList;

/**
 * User: Fryslan
 */
@ScriptManifest(
        author = "Fryslan", //Your Name.
        name = "Basic Woodcutter", //Name of your Script.
        category = Category.WOODCUTTING, //Category Object depending on the purpose of your script.
        version = 1.0, //version of your Script.
        description = "Chops Trees and Drops the Logs.", //Description of what your Script does.
        servers = {"Ikov", "PKHonor"}) //Name(s) of the Server('s) this script can be used on.

public class WoodCutter extends Script {

    //List To Store the Strategies
    private ArrayList<Strategy> strategies;
    private final int[] TREE_IDS = {1276, 1278}; //These are normal Tree ID's.
    private final int LOG_ID = 1511; //This is the Normal Log ID.


    /*
      * Class Chop
      *     Check if we have Space for Logs
      *     Check if we aren't Chopping
      *     Check if a tree is around
      *         ^ true -> Chop tree
      *
      * Class Drop
      *     Check if we don't have Space for Logs
      *         ^ true -> Drop the Logs
     */

    @Override
    public boolean onExecute() {
        //Create an new List for storing the Strategies.
        strategies = new ArrayList<>();

        //Create and Add the Chop class.
        strategies.add(new Chop());

        //Create and Add the Drop class
        strategies.add(new Drop());

        //Add the Strategies to the Bot
        provide(strategies);
        return true;
    }

    @Override
    public void onFinish() {
        System.out.println("Script Stopped");
    }

    private class Chop implements Strategy {

        SceneObject tree; // local variable to store the tree.

        @Override
        public boolean activate() {
            tree = tree(); // set the local Variable
            //Check if we need to chop the tree
            return !Inventory.isFull() && Players.getMyPlayer().getAnimation() == -1 && tree != null;
        }

        @Override
        public void execute() {
            //Chop the tree
            tree.interact(SceneObjects.Option.CHOP_DOWN);
            //Wait for the Player to chop the Tree
            Time.sleep(new SleepCondition() {
                @Override
                public boolean isValid() {
                    return Players.getMyPlayer().getAnimation() == -1;
                }
            }, 3000);
        }
    }

    /**
     * Gets the nearest tree by de given ID's.
     * @return nearest tree by de given ID's.
     */
    private SceneObject tree(){
        //Loop through all loaded Objects and return the once that match the TREE_IDS.
        for(SceneObject tree : SceneObjects.getNearest(TREE_IDS)){
            //Check if the Object is around.
            if(tree != null){
                //Return the Tree Object.
                return tree;
            }
        }
        //Return null when no Object is Found.
        return null;
    }

    private class Drop implements Strategy {
        @Override
        public boolean activate() {
            return Inventory.isFull();
        }

        @Override
        public void execute() {
            // Loop through all Inventory Items and Drop the once with Log ID.
            for(Item log : Inventory.getItems(LOG_ID)){
                //Check if Log Exists
                if(log != null){
                    //Drop the Log.
                    log.drop();
                    //Using a Static Sleep here for Tutorial sake, You can use a Dynamic one.
                    Time.sleep(1000);
                }
            }
        }
    }
}

I hope this helped you to understand the functioning of the Task framework.

If anything needs to be added please post below my next tutorial probably will be adding a paint to your script.

 

Edited by fryslan

Share this post


Link to post
Share on other sites

Great tutorial, the only problem I came across is when trying to run parabot at the end, it said 'Parabot has been updated, please reload the client' or something like that..

Just keeps doing that all the time, I also see in IntelliJ it says it has unsafe operations blocked, not sure if that has anything to do with it.

Share this post


Link to post
Share on other sites

Dang you got to work i see. :)

yup

Great tutorial, the only problem I came across is when trying to run parabot at the end, it said 'Parabot has been updated, please reload the client' or something like that..

Just keeps doing that all the time, I also see in IntelliJ it says it has unsafe operations blocked, not sure if that has anything to do with it.

Redownload the Parabot.jar

Share this post


Link to post
Share on other sites

Oops, my apologies. 

Yes I mean ikov, it keeps asking me to open the client again says it has been updated.

Yes , JKetelaar needs to update it.

You'll have to wait for that to be done.

Edited by fryslan

Share this post


Link to post
Share on other sites

I know this might be considered gravedigging, but was curious if you were planning on continuing this tutorial series. It's helped me a lot, and the only other thing I would like to know how to do is add paint, 2d or custom, and track stats such as xp/h xp total, and profit/h.

Share this post


Link to post
Share on other sites
3 hours ago, KyleHD said:

I know this might be considered gravedigging, but was curious if you were planning on continuing this tutorial series. It's helped me a lot, and the only other thing I would like to know how to do is add paint, 2d or custom, and track stats such as xp/h xp total, and profit/h.

Feel free to add me on skype and I can teach you a few things. Lordg.mage

Share this post


Link to post
Share on other sites

Hi, Napalm. Nice article, but I have a question about what you said about your original implementation.

This way, whenever a new page table was created, the physical address would be written into the page directory as part of the PDE, but it would also be mapped somewhere in virtual memory.
When you write PDE into the page directory, doesnt it means the page table already had been mapped in virtual memory? I dont understand what else you need to do besides writing PDE. Could you explain a bit little more? Thanks.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...