Jump to content
justanotherkid

EXTREMELY BASIC UNICOW KILLER

Recommended Posts

Because this script was my first script and it is not flexible I will release it for opensource because I believe the readability will be very valuable to beginning scripters. 

i'm much much better now and this script is cancer, I only spent like 5minutes adding comments and i hope some people can learn whatever from this 

gl

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.util.Arrays;

import org.osbot.rs07.api.map.Area;
import org.osbot.rs07.api.map.Position;
import org.osbot.rs07.api.model.Entity;
import org.osbot.rs07.api.model.GroundItem;
import org.osbot.rs07.api.model.NPC;
import org.osbot.rs07.api.model.RS2Object;
import org.osbot.rs07.api.ui.EquipmentSlot;
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;

@ScriptManifest(author = "justanotherkid", info = "", name = "Unicows", version = 1.0, logo = "")
public class main extends Script {

	Area area = new Area( new Position(3010,4412,0), new Position(3042,4373,0));
	Area bankarea = new Area( new Position(2443,3082,0), new Position(2438,3096,0));
	Area kandarinarea = new Area( new Position(2611,3219,0), new Position(2601,3228,0));
	Position[] toarea1 = new Position[] { new Position(2606,3222,0), new Position(2616,3222,0), new Position(2628,3222,0), new Position(2636,3223,0), new Position(2649,3225,0),};
	String state;
	Area position = new Area( new Position(3017,4409,0), new Position(3021,4408,0));
	Position ladder = new Position (2648,3213,0);
	GroundItem horn;
	NPC unicow;
	long startTime;
	long count1;
	long totalcount;
	Entity door;
	RS2Object towerdoor;
	Entity bank;
	Entity trapdoor;

	@Override
	public void onStart() {
		startTime = System.currentTimeMillis(); // start a timer in ms
		for(Skill skill : new Skill[]{Skill.HITPOINTS, Skill.ATTACK, Skill.STRENGTH, Skill.DEFENCE}) {
		    getExperienceTracker().start(skill); } // start exp trackers, you can add more skill trackers by just adding onto the list
	}
	
	private enum State {
		SUMMON,IDLE,LOOT,FIGHT,TRAVEL2BANK,BANK,TRAVEL2AREA,DROP,WORLDHOP // enum of states
	}
	
	private State getState() // below are conditions to required to execute each state, i believe the conditions are straight forward so i will not explain them
	{	
		if(area.contains(myPlayer()) && getPlayers().getAll().size() > 1 && !myPlayer().isUnderAttack())
		{
			return State.WORLDHOP;
		}
		if(horn != null && area.contains(myPlayer()) && !myPlayer().isUnderAttack() && getInventory().getAmount("Unicorn horn") < 28)
		{
			unicow = npcs.closest("Unicow");
			return State.LOOT;
		}

		if(area.contains(myPlayer()) && getInventory().contains("Cowhide") && getInventory().contains("Unicorn horn") && unicow == null)
		{
			unicow = npcs.closest("Unicow");
			return State.SUMMON;
		}
		
		if(getInventory().contains("Green satchel") || getInventory().contains("Tea flask") || getInventory().contains("Bones"))
		{
			return State.DROP;
		}

		if(!getInventory().contains("Cowhide") && bankarea.contains(myPlayer()))
		{
			return State.BANK;
		}
		if(!getInventory().contains("Cowhide") && !bankarea.contains(myPlayer()))
		{
			unicow = npcs.closest("Unicow");
			return State.TRAVEL2BANK;
		}
		if(unicow != null && area.contains(myPlayer()) || myPlayer().isUnderAttack())
		{
			unicow = npcs.closest("Unicow");
			return State.FIGHT;
		}

		if(getInventory().contains("Unicorn horn") && getInventory().contains("Unicorn horn") && !area.contains(myPlayer()))
		{
			return State.TRAVEL2AREA;
		}

		return State.IDLE;
	}

