import java.awt.Color;
import java.awt.Graphics;
import java.awt.Polygon;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.powerbot.concurrent.Task;
import org.powerbot.concurrent.strategy.Strategy;
import org.powerbot.game.api.Manifest;
import org.powerbot.game.api.methods.Walking;
import org.powerbot.game.api.methods.interactive.NPCs;
import org.powerbot.game.api.methods.node.SceneEntities;
import org.powerbot.game.api.methods.tab.Skills;
import org.powerbot.game.api.methods.widget.Camera;
import org.powerbot.game.api.util.Filter;
import org.powerbot.game.api.wrappers.Entity;
import org.powerbot.game.api.wrappers.Locatable;
import org.powerbot.game.api.wrappers.Tile;
import org.powerbot.game.api.wrappers.interactive.NPC;
import org.powerbot.game.api.wrappers.node.SceneObject;
import org.powerbot.game.bot.event.MessageEvent;
import org.powerbot.game.bot.event.listener.MessageListener;
import org.powerbot.game.bot.event.listener.PaintListener;
@Manifest(authors = { "AlexDkk", "Dragonkk" }, name = "MatrixRunespan", version = 1.02, website = "http://wwww.matrixrsps.com"
, description = "Train rc at best xp rate available!")
public final class MatrixRunespan extends DragonkkScript implements MessageListener, PaintListener {
private static final int FLOATING_ESSENCE = 15402;
private static final int ESSENCE = 24227;
public static enum CREATURES {
Air_essling(15403, 1, 9.5, false)
,Mind_essling(15404, 1, 10, false)
,Water_essling(15405, 5, 12.5, false)
,Earth_essling(15406, 9, 14.5, false)
,Fire_essling(15407, 14, 17.5, false)
,Body_esshound(15408, 20, 23.5, false)
,Cosmic_esshound(15409, 27, 26.5, true)
,Chaos_esshound(15410, 35, 30.66, true)
,Astral_esshound(15411, 40, 35.5, true)
,Nature_esshound(15412, 44, 43.5, true)
,Law_esshound(15413, 54, 54, true)
,Death_esswraith(15414, 66, 60, true)
,Blood_esswraith(15415, 77, 73, true)
,Soul_esswraith(15416, 90, 107, true)
;
private int id, level;
private double experience;
private boolean member;
private CREATURES(int id, int level, double experience, boolean member) {
this.id = id;
this.level = level;
this.experience = experience;
this.member = member;
}
}
public static enum NODES {
Cyclone(70455, 1,false, 19)
,Mind_storm(70456, 1,false, 20)
,Water_pool(70457, 5,false, 25.5)
,Rock_fragment(70458, 9,false, 28.6)
,Fireball(70459, 14,false, 34.8)
,Vine(70460, 17,false, 32.5)
,Fleshy_growth(70461, 20,false, 46.2)
,Fire_storm(70462, 27, false, 22, 42)
,Chaotic_cloud(70463, 35,true, 61.5)
,Nebula(70464, 40, true, 64, 85.5)
,Shifter(70465, 44, true, 86.8)
,Jumper(70466, 54, true, 107)
,Skulls(70467, 66, true, 120)
,Blood_pool(70468, 77, true,146)
,Bloody_skulls(70469, 83, true, 144, 176)
,Living_soul(70470, 90, true, 213)
,Undead_soul(70471, 95, true, 144, 255.5)
;
private int id, level;
private double[] experience;
private boolean member;
private NODES(int id, int level, boolean member, double... experience) {
this.id = id;
this.level = level;
this.member = member;
this.experience = experience;
}
private double getAverageExperience() {
int exp = 0;
for(double xp : experience)
exp += xp;
return exp / experience.length;
}
}
private Entity currentEntity;
private int startExperience, killedCreatures, killedNodes;
private long startTime;
private boolean gatherRunes;
private boolean memberWorld;
private Map<Integer, Integer> npcEmotes;
public static CREATURES getCreature(int id) {
for(CREATURES creature : CREATURES.values())
if(creature.id == id)
return creature;
return null;
}
public static NODES getNode(int id) {
for(NODES node : NODES.values())
if(node.id == id)
return node;
return null;
}
public boolean acceptDistance(Tile tile) {
return tile.canReach();
}
public Entity getBestAvailableResource() {
final int currentRCLevel = Skills.getLevel(Skills.RUNECRAFTING);
NPC[] possibleCreatures = NPCs.getLoaded(new Filter<NPC>() {
@Override
public boolean accept(NPC paramT) {
if(!paramT.validate() || !acceptDistance(paramT.getLocation()))
return false;
CREATURES creature = getCreature(paramT.getId());
if(creature != null && creature.level <= currentRCLevel && !(!memberWorld && !creature.member)) {
Integer emote = npcEmotes.get(paramT.getId());
if(emote != null) {
if(paramT.getAnimation() != -1 && paramT.getAnimation() != emote)
return false;
}
return true;
}
return false;
}
});
SceneObject[] possibleNodes = gatherRunes ? new SceneObject[0] : SceneEntities.getLoaded(new Filter<SceneObject>() {
@Override
public boolean accept(SceneObject paramT) {
if(!paramT.validate() || !acceptDistance(paramT.getLocation()))
return false;
NODES node = getNode(paramT.getId());
return node != null && node.level <= currentRCLevel && !(!memberWorld && !node.member);
}
});
double experience = 0;
List<Entity> entities = new ArrayList<Entity>();
for(NPC n : possibleCreatures) {
double xp = getCreature(n.getId()).experience;
if(xp > experience) {
entities.clear();
entities.add(n);
experience = xp;
}else if (xp == experience)
entities.add(n);
}
for(SceneObject o : possibleNodes) {
double xp = getNode(o.getId()).getAverageExperience();
if(xp > experience) {
entities.clear();
entities.add(o);
experience = xp;
}else if (xp == experience)
entities.add(o);
}
if(entities.isEmpty())
return null;
Entity resource = null;
int distance = Integer.MAX_VALUE;
Tile myLoc = getMyPlayer().getLocation();
for(Entity possiblity : entities) {
int dis = Calc.distanceBetween(myLoc, ((Locatable) possiblity).getLocation());
if(dis < distance) {
distance = dis;
resource = possiblity;
}
}
return resource;
}
public boolean needsEntityChange(Entity nextEntity) {
if(currentEntity == null
|| currentEntity.getClass() != nextEntity.getClass())
return true;
if(nextEntity instanceof SceneObject) {
SceneObject nextObject = (SceneObject) nextEntity;
SceneObject currentObject = (SceneObject) currentEntity;
return nextObject.getId() != currentObject.getId();
}else if(nextEntity instanceof NPC) {
NPC nextNPC = (NPC) nextEntity;
NPC currentNPC = (NPC) currentEntity;
return nextNPC.getId() != currentNPC.getId();
}
return true;
}
public boolean setNextEntity(Entity nextEntity) {
currentEntity = nextEntity;
if(!nextEntity.isOnScreen())
Camera.turnTo((Locatable) nextEntity, 15);
if(!nextEntity.isOnScreen())
Walking.walk(((Locatable) nextEntity).getLocation());
return nextEntity.interact("Siphon");
}
public int getEarnedExperience() {
return Skills.getExperience(Skills.RUNECRAFTING) - startExperience;
}
@Override
protected void setup() {
npcEmotes = new HashMap<Integer, Integer>();
super.setup();
provide(new Strategy(this, new Task() {
@Override
public void run() {
setEmote();
}
}));
}
@Override
public boolean onStart() {
startTime = System.currentTimeMillis();
startExperience = Skills.getExperience(Skills.RUNECRAFTING);
memberWorld = GameEx.isAtMemberWorld();
return true;
}
public int getRunesCount() {
return InventoryEx.getQuantity(ESSENCE);
}
@Override
public int loop() {
//widget closer does it
/* WidgetChild component = Widgets.get(1218, 73);
if(component.isOnScreen()) {
component.click(true);
return 600;
}*/
if(getRunesCount() == 0) {
if(!getMyPlayer().isMoving() && getMyPlayer().getAnimation() == -1) {
NPC n = NPCs.getNearest(FLOATING_ESSENCE);
if(!n.isOnScreen())
Camera.turnTo(n, 15);
n.interact("Collect");
gatherRunes = true;
}
return 600;
}else if (gatherRunes && getRunesCount() >= 100)
gatherRunes = false;
if (currentEntity instanceof NPC) {
NPC n = (NPC) currentEntity;
Integer emote = npcEmotes.get(n.getId());
if(emote != null) {
if(n.getAnimation() != -1 && n.getAnimation() != emote)
currentEntity = null;
}
}
if(currentEntity != null && getMyPlayer().getAnimation() != 16596 && !getMyPlayer().isMoving()) {
if(!currentEntity.isOnScreen())
currentEntity = null;
else {
sleep(3600);
if(getMyPlayer().getAnimation() != 16596 && !getMyPlayer().isMoving())
currentEntity = null;
}
}
Entity nextEntity = getBestAvailableResource();
if(nextEntity != null && needsEntityChange(nextEntity))
if(!setNextEntity(nextEntity))
currentEntity = null;
return 600;
}
public void setEmote() {
if (currentEntity instanceof NPC) {
NPC n = (NPC) currentEntity;
if(!npcEmotes.containsKey(n.getId())) {
int emote = n.getAnimation();
if(emote != -1) {
npcEmotes.put(n.getId(), emote);
}
}
}
}
@Override
public void messageReceived(MessageEvent paramMessageEvent) {
String message = paramMessageEvent.getMessage();
if(message.equals("You pick up the essence left by the creature."))
killedCreatures++;
else if(message.equals("The node you were siphoning from has been depleted of energy."))
killedNodes++;
/* switch(paramMessageEvent.getMessage()) {
case "You pick up the essence left by the creature.":
killedCreatures++;
break;
case "The node you were siphoning from has been depleted of energy.":
killedNodes++;
break;
}*/
}
private static String getFormatedTime(long seconds) {
long minutes = seconds / 60;
long hours = minutes / 60;
minutes -= hours * 60;
seconds -= (hours * 60 * 60) + (minutes * 60);
String minutesString = (minutes < 10 ? "0" : "") + minutes;
String secondsString = (seconds < 10 ? "0" : "") + seconds;
return hours+":"+minutesString+":"+secondsString;
}
private static void drawString(Graphics g, String s, Color c, int x, int y) {
g.setColor(Color.BLACK);
g.drawString(s, x + 1, y + 1);
g.setColor(c);
g.drawString(s, x, y);
}
public String getName() {
try {
Entity e = currentEntity;
if(e == null || !e.validate())
return "Nothing";
else if(e instanceof NPC) {
NPC n = (NPC) e;
return n.getName();
}else if(e instanceof SceneObject) {
SceneObject o = (SceneObject) e;
return o.getDefinition().getName();
}
}catch(Throwable e) { //getname gives errors sometimes
currentEntity = null;
}
return "Unknown";
}
@Override
public void onRepaint(Graphics g) {
int x = 350;
int y = 210;
g.setColor(new Color(64, 64, 64, 128));
g.fillRoundRect(x - 10, y - 20, 170, 110 + 30, 20, 20);
drawString(g, "Matrix Runespan version 1.02", Color.CYAN, x, y);
drawString(g, "by Dragonkk", Color.CYAN, x, y + 10);
int seconds = (int)((System.currentTimeMillis() - startTime) / 1000);
drawString(g, "Running for " + getFormatedTime(seconds), Color.WHITE, x, y + 30);
drawString(g, "Siphoning: " + getName(), Color.WHITE, x, y + 50);
drawString(g, "Creatures killed: " + killedCreatures, Color.YELLOW, x, y + 70);
drawString(g, "Nodes killed: " + killedNodes, Color.YELLOW, x, y + 90);
double totalXp = getEarnedExperience();
drawString(g, "Experience: " + totalXp + " [" + (int)(totalXp / seconds * 3600) + "/h]", Color.GREEN, x, y + 110);
Entity e = currentEntity;
if(e != null && e.validate()) {
if(e instanceof NPC) {
g.setColor(Color.GREEN);
NPC n = (NPC) e;
Polygon[] bounds = n.getBounds();
for(Polygon p : bounds)
g.drawPolygon(p);
}else if(e instanceof SceneObject) {
g.setColor(Color.RED);
SceneObject o = (SceneObject) e;
Polygon[] bounds = o.getBounds();
for(Polygon p : bounds)
g.drawPolygon(p);
}
}
g.setColor(new Color(0, 255, 255, 50));
}
}