Joseph Posted March 6, 2015 Share Posted March 6, 2015 (edited) i had a few people questioning how State-Node scripting is different from regular getState() the method getState() loops through an array of a type<?> and finds the one type<?> that returns true. getState(): ~every single time onLoop reloops. GetState() is called which then has to loop through his own array of types<?> ~so pretty much its a double consistently . onLoop will execute another getState() loop. State-Node ~every since time onLoop reloops. It refs back to the TaskTracker class. If the private field return null or false. It will loop and find the correct task. ~so pretty much it a double loop every so often. Whenever the current task is null or false A Scripting Example. I really did not type to as much but very informative. ps: i hope you like my convention of having many nested classes Also you could have the tracker class in a different place. I put it inside this class was for example purposes import org.osbot.rs07.script.Script; @ScriptManifest() public class Example extends Script { private Activity[] taskList = new Activity[] { new CutTree(), new Drop()}; private TaskTracker taskTracker; private Script script; @Override public void onStart() throws InterruptedException { this.script = this; this.taskTracker = new TaskTracker(taskList); } @Override public int onLoop() throws InterruptedException { /** onLoop() always loops * currentTask is null or false, we look for a new task. //we loop thought task array * if currentTask is true, we keep the same currentTask. //it doesnt loop, it has a valid task still * and we only repeat the run() method until boolean return false. * Now that currentTask is false we look for a new task. //we loop throught array * and it repeats. * * The taskTracker does all the work for you. */ Activity currentTask = this.taskTracker.getActive(); String status = currentTask.status(); currentTask.run(); return 1000; } private class CutTree implements Activity { @Override public String status() { return "Cut tree"; } @Override public boolean validate() throws InterruptedException { return !script.inventory.isFull(); } @Override public void run() throws InterruptedException { //if not animating //find tree. //cut it }} private class Drop implements Activity { @Override public String status() { return "Drop log"; } @Override public boolean validate() throws InterruptedException { return script.inventory.contains("log"); } @Override public void run() throws InterruptedException { //look for first item named log //if you dont want to keep it //drop it }} //does all the work for you public class TaskTracker { private Activity[] taskList; private Activity activeTask; public TaskTracker(Activity[] taskList) { this.taskList = taskList; } //return the stated task. Reloops if state return false or null. public Activity getActive() throws InterruptedException { if (this.activeTask == null || !this.activeTask.validate()) { for (Activity task: taskList) { if (task != null && task.validate()) { this.activeTask = task; break; } } } return this.activeTask; } //in case you want to force a new current task //you can set it null if you want to just it to reloop task. public void getAcitive(Activity task) { this.activeTask = task; }} } Edited March 6, 2015 by josedpay Quote Link to comment Share on other sites More sharing options...
milo1337 Posted March 6, 2015 Share Posted March 6, 2015 So what advantage does this give? Lower processing requirements? Or does it make it easier to refactor code? Or its modular so the task tracker allows for more dynamic options? Quote Link to comment Share on other sites More sharing options...
Lemons Posted March 6, 2015 Share Posted March 6, 2015 Only thing I would do different is to make the currentTask a field rather than in the onLoop. Other than that looks sweet, might add a priority system for like when you get into combat it won't continue trying to do the current task? Quote Link to comment Share on other sites More sharing options...
Joseph Posted March 6, 2015 Author Share Posted March 6, 2015 Only thing I would do different is to make the currentTask a field rather than in the onLoop. Other than that looks sweet, might add a priority system for like when you get into combat it won't continue trying to do the current task? im actually typing that up i have it in my head already.. So what advantage does this give? Lower processing requirements? Or does it make it easier to refactor code? Or its modular so the task tracker allows for more dynamic options? Lower processing requirements? yes Make the class more organized imagine my crafter script it has sub classes for every script mode. SO this helps me out a lot Quote Link to comment Share on other sites More sharing options...
Stesextro Posted March 25, 2015 Share Posted March 25, 2015 I am having a problem with my state node combat script. I have nodes for eating, attacking, and looting so far. It attacks perfectly fine, and eats when health goes below a certain %, but after it kills the monster it does not do anything. I am unsure if the problem lies in my attack node, or my node controller. Although I am assuming the problem is with the attack node. (Possibly not returning true? or getting stuck within the execute method). I will attach my Attack node source code to better help with debugging this issue. public class Attack extends Node { Constants c = new Constants(); NPC monster = sA.npcs.closest(" "); public Attack(Script sA) { super(sA); } @Override public String status() { return "Attacking!"; } @Override public boolean validate() throws InterruptedException { //If in area, and health is > 60, and inv contains lobs if (sA.inventory.contains(c.LOBSTER_ID) && sA.myPlayer().getHealth() > 60 && !sA.myPlayer().isUnderAttack()) { return true; } else { return false; } } @Override public boolean execute() throws InterruptedException { if (monster != null && monster.getHealth() > 0) { if (monster.isVisible()) { sA.camera.toEntity(monster); monster.interact("Attack"); sA.sleep(sA.random(1000, 3000)); } if (sA.myPlayer().isUnderAttack()) { return true; } } return false; } } Replaced the monster I am fighting with "monster", in order to keep some form of secrecy ;) Quote Link to comment Share on other sites More sharing options...
Joseph Posted March 26, 2015 Author Share Posted March 26, 2015 I am having a problem with my state node combat script. I have nodes for eating, attacking, and looting so far. It attacks perfectly fine, and eats when health goes below a certain %, but after it kills the monster it does not do anything. I am unsure if the problem lies in my attack node, or my node controller. Although I am assuming the problem is with the attack node. (Possibly not returning true? or getting stuck within the execute method). I will attach my Attack node source code to better help with debugging this issue. Replaced the monster I am fighting with "monster", in order to keep some form of secrecy sA.myPlayer().getHealth() > 60 this is what killing you because use the skill hp. method above only updated data when hp bar is visible i believe Quote Link to comment Share on other sites More sharing options...
Woody Posted April 11, 2015 Share Posted April 11, 2015 (edited) where's the 'Activity' class? I want to see how it's set up. EDIT: It's an interface like this? public interface Activity{ public abstract boolean activate(); public abstract void execute(); public abstract String status(); } Edited April 11, 2015 by Woody Quote Link to comment Share on other sites More sharing options...
Flamezzz Posted April 11, 2015 Share Posted April 11, 2015 Ye it is, public and abstract modifiers can be omitted in interface method declarations though Quote Link to comment Share on other sites More sharing options...
Joseph Posted April 11, 2015 Author Share Posted April 11, 2015 Ye it is, public and abstract modifiers can be omitted in interface method declarations though ;) where's the 'Activity' class? I want to see how it's set up. EDIT: It's an interface like this? public interface Activity{ public abstract boolean activate(); public abstract void execute(); public abstract String status(); } Quote Link to comment Share on other sites More sharing options...