	@Override
	public int onLoop() throws InterruptedException // the 2 lines below here are always on loop regardless of what state is executed
	{	
		unicow = npcs.closest("Unicow"); // constantly refreshing unicow to mean the closest unicow; if no unicow exists then it will return null
		horn = getGroundItems().closest("Unicorn horn"); // same as the unicow line
		
		switch(getState()) // under here is the part where we define what each state does
		{	
		case WORLDHOP:
			state = "WORLDHOPPING"; // this changes the string state to display a different word, this is helpful to debug where exactly a script error is occuring
			getWorlds().hopToP2PWorld(); //hop to a random p2p world
			break; // always add a break; after each case
			
		case DROP:
			state = "DROPPING";
			getInventory().dropAllExcept("Cowhide","Unicorn horn"); // drop all except these items
			break;
			
		case TRAVEL2AREA:
			state = "TRAVELING";
				getEquipment().interact(EquipmentSlot.CAPE, "Kandarin Monastery"); // interact with this cape
				sleep(random(2300,2800)); //sleep for the loading screen (you can use a conditional sleep)
				if(!kandarinarea.contains(myPlayer()))
				{
					door = objects.closest("Door");
							if(door.hasAction("Open")) // it will only open a door if it has the action "Open" so if the door is already open it will not execute this
							{
								door.interact("Open");
								sleep(random(800,1400));
								getWalking().walkPath(Arrays.asList(toarea1)); //this walks a predefined path, most people prefer using the webwalker
								RS2Object towerdoor = getObjects().closest("Tower door"); // defining a new RS2Object, this is bad practice, make sure you define your variable globally way up in the script to prevent junk buildup (everytime it executes this line it makes a new variable)
								if(towerdoor.hasAction("Open")) 
								{
									towerdoor.interact("Open");
									sleep(random(800,1000));
								}
							}
							else
							{
								getWalking().walkPath(Arrays.asList(toarea1));
								towerdoor = getObjects().closest("Tower door");
								if(towerdoor.hasAction("Open"))
								{
									towerdoor.interact("Open");
									sleep(random(800,1000));
								}
							}				
				}
			getWalking().webWalk(new Position[] {ladder}); // webwalking to a certain position called ladder which was globally defined above
			
			trapdoor = objects.closest("Trapdoor");
			
			if(trapdoor.hasAction("Open")) // if the trapdoor is closed then execute the first portion, else just execute the second portion (aka else statement)
			{
				trapdoor.interact("Open");
				sleep(random(600,1000));
				trapdoor.interact("Climb-down");
			}
			else
			{
				trapdoor.interact("Climb-down");
			}
			sleep(random(1600,2000));
			
			getWalking().webWalk(position);
			while(myPlayer().isMoving()){ // this is really bad practice, use a WalkingEvent, never use a while loop like this
				sleep(300);
			}
			break;
			
		case BANK:
			state = "BANKING";
			count1 = getInventory().getAmount("Unicorn horn"); // the amount of unicorn horns in the inventory
			bank = objects.closest("Bank chest");
			if(bank != null)
			{
				bank.interact("Use");
				sleep(400);
				while(myPlayer().isMoving())
				{
					sleep(300);
				}
			} // this is bad practice, what should have been done is if(bank is open) { execute banking portion } else { execute getting to bank and opening portion }
			if(getBank().isOpen())
			{
				if(!getEquipment().isWearingItemThatContains(EquipmentSlot.RING, "Ring of dueling"))
				{
					getBank().depositAll();
					totalcount += count1; // add the amount of unicorn horns banked to the total amount banked
					getBank().withdraw("Cowhide", 16);
					sleep(random(100,200));
					getBank().withdraw("Unicorn horn", 1);
					sleep(random(100,200));
					getBank().withdraw("Ring of dueling(8)", 1);
					getBank().close();
					sleep(random(100,200));
					getEquipment().equip(EquipmentSlot.RING, "Ring of dueling(8)");
				}
				else
				{
				getBank().depositAll();
				totalcount += count1;
				sleep(random(100,200));
				getBank().withdraw("Cowhide", 14);
				sleep(random(100,200));
				getBank().withdraw("Unicorn horn", 1);
				sleep(random(100,200));
				getBank().close();
				}
				
				if(getSkills().getDynamic(Skill.HITPOINTS) < 40) // if HP is below 40
				{
					bank.interact("Use");
					sleep(600);
					getBank().withdraw("Salmon", 4);
					getBank().close();
					sleep(300);
					while(getInventory().contains("Salmon")) // while inventory contains salmon, eat them
					{
					getInventory().interact("Eat","Salmon");
					sleep(600);
					}
				}
			}
			break;
			
		case TRAVEL2BANK:
			state = "TRAVELING";
			if(!bankarea.contains(myPlayer()))
			{
			getEquipment().interact(EquipmentSlot.RING, "Castle Wars");
			new ConditionalSleep(3000) // this is the conditional sleep snippet that should have been used more often, make sure you save this snippet
            {					       // the number 3000 in the line above is the timeout number (the conditional sleep will end in that time)
				@Override
				public boolean condition() throws InterruptedException 
				{
					return bankarea.contains(myPlayer()); // the condition that needs to be met to end the conditional sleep earlier
				}
			}.sleep();
			}
			break;
			
		case IDLE:
			break;
			
		case SUMMON:
			state = "SUMMONING";
			if(!position.contains(myPlayer()))
			{
				getWalking().webWalk(position); // if you choose to use a webwalker this way you should always add a sleep after the getWalking() to prevent spam clicking
			} 
			Entity fountain = getObjects().closest("Symbol of Life"); // needs to be defined globally to prevent junk buildup
			if(fountain != null)
			{
				getInventory().interact("Use", "Unicorn horn");;
				fountain.interact();
				sleep(1250);
				getInventory().interact("Use", "Cowhide");
				fountain.interact();
				sleep(500);
				fountain.interact("Activate");
				sleep(400);
				if(getDialogues().inDialogue())
				{
					getDialogues().completeDialogue("Click here to continue");
				}
			}
			sleep(1000);
			break;
			
		case FIGHT:
			state = "FIGHTING";
			if (unicow != null && unicow.exists() && unicow.isAttackable())
			{
				getInventory().deselectItem(); // failsafe since occasionally an item will be selected from the SUMMON state that will prevent combat
				unicow.interact("Attack");
	            sleep(random(400));
	            while(myPlayer().isUnderAttack()) // this should be a conditional sleep that returns true if the player is under attack
	            {
	            	sleep(random(300));
	            }
			} 
			sleep(500);
			break;
			
		case LOOT:
			state = "LOOTING";
			if(horn != null)
			{	
				if(getInventory().isFull() && getInventory().contains("Cowhide"))
				{
					getInventory().drop("Cowhide");
					horn.interact("Take");
				}
				else
				{
					horn.interact("Take");
				}
			}
			break;
		}
		return random(200) + 200;
	}

	
	@Override
	public void onExit() { //place things that you want to happen during the exiting of the script; you can add the client to type the amount of unicow horns collected in the log
	}

	
	@Override
	public void onPaint(Graphics2D g) 
	{
		long ss = (System.currentTimeMillis() - startTime) / 1000; // long ss, long mm, and long hh are used to format the timer we started way above
        long mm = ss / 60;
        long hh = mm / 60;
        long gainedexp = getExperienceTracker().getGainedXP(Skill.HITPOINTS) + 
        		getExperienceTracker().getGainedXP(Skill.ATTACK) +
        		getExperienceTracker().getGainedXP(Skill.STRENGTH) + 
        		getExperienceTracker().getGainedXP(Skill.DEFENCE); // adding all the exp gained so far
        long gainedexphr = getExperienceTracker().getGainedXPPerHour(Skill.HITPOINTS) + 
        		getExperienceTracker().getGainedXPPerHour(Skill.ATTACK) + 
        		getExperienceTracker().getGainedXPPerHour(Skill.STRENGTH) + 
        		getExperienceTracker().getGainedXPPerHour(Skill.DEFENCE); // adding the exp/hr calculations 
        
		Font font = new Font("Sans-Serif", Font.BOLD, 14); //defining a font of Sans-Serif that is bold and size 14
	    g.setColor(Color.WHITE); // setting the font color
	    g.setFont(font); // setting the font equal to what was defined 2 lines above
        g.drawString("Status: " + state, 8, 303); // drawing these strings for this line and those below
        g.drawString("Exp : " + gainedexp + " (" + gainedexphr + ")", 8, 318);
        g.drawString("Run time: " + hh + ":" + mm%60 + ":" + ss%60 , 8, 333);
        g.drawString("Amount Banked: " + totalcount, 230, 333);
	}

}
Edited by justanotherkid
  • Like 1
Link to comment
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.



  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...