All pastes #1539398 Raw Edit

Solfac

public javascript v1 · immutable
#1539398 ·published 2009-08-22 20:57 UTC
rendered paste body
import java.awt.Color;import java.awt.Dimension;import java.awt.EventQueue;import java.awt.Font;import java.awt.Graphics;import java.awt.Graphics2D;import java.awt.Image;import java.awt.Rectangle;import java.awt.RenderingHints;import java.awt.Toolkit;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.ItemEvent;import java.awt.event.ItemListener;import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.ByteArrayOutputStream;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.FileReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintStream;import java.net.URL;import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import javax.swing.ImageIcon;import javax.swing.JButton;import javax.swing.JCheckBox;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JList;import javax.swing.JMenu;import javax.swing.JMenuBar;import javax.swing.JOptionPane;import javax.swing.JPanel;import javax.swing.JRadioButton;import javax.swing.JRadioButtonMenuItem;import javax.swing.JTabbedPane;import javax.swing.JTextField;import javax.swing.WindowConstants;import javax.swing.border.BevelBorder;import javax.swing.event.ListSelectionEvent;import javax.swing.event.ListSelectionListener;import bergCoder.BergUtils;import bergCoder.LootTable;import bergCoder.Object3D;import com.jgoodies.forms.factories.DefaultComponentFactory;import impsoft.bots.ColorBot;import impsoft.bots.input.MouseCommand;import impsoft.bots.reflection.GroundItem;import impsoft.bots.reflection.NPC;import impsoft.bots.reflection.NPCIterator;import impsoft.bots.reflection.PhysicalObject;import impsoft.bots.reflection.Player;import impsoft.bots.reflection.PlayerIterator;import impsoft.scripting.ibot.builtin.itemrec.ItemSlot;import impsoft.scripting.ibot.enums.Skill;import impsoft.scripting.ibot.interfaces.AutoPaint;import impsoft.scripting.ibot.interfaces.ChatListener;import impsoft.scripting.ibot.structs.AryanTile;import impsoft.scripting.ibot.structs.RGB;import impsoft.scripting.ibot.structs.XY;import impsoft.scripting.types.ColorScript;import impsoft.scripting.types.parallel.scriptjobs.ScriptJob;import impsoft.utils.general.TextFormat;import impsoft.utils.general.Timer;import impsoft.utils.ibot.ColorMapAnaylsis;import impsoft.values.constant.Areas;/* * V0.006 *   * 		Looting : * 			* Added eatFoodForLoot, as a option. * 			* Added banking, uses erik548 deposit method. * 			* Added a speed failsafe for looting. * 				- Uses theParallelWalking, for faster speed. * 					!Uses bergs click on screen, theParallelWalking made the script hang some times. * 			* Tweaked looting, now only loots items which are on miniMap. * 				- Fixed bug where it would hang script wise, thus activating notMoving. * 			* Tweaked looting for more accurate looting. *  * 		Eating : * 			* Fixed go to bank and log bug. *  * 		Combat : * 			* Its fixer properly know whit out attacking others at the wrong time. *  * 		GUI : * 			* Actually made slayerJob toggle able, in menubar. * 			* Smooth paint moved into menubar. * 			 *  * 		General : * 			* Takes a screen shot after slayerJob, died or out of food. *  * 	V0.005 Beta *			Combat : *				* Fixed NPC pre-calculating, HP ratio 0.0 means they generated 1HP. *				* Improved NPC attacking, for agressive NPC's trough chat listener.  *					- I recommend that you battle NPC's which are not agressive until I add proper support. * *			Looting : *				* Added "basic" banking support, uses nexus worldMap to bank. TODO *				* Stabilized looting, faster and better now. * *			Eating : *				* Added food support. *				* Has ability to restock. TODO *	 * V0.004 * 		General : * 			* Added loot system, will only loot until inventory is full banking will come. *  * 		GUI : * 			* Did some changes to GUI general. * 			* Added GUI loot tab. * 				- Supports : * 					-* Clear list * 					-* Cleat item * 					-* Add item * 					-* Save list * 			* Added smooth paint jCheckBox, optional choice. * 			* Added support for ID's, as some NPC have same name but different HP. * 				- You can now choose between String[] NPC names, or int[] NPC ID's. *  * 		Combat : * 			* Added ID usage. * 				- Suggested by USA * 			* Added ID presets, only few will be alot more. * 			* Chat listener thread has a higher piority, for I'm already under attack. * *		Paint :  * 			* Added smooth paint * 				- Suggested by "ravicus". *  * V0.003 * 		Thread(s) : * 			* Made 0.5 second thread log in green. *  * 		Paint : * 			* Added pre calc info to paint. *  * 		General : * 			* Global clean-up. * 			* Now quits when slayer task is enabled, or when we have died. *  * 		Combat : * 			* Tweaked combat method. * 			* Removed isNPCFake totally, redoing it later properly. *  * V0.002 * 		General : * 			* Added paint. * 		Combat : * 			* Tuned bergs reflection clicker, resulting a great speedup and less botlike! *			* Disabled isNPCFake, was troubling to much will be fixed when I have time. *  * V0.001 * 		Combat : * 		* Updated RGB color, its the actual XY color from center. * 		* Speeded up isNPCFake, where talking about MS's * 			- Only 1 fake at the time, so we can cache the fake one until it moves. * 		* Properly added isNPCFake *		V0.0011 * 			Combat : * 				* Checking for NPC is valid should be smoother, also used getHeight != null, still needs to be tested *  				* isNPCFake(x) now checks if rgb.r >= 200 && rgb.g >= 200 && rgb.b == 0, now always returns proper. *  *  */public class sAdvancedCombat extends ColorScript implements ChatListener, AutoPaint {	public static String author = "Solfac";	public static double Version = 0.005;	public static String description = "V" + Version + ", last updated 20-aug-09 ";   		boolean restockFood = false,	quitAfterSlayerTask = false,	eatFoodForLoot = false,	bankAtFullInv = false;    	ScriptJob j = null;			private Timer runTime = new Timer(0);		public sAdvancedCombat(ColorBot Solfac) {		super(Solfac);	}				boolean depositAll() throws InterruptedException {		return depositAll(false);	}		boolean depositAll(boolean debug) throws InterruptedException {		if(theBank.isInterfaceIsUp() && theTabs.Inventory.getCount() != 0) {			if(debug) log("Inventory is not empty, depositing.");			mouseMove(new Rectangle(379,297,33, 22));			if(new Rectangle(379,297,33, 22).contains(getCurrentMouseX(), getCurrentMouseY())) {				if(debug) log("Succesfully moved mouse into rectangle.");				while(!theTopText.getTopText().contains("Deposit carried items") && new Timer(1000).isNotUp())					sleep(1);				if(theTopText.getTopText().contains("Deposit carried items")) {					mouseClickLeft(getCurrentMouseXY());					while(new Timer (4000).isNotUp() && theTabs.Inventory.countEmptySlots() != 28)						sleep(1);								if(theTabs.Inventory.getCount() == 0) {						log("Succesfully deposited our inventory!");						return true;					}				}			}		} else if(theBank.isInterfaceIsUp() && theTabs.Inventory.getCount() == 0) {			log("Inventory is already empty, not depositing.");			return true;		}		return false;	}		boolean openBankSafe() throws InterruptedException {		theWorldMap.walkToBank();		if(theBank.open()) {			Timer t = new Timer (4000);			while(t.isNotUp() && !theBank.isInterfaceIsUp()) {				log("Waiting for bank interface, countdown " + t);				sleep(1);			}			if(theBank.isInterfaceIsUp()) return true;		}		return false;	}		String[] foodNames = {"meat", "Cooked chicken","Spider on stick",		"Shrimp","Karambwanji","Sardine","Anchovies","Karambwan","Herring","Mackerel","Trout","Cod","Pike","Salmon",		"Tuna","Rainbow fish","Lobster","Bass","Swordfish","Monkfish","Shark","Sea turtle","Manta ray","snail","Bread","pie","stew",		"pizza","cake","potato","crunchies","batta", "spinach", "2", "1", "kebab", "slice"};		boolean doBank() throws InterruptedException {	    AryanTile spotLocation = getMyPlayer().getLocation();	    if(spotLocation != null) {	    	if(openBankSafe()) {	    		if(theBank.isInterfaceIsUp()) {	    			depositAll(true);	    				    			if(eatFoodForLoot) 	    			for(String foodName : foodNames) 	    				if(theBank.count(foodName.toLowerCase()) != 0)	    					theBank.doWithDrawAll(foodName.toLowerCase(), false);	    				    			theWorldMap.walkTo(spotLocation);	    			return true;	    		}	    	}	    }		return false;	}		boolean doLoot() throws InterruptedException {		if(theTabs.Inventory.isFull() && !eatFoodForLoot) {			return false;		}				AryanTile closest = null;		GroundItem result = null;		double closestDistance = 1000;			for(int i = 0; i < lootList.length; i++) {				for(GroundItem item : getAllGroundItems()) {					if(item != null &&  item.valid() && item.getName().toLowerCase().contains(lootList[i].toLowerCase())) {						double distance = getMyPlayer().getLocation().distanceToPrecise(item.getLocation());						if(distance <= 15 && distance < closestDistance) {							closest = item.getLocation();							result = item;							closestDistance = distance;						}					}				}			}		if(closest != null && result != null) {			if(theTabs.Inventory.isFull() && eatFoodForLoot) {	            if(eatAnyFoodItem()) {	            	return doLoot();	            } else if(theTabs.Inventory.isFull() && bankAtFullInv) {	    			doBank();	    		} else return false;	        } if(theTabs.Inventory.isFull())	        	return false;						log("Got data succesfull, trying to loot!");			if(result.getGameScreenLocation() == null) {				log("Walking to item, theParallelWalking.");				if(!be.walkToMinimapTarget(closest)) 					return false;				//this.theParallelWalking.walkToTile(closest);			}						if(clickReflectionObject(closest, result.getName(), (new StringBuilder("Take ")).append(result.getName()).toString(), null, false, null)) {				Timer t = new Timer(2000);				int firstCount = theTabs.Inventory.count(result.getName());				while(getMyPlayer().isMoving() || !t.isUp()) {					if(getMyPlayer().getLocation().equals(closest) && !isMoving()) {						t.reset();						while(t.isNotUp()) {							if(theTabs.Inventory.count(result.getName()) != firstCount)								return doLoot();							sleep(1);						}						break;					}					sleep(20);				}			}		}		return false;	}		/** Returns the NPC with either the passed in names or types.  Both are not needed.  tile will center the search to return nearest	  * to that spot, and maxDistance will limit how far away it will look. 	  * Added isNPCFake(NPC npc) by Solfac.*/	public NPC getNPC(String[] names, int[] types, AryanTile tile, int maxDistance) {		NPC closest = null;		double closestDistance = 1000;		AryanTile center = tile;		if (tile == null) center = getLocation();		for (NPCIterator iterator = getNPCIterator(); iterator.hasNext();) {			NPC npc = iterator.next();			if (((names != null && be.npcMatchesName(npc,names))					|| (types != null && be.npcMatchesType(npc,types)))				&& (!npc.inCombat() || npc.isInteractingWithMyPlayer()) && npc.getHeight() != 0 && npc != aNPC) {				double distance = npc.getLocation().distanceToPrecise(center);				if (npc.inCombat() && npc.isInteractingWithMyPlayer())					continue;							if (distance <= maxDistance && distance < closestDistance) {					closest = npc;					closestDistance = distance;				}			}		}		return closest;	}	public NPC getAttackingNPC() {		for (NPCIterator iterator = getNPCIterator(); iterator.hasNext();) {			NPC npc = iterator.next();			if(npc != null)				if(npc.isInteractingWithMyPlayer()) 					return npc;		}		return null;	}		public Player getLocalPlayer() {		for (PlayerIterator iterator = getPlayerIterator(); iterator.hasNext();) {			Player player = iterator.next();			if(player != null)				if(player.getName().equals(getMyPlayer().getName())); 					return player;		}		return null;	}		int combatXP() {		try {			return theTabs.Statistics.getStatExperience(Skill.ATTACK) 			+ theTabs.Statistics.getStatExperience(Skill.DEFENSE)			+ theTabs.Statistics.getStatExperience(Skill.STRENGTH)			+ theTabs.Statistics.getStatExperience(Skill.RANGED);		} catch (InterruptedException e) {			return -1;		}	}		int totalCombatXP() {		try {			return theTabs.Statistics.getStatExperience(Skill.ATTACK) 			+ theTabs.Statistics.getStatExperience(Skill.DEFENSE)			+ theTabs.Statistics.getStatExperience(Skill.STRENGTH)			+ theTabs.Statistics.getStatExperience(Skill.HITPOINTS)			+ theTabs.Statistics.getStatExperience(Skill.RANGED);		} catch (InterruptedException e) {			return -1;		}	}    	float getHPPoints(NPC npc, int maxHP) {		try {			if(npc != null && npc.inCombat()) 				return (maxHP * npc.getHPRatio()) / 255;			return maxHP;		} catch (NullPointerException e) {			return maxHP;		}	}		boolean npcDead = false, 			slayerJobDone = false,			weAreDead = false,			useOldOne = false,			smoothPaint = false,			lootSystemEnabled = true;			 	NPC aNPC, pNPC; 	int startCombatXP, startTotalCombatXP, tempXp, hSeconds; 	Object[] cache, NPChp = null; 	String[] NPCname; 	String[] lootList; 	boolean useName; 	int[] aNPCID;	turboThread turboThread;	eatThread eatThread; 		BergUtils be = new BergUtils(this);	SwingResourceManager swm = new SwingResourceManager();	 	 	int NPChp(Object[] NPChp) {		for(int i = 0; i < NPChp.length; i++) 			if(aNPC != null) {		 		if(useName && aNPC.getName().toLowerCase().equals(NPCname[i].toLowerCase())) {		 			return Integer.parseInt(NPChp[i].toString());		 		} else if(!useName && aNPC.getType() == aNPCID[i]) 		 			return Integer.parseInt(NPChp[i].toString());			} 		return -1; 	} 	 	 	 	boolean foodQuit = false;	@Override	public void script() throws InterruptedException { 		EventQueue.invokeLater(new Runnable() {			public void run() {					try {				        JFrame window = new GUI();				       				        window.setVisible(true);						} catch (Exception e) {						e.printStackTrace();					}				}			});		        while(NPChp == null)        	sleep(100);               	    if(turboThread == null){	    	turboThread = new turboThread();	    	turboThread.start();	        log("turboThread was null, (re)started thread.");	    }	    if(eatThread == null){	    	eatThread = new eatThread();	    	eatThread.start();	        log("eatThread was null, (re)started thread.");	    }	    	    		 while(!isLoggedIn()) {			 log("Waiting for login.");			 sleep(100);		 }		 			for(int i = 0; i < NPChp.length; i++) 				log(NPChp[i]);				    startCombatXP = combatXP();	    startTotalCombatXP = totalCombatXP();	    				be.clickTileXOffset = 0;		be.clickTileYOffset = 0;		be.clickAccuracy = 5;			    runTime = new Timer(0);	    	    Player test = getLocalPlayer();	    log(test);	      while(!slayerJobDone && !weAreDead && !foodQuit) {	    	  	if(useOldOne) {	    	  		aNPC = getAttackingNPC();	    	  		useOldOne = false;	    	  	} else if(useName) {	    	  		aNPC = getNPC(NPCname, null, null,50);	    	  	} else if(!useName) {	    	  		aNPC = getNPC(null, aNPCID, null,50);	    	  	}	    	  		    	  	if(aNPC != null)					if(clickReflectionObject(aNPC, null, "Attack", null, false, null)) {							waitForAnimation(2000);							if(waitForKill(aNPC)) {								npcDead = false;								useOldOne = false;							}					}				be.setFastRun(true);					if(lootSystemEnabled && !useOldOne)					doLoot();							sleep(1);		}   	    screenCaptureWithDebugInfo();	      	    if(foodQuit) {        	log("Eating failed, time to log.");        	theBank.open();        	theBank.exit();	    }	     	    if(slayerJobDone) {	    	log("We finished our slayer job !");	    } else if(weAreDead) log("We are in lumbridge/falador.");	    	    while(isLoggedIn())	    	theTabs.Logout.clickLogOut();	    	}				 boolean waitForKill(NPC npc) throws InterruptedException {		int type = npc.getType();		AryanTile tile = npc.getLocation();		while (true) {			if(!npc.inCombat() || !npc.isInteractingWithMyPlayer()) {				npc = be.getNPCByType(new int[] {type}, tile);				if(npc == null || !npc.inCombat() || !npc.isInteractingWithMyPlayer()) 					return true;			}						if(npcDead) 								return true;			if(useOldOne)				return false;			tile = npc.getLocation();			sleep(10);		}	}		/*	public boolean waitForInteractingNPC(int time, NPC npc) throws InterruptedException {		Timer t = new Timer(time);		while(t.isNotUp()) {			if(getMyPlayer().getInteractingNPC().equals(npc))				return true;			waitTillNextFrame();		}		return false;	}*/		/** used after an attack click was made.  for time millis, waits for moving to stop and for an animation(attack) to happen	  * if we hit something, returns the animation state.  Don't use sleepUntilNotMoving before this because we might swing	  * while moving */	public int waitForAnimation(int time) throws InterruptedException	{		Timer t = new Timer(time);		boolean animationStarted = false;		int animation = -1;		while(t.isNotUp() || animationStarted || isMoving()) {			if (getAnimation() != -1) {				animationStarted = true;				animation = getAnimation();			} else if (animationStarted && getAnimation() == -1 && !isMoving()) return animation;			if(isMoving())				t.reset();			waitTillNextFrame();		}		return -1;	}		@SuppressWarnings("deprecation")	public void turnOff() {		if (turboThread != null) {			turboThread.stop(); 			log("stopped turboThread");		}				if (eatThread != null) {			eatThread.stop(); 			log("stopped eatThread");		}				log("Thank you for using " + name);		log("~ Solfac.");		super.turnOff();	}			@Override	public void chat(String Solfac) throws InterruptedException {		if(Solfac.toLowerCase().contains("slayer task") && quitAfterSlayerTask)			slayerJobDone = true;				if(Solfac.toLowerCase().contains("oh dear, you are dead!"))			weAreDead = true;				if(Solfac.toLowerCase().contains("m already under attack")) {			if(Thread.currentThread().getPriority() != 2) {				log(Thread.currentThread().getName() + " piority changed.");				Thread.currentThread().setPriority(2);			}			useOldOne = true;			log("Got old NPC back.");		}	}    	float cNPChp;	Timer paintUpdate = new Timer(1200);	//boolean updatePaint = false;	String paint1 = "Waiting,", 	paint2 = "for thread", 	paint3 = "update.";		boolean leftClickInvItem(String itemName) throws InterruptedException {		be.setTab("Inventory");		ItemSlot slot = be.getClosestItemSlot(itemName);		if (slot == null) 			return false;		slot.mouseMoveOn();		XY point = getCurrentMouseXY();		if(point != null && slot.getArea().contains(point.x, point.y)) {				slot.mouseClickLeftOn();				sleep(250);				return true;		} else log("Rectangle mismatch!");		return false;	}		public boolean eatAnyFoodItem() throws InterruptedException{		be.setTab("Inventory");		for(int i = 0; i < theTabs.Inventory.SLOTS.length; i++) {			ItemSlot itemSlot = theTabs.Inventory.SLOTS[i];			if(itemSlot.isItemInSlot()				&& itemSlot.getItemName() != null				&& be.isFood(itemSlot.getItemName())){				leftClickInvItem(itemSlot.getItemName());				log("Trying to eat " + itemSlot.getItemName());				return true;			}		}		return false;	}		class eatThread extends Thread {		public void run() {			eatThread.setName("W EatThread");			 int randomHPInt = 0;			try {				randomHPInt = random(5, theTabs.Statistics.getStatBottom(Skill.HITPOINTS));			} catch (InterruptedException e1) {				e1.printStackTrace();			}			log("Eating at " + randomHPInt);			 while(!foodQuit) {				 				 try {	                 if(theTabs.Statistics.getStatTop(Skill.HITPOINTS) <= randomHPInt) {                  	             	                     log("Script piority = " + Thread.currentThread().getPriority());	                     Thread.currentThread().setPriority(1);	                     log("Script piority changed " + Thread.currentThread().getPriority());   	                     if(eatAnyFoodItem()) {	                    	 log("Succesfully ate food.");	                     } else {	                    	 log("Failed, time to exit");	                    	 foodQuit = true;	                     }	                     randomHPInt = random(5, theTabs.Statistics.getStatBottom(Skill.HITPOINTS));	                     log("Eating at " + randomHPInt);	                     Thread.currentThread().setPriority(5);	                 }                					sleep(2000);				} catch (InterruptedException e) {					e.printStackTrace();				}			}		}	}		class turboThread extends Thread {		public void run() {			 turboThread.setName("R TurboThread");			 Thread.currentThread().setPriority(1);			 tempXp =  combatXP();			 Timer t = new Timer(20000);			 while(true) {						if(t.isUp()) {					log("Took longer then 20 seconds to kill our NPC.");					npcDead = true;					t.reset();				}									if(tempXp != combatXP()) {						cNPChp = getHPPoints(aNPC, NPChp(NPChp));					if(((combatXP() - tempXp) / 4) > cNPChp) {						log("0.5 second boost!");						npcDead = true;						hSeconds++;					}					paint1 = "* NPC hp " + (float) NPChp(NPChp) + "/" + cNPChp;					paint2 = "* Next hit " + (float) ((combatXP() - tempXp) / 4);					paint3 = "* time shifted hp " + cNPChp + "/" + (cNPChp - ((combatXP() - tempXp) / 4));					tempXp = combatXP();					paintUpdate.reset();					t.reset();				} else if(paintUpdate.isUp()) {					cNPChp = getHPPoints(aNPC, NPChp(NPChp));					paint1 = "* NPC hp " + (float) NPChp(NPChp) + "/" + cNPChp;					paint2 = "* Next hit 0";					paint3 = "* time shifted hp " + cNPChp + "/" + cNPChp;					paintUpdate.reset();					t.reset();				}				try {					sleep(1);				} catch (InterruptedException e) {					e.printStackTrace();				}			}		}	}	    double round(double val, int places) {	    long factor = (long)Math.pow(10,places);	    val = val * factor;	    long tmp = Math.round(val);	    return (double)tmp / factor;    }        String npcToID(String npcNameToFind) {    	StringBuilder s = new StringBuilder();		for (NPCIterator iterator = getNPCIterator(); iterator.hasNext();) {			NPC npc = iterator.next();			if(npc != null)				if(npc.getName().toLowerCase().contains(npcNameToFind.toString().toLowerCase())) {					s.append(npc.getType() + ", ");								}		}    	return "" + s;    }        Object interactingNpcID() {		for (NPCIterator iterator = getNPCIterator(); iterator.hasNext();) {			NPC npc = iterator.next();			if(npc != null && npc.isInteractingWithMyPlayer())				return npc.getType();		}    	return "No NPC is interacting whit myPlayer()";    }        Object idToName(int ID) {		for (NPCIterator iterator = getNPCIterator(); iterator.hasNext();) {			NPC npc = iterator.next();			if(npc != null && npc.getType() == ID)				return npc.getName();		}    	return "ID is not spawned/invaled, retry.";    }        int getItemID(String itemName) throws IOException {		String item = null;		if (itemName.contains(" ")) {			String temp[] = itemName.split(" ");			for (int a = 0; a < temp.length; a++) {				item += temp[a];				if (a != temp.length)					item += "+";			}		} else			item = itemName; 		URL url = new URL("http://itemdb-rs.runescape.com/results.ws?query="				+ item + "price=all&members=");		BufferedReader in = new BufferedReader(new InputStreamReader(url				.openStream()));		String inputLine = null;		String found = null;		while ((inputLine = in.readLine()) != null && found == null)			if (inputLine.contains("./viewitem.ws?obj")					&& inputLine.contains(itemName)) {				found = inputLine;			}		in.close();		int[] number = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };		int lowestIndex = 1000000;		int highestIndex = 0;		for (int a = 0; a < number.length; a++) {			int currentIndex = found.indexOf(Integer.toString(number[a]));			if (currentIndex != -1) {				if (currentIndex < lowestIndex)					lowestIndex = currentIndex;				if (currentIndex > highestIndex) {					highestIndex = currentIndex;				}			}		}		return Integer.parseInt(found.substring(lowestIndex, highestIndex + 1));	}            LootTable loot = new LootTable();        class GUI extends JFrame {    	    	final JRadioButtonMenuItem quitSlayerJob = new JRadioButtonMenuItem();    	    	private JList list_6;    	private JList list_5;    	private JList list_4;    	private JTextField textField_1;    	private JButton addButton;    	private JButton saveButton;    	private JButton clearButton;    	private JButton rSelectedButton;    	private JList list_2;    	private JList list;    	private JTextField npcName;    	private JList list_1;    	private JTextField npcName_1;    	private JTextField npcHP;    	JRadioButton useNamesRadioButton = new JRadioButton();    	JRadioButton useNamesRadioButton_1 = new JRadioButton();    	final JRadioButtonMenuItem newRadiobuttonRadioButtonMenuItem_1 = new JRadioButtonMenuItem();    	final JRadioButtonMenuItem bankAtFullInvLoot = new JRadioButtonMenuItem();    	    	boolean lootListBoolean = true;    			public void doStart() {			EventQueue.invokeLater(new Runnable() {				public void run() {						try {					        JFrame window = new GUI();				       					        window.setVisible(true);							} catch (Exception e) {							e.printStackTrace();						}					}				});		}            	public GUI() {    		super();    		getContentPane().setBackground(Color.DARK_GRAY);    		setIconImage(swm.getImage(GUI.class, "/fighting_the_basics.jpg"));    		setResizable(false);    		setSize(500, 394);    		setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);    		setBackground(Color.BLACK);    		setAlwaysOnTop(true);    		getContentPane().setLayout(null);    		final JTabbedPane tabbedPane = new JTabbedPane();    		tabbedPane.setBorder(new BevelBorder(BevelBorder.LOWERED));    		tabbedPane.setBackground(Color.GRAY);    		tabbedPane.setMaximumSize(new Dimension(500, 370));    		tabbedPane.setMinimumSize(new Dimension(500, 370));    		tabbedPane.setBounds(0, 0, 492, 348);    		getContentPane().add(tabbedPane);    		final JPanel panel = new JPanel();    		panel.setLayout(null);    		tabbedPane.addTab("General", null/*swm.getIcon(GUI.class, "/melee_the_basics.jpg")*/, panel, null);    		npcHP = new JTextField();    		npcHP.setText("8, 5");    		npcHP.setBounds(10, 80, 190, 20);    		panel.add(npcHP);    		npcName = new JTextField();    		npcName.setText("Cow, Goblin");    		npcName.setBounds(10, 26, 190, 20);    		panel.add(npcName);    		final JCheckBox useSolfacs05CheckBox = new JCheckBox();    		useSolfacs05CheckBox.setFocusable(false);    		useSolfacs05CheckBox.setSelected(true);    		useSolfacs05CheckBox.setText("Use solfac's 0.5 second boost ?");    		useSolfacs05CheckBox.setBounds(10, 257, 214, 24);    		panel.add(useSolfacs05CheckBox);    		useSolfacs05CheckBox.addItemListener(new ItemListener() {    			public void itemStateChanged(ItemEvent e) {    				if(!useSolfacs05CheckBox.isSelected())    					useSolfacs05CheckBox.setSelected(true);    			}    		});    		final JLabel typeYoureNpcLabel = DefaultComponentFactory.getInstance().createTitle("Type you're NPC and its HP, to add more NPC's split by \",SPACE\"");    		typeYoureNpcLabel.setBounds(10, 4, 463, 16);    		panel.add(typeYoureNpcLabel);    		final JButton startButton = new JButton();    		startButton.setForeground(Color.RED);    		startButton.setFont(new Font("Dialog", Font.BOLD | Font.ITALIC, 11));    		//startButton.setBackground(Color.BLACK);    		startButton.setText("Start !");    		startButton.setBounds(355, 254, 120, 30);    		panel.add(startButton);			startButton.addActionListener(new ActionListener() {				public void actionPerformed(final ActionEvent e) {						if(useNamesRadioButton.isSelected()){								useName = true;								NPCname = npcName.getText().split(", ");							} else {								useName = false;						        String[] temp2 = (String[]) java.util.Arrays.asList(npcName_1.getText().split(", ")).toArray();						        aNPCID = new int[temp2.length];						        for(int i=0; i < temp2.length;i++) {						            temp2[i] = temp2[i].trim();						            aNPCID[i] = Integer.parseInt(temp2[i]);						        }						}												for(int i = 0; i < npcHP.getText().length(); i++) 							NPChp = java.util.Arrays.asList(npcHP.getText().split(", ")).toArray();														if(!array.isEmpty()) {														lootList = (String []) array.toArray (new String [array.size ()]);							for(int i = 0; i < lootList.length; i++)								log(lootList[i]);						} else lootSystemEnabled = false;																				if(quitSlayerJob.isSelected()) {							log("quitSlayerJob.isSelected()");							quitAfterSlayerTask  = true;						} else if(!quitSlayerJob.isSelected()) {							log("!quitSlayerJob.isSelected()");							quitAfterSlayerTask = false;						}												if(newRadiobuttonRadioButtonMenuItem_1.isSelected()) {							log("eatFoodForLoot.isSelected()");							eatFoodForLoot = true;												} else if(!newRadiobuttonRadioButtonMenuItem_1.isSelected()) {							log("!eatFoodForLoot.isSelected()");							eatFoodForLoot  = false;						}												if(bankAtFullInvLoot.isSelected()) {							log("bankAtFullInvLoot.isSelected()");							bankAtFullInv = true;												} else if(!bankAtFullInvLoot.isSelected()) {							log("!bankAtFullInvLoot.isSelected()");							bankAtFullInv  = false;						}																System.out.println("Starting script.");																	dispose();					}			});    		npcName_1 = new JTextField();    		npcName_1.setText("Alternative, use ID's");    		npcName_1.setBounds(10, 52, 190, 20);    		panel.add(npcName_1);    		useNamesRadioButton.setText("Use names");    		useNamesRadioButton.setBounds(206, 24, 109, 24);    		panel.add(useNamesRadioButton);    		npcName_1.setEnabled(false);    		npcName.setEnabled(false);    		npcHP.setEnabled(false);    		    		useNamesRadioButton.addItemListener(new ItemListener() {    			public void itemStateChanged(ItemEvent e) {    				if(useNamesRadioButton.isSelected()) {    					npcName.setEnabled(true);    					npcHP.setEnabled(true);		    					useNamesRadioButton_1.setSelected(false);    				} else {    					npcName.setEnabled(false);		    				}					    			}    		});    		useNamesRadioButton_1.setText("Use ID's");    		useNamesRadioButton_1.setBounds(206, 50, 109, 24);    		panel.add(useNamesRadioButton_1);    		useNamesRadioButton_1.addItemListener(new ItemListener() {    			public void itemStateChanged(ItemEvent e) {    				if(useNamesRadioButton_1.isSelected()) {    					npcName_1.setEnabled(true);    					npcHP.setEnabled(true);	    					useNamesRadioButton.setSelected(false);    				} else {    					npcName_1.setEnabled(false);	    				}					    			}    		});    		final JLabel typeYoureNpcLabel_1 = DefaultComponentFactory.getInstance().createTitle("Post you're presets, as it will be added to GUI as preset selectable");    		typeYoureNpcLabel_1.setForeground(Color.PINK);    		typeYoureNpcLabel_1.setBounds(10, 287, 463, 16);    		panel.add(typeYoureNpcLabel_1);    		final JButton debugNpcNameButton = new JButton();    		debugNpcNameButton.setText("NPC to ID[]");    		debugNpcNameButton.setBounds(357, 52, 118, 26);    		panel.add(debugNpcNameButton);    		    		debugNpcNameButton.addActionListener(new ActionListener() {				public void actionPerformed(final ActionEvent e) {					String npcName = JOptionPane.showInputDialog( null, "Enter NPC name to return ID's from.",							JOptionPane.QUESTION_MESSAGE);					log(npcToID(npcName));				}			});    		final JButton interactingNPCID = new JButton();    		interactingNPCID.setText("Int. NPC to ID");    		interactingNPCID.setBounds(357, 85, 118, 26);    		panel.add(interactingNPCID);    		    		interactingNPCID.addActionListener(new ActionListener() {				public void actionPerformed(final ActionEvent e) {			        JOptionPane.showMessageDialog( null,			                "Interacting NPC ID equals :\n \n" +			                "     - " + interactingNpcID() + ". \n");				}			});    		final JButton debugNpcNameButton_1 = new JButton();    		debugNpcNameButton_1.setText("ID to name");    		debugNpcNameButton_1.setBounds(357, 117, 118, 26);    		panel.add(debugNpcNameButton_1);    		    		debugNpcNameButton_1.addActionListener(new ActionListener() {				public void actionPerformed(final ActionEvent e) {					String npcID = JOptionPane.showInputDialog( null, "Enter NPC ID.",							JOptionPane.QUESTION_MESSAGE);			        JOptionPane.showMessageDialog( null,			                "Interacting NPC ID equals :\n \n" +			                "     - " + idToName(Integer.parseInt(npcID.trim())) + ". \n");				}    		});    		list = new JList();    		list.setListData(new String[] { "Cows",    										"Hobgoblin",    										"Muggers",    										"Pirate's",    										"Seagulls"});    		list.setBounds(10, 137, 190, 114);    		panel.add(list);    		    		list.addListSelectionListener(new ListSelectionListener() {				public void valueChanged(ListSelectionEvent e) {					if(list.getSelectedValue().equals("Cows")) {						useNamesRadioButton_1.setSelected(true);						npcName_1.setText("81, 397, 1767, 2310");						npcHP.setText("8, 8, 8, 6");					}										if(list.getSelectedValue().equals("Hobgoblin")) {						useNamesRadioButton.setSelected(true);						npcName.setText("Hobgoblin, ");						npcHP.setText("29, ");					}										if(list.getSelectedValue().equals("Muggers")) {						useNamesRadioButton_1.setSelected(true);						npcName_1.setText("175, ");						npcHP.setText("8, ");					}										if(list.getSelectedValue().equals("Pirate's")) {						useNamesRadioButton.setSelected(true);						npcName.setText("Pirate, ");						npcHP.setText("24, ");					}										if(list.getSelectedValue().equals("Seagulls")) {						useNamesRadioButton_1.setSelected(true);						npcName_1.setText("6116, 6115");						npcHP.setText("10, 6");					}						            }			});    		final JLabel typeYoureNpcLabel_2 = DefaultComponentFactory.getInstance().createTitle("You can also choose the presets!");    		typeYoureNpcLabel_2.setBounds(10, 115, 225, 16);    		panel.add(typeYoureNpcLabel_2);    		list_2 = new JList();    		list_2.setListData(new String[] { "NPC data helper." });    		list_2.setBorder(new BevelBorder(BevelBorder.RAISED, Color.ORANGE, Color.ORANGE));    		list_2.setBounds(355, 26, 122, 119);    		panel.add(list_2);    		    		/*npcToID(NPC npcNameToFind)*/    		final JPanel panel_2 = new JPanel();    		panel_2.setLayout(null);    		tabbedPane.addTab("Loot & food", null, panel_2, null);    		rSelectedButton = new JButton();    		rSelectedButton.setBounds(159, 240, 100, 30);    		panel_2.add(rSelectedButton);    		rSelectedButton.setFont(new Font("", Font.BOLD, 11));    		//rSelectedButton.setBackground(new Color(0, 0, 0));    		rSelectedButton.setText("Clear item!");    		    		rSelectedButton.addActionListener(new ActionListener() {    			public void actionPerformed(final ActionEvent e) {    		    	if(list_4.getSelectedIndex() != -1 && lootListBoolean) {    		    		array.remove(list_4.getSelectedIndex());    		    		list_4.setListData(array.toArray());    		    	} else if(list_6.getSelectedIndex() != -1 && !lootListBoolean) {    		    		foodArray.remove(list_6.getSelectedIndex());    		    		list_6.setListData(foodArray.toArray());    		    	} else System.out.println("You have no item selected to remove");    			}    		});    		list_4 = new JList();    		list_4.setBounds(10, 10, 120, 296);    		panel_2.add(list_4);    		list_4.setBorder(new BevelBorder(BevelBorder.LOWERED));    		clearButton = new JButton();    		clearButton.setBounds(159, 276, 100, 30);    		panel_2.add(clearButton);    		clearButton.setFont(new Font("", Font.BOLD, 11));    		//clearButton.setBackground(new Color(0, 0, 0));    		clearButton.setText("Clear list!");    		clearButton.addActionListener(new ActionListener() {    			public void actionPerformed(final ActionEvent e) {    				if(lootListBoolean) {	    		    	array.removeAll(array);	    		    	list_4.setListData(array.toArray());    				} else if(!lootListBoolean) {	    		    	foodArray.removeAll(foodArray);	    		    	list_6.setListData(foodArray.toArray());    				}    			}    		});    		    		addButton = new JButton();    		addButton.setBounds(159, 168, 100, 30);    		panel_2.add(addButton);    		addButton.setFont(new Font("", Font.BOLD, 11));    		//addButton.setBackground(new Color(0, 0, 0));    		addButton.setText("Add");    		addButton.addActionListener(new ActionListener() {    			public void actionPerformed(final ActionEvent e) {    		    	if(!textField_1.toString().isEmpty() && lootListBoolean) {    		    		if(array.toArray() != null)     		    			saveButton.setVisible(true);    				    array.add(textField_1.getText());    				    System.out.println(textField_1.getText());    				    list_4.setListData(array.toArray());    		    	} else if(!textField_1.toString().isEmpty() && !lootListBoolean) {    		    		if(foodArray.toArray() != null)     		    			saveButton.setVisible(true);    		    		foodArray.add(textField_1.getText());    				    System.out.println(textField_1.getText());    				    list_6.setListData(foodArray.toArray());    		    	}    			}    		});    		    		    		saveButton = new JButton();    		saveButton.setBounds(159, 204, 100, 30);    		panel_2.add(saveButton);    		saveButton.setVisible(false);    		saveButton.setFont(new Font("", Font.BOLD, 11));    		//saveButton.setBackground(new Color(0, 0, 0));    		saveButton.setText("Save list!");    					try {				BufferedReader  saveLootList = new BufferedReader (new FileReader("sAdvancedCombatLootList.ini"));				if(saveLootList != null)					try {						String currentLine;						while((currentLine = saveLootList.readLine()) != null)													array.add(currentLine.trim());							list_4.setListData(array.toArray());					} catch (IOException e1) {											}			} catch (FileNotFoundException e1) {							}			    		list_4.setSelectedIndex(0);    					if(array.isEmpty() ) {				saveButton.setVisible(false);			} else saveButton.setVisible(true);			    		saveButton.addActionListener(new ActionListener() {    			public void actionPerformed(final ActionEvent e) {    		    	try {    		    		PrintStream saveLootList = new PrintStream(new FileOutputStream("sAdvancedCombatLootList.ini"), true);    					    		    		for(int i = 0; i < array.toArray().length; i++) {    						saveLootList.println(array.toArray()[i].toString());    					}			    					saveLootList.flush();    					saveLootList.close();    					System.out.println("Preferd loot list successfully saved to sAdvancedCombatLootList.ini");    					} catch (IOException eDebug) {    						eDebug.printStackTrace();    					}    			}    		});    		textField_1 = new JTextField();    		textField_1.setBounds(159, 132, 100, 30);    		panel_2.add(textField_1);    		list_5 = new JList();    		list_5.setBorder(new BevelBorder(BevelBorder.RAISED, new Color(255, 200, 0), new Color(255, 200, 0)));    		list_5.setBounds(287, 54, -5, 119);    		panel_2.add(list_5);    		final JButton toggleFoodLoot = new JButton();    		toggleFoodLoot.setText("<= Loot list <=");    		toggleFoodLoot.addActionListener(new ActionListener() {    			public void actionPerformed(ActionEvent e) {    				if(!lootListBoolean) {    					toggleFoodLoot.setText("<= Loot list <=");    					lootListBoolean = true;    				} else {    					lootListBoolean = false;    					toggleFoodLoot.setText("=> Food list = >");   						    				}    			}    		});    		toggleFoodLoot.setBounds(149, 10, 120, 30);    		panel_2.add(toggleFoodLoot);    		list_6 = new JList();    		list_6.setBorder(new BevelBorder(BevelBorder.LOWERED));    		list_6.setSelectedIndex(0);    		list_6.setBounds(353, 10, 120, 296);    		panel_2.add(list_6);    		    		final JPanel panel_1 = new JPanel();    		panel_1.setForeground(Color.WHITE);    		panel_1.setLayout(null);    		tabbedPane.addTab("F.a.q", null/*swm.getIcon(GUI.class, "/combat_faq.jpg")*/, panel_1, null);    		list_1 = new JList();    		list_1.setBorder(new BevelBorder(BevelBorder.LOWERED));    		list_1.setForeground(new Color(255, 0, 0));    		list_1.setFont(new Font("Dialog", Font.BOLD | Font.ITALIC, 11));    		list_1.setBounds(0, 0, 483, 263);    		panel_1.add(list_1);    		list_1.setListData(new String[] {    				 "1. Does this walk back and keeps killing ? " ,    				 "   * No, this script automaticly logs out when w.",    				 "",    				 "",     				 "2. Can I post suggestions ?",    				 "   * Yes, always feel free to post suggestions and/or opinions aswell critiscm.",    				 "",    				 "",     				 "You are 100% responsible for you're own account.",				     				 "",});    		final JMenuBar menuBar = new JMenuBar();    		setJMenuBar(menuBar);    		final JMenu generalMenu = new JMenu();    		generalMenu.setText("General");    		menuBar.add(generalMenu);    		final JMenu foodLootMenu = new JMenu();    		foodLootMenu.setText("Food & Loot");    		generalMenu.add(foodLootMenu);    		final JMenu foodMenu = new JMenu();    		foodLootMenu.add(foodMenu);    		foodMenu.setText("Food");    		final JRadioButtonMenuItem newRadiobuttonRadioButtonMenuItem_2 = new JRadioButtonMenuItem();    		    		final JRadioButtonMenuItem newRadiobuttonRadioButtonMenuItem_3 = new JRadioButtonMenuItem();    		newRadiobuttonRadioButtonMenuItem_3.setText("Restock");    		newRadiobuttonRadioButtonMenuItem_3.addActionListener(new ActionListener() {    			public void actionPerformed(ActionEvent e) {    				if(newRadiobuttonRadioButtonMenuItem_3.isSelected()) {    					newRadiobuttonRadioButtonMenuItem_2.setEnabled(true);    					restockFood = true;    				} else {    					newRadiobuttonRadioButtonMenuItem_2.setEnabled(false);      					restockFood = false;    				}    			}    		});    		foodMenu.add(newRadiobuttonRadioButtonMenuItem_3);    		//final JRadioButtonMenuItem newRadiobuttonRadioButtonMenuItem_2 = new JRadioButtonMenuItem();    		newRadiobuttonRadioButtonMenuItem_2.setText("Log at low HP ?");    		foodMenu.add(newRadiobuttonRadioButtonMenuItem_2);    		final JMenu lootMenu = new JMenu();    		foodLootMenu.add(lootMenu);    		lootMenu.setText("Loot");    		bankAtFullInvLoot.setText("Bank at full inventory");    		lootMenu.add(bankAtFullInvLoot);    		newRadiobuttonRadioButtonMenuItem_1.setText("Sacrifice food for loot ?");    		foodLootMenu.add(newRadiobuttonRadioButtonMenuItem_1);    		final JRadioButtonMenuItem smoothPaintCheckBox = new JRadioButtonMenuItem();    		smoothPaintCheckBox.setText("Smooth paint ?");    		smoothPaintCheckBox.addItemListener(new ItemListener() {    			public void itemStateChanged(ItemEvent e) {    				if(smoothPaintCheckBox.isSelected()) {    					smoothPaint = true;    				} else smoothPaint = false;    						    			}    		});    		generalMenu.add(smoothPaintCheckBox);    		quitSlayerJob.setText("Quit after slayer job ?");    		quitSlayerJob.setBounds(10, 227, 200, 24);    		generalMenu.add(quitSlayerJob);  		    		/*    		final JRadioButtonMenuItem newRadiobuttonRadioButtonMenuItem_1 = new JRadioButtonMenuItem();    		newRadiobuttonRadioButtonMenuItem_1.setText("After full, only loot stackable");    		lootMenu.add(newRadiobuttonRadioButtonMenuItem_1);*/    	}    	    	ArrayList<String> array 	= new ArrayList<String>(),    					  foodArray = new ArrayList<String>();    }		class SwingResourceManager {				private HashMap<String, Image> m_ClassImageMap = new HashMap<String, Image>();				private Image getImage(InputStream is) {			try {				ByteArrayOutputStream baos = new ByteArrayOutputStream();				byte buf[] = new byte[1024 * 4];				while (true) {					int n = is.read(buf);					if (n == -1)						break;					baos.write(buf, 0, n);				}				baos.close();				return Toolkit.getDefaultToolkit().createImage(baos.toByteArray());			} catch (Throwable e) {				return null;			}		}				public Image getImage(Class<?> clazz, String path) {			String key = clazz.getName() + '|' + path;			Image image = m_ClassImageMap.get(key);			if (image == null) {				if ((path.length() > 0) && (path.charAt(0) == '/')) {					String newPath = path.substring(1, path.length());					image = getImage(new BufferedInputStream(clazz.getClassLoader().getResourceAsStream(newPath)));				} else {					image = getImage(clazz.getResourceAsStream(path));				}				m_ClassImageMap.put(key, image);			}			return image;		}				public Image getImage(String path) {			return getImage("default", path); //$NON-NLS-1$		}				public Image getImage(String section, String path) {			String key = section + '|' + SwingResourceManager.class.getName() + '|' + path;			Image image = m_ClassImageMap.get(key);			if (image == null) {				try {					FileInputStream fis = new FileInputStream(path);					image = getImage(fis);					m_ClassImageMap.put(key, image);					fis.close();				} catch (IOException e) {					return null;				}			}			return image;		}				public void clearImages(String section) {			for (Iterator<String> I = m_ClassImageMap.keySet().iterator(); I.hasNext();) {				String key = I.next();				if (!key.startsWith(section + '|'))					continue;				Image image = m_ClassImageMap.get(key);				image.flush();				I.remove();			}		}				public ImageIcon getIcon(Class<?> clazz, String path) {			return getIcon(getImage(clazz, path));		}				public ImageIcon getIcon(String path) {			return getIcon("default", path); //$NON-NLS-1$		}				public ImageIcon getIcon(String section, String path) {			return getIcon(getImage(section, path));		}		public ImageIcon getIcon(Image image) {			if (image == null)				return null;			return new ImageIcon(image);		}	}    public void paint(Graphics Solfac) {    	if(smoothPaint) {    		Graphics2D g2d = (Graphics2D) Solfac;    		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);    	}		long timePassed = runTime.getTimeElapsed();		long runTimer = timePassed;		long TotalSecs = runTimer / 1000;		long TotalMins = TotalSecs / 60;		long TotalHours = TotalMins / 60;		int seconds = (int) TotalSecs % 60;		int minutes = (int) TotalMins % 60;		int hours = (int) TotalHours % 60;		String time = hours + "H:" + minutes + "M:" + seconds + "S";        Solfac.setColor(Color.BLACK/*new Color(0, 0, 0, 0)*/);        Solfac.setFont(new Font("Comic Sans", Font.BOLD, 12));        Solfac.fillRoundRect(340,345, 172,  113, 1, 1);        Solfac.setColor(new Color(0, 0, 0, 90));        Solfac.fillRoundRect(140, 15, 175, 125, 1, 1);		        Solfac.setColor(Color.WHITE);        try {			Solfac.drawString("Attack level      : " + theTabs.Statistics.getStatBottom(Skill.ATTACK)     + " , " + getPercentToNextLevel(Skill.ATTACK)      + "%", 345, 355);	        Solfac.drawString("Strength level  : " + theTabs.Statistics.getStatBottom(Skill.STRENGTH)      + " , " + getPercentToNextLevel(Skill.STRENGTH)    + "%", 345, 370);	        Solfac.drawString("Defence level   : " + theTabs.Statistics.getStatBottom(Skill.DEFENSE)      + " , " + getPercentToNextLevel(Skill.DEFENSE)     + "%", 345, 385);	        Solfac.drawString("Ranged level      : " + theTabs.Statistics.getStatBottom(Skill.RANGED)       + " , " + getPercentToNextLevel(Skill.RANGED)       + "%", 345, 400);	        Solfac.drawString("Hitpoints level  : " + theTabs.Statistics.getStatBottom(Skill.HITPOINTS)     + " , " + getPercentToNextLevel(Skill.HITPOINTS)   + "%", 345, 415);		} catch (InterruptedException e) {			e.printStackTrace();		}		        Solfac.setColor(Color.CYAN);            	Solfac.drawString("Gained " + (combatXP() - startCombatXP) + " xp.", 345, 445);                Solfac.setColor(Color.GREEN);        	Solfac.drawString(paint1, 150, 35);        	Solfac.drawString(paint2, 150, 50);        	Solfac.drawString(paint3, 150, 65);                Solfac.setColor(Color.PINK);        	Solfac.drawString("Xp/h + hp : " +  avarageXpAHour(timePassed, totalCombatXP(), startTotalCombatXP), 150, 80);        	Solfac.drawString("Xp a hour : " +  avarageXpAHour(timePassed, combatXP(), startCombatXP), 150, 95);		        Solfac.setColor(Color.ORANGE);  			Solfac.drawString("Script run time: " + time, 150, 110);			Solfac.drawString("Boosted " + hSeconds + " times", 150, 125);	}        private double getPercentToNextLevel(Skill thisSkill) throws InterruptedException {		int lvl = theTabs.Statistics.getStatBottom(thisSkill);		if (lvl == 99) 			return 0;				int xpTotal = xpTable[lvl + 1] - xpTable[lvl];		if (xpTotal == 0) 			return 0;						int xpDone = theTabs.Statistics.getStatExperience(thisSkill) - xpTable[lvl];        return round((double) 100 * xpDone / xpTotal, 3);	}        int[] xpTable = { 0, 0, 83, 174, 276, 388, 512, 650, 801, 969, 1154, 1358, 1584,		1833, 2107, 2411, 2746, 3115, 3523, 3973, 4470, 5018, 5624, 6291, 7028, 7842, 8740, 9730,		10824, 12031, 13363, 14833, 16456, 18247, 20224, 22406, 24815, 27473, 30408, 33648, 37224,		41171, 45529, 50339, 55649, 61512, 67983, 75127, 83014, 91721, 101333, 111945, 123660,		136594, 150872, 166636, 184040, 203254, 224466, 247886, 273742, 302288, 333804, 368599,		407015, 449428, 496254, 547953, 605032, 668051, 737627, 814445,  899257, 992895, 1096278,		1210421, 1336443, 1475581, 1629200, 1798808, 1986068, 2192818, 2421087, 2673114, 2951373,		3258594, 3597792, 3972294, 4385776, 4842295, 5346332, 5902831, 6517253, 7195629, 7944614,		8771558, 9684577, 10692629, 11805606, 13034431 };    	float avarageXpAHour(long timePassed, int currentXp, int startXp) {		long tempTime = timePassed / 60 / 60;		float avgTime = (float)tempTime / (currentXp - startXp);		return 1000 / avgTime;	}	public boolean clickReflectionObject(Object obj, String name, String action, Object3D obj3D, boolean boundary, int[] ids) throws InterruptedException {		if (obj == null) return false;		NPC npc = null;		PhysicalObject po = null;		GroundItem item = null;		AryanTile clickTile = null;		AryanTile myLocation = getLocation();		AryanTile targetTile = null;		int idType = 0;				if (obj instanceof NPC) npc = (NPC)obj;		else if (obj instanceof PhysicalObject) po = (PhysicalObject)obj;		else if (obj instanceof GroundItem) item = (GroundItem)obj;		else if (obj instanceof AryanTile) clickTile = (AryanTile)obj;		else throw new InterruptedException("Not a clickable Reflection object, scripter error.");		// instances change, cache the targets tile to watch for reflection errors causing target switches		if (npc != null) targetTile = npc.getLocation();		else if (item != null) targetTile = item.getLocation();		else if (po != null) targetTile = po.getLocation();		// instances change, cache the targets ID or type to watch for reflection errors causing errors or target's state change during click		if (npc != null) idType = npc.getType();		else if (item != null) idType = item.getID();		else if (po != null) idType = po.getID();		// default 3D bounds		if (po != null && obj3D == null) obj3D = new Object3D(-30,30,-30,30,0,20,false);		if (item != null && obj3D == null) obj3D = new Object3D(-15, 15, -15, 15, 0, 5,false);		if (clickTile != null && obj3D == null) obj3D = new Object3D(-15+be.clickTileXOffset, 15+be.clickTileXOffset, -15+be.clickTileYOffset, 15+be.clickTileYOffset, 0, 5,false);		if (npc != null && obj3D == null && npc.getName().equals("Fishing spot")) obj3D = new Object3D(-30,30,-30,30,0,5, false); // fishing spot default bounds		else if (npc != null && obj3D == null) obj3D = new Object3D(-15,15,-15,15,75,160, false); // torso of a man		if (name == null && npc != null)		{			name = npc.getName();			if (name == null) return false;		}		if (action != null) action = TextFormat.format(action);		if (name != null)		{			name = TextFormat.format(name);			if (name.contains("'")) name = name.replaceAll("'"," ");  // apostrophe doesn't OCR well		}		Timer totalTime = new Timer(5000);		Timer temp = new Timer(200);		int notIt = 0;		while (true) {			temp.reset();			if (totalTime.isUp() && !isMoving()) return false;			if (npc != null && (npc.inCombat() || !npc.valid())) return false; //TODO test			if (item != null && !item.valid()) return false;			if (po != null && (!po.valid() || !be.objMatchesID(po, ids))) return false;			// recheck our instance			if (npc != null && !npc.getLocation().equals(targetTile)) {				npc = be.getNPCByType(new int[] {idType}, targetTile);				targetTile = npc.getLocation();  // adjust since npcs move				if (npc == null) {					log("NPC gone since command initiated, aborting.");					return false;				}			}			else if (item != null && !item.getLocation().equals(targetTile))			{				item = be.getGroundItem(new int[] {idType}, targetTile);				if (item == null)				{					log("Ground Item changed position or IDs since command initiated, aborting.");					return false;				}			} else if (po != null && !po.getLocation().equals(targetTile)) {				po = be.getPhysicalObject(ids, targetTile, true, 50, boundary);				if (po == null)				{					log("Physical Object changed position or IDs since command initiated, aborting.");					return false;				}			}			be.resetBestPointToClick();			XY point = be.getBestPointToClick(obj, obj3D,boundary,ids);			XY lastPosition = point;  // keep track of the value without adding a lead to it			if (point != null) {				paintPoint(point, new Color(255, 0, 0, 60), 1000, 10);				MouseCommand mc = MouseCommand.Move(getPriority(), Thread.currentThread(), point.x, point.y);				enterCommand(mc, false);				Timer seek = new Timer(2000);				notIt = 0;				boolean possibleRightClick = false;				// once we reach our target and don't have the toptext we want or a suitable right click target,				// chase it for the seek time and see if we get a suitable clicking spot.				String top = null;				while(seek.isNotUp() && point != null) {					if (npc != null && /*(npc.inCombat() || */!npc.valid()/*)*/)  { //TODO test						return false;					} else if (item != null && !item.valid()) {						return false;					} else if (po != null && !po.valid()) return false;					sleep(1); //Solfac speedup					top = TextFormat.format(theTopText.getTopText());					//log(top + " " + notIt);					// top text hit during mouse chase					if ((action == null || top.contains(action)) && (name == null || top.contains(name)) && getCurrentMouseXY().distanceTo(point) < be.clickAccuracy) {						point = getCurrentMouseXY();						break;					}					// if the point is reached and it's a possible rightclick, wait for one more cycle before trying the right click					else if ((clickTile != null || !top.equals("walk here")) && getCurrentMouseXY().x == point.x && getCurrentMouseXY().y == point.y)					{						if (possibleRightClick)						{							//log(possibleRightClick);							point = getCurrentMouseXY();							break;						}						else possibleRightClick = true;					}					XY point2 = be.getBestPointToClick(obj, obj3D,boundary,ids);					if (point2 != null)					{						paintPoint(point2, new Color(0, 255, 0, 60), 1000, 5);						//paintPoint(new XY(this.getCurrentMouseXY().x,this.getCurrentMouseXY().y), new Color(255, 255, 255, 60), 5000, 1);						int leadMultiplier = 0;						int mouseDistanceToTarget = point2.distanceTo(getCurrentMouseXY());						if (mouseDistanceToTarget > 300) leadMultiplier = 4;  // target 400ms ahead for intercept						else if (mouseDistanceToTarget > 200) leadMultiplier = 3;  // target 300ms ahead for intercept						else if (mouseDistanceToTarget > 100) leadMultiplier = 2;  // target 200ms ahead for intercept						else if (mouseDistanceToTarget > 0) leadMultiplier = 1;  // target 100ms ahead for steady toptext						XY targetPoint = new XY(point2.x+((point2.x-lastPosition.x)*leadMultiplier), point2.y+((point2.y-lastPosition.y)*leadMultiplier));						if (targetPoint.distanceTo(point) > 0)						{							point = targetPoint;							lastPosition = point2;							//point = point2;							if (mc.isDone())							{								mc = MouseCommand.Move(getPriority(), Thread.currentThread(), point.x, point.y);								enterCommand(mc, false);							}							else							{								mc.changeDestination(point.x, point.y);							}						}						else if (point2.distanceTo(point) == 0 && getCurrentMouseXY().x == point2.x && getCurrentMouseXY().y == point2.y)						{							notIt++;						}					}					int movedDistance = getLocation().distanceTo(myLocation);					if (movedDistance > be.teleportDetectionRange)					{						log("We moved " + movedDistance + " since this click command was issued.  Quitting from possible teleport.");						return false;					}					if (notIt >= 3) break;  // get best point gaves us an invalid spot				}				if (point == null) return false;				if (!((action == null || top.contains(action)) && (name == null || top.contains(name))))					waitTillNextFrame(); // slight pause for toptext				top = TextFormat.format(theTopText.getTopText());				paintPoint(point, new Color(0, 0, 255, 60), 1000, 10);				log(top + " " + action + " " + name);				if ((action == null || top.contains(action)) && (name == null || top.contains(name)))				{					mouseClickLeft(point);					// Watch the onscreen X to see if we clicked a red X interactive object or yellow walked					Timer xt = new Timer(200);					while(xt.isNotUp())					{						// test the onscreen X to see if it is red						XY clickedPoint = getCurrentMouseXY();						if (Areas.GAME.contains(clickedPoint.x, clickedPoint.y))						{							if (clickedPoint.x - 5 <= 0									||clickedPoint.x - 5 >= 746									|| clickedPoint.y - 5 >= 501									|| clickedPoint.y - 5 <= 0)							{								log("Area offscreen");								return true;							}							else							{								int x = clickedPoint.x - 10;								int y = clickedPoint.y - 10;								if (x < 0) x = 0;								if (y < 0) y = 0;								Rectangle area = new Rectangle(x, y, 20, 20);								boolean redX = (ColorMapAnaylsis.findRGB(getColorMap(), new RGB(255, 0, 0), area) != null);								if (clickTile != null && !redX) return true;								else if (redX) return true;							}						}						else						{							log("Not in game screen.");							return true;						}						waitTillNextFrame();					}					return false;				}				else if (clickTile != null || !top.equals("walk here")) // if it is just walk here without any options, we are not over a possible target unless we are trying to click a tile for walking				{					mouseClickRight(point);					waitTillNextFrame();					impsoft.scripting.ibot.builtin.ocr.Menu m = null;					Timer mTimer = new Timer(1000);					while((m = theMenuFinder.getMenu()) == null && mTimer.isNotUp()) sleep(100);					if (m != null)					{						sleep(100,250); // slow down the right click menu, humans need to look						if (m.clickContains(action + " " + name))						{							return true;						}						// Work-around for clicking on Bank Banker so that it doesn't match the toptext and try to talk						else if (action != null && action.contains(" ") && m.clickContains(action))						{							return true;						}						else						{							boolean nameFound = false;							// deal with partial or sloppy input							for(int i=0; i<m.getNumOfOptions(); i++)							{								String option = TextFormat.format(m.getOption(i));								if (name != null && option.contains(name)) nameFound = true;								if ((action == null || option.contains(action)) && (name == null || option.contains(name))) {									m.clickOption(i);									return true;								}							}							// special case, misclick on bank booth, but snag a banker							if (name != null && (name.contains("bank") || name.contains("booth")) && action.contains("quick")) {								if (m.clickContains("Bank Banker") || m.clickContains("Bank Bank Tutor")) {									return true;								}							}							m.exit();							if(nameFound) {								log("Rightclick menu had the name but not the action.  We think we clicked right, but option not available.");								return false;							}							//test if point is within 20 pixels of the screen boundary?  If so screenwalk half-way there.							if (point.x <= 20 || point.x >= 495 || point.y <= 20 || point.y >= 317)							{								log("target point is on boundary and might be obscured, moving forward");								AryanTile goal = null;								if (npc != null) goal = npc.getLocation();								else if (po != null) goal = po.getLocation();								else if (item != null) goal = item.getLocation();								else if (clickTile != null) goal = clickTile;								AryanTile here = getLocation();								AryanTile halfway = new AryanTile(here.x + (goal.x-here.x)/2, here.y + (goal.y-here.y)/2);								be.screenWalkToTile(halfway);							}						}					}				}			} else if (be.walkToTile) {				if (!isMoving()) {					int movedDistance = getLocation().distanceTo(myLocation);					if (movedDistance > be.teleportDetectionRange) {						log("We moved " + movedDistance + " since this click command was issued.  Quitting from possible teleport.");						return false;					}					boolean walkTo = false;					AryanTile goal = null;					if (npc != null) goal = npc.getLocation();					else if (po != null) goal = po.getLocation();					else if (item != null) goal = item.getLocation();					else if (clickTile != null) goal = clickTile;					if (goal.distanceTo(getLocation()) > 10) {						walkTo = true;					} else {						if (be.moveCamera) {							this.theParallelCompass.setCameraToTile(goal);						}						if (be.getBestPointToClick(obj, obj3D,boundary,ids) == null) {							walkTo = true;						}					}					if(walkTo) {							this.theParallelCompass.setCameraToTile(goal);													if(getLocation().distanceTo(goal) <= 12) {																			int times = 0;								while(npc != null && npc.getGameScreenLocation() == null) {									AryanTile[] t = generateOnScreenPath(getLocation(), aNPC.getLocation());																			for(int i = 0; i < t.length; i++) {										if(be.screenWalkToTile(t[i])) {											log("Using onScreenWalk");											while(getLocation().distanceTo(t[i]) >= 1 && isMoving())												sleep(20);											times++;										} else {											be.walkToMinimapTarget(goal);										}									}																			if(times > 5) {										log("Failed to see NPC in 5 times.");										break;									}								}							} else be.walkToMinimapTarget(goal);							totalTime = new Timer(7000); // allow a little more time					}				}			}			int movedDistance = getLocation().distanceTo(myLocation);			if (movedDistance > be.teleportDetectionRange) {				log("We moved " + movedDistance + " since this click command was issued.  Quitting from possible teleport.");				return false;			}			long timetemp = temp.getTimeRemaining();			if (timetemp > 0)			sleep(timetemp);		}	}	ScriptJob sj = null;		AryanTile[] generateOnScreenPath(AryanTile start, AryanTile dest) { 		int startX = start.x, startY = start.y, destX = dest.x, destY = dest.y;		double dx, dy;		ArrayList<AryanTile> list = new ArrayList<AryanTile>();		while (Math.hypot(destY - startY, destX - startX) > 5) {			dx = destX - startX;			dy = destY - startY;			int random = random(4, 5);			while(Math.hypot(dx, dy) > random) {				dx *= .95;				dy *= .95;			}			startX += (int) dx;			startY += (int) dy;						//list.add(new AryanTile(startX, startY));		}		if(list.toArray().length == 0)		 list.add(dest);				return list.toArray(new AryanTile[list.size()]);	}	}