Cosine
Members-
Posts
5 -
Joined
-
Last visited
-
Feedback
0%
Profile Information
-
Gender
Male
Recent Profile Visitors
The recent visitors block is disabled and is not being shown to other users.
Cosine's Achievements
Newbie (1/10)
1
Reputation
-
"Finished" my second script. Was hoping for feedback
Cosine replied to Cosine's topic in Scripting Help
Is there anything about my ConditionalSleep that you think is bad at all? I added those single line methods to try and increase the readability of my onLoop method. I could probably remove them without having big impact on the script readability, but I somewhat like being able to read a method name in a conditional and know instantly what it does/why it's needed -
"Finished" my second script. Was hoping for feedback
Cosine replied to Cosine's topic in Scripting Help
Great idea. Hadn't thought about that. I'll remove the camera checks too, thanks -
I've just finished writing my second script which kills cows in Falador farm. It supports healing with Salmon, banking when out of food, and opens the gate when its closed to get into the field. It was intended to train low level pures, which is why it needs Salmon in the bank as you will need to heal eventually. I was hoping to get some feedback on the code I've written to see if there's anything obvious that I'm doing poorly, or where I could optimize (not a Java programmer or experienced scripter). package core; import org.osbot.rs07.api.filter.Filter; import org.osbot.rs07.api.map.Area; import org.osbot.rs07.api.map.constants.Banks; import org.osbot.rs07.api.model.NPC; import org.osbot.rs07.api.model.RS2Object; import org.osbot.rs07.api.ui.Skill; import org.osbot.rs07.script.Script; import org.osbot.rs07.script.ScriptManifest; import java.awt.*; @ScriptManifest(name = "CowKiller", author = "Cosine", version = 1.0, info = "", logo = "") public class Main extends Script { private long startTime; private long runTime; private Area cowField = new Area(3043, 3313, 3021, 3298); private Area gateArea = new Area(3044, 3314, 3025, 3325); private int foodId = 329; @Override public void onStart() { startTime = System.currentTimeMillis(); getExperienceTracker().startAll(); } @Override public void onExit() { } @Override public int onLoop() throws InterruptedException { if (atCowField()) { if (lowHealth() && !eatFood()) { if (gateClosed()) { openGate(); } walkToBank(); } else if (inCombat()) { waitToAttack().sleep(); } else if (attackCow()) { waitToAttack().sleep(); } } else if (atBank()) { if (canHeal()) { eatFood(); } else if (spaceForFood()) { if (!withdrawFood()) { stop(false); //no food left, idle till logout } } else { walkToGate(); } } else if (spaceForFood()) { walkToBank(); } else if (atGate()) { if (gateExists()) { if (gateClosed()) { openGate(); } else { walkToCows(); } } } else { walkToGate(); } return(random(300, 400)); } //----- [START] AREA/WALKING METHODS [START] ----- private boolean atBank() { return Banks.FALADOR_EAST.contains(myPlayer()); } private boolean atCowField() { return cowField.contains(myPlayer()); } private boolean atGate() { return gateArea.contains(myPlayer()); } private void walkToBank() { getWalking().walk(Banks.FALADOR_EAST); } private void walkToCows() { getWalking().walk(cowField); } private void walkToGate() { getWalking().walk(gateArea); } private RS2Object fieldGate() { return getObjects().closest("Gate"); } private boolean gateClosed() { return fieldGate().hasAction("Open"); } private boolean gateExists() { return fieldGate() != null; } private void openGate() { if (!fieldGate().isVisible()) { camera.toEntity(fieldGate()); } fieldGate().interact("Open"); waitToAttack().sleep(); } //----- [END] AREA/WALKING METHODS [END] ----- //----- [START] BANKING/EATING METHODS [START] ----- private boolean foodInBank() { return getBank().contains(foodId); } private boolean withdrawFood() throws InterruptedException { if (getBank().open()) { if (foodInBank()) { getBank().withdraw(foodId, 28); return true; } } return false; } private boolean spaceForFood() { return getInventory().getEmptySlotCount() > 0; } private boolean fullHP() { return getSkills().getDynamic(Skill.HITPOINTS) == getSkills().getStatic(Skill.HITPOINTS); } private boolean lowHealth() { return myPlayer().getHealthPercent() < random(30, 50); } private boolean haveFood() { return getInventory().contains(foodId); } private boolean canHeal() { return !fullHP() && haveFood(); } private boolean eatFood() { if (haveFood()) { getInventory().getItem(foodId).interact("Eat"); return true; } return false; } //----- [END] BANKING/EATING METHODS [END] ----- //----- [START] COMBAT METHODS [START] ----- private boolean inCombat() { return getCombat().isFighting() || myPlayer().isMoving(); } private boolean attackCow() { NPC cow = getNpcs().closest(cowFilter()); if (cow != null) { if (!cow.isVisible()) { camera.toEntity(cow); } cow.interact("Attack"); return true; } return false; } private Filter cowFilter() { return new Filter<NPC>() { @Override public boolean match(NPC npc) { return npc.getName().startsWith("Cow") && npc.isAttackable() && cowField.contains(npc); } }; } private Sleep waitToAttack() { return new Sleep(() -> !inCombat(), 5000); } //----- [END] COMBAT METHODS [END] ----- public final String formatTime(final long ms) { long s = ms / 1000, m = s / 60, h = m / 60; s %= 60; m %= 60; h %= 24; return String.format("%02d:%02d:%02d", h, m, s); } @Override public void onPaint(Graphics2D g) { runTime = System.currentTimeMillis() - startTime; g.setColor(new Color(252, 200, 20, 255)); g.fillRect(10, 220, 180, 110); g.setColor(Color.decode("#FFFFFF")); g.drawString("Runtime: " + formatTime(runTime), 17, 240); g.drawString("Attack XP: " + getExperienceTracker().getGainedXP(Skill.ATTACK) + " (" + getExperienceTracker().getGainedLevels(Skill.ATTACK)+ ")", 17, 260); g.drawString("Strength XP: " + getExperienceTracker().getGainedXP(Skill.STRENGTH) + " (" + getExperienceTracker().getGainedLevels(Skill.STRENGTH)+ ")", 17, 280); g.drawString("Defence XP: " + getExperienceTracker().getGainedXP(Skill.DEFENCE) + " (" + getExperienceTracker().getGainedLevels(Skill.DEFENCE)+ ")", 17, 300); g.drawString("Hitpoints XP: " + getExperienceTracker().getGainedXP(Skill.HITPOINTS) + " (" + getExperienceTracker().getGainedLevels(Skill.HITPOINTS)+ ")", 17, 320); } } Sleep class taken from Explv's Scripting 101 package core; import org.osbot.rs07.utility.ConditionalSleep; import java.util.function.BooleanSupplier; public final class Sleep extends ConditionalSleep { private final BooleanSupplier condition; public Sleep(final BooleanSupplier condition, final int timeout) { super(timeout); this.condition = condition; } @Override public final boolean condition() throws InterruptedException { return condition.getAsBoolean(); } public static boolean sleepUntil(final BooleanSupplier condition, final int timeout) { return new Sleep(condition, timeout).sleep(); } } I think more specifically I was hoping to hear some ideas about how I could maybe split this up into more classes, as there's so many methods in this class and its a nightmare to scroll through them all. So if you've scripted before, how do you usually split up your bot into classes? If anyone would like to test that would be great too. Start in Falador bank with a bunch of Salmon in the bank and then it should run cleanly from there!
-
Just made my first script, but had a few problems
Cosine replied to Cosine's topic in Scripting Help
Thanks for the help all of you. I made a few changes to my script and for now I'm considering it finished as I'm going to move on to a Cow killer because I want my own scripts to test up accounts from scratch at each level If you guys like, you can have another look at my updated code and maybe see if I'm doing anything incorrect/doing any bad practices. package core; import org.osbot.rs07.api.filter.Filter; import org.osbot.rs07.api.map.Area; import org.osbot.rs07.api.model.NPC; import org.osbot.rs07.api.ui.Skill; import org.osbot.rs07.script.Script; import org.osbot.rs07.script.ScriptManifest; import org.osbot.rs07.utility.ConditionalSleep; import java.awt.*; @ScriptManifest(name = "ChickenKiller", author = "Cosine", version = 1.0, info = "", logo = "") public class Main extends Script { private final Area chickenCoop = new Area(3225, 3301, 3236, 3295); private final Area gateArea = new Area(3236, 3294, 3231, 3287); private long startTime; private long runTime; @Override public void onStart() { startTime = System.currentTimeMillis(); getExperienceTracker().startAll(); } @Override public void onExit() { } @Override public int onLoop() { if(atChickenPen()) { if (inCombat()) { waitToAttack().sleep(); } else if (attackChicken()) { waitToAttack().sleep(); } } else { walkToChickens(); } return(random(300, 400)); } private boolean atChickenPen() { return chickenCoop.contains(myPlayer()) || gateArea.contains(myPlayer()); } private boolean inCombat() { return getCombat().isFighting() || myPlayer().isMoving(); } private ConditionalSleep waitToAttack() { return new ConditionalSleep(5000, 250) { @Override public boolean condition() { return !inCombat(); } }; } private boolean attackChicken() { NPC chicken = getNpcs().closest(chickenFilter()); if (chicken != null) { if (!chicken.isVisible()) { camera.toEntity(chicken); } chicken.interact("Attack"); return true; } return false; } private Filter<NPC> chickenFilter() { return new Filter<NPC>() { @Override public boolean match(NPC npc) { return npc.getName().startsWith("Chicken") && npc.isAttackable() && (chickenCoop.contains(npc) || gateArea.contains(npc)) && npc.isVisible(); } }; } private void walkToChickens() { getWalking().walk(chickenCoop); } public final String formatTime(final long ms) { long s = ms / 1000, m = s / 60, h = m / 60; s %= 60; m %= 60; h %= 24; return String.format("%02d:%02d:%02d", h, m, s); } @Override public void onPaint(Graphics2D g) { runTime = System.currentTimeMillis() - startTime; g.setColor(new Color(252, 200, 20, 255)); g.fillRect(10, 220, 180, 110); g.setColor(Color.decode("#FFFFFF")); g.drawString("Runtime: " + formatTime(runTime), 17, 240); g.drawString("Attack XP: " + getExperienceTracker().getGainedXP(Skill.ATTACK) + " (" + getExperienceTracker().getGainedLevels(Skill.ATTACK)+ ")", 17, 260); g.drawString("Strength XP: " + getExperienceTracker().getGainedXP(Skill.STRENGTH) + " (" + getExperienceTracker().getGainedLevels(Skill.STRENGTH)+ ")", 17, 280); g.drawString("Defence XP: " + getExperienceTracker().getGainedXP(Skill.DEFENCE) + " (" + getExperienceTracker().getGainedLevels(Skill.DEFENCE)+ ")", 17, 300); g.drawString("Hitpoints XP: " + getExperienceTracker().getGainedXP(Skill.HITPOINTS) + " (" + getExperienceTracker().getGainedLevels(Skill.HITPOINTS)+ ")", 17, 320); } } Thanks again -
I just made a Chicken Killer as my first OSBot script to learn the ropes. It works fine, but I had a few questions/problems... package core; import org.osbot.rs07.api.filter.Filter; import org.osbot.rs07.api.model.NPC; import org.osbot.rs07.script.Script; import org.osbot.rs07.script.ScriptManifest; import org.osbot.rs07.utility.ConditionalSleep; import java.awt.*; @ScriptManifest(name = "ChickenKiller", author = "Cosine", version = 1.0, info = "", logo = "") public class Main extends Script { @Override public void onStart() { //Code here will execute before the loop is started } @Override public void onExit() { //Code here will execute after the script ends } @Override public int onLoop() { if (inCombat()) { waitToAttack().sleep(); } else { if (attackChicken()) { waitToAttack().sleep(); } } return(random(200, 300)); } @SuppressWarnings("unchecked") private boolean attackChicken() { NPC chicken = getNpcs().closest(chickenFilter()); if (chicken != null) { chicken.interact("Attack"); new ConditionalSleep(random(300, 400)) { //cant get sleep(random(300, 400)) to work... wants to wrap in try/catch @Override public boolean condition() { return false; } }.sleep(); return true; } return false; } private ConditionalSleep waitToAttack() { return new ConditionalSleep(random(1500, 2000)) { @Override public boolean condition() { return !inCombat(); } }; } private Filter<NPC> chickenFilter() { return new Filter<NPC>() { @Override public boolean match(NPC npc) { return npc.getName().startsWith("Chicken") && npc.isAttackable(); } }; } private boolean inCombat() { return getCombat().isFighting() || myPlayer().isMoving(); } @Override public void onPaint(Graphics2D g) { //This is where you will put your code for paint(s) } } My first issue is that for whatever reason, I can't get a standard sleep to work anywhere in my script. I wanted to use one in my attackChicken method, but it wants me to wrap it in a try/catch. I have no idea why this is happening as Script already throws an InterruptedException. My workaround is to use a ConditionalSleep with a hardcoded false condition, but it's not practical... Does anything look wrong with my code that could be causing this? My second issue is that whenever I make a change to my script, I need to close OSBot and then re-open it, login and run it again. Shouldn't I be able to run the script right from exporting it from my IDE? The IDE I'm using is Eclipse. Anyone know how to fix these issues?