Jump to content

EXTREMELY BASIC UNICOW KILLER


justanotherkid

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

  • 2 weeks later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

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...