Equinox

EquinoxZMICrafter.java

Apr 5th, 2011
120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 56.98 KB | None | 0 0
  1. import java.awt.Color;
  2. import java.awt.Graphics;
  3. import java.awt.Graphics2D;
  4. import java.awt.Point;
  5. import java.awt.Polygon;
  6. import java.awt.Rectangle;
  7. import java.lang.reflect.Method;
  8. import java.util.ArrayList;
  9. import java.util.EnumSet;
  10. import java.util.HashMap;
  11. import java.util.List;
  12. import java.util.Random;
  13.  
  14. import javax.swing.JOptionPane;
  15.  
  16. import org.rsbot.event.events.MessageEvent;
  17. import org.rsbot.event.listeners.MessageListener;
  18. import org.rsbot.event.listeners.PaintListener;
  19. import org.rsbot.script.Script;
  20. import org.rsbot.script.ScriptManifest;
  21. import org.rsbot.script.methods.Equipment;
  22. import org.rsbot.script.methods.Game;
  23. import org.rsbot.script.methods.GrandExchange;
  24. import org.rsbot.script.methods.GrandExchange.GEItem;
  25. import org.rsbot.script.methods.Magic;
  26. import org.rsbot.script.methods.Skills;
  27. import org.rsbot.script.wrappers.RSComponent;
  28. import org.rsbot.script.wrappers.RSInterface;
  29. import org.rsbot.script.wrappers.RSItem;
  30. import org.rsbot.script.wrappers.RSNPC;
  31. import org.rsbot.script.wrappers.RSObject;
  32. import org.rsbot.script.wrappers.RSPath.TraversalOption;
  33. import org.rsbot.script.wrappers.RSTile;
  34. import org.rsbot.script.wrappers.RSTilePath;
  35.  
  36. @ScriptManifest(authors = "Equinox_", keywords = "Runecrafting", name = "Equinox_ ZMI Crafter", version = 0.7, description = "Beta Version")
  37. /**
  38.  * @author Equinox_
  39.  */
  40. public class EquinoxZMICrafter extends Script implements MessageListener,
  41.         PaintListener {
  42.  
  43.     // Variables
  44.     final String baseURL = "http://equinox-scripts.web44.net/scripts/natcrafter";
  45.     final double VERSION = getClass().getAnnotation(ScriptManifest.class)
  46.             .version();
  47.     final String author = PaintFormatter.formatList(getClass().getAnnotation(
  48.             ScriptManifest.class).authors());
  49.     final String name = getClass().getAnnotation(ScriptManifest.class).name();
  50.     public final static int COSMIC_RUNE_ID = 564;
  51.     public final static int ASTRAL_RUNE_ID = 9075;
  52.     public static final int AIR_STAFF_ID = 1405;
  53.     public final static int PURE_ESS_ID = 7936;
  54.     public final static int ZMI_ALTAR_ID = 26847;
  55.     public final static int AIR_RUNE_ID = 556;
  56.     public final static int NPC_CONTACT_ANIM = 4413;
  57.     public final static int BANKER_ID = 6362;
  58.     public final static int CRAFT_RUNE_ANIM = 791;
  59.     public final static int FIRE_RUNE_ID = 554;
  60.     public final static int CRACK_IN = 26844;
  61.     public final static int CRACK_OUT = 26845;
  62.     public final static RSTile alterDet = new RSTile(3314, 4813, 0);
  63.     public final static int PAY_BANK_INTERFACE = 619;
  64.     public final static int LAW_RUNE = 563;
  65.     public final static int ASTRAL_RUNE = 9075;
  66.     public final static int EARTH_RUNE = 557;
  67.     public final static String[] PAY_BANKER_ORDER = { "fire", "air", "mind",
  68.             "body", "water", "earth", "cosmic", "chaos", "astral", "law",
  69.             "death", "blood", "nature", "soul" };
  70.  
  71.     public final static RSTile[][] SAFE_MESH = { { new RSTile(3273, 4856, 0) },
  72.             { new RSTile(3280, 4848, 0) }, { new RSTile(3279, 4839, 0) },
  73.             { new RSTile(3286, 4832, 0) }, { new RSTile(3297, 4834, 0) },
  74.             { new RSTile(3309, 4836, 0) }, { new RSTile(3320, 4833, 0) },
  75.             { new RSTile(3310, 4828, 0) }, { new RSTile(3301, 4828, 0) },
  76.             { new RSTile(3289, 4829, 0) }, { new RSTile(3280, 4822, 0) },
  77.             { new RSTile(3290, 4820, 0) }, { new RSTile(3301, 4820, 0) },
  78.             { new RSTile(3308, 4820, 0) } };
  79.  
  80.     public final static RSTile[][] DANGER_MESH = {
  81.             { new RSTile(3272, 4851, 0), new RSTile(3269, 4854, 0) },
  82.             { new RSTile(3272, 4844, 0), new RSTile(3268, 4846, 0) },
  83.             { new RSTile(3271, 4837, 0), new RSTile(3268, 4838, 0) },
  84.             { new RSTile(3272, 4828, 0), new RSTile(3267, 4832, 0) },
  85.             { new RSTile(3273, 4821, 0), new RSTile(3268, 4825, 0) },
  86.             { new RSTile(3270, 4814, 0), new RSTile(3268, 4819, 0) },
  87.             { new RSTile(3275, 4808, 0), new RSTile(3276, 4814, 0) },
  88.             { new RSTile(3283, 4806, 0), new RSTile(3279, 4810, 0) },
  89.             { new RSTile(3288, 4812, 0), new RSTile(3287, 4807, 0) },
  90.             { new RSTile(3295, 4813, 0), new RSTile(3293, 4814, 0) },
  91.             { new RSTile(3300, 4807, 0), new RSTile(3298, 4813, 0) },
  92.             { new RSTile(3309, 4812, 0), new RSTile(3305, 4807, 0) } };
  93.     public final RSTile[] OURANIA_PATH = { new RSTile(2469, 3245),
  94.             new RSTile(2459, 3249), new RSTile(2455, 3239),
  95.             new RSTile(2453, 3232) };
  96.     public final static int POUCH_TRIES = 20;
  97.     public final static int[] food = { 333, 329, 379, 373, 7946, 361, 1901,
  98.             1899, 1897, 1895, 1893, 1891, 2142 };
  99.     public static final int LADDER_ID = 26849;
  100.  
  101.     // Pouch IDs
  102.     public static class Pouch {
  103.         public final static int SMALL = 5509;
  104.         public final static int MEDIUM = 5510;
  105.         public final static int MEDIUM_DEGRADED = 5511;
  106.         public final static int LARGE = 5512;
  107.         public final static int LARGE_DEGRADED = 5513;
  108.         public final static int GIANT = 5514;
  109.         public final static int GIANT_DEGRADED = 5515;
  110.         public final static int[] ALL = { SMALL, MEDIUM, MEDIUM_DEGRADED,
  111.                 LARGE, LARGE_DEGRADED, GIANT, GIANT_DEGRADED };
  112.         public final static int[] ALL_REPAIRED = { SMALL, MEDIUM, LARGE, GIANT };
  113.         public final static int[] ALL_DEGRADED = { MEDIUM_DEGRADED,
  114.                 LARGE_DEGRADED, GIANT_DEGRADED };
  115.         public final static int[] ALL_DEGRADEABLE = { MEDIUM, MEDIUM_DEGRADED,
  116.                 LARGE, LARGE_DEGRADED, GIANT, GIANT_DEGRADED };
  117.     }
  118.  
  119.     public static String serverMsg = "";
  120.     public HashMap<PouchType, PouchState> pouches = new HashMap<PouchType, PouchState>();
  121.     State currentState = State.LOST;
  122.     public MeshPath alterMeshPath;
  123.     public MeshPath bankMeshPath;
  124.     public NPCContact npcContact = new NPCContact();
  125.     public OptionsClass.Path pathTypeCurrent;
  126.     public OptionsClass Options = new OptionsClass();
  127.  
  128.     // Options
  129.     public static class OptionsClass {
  130.         public pouchRepairOption pouchRepair = pouchRepairOption.ONE;
  131.         public boolean hasAirStaff = true;
  132.         public boolean hasEarthStaff = true;
  133.         public PouchCheckSystem pouchCheckSystem = PouchCheckSystem.SERVER_MSG;
  134.         public Range walkingDistance = new Range(4, 6);
  135.         public Path pathType = Path.Danger;
  136.         public boolean chargeEnergy = true;
  137.         public boolean tryOuraniaTeleport = true;
  138.         public boolean onLunars = false;
  139.  
  140.         enum Path {
  141.             Danger, Safe
  142.         }
  143.  
  144.         /**
  145.          * When to repair pouches
  146.          *
  147.          * @author Equinox_
  148.          *
  149.          */
  150.         public enum pouchRepairOption {
  151.             ONE, TWO, ALL, NEVER
  152.         }
  153.  
  154.         /**
  155.          * How to determine a pouch's state
  156.          *
  157.          * @author Equinox_
  158.          *
  159.          */
  160.         public enum PouchCheckSystem {
  161.             SERVER_MSG, INVENTORY_STATUS
  162.         }
  163.  
  164.         /**
  165.          * A range class for randomized items
  166.          *
  167.          * @author Equinox_
  168.          *
  169.          */
  170.         public static class Range {
  171.             public int MAX;
  172.             public int MIN;
  173.  
  174.             public Range(int min, int max) {
  175.                 MAX = Math.max(min, max);
  176.                 MIN = Math.min(min, max);
  177.             }
  178.  
  179.             public Range() {
  180.                 MAX = 1;
  181.                 MIN = -1;
  182.             }
  183.  
  184.             /**
  185.              * Get a random number in the range
  186.              *
  187.              * @return random int between min and max
  188.              */
  189.             public int random() {
  190.                 return (int) (Math.random() * (MAX - MIN)) + MIN;
  191.             }
  192.  
  193.             /**
  194.              * Returns a normally distributed pseudorandom integer about a mean
  195.              * centered between min and max with a provided standard deviation.
  196.              *
  197.              * @param sd
  198.              *            The standard deviation. A higher value will increase
  199.              *            the probability of numbers further from the mean being
  200.              *            returned.
  201.              * @return Random integer min <= n < max from the normal
  202.              *         distribution described by the parameters.
  203.              */
  204.             public int random(int sd) {
  205.                 int mean = MIN + (MAX - MIN) / 2;
  206.                 int rand;
  207.                 do {
  208.                     rand = (int) (new Random().nextGaussian() * sd + mean);
  209.                 } while (rand < MIN || rand >= MAX);
  210.                 return rand;
  211.             }
  212.  
  213.             /**
  214.              * Returns a normally distributed pseudorandom integer about a mean
  215.              * centered between min and max with a calculated standard
  216.              * deviation.
  217.              *
  218.              * @return Random integer min <= n < max from the normal
  219.              *         distribution described by the parameters.
  220.              */
  221.             public int randomNormalDistribution() {
  222.                 int mean = MIN + (MAX - MIN) / 2;
  223.                 int rand;
  224.                 int sd = (MAX - MIN) / 3;
  225.                 do {
  226.                     rand = (int) (new Random().nextGaussian() * sd + mean);
  227.                 } while (rand < MIN || rand >= MAX);
  228.                 return rand;
  229.             }
  230.  
  231.             public String toString() {
  232.                 return MIN + "-" + MAX;
  233.             }
  234.         }
  235.     }
  236.  
  237.     public static int[] mergeArrays(int[] a1, int... a2) {
  238.         int[] newArr = new int[a1.length + a2.length];
  239.         for (int i = 0; i < a1.length; i++)
  240.             newArr[i] = a1[i];
  241.         for (int i = 0; i < a2.length; i++)
  242.             newArr[a1.length + i] = a2[i];
  243.         return newArr;
  244.     }
  245.  
  246.     /**
  247.      * Possible states in the process of nature runecrafting
  248.      *
  249.      * @author Equinox_
  250.      *
  251.      */
  252.     public enum State {
  253.         NEAR_BANK, NPC_CONTACT, BANK_WITHDRAW, BANK_DEPOSIT, FILL_POUCHES, TRAVERSE_ALTER, CRAFT_RUNES, EMPTY_POUCHES, TRAVERSE_BANK, LOST, EAT_FOOD, CHARGE_ENERGY, OURANIA_TELEPORT, LADDER_DOWN, TRAVERSE_OURANIA
  254.     }
  255.  
  256.     /**
  257.      * Possible states of pouches, Empty or Full
  258.      *
  259.      * @author Equinox_
  260.      *
  261.      */
  262.     public enum PouchState {
  263.         Empty, Full
  264.     }
  265.  
  266.     /**
  267.      * Different pouches and their possible IDs
  268.      *
  269.      * @author Equinox_
  270.      *
  271.      */
  272.     public enum PouchType {
  273.         Small(Pouch.SMALL), Medium(Pouch.MEDIUM, Pouch.MEDIUM_DEGRADED), Large(
  274.                 Pouch.LARGE, Pouch.LARGE_DEGRADED), Giant(Pouch.GIANT,
  275.                 Pouch.GIANT_DEGRADED);
  276.         public int[] ids;
  277.  
  278.         private PouchType(int... ids) {
  279.             this.ids = ids;
  280.         }
  281.     }
  282.  
  283.     /**
  284.      * Gets the current state
  285.      *
  286.      * @return State the current state
  287.      * @throws Exception
  288.      *             so we can pipe errors back to the recorder
  289.      */
  290.     public State getState() throws Exception {
  291.         if (objects.getNearest(LADDER_ID) != null
  292.                 && objects.getNearest(LADDER_ID).isOnScreen())
  293.             return State.LADDER_DOWN;
  294.         if (objects.getNearest(ZMI_ALTAR_ID) != null
  295.                 && objects.getNearest(ZMI_ALTAR_ID).getLocation() != null)
  296.             if (calc.tileOnMap(objects.getNearest(ZMI_ALTAR_ID).getLocation())
  297.                     && (Options.pathType.equals(OptionsClass.Path.Danger) || calc
  298.                             .pathLengthTo(alterDet, true) <= 15)) {
  299.                 if ((inventory.isFull() || !pouches
  300.                         .containsValue(PouchState.Full))
  301.                         && inventory.contains(PURE_ESS_ID))
  302.                     return State.CRAFT_RUNES;
  303.                 else if (pouches.containsValue(PouchState.Full))
  304.                     return State.EMPTY_POUCHES;
  305.                 // Check path type change
  306.                 if (!pathTypeCurrent.equals(Options.pathType)) {
  307.                     pathTypeCurrent = Options.pathType;
  308.                     // Set up path:
  309.                     if (Options.pathType.equals(OptionsClass.Path.Danger))
  310.                         alterMeshPath = new MeshPath(DANGER_MESH);
  311.                     else
  312.                         alterMeshPath = new MeshPath(SAFE_MESH);
  313.                     bankMeshPath = alterMeshPath.reverse();
  314.                 }
  315.             }
  316.  
  317.         // Banking
  318.         if (npcs.getNearest(BANKER_ID) != null) {
  319.             if (npcs.getNearest(BANKER_ID).isOnScreen() || bank.isOpen()) {
  320.                 // Check path type change
  321.                 if (!pathTypeCurrent.equals(Options.pathType)) {
  322.                     pathTypeCurrent = Options.pathType;
  323.                     // Set up path:
  324.                     if (Options.pathType.equals(OptionsClass.Path.Danger))
  325.                         alterMeshPath = new MeshPath(DANGER_MESH);
  326.                     else
  327.                         alterMeshPath = new MeshPath(SAFE_MESH);
  328.                     bankMeshPath = alterMeshPath.reverse();
  329.                 }
  330.                 if (!bank.isOpen() && walking.getEnergy() < 10
  331.                         && Options.chargeEnergy)
  332.                     return State.CHARGE_ENERGY;
  333.                 // Pouch Repair
  334.                 if (shouldRepairPouches())
  335.                     return State.NPC_CONTACT;
  336.                 if ((combat.getLifePoints() + 200 < skills
  337.                         .getCurrentLevel(Skills.CONSTITUTION) * 10)
  338.                         || combat.getHealth() < 50)
  339.                     return State.EAT_FOOD;
  340.                 if (inventory.getCount(Pouch.ALL)
  341.                         + inventory.getCount(PURE_ESS_ID)
  342.                         + inventory.getCount(FIRE_RUNE_ID) != inventory
  343.                         .getCount())
  344.                     return State.BANK_DEPOSIT;
  345.  
  346.                 if (inventory.contains(PURE_ESS_ID)
  347.                         && pouches.containsValue(PouchState.Empty))
  348.                     return State.FILL_POUCHES;
  349.  
  350.                 if (!inventory.isFull())
  351.                     return State.BANK_WITHDRAW;
  352.             } else if (!inventory.contains(PURE_ESS_ID))
  353.                 return State.NEAR_BANK;
  354.  
  355.         }
  356.  
  357.         if (inventory.contains(PURE_ESS_ID) && !shouldRepairPouches())
  358.             return State.TRAVERSE_ALTER;
  359.         else {
  360.             if (objects.getNearest(LADDER_ID) != null)
  361.                 return State.TRAVERSE_OURANIA;
  362.             if (Options.tryOuraniaTeleport
  363.                     && skills.getCurrentLevel(Skills.MAGIC) >= 71
  364.                     && inventory.contains(LAW_RUNE)
  365.                     && inventory.getCount(true, ASTRAL_RUNE) >= 2
  366.                     && (inventory.getCount(true, EARTH_RUNE) >= 6 || Options.hasEarthStaff))
  367.                 return State.OURANIA_TELEPORT;
  368.             return State.TRAVERSE_BANK;
  369.         }
  370.         // return State.LOST;
  371.     }
  372.  
  373.     /**
  374.      * Internal use only. When the client receives a message this method is
  375.      * invoked, saving the message for later use.
  376.      */
  377.     public void messageReceived(MessageEvent msg) {
  378.         if (msg.getID() == MessageEvent.MESSAGE_ACTION
  379.                 || msg.getID() == MessageEvent.MESSAGE_SERVER) {
  380.             serverMsg = msg.getMessage().toLowerCase();
  381.         }
  382.     }
  383.  
  384.     /**
  385.      * Determines if pouches need repairing by using the method defined in the
  386.      * Options class
  387.      *
  388.      * @return boolean should repair pouches
  389.      */
  390.     public boolean shouldRepairPouches() {
  391.         int degradeable = inventory.getCount(Pouch.ALL_DEGRADEABLE);
  392.         int degraded = inventory.getCount(Pouch.ALL_DEGRADED);
  393.         switch (Options.pouchRepair) {
  394.         case ONE:
  395.             return degraded > 0;
  396.         case TWO:
  397.             return degraded > 1 || degradeable < 2;
  398.         case ALL:
  399.             return degradeable == degraded;
  400.         case NEVER:
  401.             return false;
  402.         default:
  403.             return degraded > 1 || degradeable < 2;
  404.         }
  405.     }
  406.  
  407.     /**
  408.      * Tries to open the bank
  409.      *
  410.      * @return boolean did bank open
  411.      */
  412.     public boolean openBank() {
  413.         if (!alterMeshPath.hasPath())
  414.             alterMeshPath.findPath();
  415.         if (bankMeshPath.hasPath())
  416.             bankMeshPath.clearPath();
  417.  
  418.         for (byte b = 0; b < 10; b++) {
  419.             if (interfaces.get(PAY_BANK_INTERFACE) != null
  420.                     && interfaces.get(PAY_BANK_INTERFACE).isValid())
  421.                 payBankCharge();
  422.             if (npcs.getNearest(BANKER_ID) != null) {
  423.                 if (bank.isOpen())
  424.                     return true;
  425.                 npcs.getNearest(BANKER_ID).doAction("Bank");
  426.                 sleep(100, 250);
  427.             }
  428.             sleep(1000);
  429.         }
  430.         return false;
  431.     }
  432.  
  433.     public void payBankCharge() {
  434.         RSInterface pay = interfaces.get(PAY_BANK_INTERFACE);
  435.         if (pay != null && pay.isValid())
  436.             for (String rune : PAY_BANKER_ORDER)
  437.                 for (RSComponent c : pay.getComponents())
  438.                     if (c != null
  439.                             && c.isValid()
  440.                             && c.getTooltip() != null
  441.                             && c.getTooltip().toLowerCase()
  442.                                     .contains(rune.toLowerCase()))
  443.                         if (inventoryCount(rune) >= 20)
  444.                             if (c.doClick()) {
  445.                                 sleep(1500);
  446.                                 return;
  447.                             }
  448.         log.severe("Unable to pay banker!");
  449.     }
  450.  
  451.     public int inventoryCount(String name) {
  452.         for (RSItem i : inventory.getCachedItems())
  453.             if (i != null
  454.                     && i.getName().toLowerCase().contains(name.toLowerCase()))
  455.                 return i.getStackSize();
  456.         return 0;
  457.     }
  458.  
  459.     /**
  460.      * Deposit all non necessary items.
  461.      */
  462.     public void deposit() {
  463.         if (!openBank())
  464.             return;
  465.         int invBefore = inventory.getCount();
  466.         int pouchesBefore = inventory.getCount(Pouch.ALL);
  467.         bank.depositAll();
  468.         for (byte b = 0; b < 15 && invBefore >= inventory.getCount(); b++)
  469.             sleep(100, 125);
  470.         for (byte b = 0; b < 5 && !inventory.contains(FIRE_RUNE_ID); b++) {
  471.             bank.withdraw(FIRE_RUNE_ID, 0);
  472.             sleep(250, 300);
  473.         }
  474.         int[] pouchIds = {};
  475.         for (PouchType p : pouches.keySet())
  476.             pouchIds = mergeArrays(pouchIds, p.ids);
  477.         for (byte b = 0; b < 5 && inventory.getCount(Pouch.ALL) < pouchesBefore; b++) {
  478.             for (RSItem item : bank.getItems())
  479.                 if (item != null)
  480.                     for (int id : pouchIds)
  481.                         if (item.getID() == id)
  482.                             if (bank.withdraw(item.getID(), 1))
  483.                                 sleep(250, 300);
  484.         }
  485.  
  486.         // Paint.runsMade++; TODO
  487.     }
  488.  
  489.     /**
  490.      * Tries to open the bank if the bank is not open, then tries to withdraw
  491.      * the item
  492.      *
  493.      * @param id
  494.      *            the item to withdraw
  495.      * @param amount
  496.      *            the amount to withdraw, 0 for all
  497.      * @return boolean successfully withdraw
  498.      */
  499.     public boolean withdrawItem(int id, int amount) {
  500.         if (!openBank())
  501.             return false;
  502.         boolean returns = bank.withdraw(id, amount);
  503.         sleep(250, 500);
  504.         return returns;
  505.     }
  506.  
  507.     /**
  508.      * Withdraws pure essence
  509.      *
  510.      * @return boolean did withdraw item
  511.      */
  512.     public boolean withdrawEss() {
  513.         return withdrawItem(PURE_ESS_ID, 0);
  514.     }
  515.  
  516.     /**
  517.      * Gets the count of items by the provided id(s) in both the bank and
  518.      * inventory. Includes stack sizes
  519.      *
  520.      * @param id
  521.      *            item ids to search
  522.      * @return int number of items in bank and inventory
  523.      */
  524.     public int getCountBankInv(int... id) {
  525.         int count = 0;
  526.         if (bank.isOpen())
  527.             count += bank.getCount(id);
  528.         count += inventory.getCount(true, id);
  529.         return count;
  530.     }
  531.  
  532.     /**
  533.      * Emptys pouches using the method set in the Options class
  534.      */
  535.     public void emptyPouches() {
  536.         if (game.getCurrentTab() == Game.TAB_INVENTORY)
  537.             updatePouches();
  538.         for (PouchType pType : pouches.keySet()) {
  539.             if (inventory.isFull())
  540.                 break;
  541.             if (inventory.containsOneOf(pType.ids)) {
  542.                 if (pouches.get(pType).equals(PouchState.Full)) {
  543.                     RSItem item = inventory.getItem(pType.ids);
  544.                     if (item != null) {
  545.                         int invCount = inventory.getCount();
  546.                         if (item.doAction("Empty"))
  547.                             switch (Options.pouchCheckSystem) {
  548.                             case SERVER_MSG:
  549.                                 for (int i = 0; i < POUCH_TRIES; i++) {
  550.                                     if (serverMsg != null)
  551.                                         if (serverMsg
  552.                                                 .contains("pouch has no ess")
  553.                                                 || serverMsg
  554.                                                         .contains("are no essences in your pouch")) {
  555.                                             pouches.put(pType, PouchState.Empty);
  556.                                             serverMsg = "";
  557.                                             break;
  558.                                         }
  559.                                     sleep(80, 120);
  560.                                 }
  561.                                 break;
  562.                             case INVENTORY_STATUS:
  563.                                 for (int i = 1; i <= POUCH_TRIES; i++)
  564.                                     if (inventory.getCount() == invCount
  565.                                             && i != POUCH_TRIES)
  566.                                         sleep(100, 150);
  567.                                     else {
  568.                                         if (!inventory.isFull())
  569.                                             pouches.put(pType, PouchState.Empty);
  570.                                         break;
  571.                                     }
  572.  
  573.                                 break;
  574.                             }
  575.                     }
  576.                 }
  577.             }
  578.         }
  579.     }
  580.  
  581.     /**
  582.      * Fills pouches using the method set in the Options class
  583.      */
  584.     public void fillPouches() {
  585.         if (game.getCurrentTab() == Game.TAB_INVENTORY)
  586.             updatePouches();
  587.         for (PouchType pType : pouches.keySet()) {
  588.             if (!inventory.contains(PURE_ESS_ID))
  589.                 break;
  590.             if (inventory.containsOneOf(pType.ids)) {
  591.                 if (pouches.get(pType).equals(PouchState.Empty)) {
  592.                     RSItem item = inventory.getItem(pType.ids);
  593.                     if (item != null) {
  594.                         int invCount = inventory.getCount();
  595.                         if (item.doAction("Fill"))
  596.                             switch (Options.pouchCheckSystem) {
  597.                             case SERVER_MSG:
  598.                                 for (int i = 0; i < POUCH_TRIES; i++) {
  599.                                     if (serverMsg != null)
  600.                                         if (serverMsg.contains("pouch is ful")) {
  601.                                             pouches.put(pType, PouchState.Full);
  602.                                             serverMsg = "";
  603.                                             break;
  604.                                         }
  605.                                     sleep(80, 120);
  606.                                 }
  607.                                 break;
  608.                             case INVENTORY_STATUS:
  609.                                 for (int i = 1; i <= POUCH_TRIES; i++)
  610.                                     if (inventory.getCount() == invCount
  611.                                             && i != POUCH_TRIES)
  612.                                         sleep(100, 150);
  613.                                     else {
  614.                                         if (inventory.contains(PURE_ESS_ID))
  615.                                             pouches.put(pType, PouchState.Full);
  616.                                         break;
  617.                                     }
  618.  
  619.                                 break;
  620.                             }
  621.                     }
  622.                 }
  623.             }
  624.         }
  625.     }
  626.  
  627.     /**
  628.      * Rechecks pouches with the inventory's current contents. If a pouch in the
  629.      * list no longer exists it removes it, if there's a pouch in the inventory
  630.      * not in the list it adds it as an empty pouch
  631.      */
  632.     public void updatePouches() {
  633.         for (PouchType pouch : PouchType.values())
  634.             if (inventory.containsOneOf(pouch.ids)) {
  635.                 if (!pouches.containsKey(pouch))
  636.                     pouches.put(pouch, PouchState.Empty);
  637.             } else if (pouches.containsKey(pouch))
  638.                 pouches.remove(pouch);
  639.     }
  640.  
  641.     public int getRuneCount(boolean cache) {
  642.         int count = 0;
  643.         for (RSItem i : cache ? inventory.getCachedItems() : inventory
  644.                 .getItems())
  645.             if (i.getName() != null
  646.                     && i.getName().toLowerCase().contains("rune"))
  647.                 count += i.getStackSize();
  648.         return count;
  649.     }
  650.  
  651.     /**
  652.      * Crafts essence at the alter
  653.      */
  654.     public void craftEssence() {
  655.         if (alterMeshPath.hasPath())
  656.             alterMeshPath.clearPath();
  657.         if (!bankMeshPath.hasPath())
  658.             bankMeshPath.findPath();
  659.  
  660.         RSObject alter = objects.getNearest(ZMI_ALTAR_ID);
  661.         if (!alter.isOnScreen()
  662.                 && (!getMyPlayer().isMoving()
  663.                         || walking.getDestination() == null || calc
  664.                         .distanceBetween(
  665.                                 alter.getArea().getNearestTile(
  666.                                         getMyPlayer().getLocation()),
  667.                                 walking.getDestination()) > 2))
  668.             walking.walkTileMM(alter.getArea().getNearestTile(
  669.                     getMyPlayer().getLocation()));
  670.  
  671.         //int invBefore = inventory.getCount(PURE_ESS_ID);
  672.         //int runesBefore = getRuneCount(false);
  673.         alter.doAction("Craft-rune");
  674.         sleep(1000);
  675.         for (byte b = 0; b < 50
  676.                 && (getMyPlayer().getAnimation() == CRAFT_RUNE_ANIM
  677.                         || getMyPlayer().isMoving() || walking.getDestination() != null); b++)
  678.             sleep(100, 125);
  679.  
  680.         // Paint.essUsed += invBefore - inventory.getCount(PURE_ESS_ID); TODO
  681.         // Paint.runesMade += getRuneCount(false) - runesBefore;
  682.     }
  683.  
  684.     public boolean onStart() {
  685.         if (game.getCurrentTab() != Game.TAB_MAGIC)
  686.             game.openTab(Game.TAB_MAGIC);
  687.         Options.onLunars = magic.getInterface() != null
  688.                 && magic.getInterface().getIndex() == Magic.Book.LUNAR
  689.                         .getInterfaceID();
  690.         Options.tryOuraniaTeleport = (skills.getCurrentLevel(Skills.MAGIC) >= 71 && Options.onLunars);
  691.  
  692.         pathTypeCurrent = Options.pathType;
  693.         // Set up path:
  694.         if (Options.pathType.equals(OptionsClass.Path.Danger))
  695.             alterMeshPath = new MeshPath(DANGER_MESH);
  696.         else
  697.             alterMeshPath = new MeshPath(SAFE_MESH);
  698.         bankMeshPath = alterMeshPath.reverse();
  699.  
  700.         // Set up the pouches:
  701.         updatePouches();
  702.  
  703.         RSItem wep = equipment.getItem(Equipment.WEAPON);
  704.         if (wep != null) {
  705.             Options.hasAirStaff = (wep.getName().toLowerCase()
  706.                     .contains("staff") && wep.getName().toLowerCase()
  707.                     .contains("air"));
  708.             Options.hasEarthStaff = (wep.getName().toLowerCase()
  709.                     .contains("staff") && (wep.getName().toLowerCase()
  710.                     .contains("earth")
  711.                     || wep.getName().toLowerCase().contains("mud") || wep
  712.                     .getName().toLowerCase().contains("lava")));
  713.         }
  714.  
  715.         new DataLoader(this);
  716.  
  717.         // optimal alt
  718.         camera.setPitch(random(0, 10));
  719.  
  720.         log.info("Script initiation successful!");
  721.         log.info("--Setup--");
  722.         log.info("Air staff: " + (Options.hasAirStaff ? "yes" : "no"));
  723.         log.info("Earth staff: " + (Options.hasEarthStaff ? "yes" : "no"));
  724.         log.info("Walking range: " + Options.walkingDistance.toString());
  725.         log.info("Pouch method: "
  726.                 + PaintFormatter.properCaseAll(Options.pouchCheckSystem.name()
  727.                         .replaceAll("_", " ")));
  728.         log.info("Pouch repair system: "
  729.                 + PaintFormatter.properCaseAll(Options.pouchRepair.name()
  730.                         .replaceAll("_", " ")));
  731.         log.info("Walking style: "
  732.                 + PaintFormatter.properCaseAll(Options.pathType.name()));
  733.         log.info("Recharge Energy: "
  734.                 + (Options.chargeEnergy ? "True" : "False"));
  735.         log.info("Try Ourania Teleport: "
  736.                 + (Options.tryOuraniaTeleport ? "True" : "False"));
  737.         return true;
  738.     }
  739.  
  740.     public boolean isResting() {
  741.         int anim = getMyPlayer().getAnimation();
  742.         return (anim == 12108 || anim == 2033 || anim == 2716 || anim == 11786 || anim == 5713);
  743.     }
  744.  
  745.     public void rest() {
  746.         for (int d = 0; d < 5; d++) {
  747.             interfaces.getComponent(walking.INTERFACE_RUN_ORB, 1).doAction(
  748.                     "Rest");
  749.             mouse.moveSlightly();
  750.             sleep(random(400, 600));
  751.             int anim = players.getMyPlayer().getAnimation();
  752.             if (anim == 12108 || anim == 2033 || anim == 2716 || anim == 11786
  753.                     || anim == 5713) {
  754.                 break;
  755.             }
  756.         }
  757.     }
  758.  
  759.     public int loop() {
  760.         mouse.setSpeed(random(4, 6));
  761.         if (!walking.isRunEnabled() && walking.getEnergy() > 50 && !isResting())
  762.             walking.setRun(true);
  763.         try {
  764.             currentState = getState();
  765.             switch (currentState) {
  766.             case LADDER_DOWN:
  767.                 if (objects.getNearest(LADDER_ID).isOnScreen())
  768.                     if (objects.getNearest(LADDER_ID).doAction("Climb"))
  769.                         sleep(500, 750);
  770.                 break;
  771.             case OURANIA_TELEPORT:
  772.                 if (magic.castSpell(Magic.SPELL_OURANIA_TELEPORT))
  773.                     for (byte b = 0; b < 30 && !calc.tileOnMap(OURANIA_PATH[0]); b++)
  774.                         sleep(100, 125);
  775.                 sleep(500, 750);
  776.                 break;
  777.             case TRAVERSE_OURANIA:
  778.                 RSTilePath tPath = walking.newTilePath(OURANIA_PATH).randomize(
  779.                         2, 2);
  780.                 for (byte b = 0; b < 300 && tPath.isValid()
  781.                         && (objects.getNearest(LADDER_ID) != null) ? !objects
  782.                         .getNearest(LADDER_ID).isOnScreen() : true; b++) {
  783.                     tPath.traverse();
  784.                     sleep(95, 105);
  785.                 }
  786.                 break;
  787.             case CHARGE_ENERGY:
  788.                 if (!isResting())
  789.                     rest();
  790.                 if (isResting())
  791.                     while (walking.getEnergy() < 100 && isResting()
  792.                             && isActive())
  793.                         sleep(200);
  794.                 break;
  795.             case NEAR_BANK:
  796.                 RSNPC banker = npcs.getNearest(BANKER_ID);
  797.                 if (banker != null)
  798.                     if (!banker.isOnScreen()) {
  799.                         RSTile loc = banker.getLocation();
  800.                         if (calc.tileOnMap(loc)) {
  801.                             walking.walkTileMM(loc);
  802.                             for (byte b = 0; b < 22 && !banker.isOnScreen(); b++)
  803.                                 sleep(100, 115);
  804.                         }
  805.                     }
  806.                 break;
  807.             case BANK_DEPOSIT:
  808.                 deposit();
  809.                 break;
  810.             case BANK_WITHDRAW:
  811.                 withdrawEss();
  812.                 break;
  813.             case CRAFT_RUNES:
  814.                 craftEssence();
  815.                 break;
  816.             case EMPTY_POUCHES:
  817.                 emptyPouches();
  818.                 break;
  819.             case EAT_FOOD:
  820.                 if (!inventory.containsOneOf(food)) {
  821.                     openBank();
  822.                     for (int id : food)
  823.                         if (bank.getCount(id) > 0)
  824.                             if (bank.withdraw(id, 1))
  825.                                 break;
  826.                 }
  827.                 if (bank.isOpen())
  828.                     bank.close();
  829.                 if (inventory.containsOneOf(food)) {
  830.                     RSItem foodI = inventory.getItem(food);
  831.                     if (foodI != null)
  832.                         foodI.doAction("Eat");
  833.                 }
  834.                 break;
  835.             case FILL_POUCHES:
  836.                 fillPouches();
  837.                 break;
  838.             case NPC_CONTACT:
  839.                 npcContact.main();
  840.                 break;
  841.             case TRAVERSE_BANK:
  842.                 if (!bankMeshPath.hasPath())
  843.                     bankMeshPath.findPath(MeshPathType.FULL);
  844.                 if (Options.pathType.equals(OptionsClass.Path.Safe)
  845.                         && (bankMeshPath.getNearestByPath() == null || !bankMeshPath
  846.                                 .getNearestByPath().equals(
  847.                                         bankMeshPath.getEnd())))
  848.                     if (objects.getNearest(CRACK_OUT) != null
  849.                             && objects.getNearest(CRACK_OUT).isOnScreen()
  850.                             && objects.getNearest(CRACK_OUT).doAction(
  851.                                     "Squeeze-through")) {
  852.                         sleep(500);
  853.                         for (byte b = 0; b < 20
  854.                                 && getMyPlayer().getAnimation() != -1; b++)
  855.                             sleep(100, 110);
  856.                         break;
  857.                     }
  858.                 bankMeshPath.traverse();
  859.                 break;
  860.             case TRAVERSE_ALTER:
  861.                 if (!alterMeshPath.hasPath())
  862.                     alterMeshPath.findPath(MeshPathType.ALL_CENTER);
  863.                 if ((calc.pathLengthTo(alterDet, true) > 25 || calc
  864.                         .pathLengthTo(alterDet, true) < 0)
  865.                         && Options.pathType.equals(OptionsClass.Path.Safe))
  866.                     if (objects.getNearest(CRACK_IN) != null)
  867.                         if (objects.getNearest(CRACK_IN).isOnScreen()
  868.                                 && objects.getNearest(CRACK_IN).doAction(
  869.                                         "Squeeze-through")) {
  870.                             sleep(500);
  871.                             for (byte b = 0; b < 20
  872.                                     && getMyPlayer().getAnimation() != -1; b++)
  873.                                 sleep(100, 110);
  874.                             break;
  875.                         }
  876.                 alterMeshPath.traverse();
  877.                 break;
  878.             }
  879.         } catch (Exception e) {
  880.             logError(e);
  881.         }
  882.         return random(50, 100);
  883.     }
  884.  
  885.     public void onFinish() {
  886.         FailSafe();
  887.         // Paint.paintMenu.saveProggie();
  888.     }
  889.  
  890.     /**
  891.      * Logs an exception to the Logger and to the error cache
  892.      *
  893.      * @param e
  894.      *            as the Exception to log
  895.      */
  896.     public void logError(Exception e) {
  897.         String s = e.getMessage();
  898.         log.severe(s);
  899.         for (StackTraceElement ele : e.getStackTrace()) {
  900.             s += "\n" + ele.toString();
  901.             log.severe(ele.toString());
  902.         }
  903.     }
  904.  
  905.     /**
  906.      * {@inheritDoc}
  907.      */
  908.     public void onRepaint(Graphics g1) {
  909.         Graphics2D g = (Graphics2D) g1;
  910.         try {
  911.             // MeshPaths
  912.             alterMeshPath.paintAll(g);
  913.             if (bankMeshPath.hasPath()) {
  914.                 bankMeshPath.paintPath(g);
  915.             }
  916.         } catch (NullPointerException e) {
  917.             logError(e);
  918.         }
  919.     }
  920.  
  921.     /**
  922.      * Use these enums to define the type of path <br />
  923.      * ALL_Center: All points are near the middle of the lines <br />
  924.      * Full: Points can be anywhere on the line<br />
  925.      * WEIGHT_CENTER: Weighted to center, possibility of being on sides, but
  926.      * lower
  927.      *
  928.      * @author Equinox_
  929.      *
  930.      */
  931.     enum MeshPathType {
  932.         ALL_CENTER, FULL, WEIGHT_CENTER
  933.     }
  934.  
  935.     /**
  936.      * A class that will take a specified mesh, generate a path through it, then
  937.      * round the path off with Bezier curves.
  938.      *
  939.      * @author Equinox_
  940.      *
  941.      */
  942.     public class MeshPath {
  943.         private final Color MESH_FILL = new Color(0.5f, 0.5f, 0.5f, 0.75f);
  944.         private final Color MESH_BORDER = new Color(0.75f, 0.75f, 0.75f, 0.75f);
  945.         private final Color PATH_COLOR = new Color(0f, 1f, 0f, 1f);
  946.         private final Color SMOOTH_PATH_COLOR = new Color(0f, 0f, 1f, 1f);
  947.         private final Color SUBDIVIDED_PATH_COLOR = new Color(1f, 0f, 1f, 1f);
  948.  
  949.         private List<RSTile[]> mesh = new ArrayList<RSTile[]>();
  950.         private List<RSTile> blockPath = new ArrayList<RSTile>();
  951.         private List<RSTile> smoothPath = new ArrayList<RSTile>();
  952.         private boolean end;
  953.         private List<RSTile> subdividedPath = new ArrayList<RSTile>();
  954.  
  955.         /**
  956.          * Creates a MeshPath with a blank mesh
  957.          */
  958.         public MeshPath() {
  959.  
  960.         }
  961.  
  962.         /**
  963.          * Creates a MeshPath using the provided mesh
  964.          *
  965.          * @param mesh
  966.          *            as RSTile[][]
  967.          */
  968.         public MeshPath(RSTile[][] mesh) {
  969.             setMesh(mesh);
  970.         }
  971.  
  972.         /**
  973.          * Adds a line to the mesh with the given tiles
  974.          *
  975.          * @param tiles
  976.          *            the RSTiles making up the line
  977.          */
  978.         public void addLine(RSTile... tiles) {
  979.             mesh.add(tiles);
  980.         }
  981.  
  982.         /**
  983.          * Gets the number of lines in the mesh
  984.          *
  985.          * @return int size
  986.          */
  987.         public int meshSize() {
  988.             return mesh.size();
  989.         }
  990.  
  991.         /**
  992.          * Adds all the lines of a specified mesh to the current mesh.
  993.          *
  994.          * @param mesh
  995.          *            as RSTile[][]
  996.          */
  997.         public void addMesh(RSTile[][] mesh) {
  998.             for (RSTile[] line : mesh)
  999.                 this.mesh.add(line);
  1000.         }
  1001.  
  1002.         /**
  1003.          * Sets the current mesh to the provided mesh
  1004.          *
  1005.          * @param mesh
  1006.          *            as RSTile[][]
  1007.          */
  1008.         public void setMesh(RSTile[][] mesh) {
  1009.             this.mesh.clear();
  1010.             addMesh(mesh);
  1011.         }
  1012.  
  1013.         public List<RSTile> getTilesOnLine(RSTile a, RSTile b) {
  1014.             List<RSTile> sublineTiles = new ArrayList<RSTile>();
  1015.             int deltaX = b.getX() - a.getX();
  1016.             int deltaY = b.getY() - a.getY();
  1017.             double dist = calc.distanceBetween(a, b);
  1018.             if (dist == 0)
  1019.                 dist = 1;
  1020.             double eX = deltaX / dist, eY = deltaY / dist;
  1021.             for (int i = 0; i <= dist; i++)
  1022.                 sublineTiles.add(new RSTile(a.getX() + (int) (eX * i), a.getY()
  1023.                         + (int) (eY * i)));
  1024.             return sublineTiles;
  1025.         }
  1026.  
  1027.         /**
  1028.          * Gets all the tiles on the provided line
  1029.          *
  1030.          * @param line
  1031.          *            as RSTile...
  1032.          * @return List<RSTile> tiles on line
  1033.          */
  1034.         public List<RSTile> getTilesOnLines(RSTile... line) {
  1035.             List<RSTile> sublineTiles = new ArrayList<RSTile>();
  1036.             if (line.length == 1)
  1037.                 sublineTiles.add(line[0]);
  1038.             else
  1039.                 for (int i = 1; i < line.length; i++) {
  1040.                     RSTile a = line[i - 1];
  1041.                     RSTile b = line[i];
  1042.                     sublineTiles.addAll(getTilesOnLine(a, b));
  1043.                 }
  1044.             return sublineTiles;
  1045.         }
  1046.  
  1047.         /**
  1048.          * Gets a tile on the provided line using the ALL_CENTER method
  1049.          *
  1050.          * @param line
  1051.          *            as RSTile...
  1052.          * @return RSTile tile on line
  1053.          */
  1054.         public RSTile getTileOnLine(RSTile... line) {
  1055.             return getTileOnLine(MeshPathType.ALL_CENTER, line);
  1056.         }
  1057.  
  1058.         /**
  1059.          * Gets a tile on the provided line using the provided method
  1060.          *
  1061.          * @param placement
  1062.          *            as MeshPathType
  1063.          * @param line
  1064.          *            as RSTile...
  1065.          * @return RSTile tile on line
  1066.          */
  1067.         public RSTile getTileOnLine(MeshPathType placement, RSTile... line) {
  1068.             List<RSTile> tiles = getTilesOnLines(line);
  1069.             int index = 0;
  1070.             switch (placement) {
  1071.             case ALL_CENTER:
  1072.                 index = random(tiles.size() / 4, 3 * tiles.size() / 4 + 1);
  1073.                 // +1 due to exclusive upper bound
  1074.                 break;
  1075.             case FULL:
  1076.                 index = random(0, tiles.size());
  1077.                 break;
  1078.             case WEIGHT_CENTER:
  1079.                 index = random(tiles.size() / 4, 3 * tiles.size() / 4 + 1);
  1080.                 // +1 due to exclusive upper bound
  1081.  
  1082.                 int rand = random(-10, tiles.size() / 4);
  1083.                 index += rand > 0 ? rand : 0;
  1084.                 break;
  1085.             }
  1086.  
  1087.             if (index < 0)
  1088.                 index = 0;
  1089.             if (index >= tiles.size())
  1090.                 index = tiles.size() - 1;
  1091.  
  1092.             if (tiles.size() > 0)
  1093.                 return tiles.get(index);
  1094.             else
  1095.                 return null;
  1096.         }
  1097.  
  1098.         /**
  1099.          * Paints the mesh to the provided graphics context in the minimap
  1100.          *
  1101.          * @param g
  1102.          *            as Graphics2D
  1103.          */
  1104.         public void paintMesh(Graphics2D g) {
  1105.             if (mesh.size() > 1) {
  1106.                 for (int i = 1; i < mesh.size(); i++) {
  1107.                     RSTile[] lineA = mesh.get(i - 1).clone();
  1108.                     RSTile[] lineB = mesh.get(i).clone();
  1109.                     Polygon poly = new Polygon();
  1110.                     RSTile a = lineA[0];
  1111.                     RSTile b = lineB[0];
  1112.                     RSTile c = lineA[lineA.length - 1];
  1113.                     RSTile d = lineB[lineB.length - 1];
  1114.                     boolean onMap = true;
  1115.                     double distA = calc.distanceBetween(c, b)
  1116.                             + calc.distanceBetween(a, d);
  1117.                     double distB = calc.distanceBetween(a, b)
  1118.                             + calc.distanceBetween(c, d);
  1119.  
  1120.                     if (distA > distB) {
  1121.                         // Reverse lineB.
  1122.                         RSTile[] newLineB = new RSTile[lineB.length];
  1123.                         int start = lineB.length - 1;
  1124.                         for (RSTile t : lineB) {
  1125.                             if (start >= 0)
  1126.                                 newLineB[start] = t;
  1127.                             start--;
  1128.                         }
  1129.                         lineB = newLineB;
  1130.                     }
  1131.  
  1132.                     if (lineA != null)
  1133.                         for (RSTile t : lineA) {
  1134.                             Point p = calc.tileToMinimap(t);
  1135.                             if (p.x == -1 || p.y == -1) {
  1136.                                 onMap = false;
  1137.                                 break;
  1138.                             }
  1139.                             poly.addPoint(p.x, p.y);
  1140.                         }
  1141.  
  1142.                     if (lineB != null)
  1143.                         for (RSTile t : lineB) {
  1144.                             Point p = calc.tileToMinimap(t);
  1145.                             if (p.x == -1 || p.y == -1) {
  1146.                                 onMap = false;
  1147.                                 break;
  1148.                             }
  1149.                             poly.addPoint(p.x, p.y);
  1150.                         }
  1151.  
  1152.                     if (onMap) {
  1153.                         g.setColor(MESH_BORDER);
  1154.                         g.draw(poly);
  1155.                         g.setColor(MESH_FILL);
  1156.                         g.fill(poly);
  1157.                     }
  1158.                 }
  1159.             }
  1160.         }
  1161.  
  1162.         public RSTile getTileOnMap(RSTile t) {
  1163.             List<RSTile> tiles = getTilesOnLine(t, getMyPlayer().getLocation());
  1164.             for (RSTile tt : tiles)
  1165.                 if (calc.tileOnMap(tt))
  1166.                     return tt;
  1167.             return null;
  1168.         }
  1169.  
  1170.         /**
  1171.          * Paints the current un-smoothed path to the minimap using the provided
  1172.          * graphics object
  1173.          *
  1174.          * @param g
  1175.          *            as Graphics2D
  1176.          */
  1177.         public void paintPath(Graphics2D g) {
  1178.             if (blockPath.size() > 1) {
  1179.                 g.setColor(PATH_COLOR);
  1180.                 for (int i = 1; i < blockPath.size(); i++) {
  1181.                     Point a = calc.tileToMinimap(blockPath.get(i - 1));
  1182.                     Point b = calc.tileToMinimap(blockPath.get(i));
  1183.                     if (a.x > 0 && a.y > 0)
  1184.                         g.fillOval(a.x - 2, a.y - 2, 5, 5);
  1185.                     if (b.x > 0 && b.y > 0)
  1186.                         g.fillOval(b.x - 2, b.y - 2, 5, 5);
  1187.                     if (a.x > 0 && a.y > 0 && b.x > 0 && b.y > 0)
  1188.                         g.drawLine(a.x, a.y, b.x, b.y);
  1189.                 }
  1190.             }
  1191.         }
  1192.  
  1193.         /**
  1194.          * Paints the smoothed version of the current path to the minimap using
  1195.          * the provided graphics object
  1196.          *
  1197.          * @param g
  1198.          *            as Graphics2D
  1199.          */
  1200.         public void paintSmoothPath(Graphics2D g) {
  1201.             if (smoothPath.size() > 1) {
  1202.                 g.setColor(SMOOTH_PATH_COLOR);
  1203.                 for (int i = 1; i < smoothPath.size(); i++) {
  1204.                     Point a = calc.tileToMinimap(smoothPath.get(i - 1));
  1205.                     Point b = calc.tileToMinimap(smoothPath.get(i));
  1206.                     if (a.x > 0 && a.y > 0)
  1207.                         g.fillOval(a.x - 2, a.y - 2, 5, 5);
  1208.                     if (b.x > 0 && b.y > 0)
  1209.                         g.fillOval(b.x - 2, b.y - 2, 5, 5);
  1210.                     if (a.x > 0 && a.y > 0 && b.x > 0 && b.y > 0)
  1211.                         g.drawLine(a.x, a.y, b.x, b.y);
  1212.                 }
  1213.             }
  1214.         }
  1215.  
  1216.         /**
  1217.          * Paints the subdivided smoothed version of the current path to the
  1218.          * minimap using the provided graphics object
  1219.          *
  1220.          * @param g
  1221.          *            as Graphics2D
  1222.          */
  1223.         public void paintSubdividedPath(Graphics2D g) {
  1224.             if (subdividedPath.size() > 0) {
  1225.                 g.setColor(SUBDIVIDED_PATH_COLOR);
  1226.                 for (RSTile t : subdividedPath) {
  1227.                     Point tileLoc = calc.tileToMinimap(t);
  1228.                     if (tileLoc.x > 0 && tileLoc.y > 0)
  1229.                         g.fillOval(tileLoc.x, tileLoc.y, 5, 5);
  1230.                 }
  1231.             }
  1232.         }
  1233.  
  1234.         /**
  1235.          * Paints the mesh, and all versions of the current path to the minimap
  1236.          * using the provided graphics object
  1237.          *
  1238.          * @param g
  1239.          *            as Graphics2D
  1240.          */
  1241.         public void paintAll(Graphics2D g) {
  1242.             paintMesh(g);
  1243.             paintPath(g);
  1244.             paintSmoothPath(g);
  1245.             paintSubdividedPath(g);
  1246.         }
  1247.  
  1248.         /**
  1249.          * Finds a path between the start index and the end index using the
  1250.          * provided placement type, then sets the current path to the found path
  1251.          *
  1252.          * @param placement
  1253.          *            as MeshPathType
  1254.          * @param start
  1255.          *            index
  1256.          * @param end
  1257.          *            index
  1258.          */
  1259.         public void findPath(MeshPathType placement, int start, int end) {
  1260.             blockPath.clear();
  1261.             RSTile lineTile = getTileOnLine(mesh.get(start));
  1262.             String s = lineTile.toString();
  1263.             blockPath.add(lineTile);
  1264.             for (int i = start + 1; i <= end; i++) {
  1265.                 lineTile = getTileOnLine(placement, mesh.get(i));
  1266.                 blockPath.add(lineTile);
  1267.                 s += "," + lineTile.toString();
  1268.             }
  1269.             smoothPath = smoothPath(blockPath);
  1270.             subdividedPath = subdividePath(smoothPath);
  1271.         }
  1272.  
  1273.         /**
  1274.          * Finds a path between the beginning and end of the mesh using the
  1275.          * provided placement type, then sets the current path to the found path
  1276.          *
  1277.          * @param placement
  1278.          *            as MeshPathType
  1279.          */
  1280.         public void findPath(MeshPathType placement) {
  1281.             findPath(placement, 0, mesh.size() - 1);
  1282.         }
  1283.  
  1284.         /**
  1285.          * Finds a path between the beginning and end of the mesh using the
  1286.          * ALL_CENTER placement type, then sets the current path to the found
  1287.          * path
  1288.          */
  1289.         public void findPath() {
  1290.             findPath(MeshPathType.ALL_CENTER);
  1291.         }
  1292.  
  1293.         /**
  1294.          * Clears the current path and all refined versions of it.
  1295.          */
  1296.         public void clearPath() {
  1297.             blockPath.clear();
  1298.             smoothPath.clear();
  1299.             subdividedPath.clear();
  1300.         }
  1301.  
  1302.         /**
  1303.          * Smoothes the provided List of RSTiles using Bezier curves
  1304.          *
  1305.          * @param path
  1306.          *            as List
  1307.          * @return List<RSTile> smoothed path
  1308.          */
  1309.         public List<RSTile> smoothPath(List<RSTile> path) {
  1310.             List<RSTile> smoothed = new ArrayList<RSTile>();
  1311.             smoothed.addAll(path);
  1312.             if (path.size() >= 3) {
  1313.                 for (int b = 0; b < path.size(); b++) {
  1314.                     if (b + 2 < path.size()) {
  1315.                         double x2, y2;
  1316.  
  1317.                         double t = 0.5;
  1318.                         // use Berstein polynomials
  1319.                         x2 = (path.get(b + 0).getX() + t
  1320.                                 * (-path.get(b + 0).getX() * 3 + t
  1321.                                         * (3 * path.get(b + 0).getX() - path
  1322.                                                 .get(b + 0).getX() * t)))
  1323.                                 + t
  1324.                                 * (3 * path.get(b + 1).getX() + t
  1325.                                         * (-6 * path.get(b + 1).getX() + path
  1326.                                                 .get(b + 1).getX() * 3 * t))
  1327.                                 + t
  1328.                                 * t
  1329.                                 * (path.get(b + 1).getX() * 3 - path.get(b + 1)
  1330.                                         .getX() * 3 * t)
  1331.                                 + path.get(b + 2).getX() * t * t * t;
  1332.                         y2 = (path.get(b + 0).getY() + t
  1333.                                 * (-path.get(b + 0).getY() * 3 + t
  1334.                                         * (3 * path.get(b + 0).getY() - path
  1335.                                                 .get(b + 0).getY() * t)))
  1336.                                 + t
  1337.                                 * (3 * path.get(b + 1).getY() + t
  1338.                                         * (-6 * path.get(b + 1).getY() + path
  1339.                                                 .get(b + 1).getY() * 3 * t))
  1340.                                 + t
  1341.                                 * t
  1342.                                 * (path.get(b + 1).getY() * 3 - path.get(b + 1)
  1343.                                         .getY() * 3 * t)
  1344.                                 + path.get(b + 2).getY() * t * t * t;
  1345.                         RSTile loc = new RSTile((int) x2, (int) y2);
  1346.                         smoothed.set(b + 1, getTileInMesh(loc));
  1347.  
  1348.                     }
  1349.                 }
  1350.             }
  1351.             return smoothed;
  1352.         }
  1353.  
  1354.         /**
  1355.          * Gets the nearest tile in the mesh to the provided RSTile
  1356.          *
  1357.          * @param tile
  1358.          *            the RSTile to use
  1359.          * @return RSTile tile in mesh
  1360.          */
  1361.         public RSTile getTileInMesh(RSTile tile) {
  1362.             if (inMesh(tile))
  1363.                 return tile;
  1364.             double bestDist = Double.MAX_VALUE;
  1365.             RSTile nearest = null;
  1366.             if (mesh.size() > 1) {
  1367.                 for (int i = 1; i < mesh.size(); i++) {
  1368.                     RSTile[] lineA = mesh.get(i - 1);
  1369.                     RSTile[] lineB = mesh.get(i);
  1370.                     if (lineA != null && lineB != null) {
  1371.                         RSTile a = lineA[0];
  1372.                         RSTile b = lineB[0];
  1373.                         RSTile c = lineA[lineA.length - 1];
  1374.                         RSTile d = lineB[lineB.length - 1];
  1375.                         if (calc.distanceBetween(a, b) > calc.distanceBetween(
  1376.                                 a, d)) {
  1377.                             // Wrong order, switch b and d.
  1378.                             RSTile clone = new RSTile(b.getX(), b.getY(),
  1379.                                     b.getZ());
  1380.                             b = new RSTile(d.getX(), d.getY(), d.getZ());
  1381.                             d = clone;
  1382.                         }
  1383.                         for (RSTile t : getTilesOnLine(a, b)) {
  1384.                             double dist = calc.distanceBetween(tile, t);
  1385.                             if (dist < bestDist) {
  1386.                                 bestDist = dist;
  1387.                                 nearest = t;
  1388.                             }
  1389.                         }
  1390.                         for (RSTile t : getTilesOnLine(c, d)) {
  1391.                             double dist = calc.distanceBetween(tile, t);
  1392.                             if (dist < bestDist) {
  1393.                                 bestDist = dist;
  1394.                                 nearest = t;
  1395.                             }
  1396.                         }
  1397.                     }
  1398.                 }
  1399.             }
  1400.             return nearest;
  1401.         }
  1402.  
  1403.         /**
  1404.          * Checks to see if the provided RSTile is inside the mesh
  1405.          *
  1406.          * @param tile
  1407.          *            the RSTile to check
  1408.          * @return boolean is in mesh
  1409.          */
  1410.         public boolean inMesh(RSTile tile) {
  1411.             if (mesh.size() > 1) {
  1412.                 for (int i = 1; i < mesh.size(); i++) {
  1413.                     RSTile[] lineA = mesh.get(i - 1);
  1414.                     RSTile[] lineB = mesh.get(i);
  1415.                     Polygon poly = new Polygon();
  1416.                     if (lineA != null)
  1417.                         for (RSTile t : lineA)
  1418.                             poly.addPoint(t.getX(), t.getY());
  1419.  
  1420.                     if (lineB != null)
  1421.                         for (RSTile t : lineB)
  1422.                             poly.addPoint(t.getX(), t.getY());
  1423.  
  1424.                     if (poly.npoints >= 2)
  1425.                         if (poly.contains(new Point(tile.getX(), tile.getY())))
  1426.                             return true;
  1427.                 }
  1428.             }
  1429.             return false;
  1430.         }
  1431.  
  1432.         /**
  1433.          * Takes the provided path and subdivides it using the length provided
  1434.          * in the Options class
  1435.          *
  1436.          * @param smoothPath
  1437.          *            path to subdivide as a List<RSTile>
  1438.          * @return List<RSTile> subdivided path
  1439.          */
  1440.         public List<RSTile> subdividePath(List<RSTile> smoothPath) {
  1441.             RSTile[] smoothpathArray = new RSTile[smoothPath.size()];
  1442.             List<RSTile> path = getTilesOnLines(smoothPath
  1443.                     .toArray(smoothpathArray));
  1444.             List<RSTile> subdividedPath = new ArrayList<RSTile>();
  1445.             RSTile previous = null;
  1446.             for (RSTile next : path) {
  1447.                 if ((previous == null ? true : calc.distanceBetween(previous,
  1448.                         next) > Options.walkingDistance.random())
  1449.                         || next == path.get(path.size() - 1)) {
  1450.                     previous = new RSTile(next.getX(), next.getY());
  1451.                     subdividedPath.add(previous);
  1452.                 }
  1453.             }
  1454.             return subdividedPath;
  1455.         }
  1456.  
  1457.         /**
  1458.          * Takes a step along this path if appropriate. Specifies only
  1459.          * TraversalOption.SPACE_ACTIONS.
  1460.          *
  1461.          * @return <tt>true</tt> if this path is currently valid for the player;
  1462.          *         otherwise <tt>false</tt>.
  1463.          * @see #traverse(EnumSet)
  1464.          */
  1465.         public boolean traverse() {
  1466.             return this.traverse(EnumSet.of(TraversalOption.HANDLE_RUN,
  1467.                     TraversalOption.SPACE_ACTIONS));
  1468.         }
  1469.  
  1470.         /**
  1471.          * Takes a step along this path if appropriate. If the path cannot be
  1472.          * traversed due to the player being too far from its vertices or
  1473.          * already at the end vertex, <tt>false</tt> will be returned. In all
  1474.          * other cases, <tt>true</tt> will be returned, but an action will not
  1475.          * necessarily be performed (based on the given options).
  1476.          *
  1477.          * @param options
  1478.          *            Walking style options.
  1479.          * @return <tt>true</tt> if this path is currently valid for the player;
  1480.          *         otherwise <tt>false</tt>.
  1481.          */
  1482.         public boolean traverse(EnumSet<TraversalOption> options) {
  1483.             RSTile next = getNext();
  1484.             if (next == null)
  1485.                 return false;
  1486.             int nextIdx = getNearestIndexTo(next);
  1487.  
  1488.             if (next.equals(getEnd())) {
  1489.                 if (calc.distanceTo(next) <= 1
  1490.                         || (end && players.getMyPlayer().isMoving())
  1491.                         || next.equals(walking.getDestination())) {
  1492.                     return false;
  1493.                 }
  1494.                 end = true;
  1495.             } else {
  1496.                 end = false;
  1497.             }
  1498.             if (options.contains(TraversalOption.HANDLE_RUN)
  1499.                     && !walking.isRunEnabled() && walking.getEnergy() > 50) {
  1500.                 walking.setRun(true);
  1501.                 sleep(300);
  1502.             }
  1503.             if (walking.getDestination() != null
  1504.                     && getNearestIndexTo(walking.getDestination()) >= nextIdx)
  1505.                 return false;
  1506.             if (options.contains(TraversalOption.SPACE_ACTIONS)) {
  1507.                 RSTile dest = walking.getDestination();
  1508.                 if (dest != null && players.getMyPlayer().isMoving()
  1509.                         && calc.distanceBetween(next, dest) < 3) {
  1510.                     return true;
  1511.                 }
  1512.             }
  1513.             return walking.walkTileMM(next, 0, 0);
  1514.         }
  1515.  
  1516.         /**
  1517.          * Checks whether or not this path can be traversed by the player. This
  1518.          * will be the case provided that the player near to one of its
  1519.          * vertices, but not already standing on the end vertex.
  1520.          *
  1521.          * @return <tt>true</tt> if the player can walk along this path;
  1522.          *         otherwise <tt>false</tt>.
  1523.          */
  1524.         public boolean isValid() {
  1525.             if (!(subdividedPath.size() > 0 && !players.getMyPlayer()
  1526.                     .getLocation().equals(getEnd())))
  1527.                 return false;
  1528.             else
  1529.                 for (int i = subdividedPath.size() - 1; i >= 0; i--)
  1530.                     if (calc.tileOnMap(subdividedPath.get(i)))
  1531.                         return true;
  1532.             return false;
  1533.         }
  1534.  
  1535.         /**
  1536.          * Gets the start tile of this path.
  1537.          *
  1538.          * @return The start <code>RSTile</code>.
  1539.          */
  1540.         public RSTile getStart() {
  1541.             if (subdividedPath.size() > 0)
  1542.                 return subdividedPath.get(0);
  1543.             else
  1544.                 return null;
  1545.         }
  1546.  
  1547.         /**
  1548.          * Gets the next immediately available vertex in this path.
  1549.          *
  1550.          * @return The next walkable <code>RSTile</code>.
  1551.          */
  1552.         public RSTile getNext() {
  1553.             if (subdividedPath.size() > 0) {
  1554.                 for (int i = subdividedPath.size() - 1; i >= 0; i--)
  1555.                     if (calc.tileOnMap(subdividedPath.get(i)))
  1556.                         return subdividedPath.get(i);
  1557.                 return getTileOnMinimap(getNearest());
  1558.             } else
  1559.                 return null;
  1560.         }
  1561.  
  1562.         public RSTile getTileOnMinimap(RSTile base) {
  1563.             if (calc.tileOnMap(base))
  1564.                 return base;
  1565.             RSTile me = getMyPlayer().getLocation();
  1566.             int deltaX = base.getX() - me.getX();
  1567.             int deltaY = base.getY() - me.getY();
  1568.             double dist = calc.distanceBetween(base, me);
  1569.             double eX = deltaX / dist, eY = deltaY / dist;
  1570.             return new RSTile(me.getX() + (int) (eX * 14), me.getY()
  1571.                     + (int) (eY * 14));
  1572.         }
  1573.  
  1574.         public RSTile getNearest() {
  1575.             int len = Integer.MAX_VALUE;
  1576.             RSTile best = null;
  1577.             for (RSTile t : subdividedPath)
  1578.                 if (calc.distanceTo(t) < len) {
  1579.                     best = t;
  1580.                     len = calc.distanceTo(t);
  1581.                 }
  1582.             return best;
  1583.         }
  1584.  
  1585.         public RSTile getNearestByPath() {
  1586.             int len = Integer.MAX_VALUE;
  1587.             RSTile best = null;
  1588.             for (RSTile t : subdividedPath) {
  1589.                 int pLen = calc.pathLengthTo(t, false);
  1590.                 if (pLen < len && pLen >= 0) {
  1591.                     best = t;
  1592.                     len = pLen;
  1593.                 }
  1594.             }
  1595.             return best;
  1596.         }
  1597.  
  1598.         public int getNearestIndexTo(RSTile t) {
  1599.             int len = Integer.MAX_VALUE;
  1600.             int bestIndex = -1;
  1601.             if (walking.getDestination() != null)
  1602.                 for (int i = 0; i < subdividedPath.size(); i++)
  1603.                     if (calc.distanceBetween(t, subdividedPath.get(i)) < len) {
  1604.                         bestIndex = i;
  1605.                         len = calc.distanceTo(t);
  1606.                     }
  1607.             return bestIndex;
  1608.         }
  1609.  
  1610.         /**
  1611.          * Gets the end tile of this path.
  1612.          *
  1613.          * @return The end <code>RSTile</code>.
  1614.          */
  1615.         public RSTile getEnd() {
  1616.             if (subdividedPath.size() > 0)
  1617.                 return subdividedPath.get(subdividedPath.size() - 1);
  1618.             else
  1619.                 return null;
  1620.         }
  1621.  
  1622.         /**
  1623.          * Reverses this mesh.
  1624.          *
  1625.          * @return
  1626.          *
  1627.          * @return This path.
  1628.          */
  1629.         public MeshPath reverse() {
  1630.             MeshPath newPath = new MeshPath();
  1631.             for (int i = mesh.size() - 1; i >= 0; i--)
  1632.                 newPath.addLine(mesh.get(i));
  1633.             return newPath;
  1634.         }
  1635.  
  1636.         /**
  1637.          * Returns an array containing all of the vertices in this path.
  1638.          *
  1639.          * @return an array containing all of the vertices in this path.
  1640.          */
  1641.         public RSTile[] getTilePath() {
  1642.             RSTile[] tiles = new RSTile[subdividedPath.size()];
  1643.             for (int i = 0; i < tiles.length; i++)
  1644.                 tiles[i] = new RSTile(subdividedPath.get(i).getX(),
  1645.                         subdividedPath.get(i).getY());
  1646.             return tiles;
  1647.         }
  1648.  
  1649.         /**
  1650.          * Checks if we have a path
  1651.          *
  1652.          * @return boolean has a path
  1653.          */
  1654.         public boolean hasPath() {
  1655.             return subdividedPath.size() > 0;
  1656.         }
  1657.     }
  1658.  
  1659.     /**
  1660.      * The different states the NPC contact process can be in
  1661.      *
  1662.      * @author Equinox_
  1663.      *
  1664.      */
  1665.     enum npcContactState {
  1666.         CAST, SCROLL, SELECT, WAIT, CONTINUE, MENU, WITHDRAW_ASTRAL, WITHDRAW_COSMIC, WITHDRAW_AIR, OUT_OF_RUNES
  1667.     }
  1668.  
  1669.     /**
  1670.      * A class to contact people using NPC contact
  1671.      *
  1672.      * @author Equinox_
  1673.      *
  1674.      */
  1675.     class NPCContact {
  1676.         public npcContactState currentState = npcContactState.WAIT;
  1677.         private final int MAIN_FRAME = 88;
  1678.         private final int SCROLL_BAR = 20;
  1679.         private final int SCROLL_BAR_DOWN = 0;
  1680.         private final int VISIBLE_NPCS_CONTAINER = 21;
  1681.         private final int NPCS_CONTAINER = 22;
  1682.         private final int NPC_CONTACT_ANIM = 4413;
  1683.  
  1684.         private final int NPC_TO_SELECT = 14;
  1685.         private final String[] MENU_ITEM = { "repair", "pouch" };
  1686.  
  1687.         /**
  1688.          * Gets the current npcContactState
  1689.          *
  1690.          * @return the current npcContactState
  1691.          */
  1692.         private npcContactState getState() {
  1693.             if (interfaces.get(MAIN_FRAME).isValid()) {
  1694.                 if (interfaces.get(MAIN_FRAME).getComponent(NPCS_CONTAINER)
  1695.                         .isValid()) {
  1696.                     Point npcPoint = interfaces.get(MAIN_FRAME)
  1697.                             .getComponent(NPCS_CONTAINER)
  1698.                             .getComponent(NPC_TO_SELECT).getCenter();
  1699.                     Rectangle visible = interfaces.get(MAIN_FRAME)
  1700.                             .getComponent(VISIBLE_NPCS_CONTAINER).getArea();
  1701.                     if (!visible.contains(npcPoint))
  1702.                         return npcContactState.SCROLL;
  1703.                     else
  1704.                         return npcContactState.SELECT;
  1705.                 }
  1706.             }
  1707.  
  1708.             if (interfaces.canContinue())
  1709.                 return npcContactState.CONTINUE;
  1710.  
  1711.             if (getComponent(MENU_ITEM) != null)
  1712.                 return npcContactState.MENU;
  1713.  
  1714.             if (!interfaces.canContinue()
  1715.                     && getMyPlayer().getAnimation() != NPC_CONTACT_ANIM
  1716.                     && getComponent(MENU_ITEM) == null
  1717.                     && getComponent("lease wai") == null) {
  1718.                 if (!inventory.contains(ASTRAL_RUNE_ID))
  1719.                     return npcContactState.WITHDRAW_ASTRAL;
  1720.                 if (!inventory.contains(COSMIC_RUNE_ID))
  1721.                     return npcContactState.WITHDRAW_COSMIC;
  1722.                 if (inventory.getCount(true, AIR_RUNE_ID) < 2
  1723.                         && !Options.hasAirStaff)
  1724.                     return npcContactState.WITHDRAW_AIR;
  1725.                 return npcContactState.CAST;
  1726.             }
  1727.             return npcContactState.WAIT;
  1728.         }
  1729.  
  1730.         /**
  1731.          * Finds a RSComponent with the specified string
  1732.          *
  1733.          * @param s
  1734.          *            The String to search
  1735.          * @return RSComponent with string, otherwise null
  1736.          */
  1737.         private RSComponent getComponent(String... s) {
  1738.             RSInterface[] valid = interfaces.getAll();
  1739.             for (RSInterface iface : valid) {
  1740.                 if (iface.getIndex() != 137) {
  1741.                     int len = iface.getChildCount();
  1742.                     for (int i = 0; i < len; i++) {
  1743.                         RSComponent child = iface.getComponent(i);
  1744.                         boolean b = (child.isValid()
  1745.                                 && child.getAbsoluteX() > 10 && child
  1746.                                 .getAbsoluteY() > 300);
  1747.                         for (String sub : s)
  1748.                             if (!child.getText().toLowerCase()
  1749.                                     .contains(sub.toLowerCase()))
  1750.                                 b = false;
  1751.                         if (b)
  1752.                             return child;
  1753.                     }
  1754.                 }
  1755.             }
  1756.             return null;
  1757.         }
  1758.  
  1759.         /**
  1760.          * Checks if the inventory or bank contains the specified item
  1761.          *
  1762.          * @param id
  1763.          *            the item id
  1764.          * @return <tt>true</tt> if the bank or inventory contains the item,
  1765.          *         otherwise, <tt>false</tt>
  1766.          */
  1767.         boolean invBank(int id) {
  1768.             return bank.getCount(id) > 0 || inventory.containsOneOf(id);
  1769.         }
  1770.  
  1771.         /**
  1772.          * Gets the count of a specified item in the inventory and bank
  1773.          *
  1774.          * @param int itemId
  1775.          * @return the item count
  1776.          */
  1777.         int invBankCount(int id) {
  1778.             return bank.getCount(id) + inventory.getCount(true, id);
  1779.         }
  1780.  
  1781.         /**
  1782.          * The main loop. Call this to do the next action for the contact
  1783.          * process.
  1784.          */
  1785.         public void main() {
  1786.             switch (currentState = getState()) {
  1787.             case WITHDRAW_ASTRAL:
  1788.                 withdrawItem(ASTRAL_RUNE_ID, 1);
  1789.                 if (!invBank(ASTRAL_RUNE_ID))
  1790.                     removePouches();
  1791.                 break;
  1792.             case WITHDRAW_COSMIC:
  1793.                 withdrawItem(COSMIC_RUNE_ID, 1);
  1794.                 if (!invBank(COSMIC_RUNE_ID))
  1795.                     removePouches();
  1796.                 break;
  1797.             case WITHDRAW_AIR:
  1798.                 if (!inventory.contains(AIR_RUNE_ID)) {
  1799.                     if (inventory.isFull())
  1800.                         bank.deposit(PURE_ESS_ID, 1);
  1801.                     withdrawItem(AIR_RUNE_ID, 1);
  1802.                 }
  1803.                 withdrawItem(AIR_RUNE_ID, 1);
  1804.                 if (invBankCount(AIR_RUNE_ID) < 2)
  1805.                     removePouches();
  1806.                 break;
  1807.             case CAST:
  1808.                 for (byte b = 0; b < 5; b++)
  1809.                     if (bank.isOpen()) {
  1810.                         bank.close();
  1811.                         for (byte b2 = 0; b2 < 25; b2++)
  1812.                             if (bank.isOpen())
  1813.                                 break;
  1814.                             else
  1815.                                 sleep(95, 115);
  1816.                     }
  1817.                 if (game.getCurrentTab() != Game.TAB_MAGIC)
  1818.                     game.openTab(Game.TAB_MAGIC);
  1819.  
  1820.                 sleep(500, 1250);
  1821.                 magic.castSpell(Magic.SPELL_NPC_CONTACT);
  1822.                 sleep(750, 1250);
  1823.                 break;
  1824.             case SCROLL:
  1825.                 // Scroll
  1826.                 RSComponent bar = interfaces.get(MAIN_FRAME)
  1827.                         .getComponent(SCROLL_BAR).getComponent(SCROLL_BAR_DOWN);
  1828.                 Point p = bar.getCenter();
  1829.                 p.y = bar.getAbsoluteY() + bar.getHeight() - 5;
  1830.                 mouse.click(p, true);
  1831.                 break;
  1832.             case SELECT:
  1833.                 interfaces.get(MAIN_FRAME).getComponent(NPCS_CONTAINER)
  1834.                         .getComponent(NPC_TO_SELECT).doClick();
  1835.                 break;
  1836.             case WAIT:
  1837.                 break;
  1838.             case CONTINUE:
  1839.                 if (interfaces.canContinue())
  1840.                     interfaces.clickContinue();
  1841.                 break;
  1842.             case MENU:
  1843.                 if (getComponent(MENU_ITEM) != null)
  1844.                     getComponent(MENU_ITEM).doClick();
  1845.                 break;
  1846.             }
  1847.             sleep(900, 1200);
  1848.         }
  1849.  
  1850.         public void removePouches() {
  1851.             if (!openBank())
  1852.                 return;
  1853.             // not enough runes, bank pouches:
  1854.             for (int id : Pouch.ALL_DEGRADED)
  1855.                 if (inventory.contains(id)) {
  1856.                     if (bank.deposit(id, 1))
  1857.                         sleep(500, 600);
  1858.                 }
  1859.             updatePouches();
  1860.         }
  1861.     }
  1862.  
  1863.     /**
  1864.      * Loads script data as the actual script runs. Useful for images that are
  1865.      * non-essential.
  1866.      *
  1867.      * @author Equinox_
  1868.      *
  1869.      */
  1870.     public static class DataLoader extends Thread {
  1871.         EquinoxZMICrafter crafter;
  1872.  
  1873.         public DataLoader(EquinoxZMICrafter crafter) {
  1874.             super("Data Loader");
  1875.             this.crafter = crafter;
  1876.             this.start();
  1877.         }
  1878.  
  1879.         // Item Info
  1880.         public void checkGE() {
  1881.             long before = System.currentTimeMillis();
  1882.             GEItem item = crafter.getGE().lookup(PURE_ESS_ID);
  1883.             if (item != null) {
  1884.                 // crafter.Paint.essPrice = getItemPrice(item);
  1885.                 crafter.log("Price of " + item.getName() + ": "
  1886.                         + getItemPrice(item));
  1887.                 crafter.log("Loaded essence information in "
  1888.                         + PaintFormatter.getFormattedTime(System
  1889.                                 .currentTimeMillis() - before));
  1890.             }
  1891.         }
  1892.  
  1893.         public void run() {
  1894.             checkGE();
  1895.             try {
  1896.                 if (JOptionPane.NO_OPTION == JOptionPane.showConfirmDialog(
  1897.                         null, "Would you like to load some images?",
  1898.                         "Equinox_ Data Loader", JOptionPane.YES_NO_OPTION))
  1899.                     throw new Exception();
  1900.  
  1901.                 /*
  1902.                  * long before = System.currentTimeMillis();
  1903.                  * crafter.Paint.putImage( "homeicon", ImageIO.read(new
  1904.                  * URL(crafter.baseURL + "/images/houseIcon.png")));
  1905.                  * crafter.log("Loaded home image in " +
  1906.                  * PaintFormatter.getFormattedTime(System .currentTimeMillis() -
  1907.                  * before));
  1908.                  *
  1909.                  * before = System.currentTimeMillis(); crafter.Paint .putImage(
  1910.                  * "rcicon", ImageIO.read(new URL(
  1911.                  * "http://www.runescape.com/img/hiscores/skill_icon_Runecrafting1.gif"
  1912.                  * ))); crafter.log("Loaded runecrafting image in " +
  1913.                  * PaintFormatter.getFormattedTime(System .currentTimeMillis() -
  1914.                  * before));
  1915.                  *
  1916.                  * before = System.currentTimeMillis(); crafter.Paint.putImage(
  1917.                  * "toolsicon", ImageIO.read(new URL(crafter.baseURL +
  1918.                  * "/images/tools.png"))); crafter.log("Loaded tools icon in " +
  1919.                  * PaintFormatter.getFormattedTime(System .currentTimeMillis() -
  1920.                  * before));
  1921.                  */
  1922.             } catch (Exception e) {
  1923.                 crafter.log("Failed to load images");
  1924.             }
  1925.         }
  1926.     }
  1927.  
  1928.     /**
  1929.      * Gets the grandExchange singleton for reference by other classes msg
  1930.      *
  1931.      * @return GrandExchange reference
  1932.      */
  1933.     public GrandExchange getGE() {
  1934.         return grandExchange;
  1935.     }
  1936.  
  1937.     /**
  1938.      * gets the item price based on class. Works with all versions of
  1939.      * grandExchange.class
  1940.      *
  1941.      * @param item
  1942.      *            the GEItem to get the price from
  1943.      * @return int the price
  1944.      *
  1945.      * @author Equinox_
  1946.      */
  1947.     public static int getItemPrice(GEItem item) {
  1948.         for (Method m : item.getClass().getMethods())
  1949.             if (m.getName().equals("getGuidePrice")
  1950.                     || m.getName().equals("getMinPrice"))
  1951.                 try {
  1952.                     return (Integer) (m.invoke(item));
  1953.                 } catch (Exception e) {
  1954.                 }
  1955.         return 0;
  1956.     }
  1957.  
  1958.     public void FailSafe() {
  1959.         log.info("FailSafe Activated!");
  1960.  
  1961.         // Set up path:
  1962.         if (pathTypeCurrent.equals(OptionsClass.Path.Danger))
  1963.             alterMeshPath = new MeshPath(DANGER_MESH);
  1964.         else
  1965.             alterMeshPath = new MeshPath(SAFE_MESH);
  1966.         bankMeshPath = alterMeshPath.reverse();
  1967.         if (!bankMeshPath.hasPath())
  1968.             bankMeshPath.findPath(MeshPathType.FULL);
  1969.         while (bankMeshPath.isValid()
  1970.                 && calc.distanceTo(bankMeshPath.getEnd()) >= 2) {
  1971.             if (Options.pathType.equals(OptionsClass.Path.Safe)
  1972.                     && (bankMeshPath.getNearestByPath() == null || !bankMeshPath
  1973.                             .getNearestByPath().equals(bankMeshPath.getEnd())))
  1974.                 if (objects.getNearest(CRACK_OUT) != null
  1975.                         && objects.getNearest(CRACK_OUT).isOnScreen()
  1976.                         && objects.getNearest(CRACK_OUT).doAction(
  1977.                                 "Squeeze-through")) {
  1978.                     sleep(500);
  1979.                     for (byte b = 0; b < 20
  1980.                             && getMyPlayer().getAnimation() != -1; b++)
  1981.                         sleep(100);
  1982.                     continue;
  1983.                 }
  1984.  
  1985.             bankMeshPath.traverse();
  1986.  
  1987.         }
  1988.         log.info("Failsafe Complete");
  1989.     }
  1990. }
Advertisement
Add Comment
Please, Sign In to add comment