I'm providing the full script to the second script I've written, I've tried to make best use of the API. However, on loop methods aren't my strong point and I'm looking for criticisms and preferably ways to improve this script for future developments.
After my account surpassed the requirement for my first 'chicken killer' script, I decided to move onto an area that would provide a little more exp as well as loot. This is a Hill Giant Killer; it prioritises looting over killing and banks when the inventory is full or when out of food. It has a conditional wait after each kill to prevent running around back and forth after a kill to then loot.
Please let me know your opinions as well as any improvements I could apply.
import org.osbot.rs07.api.filter.NameFilter;
import org.osbot.rs07.api.map.Area;
import org.osbot.rs07.api.map.Position;
import org.osbot.rs07.api.map.constants.Banks;
import org.osbot.rs07.api.model.GroundItem;
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 = "Hill Giant Killer", author = "Smokehut", version = 1.0, info = "", logo = "")
public class Main extends Script {
public static String updateString;
public static int currentHealth;
public static int currentEnergy;
public static String foodType = "Tuna";
public String[] lootTable = {"Big Bones", "Law rune", "Chaos rune", "Death rune", "Limpwurt root", "Giant key", "Uncut Emerald", "Uncut Sapphire", "Nature rune"};
public NPC currentGiant;
public Area cave;
public int counter = 0;
public int combatCounter = 0;
public boolean waitAfterCombat = false;
@Override
public void onStart() {
//Code here will execute before the loop is started
updateString = "Loading Variables";
cave = new Area(3095,9853,3125,9824);
}
@Override
public void onExit() {
//Code here will execute after the script ends
}
@Override
public int onLoop() {
currentHealth = getSkills().getDynamic(Skill.HITPOINTS);
currentEnergy = getSettings().getRunEnergy();
if (currentHealth < getSkills().getStatic(Skill.HITPOINTS) /2 && getInventory().contains(foodType)) {
getInventory().interact("Eat", foodType);
updateString = "Eating Food";
}
if (isAttackingGiant() && !waitAfterCombat) {
combatCounter++;
if (combatCounter > 8) {
combatCounter = 0;
waitAfterCombat = true;
updateString = "Conditional Wait Initiated.";
return random(700,2000);
}
} else {
combatCounter = 0;
}
if (waitAfterCombat && !isAttackingGiant()) {
counter++;
if (counter > 9) {
counter = 0;
waitAfterCombat = false;
}
}
if (!getInventory().contains(foodType) || inventory.isFull()) {
//we need to bank!
if (Banks.VARROCK_WEST.contains(myPlayer().getPosition())) {
//We're in the bank, lets sort our inventory.
updateString = "We're in the bank!";
if (bank.isOpen()) {
if (inventory.isEmpty()) {
bankHandling();
} else {
bank.depositAll();
}
} else {
getObjects().closest("Bank booth").interact("Bank");
}
} else {
//We're not quite at the bank, lets walk there.
updateString = "Walking to bank";
getWalking().webWalk(Banks.VARROCK_WEST);
}
} else {
//we're okay to fight
if (cave.contains(myPlayer().getPosition())){
//Sets run energy
if (currentEnergy > 50 && !getSettings().isRunning()) {
getSettings().setRunning(true);
updateString = "Setting Run Energy";
}
if (lootExists() && !myPlayer().isMoving() && !isAttackingGiant() && !inventory.isFull()) {
updateString = "Collecting loot";
//Collect Loot
pickupLoot();
} else {
//Fight
if (!isAttackingGiant() && !myPlayer().isMoving() && !waitAfterCombat) {
updateString = "Looking to fight!";
attackGiant();
}
}
} else {
getWalking().webWalk(cave);
}
}
return random(700,800); //The amount of time in milliseconds before the loop starts over
}
//Fighting Methods
private boolean isAttackingGiant() {
return currentGiant != null && currentGiant.exists() && currentGiant.getHealthPercent() > 0 && myPlayer().isInteracting(currentGiant) && currentGiant.isUnderAttack();
}
private void attackGiant() {
currentGiant = getClosestGiant();
if (currentGiant != null && currentGiant.interact("Attack")) {
new ConditionalSleep(5000) {
@Override
public boolean condition() throws InterruptedException {
return myPlayer().isInteracting(currentGiant) || !isAttackableTarget(currentGiant);
}
};
}
}
public NPC getClosestGiant() {
return getNpcs().closest(new NameFilter<>("Hill Giant"), this::isAttackableTarget);
}
private boolean isAttackableTarget(final NPC target) {
return target != null && target.exists() && target.getHealthPercent() > 0 && !target.isUnderAttack() && !isSplashed(target) && isInArea(target.getPosition());
}
private boolean isSplashed(NPC target) {
return !getPlayers().filter(p -> p.isInteracting(target)).isEmpty();
}
private boolean isInArea(Position target) {
return cave.contains(target);
}
//Looting Methods
private boolean lootExists() {
for (int i = 0; i < lootTable.length; i++) {
GroundItem item = groundItems.closest(lootTable[i]);
if (item != null && item.exists()) {
return true;
}
}
return false;
}
private void pickupLoot() {
for (int i = 0; i < lootTable.length; i++) {
GroundItem item = groundItems.closest(lootTable[i]);
if (item != null && item.exists()) {
if (item.isVisible()) {
item.interact("Take");
} else {
getWalking().walk(item.getPosition());
}
}
}
}
//Banking Methods
private void bankHandling() {
bank.withdraw("Brass key", 1);
bank.withdraw(foodType, 5);
bank.close();
}
@Override
public void onPaint(Graphics2D g) {
g.setColor(Color.WHITE);
//This is where you will put your code for paint(s)
g.drawString(updateString, 10, 10);
// Get current mouse position
Point mP = getMouse().getPosition();
// Draw a line from top of screen (0), to bottom (500), with mouse x coordinate
g.drawLine(mP.x, 0, mP.x, 500);
// Draw a line from left of screen (0), to right (800), with mouse y coordinate
g.drawLine(0, mP.y, 800, mP.y);
//This is where you will put your code for paint(s)
}
}
This is merely provided to assist my improvement, if people are not happy with me sharing a full script or it devalues another, please let me know and I'll remove.