Equinox

EquinoxLunarPlanker

May 18th, 2011
1,780
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 62.57 KB | None | 0 0
  1. import java.awt.*;
  2. import java.awt.event.*;
  3. import java.awt.font.FontRenderContext;
  4. import java.awt.geom.AffineTransform;
  5. import java.awt.geom.RoundRectangle2D;
  6. import java.awt.image.BufferedImage;
  7. import java.io.File;
  8. import java.io.IOException;
  9. import java.lang.reflect.Method;
  10. import java.net.MalformedURLException;
  11. import java.net.URL;
  12. import java.text.DecimalFormat;
  13. import java.util.*;
  14. import java.util.List;
  15. import java.util.logging.Logger;
  16.  
  17. import javax.imageio.ImageIO;
  18. import javax.swing.JOptionPane;
  19.  
  20. import org.rsbot.Configuration;
  21. import org.rsbot.event.listeners.PaintListener;
  22. import org.rsbot.script.Script;
  23. import org.rsbot.script.ScriptManifest;
  24. import org.rsbot.script.methods.*;
  25. import org.rsbot.script.methods.GrandExchange.GEItem;
  26. import org.rsbot.script.wrappers.*;
  27.  
  28. @ScriptManifest(authors = { "Equinox_" }, version = 1.1, name = "Equinox_ Lunar Planker", description = "Uses the lunar spell plank-make to create planks.")
  29. public class EquinoxLunarPlanker extends Script implements MouseListener,
  30.     MouseMotionListener, PaintListener {
  31.     PaintInterface Paint;
  32.     ModifiedDrawMouse drawMouse = new ModifiedDrawMouse();
  33.  
  34.     final String baseURL = "http://equinox-scripts.web44.net/scripts/natcrafter";
  35.     final double VERSION = getClass().getAnnotation(ScriptManifest.class)
  36.         .version();
  37.     final String author = PaintFormatter.formatList(getClass().getAnnotation(
  38.         ScriptManifest.class).authors());
  39.     final String name = PaintFormatter.properCaseAll(getClass().getAnnotation(
  40.         ScriptManifest.class).name());
  41.  
  42.     // Logs And Planks
  43.     static final int MLog = 6332;
  44.     static final int MPlank = 8782;
  45.     static final int MCost = 1095;
  46.     static final int TLog = 6333;
  47.     static final int TPlank = 8780;
  48.     static final int TCost = 350;
  49.     static final int OLog = 1521;
  50.     static final int OPlank = 8778;
  51.     static final int OCost = 175;
  52.     static final int RLog = 1511;
  53.     static final int RPlank = 960;
  54.     static final int RCost = 70;
  55.  
  56.     static final int NatRune = 561;
  57.     static final int AstralRune = 9075;
  58.     static final int EarthRune = 557;
  59.     static int PlankID;
  60.     static int LogID;
  61.     static int coinsPerPlank;
  62.  
  63.     int Coins = 995;
  64.     int logCount = 0;
  65.     int plankCount = 0;
  66.     boolean spellSelected = false;
  67.     Rectangle spell = null;
  68.     Rectangle[] invItems;
  69.     int nextSlot;
  70.     public boolean hasEarthStaff = false;
  71.  
  72.     int tabTries = 5;
  73.     int invTries = 0;
  74.     int mageTries = 0;
  75.  
  76.     enum State {
  77.     Cast, Select, Bank, Revert_Magic, Wait
  78.     }
  79.  
  80.     public RSComponent getSpell(int spell) {
  81.     if (game.getCurrentTab() != Game.TAB_MAGIC) {
  82.         game.openTab(Game.TAB_MAGIC);
  83.         for (int i = 0; i < 100; i++) {
  84.         sleep(20);
  85.         if (game.getCurrentTab() == Game.TAB_MAGIC) {
  86.             break;
  87.         }
  88.         }
  89.         sleep(random(150, 250));
  90.     }
  91.     if (game.getCurrentTab() == Game.TAB_MAGIC) {
  92.         RSInterface inter = magic.getInterface();
  93.         if (inter != null) {
  94.         RSComponent comp = inter.getComponent(spell);
  95.         return comp;
  96.         }
  97.     }
  98.     return null;
  99.     }
  100.  
  101.     @Override
  102.     public boolean onStart() {
  103.     RSItem logI = inventory.getItem(RLog, OLog, TLog, MLog);
  104.     if (logI == null) {
  105.         log.severe("You must start with a Regular, Oak, Teak, or Mahogany log in your inventory!");
  106.         return false;
  107.     }
  108.     switch (logI.getID()) {
  109.     case MLog:
  110.         LogID = MLog;
  111.         coinsPerPlank = MCost;
  112.         PlankID = MPlank;
  113.         break;
  114.     case TLog:
  115.         LogID = TLog;
  116.         coinsPerPlank = TCost;
  117.         PlankID = TPlank;
  118.         break;
  119.     case OLog:
  120.         LogID = OLog;
  121.         coinsPerPlank = OCost;
  122.         PlankID = OPlank;
  123.         break;
  124.     case RLog:
  125.         LogID = RLog;
  126.         coinsPerPlank = RCost;
  127.         PlankID = RPlank;
  128.         break;
  129.     default:
  130.         return false;
  131.     }
  132.     RSItem wep = equipment.getItem(Equipment.WEAPON);
  133.     if (wep != null)
  134.         hasEarthStaff = (wep.getName().toLowerCase().contains("staff") && (wep
  135.             .getName().toLowerCase().contains("earth") || wep.getName()
  136.             .toLowerCase().contains("mud")));
  137.     if (!(inventory.containsAll(AstralRune, NatRune))) {
  138.         log.severe("You must start with Astral Runes and Nature Runes in inventory!");
  139.         return false;
  140.     }
  141.     if (!(hasEarthStaff || inventory.contains(EarthRune))) {
  142.         log.severe("You must start with either an Earth-Type staff equipped or Earth Runes in inventory");
  143.         return false;
  144.     }
  145.  
  146.     Paint = new PaintInterface(this, log, Skills.MAGIC);
  147.     new DataLoader(this);
  148.     logCount = inventory.getCount(LogID);
  149.     plankCount = inventory.getCount(PlankID);
  150.     Paint.startAstrals = inventory.getCount(true, AstralRune);
  151.     Paint.startCoins = inventory.getCount(true, Coins);
  152.     Paint.startEarths = inventory.getCount(true, EarthRune);
  153.     Paint.startNatures = inventory.getCount(true, NatRune);
  154.  
  155.     RSComponent invIface = inventory.getInterface();
  156.     if (invIface != null)
  157.         if (invIface.isValid()) {
  158.         invItems = new Rectangle[invIface.getComponents().length];
  159.         for (int i = 0; i < invItems.length; i++)
  160.             invItems[i] = (Rectangle) invIface.getComponent(i)
  161.                 .getArea().clone();
  162.         }
  163.  
  164.     spell = getSpell(Magic.SPELL_PLANK_MAKE).getArea();
  165.     return true;
  166.     }
  167.  
  168.     State getState() {
  169.     if (game.getCurrentTab() == Game.TAB_INVENTORY)
  170.         if (inventory.isItemSelected())
  171.         return State.Revert_Magic;
  172.     // "The Abbyssal Services Department apologizes...."
  173.     if (interfaces.canContinue())
  174.         interfaces.clickContinue();
  175.     if (logCount <= 0)
  176.         return State.Bank;
  177.     if (!spellSelected)
  178.         return State.Cast;
  179.     if (spellSelected)
  180.         return State.Select;
  181.     if (logCount <= 0)
  182.         return State.Bank;
  183.     return State.Wait;
  184.     }
  185.  
  186.     void updateInv() {
  187.     logCount = inventory.getCount(LogID);
  188.     if (inventory.getCount(PlankID) > plankCount)
  189.         Paint.planksMade += inventory.getCount(PlankID) - plankCount;
  190.     plankCount = inventory.getCount(PlankID);
  191.     // if (inventory.getCount(true,Coins) < coinsPerPlank)
  192.     // stopScript(true);
  193.     Paint.usedAstrals = inventory.getCount(true, AstralRune)
  194.         - Paint.startAstrals;
  195.     Paint.usedNatures = inventory.getCount(true, NatRune)
  196.         - Paint.startNatures;
  197.     Paint.usedEarths = inventory.getCount(true, EarthRune)
  198.         - Paint.startEarths;
  199.     Paint.usedCoins = inventory.getCount(true, Coins) - Paint.startCoins;
  200.  
  201.     Paint.castsLeft = Math.min(inventory.getCount(true, AstralRune) / 2,
  202.         inventory.getCount(true, NatRune));
  203.     if (!hasEarthStaff)
  204.         Paint.castsLeft = Math.min(Paint.castsLeft,
  205.             inventory.getCount(true, EarthRune) / 15);
  206.     Paint.coinsLeft = inventory.getCount(true, Coins) / coinsPerPlank;
  207.     }
  208.  
  209.     @Override
  210.     public int loop() {
  211.     mouse.setSpeed(random(4, 6));
  212.     if (game.getCurrentTab() == Game.TAB_INVENTORY)
  213.         updateInv();
  214.  
  215.     try {
  216.         switch (getState()) {
  217.         case Cast:
  218.         if (game.getCurrentTab() == Game.TAB_MAGIC && !spellSelected) {
  219.             if (magic.castSpell(Magic.SPELL_PLANK_MAKE))
  220.             spellSelected = true;
  221.             mageTries = 0;
  222.         } else if (mageTries >= tabTries)
  223.             game.openTab(Game.TAB_MAGIC);
  224.         else
  225.             mageTries++;
  226.         break;
  227.         case Revert_Magic:
  228.         game.openTab(Game.TAB_MAGIC);
  229.         break;
  230.         case Select:
  231.         if (game.getCurrentTab() == Game.TAB_INVENTORY && spellSelected) {
  232.             if (getNextLog().doClick(true)) {
  233.             spellSelected = false;
  234.             logCount--;
  235.             plankCount++;
  236.             invTries = 0;
  237.             if (spell != null)
  238.                 mouse.move(new Point(spell.x
  239.                     + random(3, spell.width - 3), spell.y
  240.                     + random(3, spell.height - 3)));
  241.             }
  242.         } else if (invTries >= tabTries)
  243.             game.openTab(Game.TAB_INVENTORY);
  244.         else
  245.             invTries++;
  246.         break;
  247.         case Bank:
  248.         if (logCount <= 0) {
  249.             if (!bank.isOpen())
  250.             bank.open();
  251.             if (inventory.getCount() != inventory.getCount(AstralRune,
  252.                 NatRune, Coins))
  253.             bank.depositAllExcept(AstralRune, NatRune, Coins,
  254.                 EarthRune);
  255.             sleep(500);
  256.             Paint.logsLeft = bank.getCount(LogID);
  257.             bank.withdraw(LogID, 0);
  258.         }
  259.         updateInv();
  260.         bank.close();
  261.         if (game.getCurrentTab() != Game.TAB_MAGIC) {
  262.             game.openTab(Game.TAB_MAGIC);
  263.             for (int i = 0; i < 100; i++) {
  264.             sleep(20);
  265.             if (game.getCurrentTab() == Game.TAB_MAGIC) {
  266.                 break;
  267.             }
  268.             }
  269.             sleep(random(150, 250));
  270.         }
  271.         spellSelected = false;
  272.         nextSlot = 0;
  273.         break;
  274.         }
  275.     } catch (Exception e) {
  276.     }
  277.     return 250;
  278.     }
  279.  
  280.     @Override
  281.     public void onRepaint(Graphics render) {
  282.     Graphics2D g = (Graphics2D) render;
  283.     g.setColor(Color.GREEN);
  284.     g.draw(spell);
  285.  
  286.     g.setColor(Color.RED);
  287.     if (invItems != null)
  288.         if (nextSlot >= 0 && nextSlot < invItems.length)
  289.         g.draw(invItems[nextSlot]);
  290.  
  291.     drawMouse.onRepaint(render);
  292.     if (Paint != null)
  293.         Paint.render(g);
  294.     }
  295.  
  296.     public RSItem getNextLog() {
  297.     RSItem[] inv = inventory.getItems();
  298.     // Checks for a plank, then a log, then a plank. Obvious skip.
  299.     for (int i = 1; i < inv.length - 1; i++) {
  300.         RSItem left = inv[i - 1];
  301.         RSItem right = inv[i + 1];
  302.         RSItem thisItem = inv[i];
  303.         if (left != null && right != null && thisItem != null
  304.             && right.getID() == PlankID && left.getID() == PlankID
  305.             && thisItem.getID() == LogID) {
  306.         nextSlot = i + 1;
  307.         return thisItem;
  308.         }
  309.     }
  310.     while (nextSlot < inv.length) {
  311.         if (nextSlot >= inv.length)
  312.         nextSlot = 0;
  313.         else if (nextSlot < 0)
  314.         nextSlot = 0;
  315.  
  316.         if (inv[nextSlot] == null || inv[nextSlot].getID() != LogID) {
  317.         nextSlot++;
  318.         continue;
  319.         } else {
  320.         // all good
  321.         nextSlot++;
  322.         return inv[nextSlot - 1];
  323.         }
  324.     }
  325.     nextSlot = -1;
  326.     return null;
  327.     }
  328.  
  329.     /**
  330.      * Used to format data into more conventional formats
  331.      *
  332.      * @author Equinox_
  333.      *
  334.      */
  335.     public static class PaintFormatter {
  336.     /**
  337.      * Converts the first letter of every word to uppercase, and the rest
  338.      * lowercase.
  339.      *
  340.      * @param s
  341.      *            The input String
  342.      * @return the properly formatted string
  343.      */
  344.     public static String properCaseAll(String s) {
  345.         String[] words = s.split(" ");
  346.         String result = "";
  347.         for (int i = 0; i < words.length; i++) {
  348.         String f = words[i].substring(0, 1).toUpperCase();
  349.         words[i] = f + words[i].substring(1).toLowerCase();
  350.         result += " " + words[i];
  351.         }
  352.         return result.substring(1);
  353.     }
  354.  
  355.     /**
  356.      * Capitalizes the first letter of every sentence, with every other
  357.      * letter lowercase.
  358.      *
  359.      * @param s
  360.      *            The input string
  361.      * @return The properly formatted String
  362.      */
  363.     public static String properCaseFirst(String s) {
  364.         String[] sentences = new String[] { s };
  365.         if (s.contains("."))
  366.         sentences = s.split(".");
  367.         String result = "";
  368.         for (int i = 0; i < sentences.length; i++) {
  369.         String f = sentences[i].substring(0, 1).toUpperCase();
  370.         sentences[i] = f + sentences[i].substring(1).toLowerCase();
  371.         result += " " + sentences[i];
  372.         }
  373.         return result.substring(1);
  374.     }
  375.  
  376.     /**
  377.      * Formats time to DD:HH:MM:SS:MSMS with days and millis optional
  378.      *
  379.      * @param timeMillis
  380.      *            long milliseconds of time
  381.      * @param sep
  382.      *            String seperation character
  383.      * @param millisInc
  384.      *            boolean include milliseconds
  385.      * @return
  386.      */
  387.     public static String getFormattedTime(final long timeMillis,
  388.         String sep, boolean millisInc) {
  389.         long millis = timeMillis;
  390.         final long days = millis / (24 * 1000 * 60 * 60);
  391.         millis -= days * (24 * 1000 * 60 * 60);
  392.         final long hours = millis / (1000 * 60 * 60);
  393.         millis -= hours * 1000 * 60 * 60;
  394.         final long minutes = millis / (1000 * 60);
  395.         millis -= minutes * 1000 * 60;
  396.         final long _seconds = millis / 1000;
  397.         millis -= _seconds * 1000;
  398.         String dayString = String.valueOf(days);
  399.         String hoursString = String.valueOf(hours);
  400.         String minutesString = String.valueOf(minutes);
  401.         String secondsString = String.valueOf(_seconds);
  402.         if (hours < 10) {
  403.         hoursString = 0 + hoursString;
  404.         }
  405.         if (minutes < 10) {
  406.         minutesString = 0 + minutesString;
  407.         }
  408.         if (_seconds < 10) {
  409.         secondsString = 0 + secondsString;
  410.         }
  411.         String s = "";
  412.         if (days > 0)
  413.         s = dayString + sep;
  414.         s += hoursString + sep + minutesString + sep + secondsString;
  415.         if (millisInc)
  416.         s += sep + String.valueOf(millis);
  417.         return s;
  418.     }
  419.  
  420.     /**
  421.      * Converts the milliseconds to DD:HH:MM:SS with the days optional.
  422.      *
  423.      * @param timeMillis
  424.      *            the number of milliseconds
  425.      * @return the properly formatted time as a String
  426.      */
  427.     public static String getFormattedTime(final long timeMillis) {
  428.         return getFormattedTime(timeMillis, ":", false);
  429.     }
  430.  
  431.     /**
  432.      * Formats a specified amount into thousands, millions or billions, then
  433.      * adds the proper suffix
  434.      *
  435.      * @param money
  436.      *            the amount of money
  437.      * @return the formatted string
  438.      */
  439.     public static String getFormattedMoney(long money) {
  440.         /*
  441.          * String suffix = ""; int t = 1; if (money >= 10000) { t *= 1000;
  442.          * suffix = "K"; } if (money / t > 10000) { t *= 1000; suffix = "M";
  443.          * } if (money / t > 10000) { t *= 1000; suffix = "B"; } return
  444.          * String.valueOf((money / t)) + suffix;
  445.          */
  446.         return new DecimalFormat("###,###,###,###,###,###").format(money);
  447.     }
  448.  
  449.     /**
  450.      * Converts an array of strings into one string, using commas and 'and' <br>
  451.      * <br>
  452.      * Examples: <br>
  453.      * {"option1"} returns "option1"<br>
  454.      * {"option1","option2"} returns "option1 and option2"<br>
  455.      * {"op1","op2","op3"} returns "op1, op2, and op3"<br>
  456.      * <br>
  457.      *
  458.      * @param list
  459.      *            The array of strings making up the list.
  460.      * @return The properly formatted string
  461.      */
  462.     public static String formatList(String[] list) {
  463.         String s = "";
  464.         if (list != null)
  465.         if (list.length == 2) {
  466.             s = list[0] + " and " + list[1];
  467.         } else if (list.length > 2) {
  468.             for (int i = 0; i < list.length - 1; i++)
  469.             s += list[i] + ", ";
  470.             s += "and " + list[list.length - 1];
  471.         } else if (list.length == 1)
  472.             s = list[0];
  473.         return s;
  474.     }
  475.     }
  476.  
  477.     /**
  478.      * A class used to represent the paint interface for this script
  479.      *
  480.      * @author Equinox_
  481.      *
  482.      */
  483.     public class PaintInterface {
  484.     // Constant
  485.     public final int[] SKILL_INTERFACES = { Skills.INTERFACE_ATTACK,
  486.         Skills.INTERFACE_DEFENSE, Skills.INTERFACE_STRENGTH,
  487.         Skills.INTERFACE_CONSTITUTION, Skills.INTERFACE_RANGE,
  488.         Skills.INTERFACE_PRAYER, Skills.INTERFACE_MAGIC,
  489.         Skills.INTERFACE_COOKING, Skills.INTERFACE_WOODCUTTING,
  490.         Skills.INTERFACE_FLETCHING, Skills.INTERFACE_FISHING,
  491.         Skills.INTERFACE_FIREMAKING, Skills.INTERFACE_CRAFTING,
  492.         Skills.INTERFACE_SMITHING, Skills.INTERFACE_MINING,
  493.         Skills.INTERFACE_HERBLORE, Skills.INTERFACE_AGILITY,
  494.         Skills.INTERFACE_THIEVING, Skills.INTERFACE_SLAYER,
  495.         Skills.INTERFACE_FARMING, Skills.INTERFACE_RUNECRAFTING,
  496.         Skills.INTERFACE_HUNTER, Skills.INTERFACE_CONSTRUCTION,
  497.         Skills.INTERFACE_SUMMONING, Skills.INTERFACE_DUNGEONEERING };
  498.  
  499.     // Paint data
  500.     public long startTime = 0;
  501.     public int startLevel;
  502.     public int startExp;
  503.     public int startCoins;
  504.     public int startAstrals;
  505.     public int startEarths;
  506.     public int startNatures;
  507.  
  508.     // Used info
  509.     public int usedCoins;
  510.     public int usedAstrals;
  511.     public int usedEarths;
  512.     public int usedNatures;
  513.  
  514.     // Price info
  515.     public int coinsPrice;
  516.     public int astralPrice;
  517.     public int earthPrice;
  518.     public int naturePrice;
  519.     public int plankPrice;
  520.     public int logPrice;
  521.  
  522.     // Remaining info
  523.     public int castsLeft;
  524.     public int logsLeft;
  525.     public int coinsLeft;
  526.  
  527.     // Goal
  528.     public int goalExp;
  529.     public int goalLevel;
  530.  
  531.     public int planksMade;
  532.  
  533.     // Images
  534.     public Map<String, Image> icons = new HashMap<String, Image>();
  535.  
  536.     public void putImage(String name, Image img) {
  537.         icons.put(name.toLowerCase(), img);
  538.     }
  539.  
  540.     public Image getImage(String name) {
  541.         if (icons.containsKey(name.toLowerCase()))
  542.         return icons.get(name.toLowerCase());
  543.         return null;
  544.     }
  545.  
  546.     public FontRenderContext frc = new FontRenderContext(
  547.         new AffineTransform(), false, false);
  548.  
  549.     public PaintStyle style = new PaintStyle();
  550.     public Point mouseLoc = new Point(0, 0);
  551.  
  552.     final EquinoxLunarPlanker planker;
  553.     final Logger log;
  554.     int SkillID = -1;
  555.     public Menu paintMenu;
  556.  
  557.     /**
  558.      * Constructs a PaintInterface using the provided parent and logger
  559.      * object and no skill progress bars
  560.      *
  561.      * @param planker
  562.      *            the parent NatCrafter
  563.      * @param log
  564.      *            the Logger object
  565.      */
  566.     public PaintInterface(EquinoxLunarPlanker planker, Logger log) {
  567.         this(planker, log, -1);
  568.     }
  569.  
  570.     /**
  571.      * Constructs a PaintInterface with the provided EquinoxLunarPlanker
  572.      * instance, Logger instance, and SkillID
  573.      *
  574.      * @param planker
  575.      *            EquinoxLunarPlanker
  576.      * @param log
  577.      *            Logger
  578.      * @param SkillID
  579.      *            int
  580.      */
  581.     public PaintInterface(EquinoxLunarPlanker planker, Logger log,
  582.         int SkillID) {
  583.         this.planker = planker;
  584.         this.log = log;
  585.         this.SkillID = SkillID;
  586.         if (SkillID >= 0 && SkillID < Skills.SKILL_NAMES.length) {
  587.         startExp = skills.getCurrentExp(SkillID);
  588.         startTime = System.currentTimeMillis();
  589.         startLevel = skills.getCurrentLevel(SkillID);
  590.         setUpGoal();
  591.         }
  592.         init();
  593.     }
  594.  
  595.     /**
  596.      * Initializes paintMenu
  597.      */
  598.     public void init() {
  599.         RSComponent screen = interfaces.get(548).getComponent(3);
  600.         Point bottomRight = new Point(screen.getAbsoluteX()
  601.             + screen.getWidth(), screen.getAbsoluteY()
  602.             + screen.getHeight());
  603.         paintMenu = new Menu(this, bottomRight, Anchor.DOWN_RIGHT);
  604.         paintMenu.setFlowType(FlowType.HORIZONTAL);
  605.         paintMenu.addMouseListener(new MouseListen() {
  606.         @Override
  607.         void MouseAction(MouseEvent e) {
  608.             if (e.getID() == MouseEvent.MOUSE_CLICKED)
  609.             paintMenu.toggleShowAll();
  610.         }
  611.         });
  612.         if (SkillID >= 0 && SkillID < Skills.SKILL_NAMES.length) {
  613.         MenuProgressBar progressBar = new MenuProgressBar("nextlvl",
  614.             paintMenu, new GetPercent() {
  615.                 @Override
  616.                 int getPercent() {
  617.                 return skills.getPercentToNextLevel(SkillID);
  618.                 }
  619.             }, "Next Level", new GetPopup() {
  620.                 @Override
  621.                 MenuPopUp getPopUp() {
  622.                 long millis = Math.abs(System
  623.                     .currentTimeMillis() - startTime);
  624.                 if (millis <= 0)
  625.                     millis = 1;
  626.                 long expGained = skills.getCurrentExp(SkillID)
  627.                     - startExp;
  628.                 long expPerHour = (expGained * 3600000l)
  629.                     / millis;
  630.                 String TTL = "";
  631.                 int TTLunf = (int) ((expPerHour > 0) ? (((float) skills
  632.                     .getExpToNextLevel(SkillID))
  633.                     / ((float) expPerHour) * 3600000f) : 0);
  634.                 if (TTLunf != 0)
  635.                     TTL = PaintFormatter
  636.                         .getFormattedTime(TTLunf);
  637.                 else
  638.                     TTL = "No exp gained";
  639.                 String[] lines = new String[4];
  640.                 lines[0] = "Exp gained: "
  641.                     + PaintFormatter
  642.                         .getFormattedMoney(expGained);
  643.                 lines[1] = "Exp per Hour: "
  644.                     + PaintFormatter
  645.                         .getFormattedMoney(expPerHour);
  646.                 lines[2] = "Exp 'till level: "
  647.                     + PaintFormatter.getFormattedMoney(skills
  648.                         .getExpToNextLevel(SkillID));
  649.                 lines[3] = "Time 'till level: " + TTL;
  650.                 return new MenuPopUp(lines, "nextlevel");
  651.                 }
  652.  
  653.             });
  654.         paintMenu.add(progressBar);
  655.  
  656.         if (goalExp > skills.getCurrentExp(SkillID)) {
  657.             MenuProgressBar goalBar = new MenuProgressBar("goal",
  658.                 paintMenu, new GetPercent() {
  659.                 @Override
  660.                 int getPercent() {
  661.                     float expTillGoalStart = goalExp - startExp;
  662.                     double expGained = skills
  663.                         .getCurrentExp(SkillID) - startExp;
  664.                     double result = expGained
  665.                         / expTillGoalStart;
  666.                     if (result > 1)
  667.                     result = 1;
  668.                     if (result < 0)
  669.                     result = 0;
  670.                     return (int) (result * 100);
  671.                 }
  672.                 }, "Goal", new GetPopup() {
  673.                 @Override
  674.                 MenuPopUp getPopUp() {
  675.                     long millis = Math.abs(System
  676.                         .currentTimeMillis() - startTime);
  677.                     if (millis <= 0)
  678.                     millis = 1;
  679.                     long expGained = skills
  680.                         .getCurrentExp(SkillID) - startExp;
  681.                     long expPerHour = (expGained * 3600000l)
  682.                         / millis;
  683.                     int expTillGoal = goalExp
  684.                         - skills.getCurrentExp(SkillID);
  685.                     String TTG = "";
  686.                     int TTGunf = (int) ((expPerHour > 0) ? (((float) expTillGoal)
  687.                         / ((float) expPerHour) * 3600000f)
  688.                         : 0);
  689.                     if (TTGunf != 0)
  690.                     TTG = PaintFormatter
  691.                         .getFormattedTime(TTGunf);
  692.                     else
  693.                     TTG = "No exp gained";
  694.                     String[] lines = new String[goalLevel > 0 ? 6
  695.                         : 5];
  696.                     int off = goalLevel > 0 ? 1 : 0;
  697.                     if (goalLevel > 0)
  698.                     lines[0] = "Goal Level: " + goalLevel;
  699.                     lines[0 + off] = "Goal Exp: "
  700.                         + PaintFormatter
  701.                             .getFormattedMoney(goalExp);
  702.                     lines[1 + off] = "Exp gained: "
  703.                         + PaintFormatter
  704.                             .getFormattedMoney(expGained);
  705.                     lines[2 + off] = "Exp per Hour: "
  706.                         + PaintFormatter
  707.                             .getFormattedMoney(expPerHour);
  708.                     lines[3 + off] = "Exp 'till goal: "
  709.                         + PaintFormatter
  710.                             .getFormattedMoney(expTillGoal);
  711.                     lines[4 + off] = "Time 'till goal: " + TTG;
  712.                     return new MenuPopUp(lines, "goalbar");
  713.                 }
  714.  
  715.                 });
  716.             paintMenu.add(goalBar);
  717.         }
  718.         }
  719.  
  720.         // Actual buttons:
  721.         MenuButton planks = new MenuButton("planks", paintMenu,
  722.             "plankicon", new GetPopup() {
  723.             @Override
  724.             MenuPopUp getPopUp() {
  725.                 long millis = Math.abs(System.currentTimeMillis()
  726.                     - startTime);
  727.                 if (millis <= 0)
  728.                 millis = 1;
  729.                 int planksPerHour = (int) ((planksMade * 3600000l) / millis);
  730.                 int costPerCastR = (2 * astralPrice) + naturePrice
  731.                     + (hasEarthStaff ? 0 : 15 * earthPrice);
  732.                 int costPerCastLC = logPrice + coinsPerPlank;
  733.                 int costPerCast = costPerCastLC + costPerCastR;
  734.                 int profit = (plankPrice - costPerCast)
  735.                     * planksMade;
  736.                 int profitPhour = (int) ((profit * 3600000l) / millis);
  737.                 int totalCastsLeft = Math.min(
  738.                     Math.min(logsLeft, castsLeft), coinsLeft);
  739.                 String[] lines = new String[totalCastsLeft > 0 ? 9
  740.                     : 7];
  741.                 lines[0] = "Planks made: " + planksMade;
  742.                 lines[1] = "Planks per hour: " + planksPerHour;
  743.                 lines[2] = "Cost per cast: " + costPerCast;
  744.                 lines[3] = "Price of plank: " + plankPrice;
  745.                 lines[4] = "Profit per cast: "
  746.                     + (costPerCast - plankPrice);
  747.                 lines[5] = "Profit: "
  748.                     + PaintFormatter.getFormattedMoney(profit);
  749.                 lines[6] = "Profit per hour: " + profitPhour;
  750.                 if (totalCastsLeft > 0) {
  751.                 String timeTillCastsOut = PaintFormatter
  752.                     .getFormattedTime((long) (((double) totalCastsLeft) / (((double) planksMade) / ((double) millis))));
  753.                 lines[7] = "Casts remaining: " + totalCastsLeft;
  754.                 lines[8] = "No materials in: "
  755.                     + timeTillCastsOut;
  756.                 }
  757.  
  758.                 return new MenuPopUp(lines, "planks");
  759.  
  760.             }
  761.             });
  762.         paintMenu.add(planks);
  763.  
  764.         MenuButton home = new MenuButton("home", paintMenu, "homeicon",
  765.             new GetPopup() {
  766.             @Override
  767.             MenuPopUp getPopUp() {
  768.                 long millis = Math.abs(System.currentTimeMillis()
  769.                     - startTime);
  770.                 if (millis <= 0)
  771.                 millis = 1;
  772.                 String[] lines = new String[5];
  773.                 lines[0] = planker.name;
  774.                 lines[1] = "By: " + planker.author;
  775.                 lines[2] = "Version " + planker.VERSION;
  776.                 lines[3] = "Runtime: "
  777.                     + PaintFormatter.getFormattedTime(millis);
  778.                 lines[4] = PaintFormatter.properCaseAll(planker
  779.                     .getState().name().replace("_", " "));
  780.                 return new MenuPopUp(lines, "home");
  781.             }
  782.             });
  783.         paintMenu.add(home);
  784.  
  785.         MenuButton tools = new MenuButton("tools", paintMenu, "toolsicon",
  786.             new GetPopup() {
  787.             @Override
  788.             MenuPopUp getPopUp() {
  789.                 MenuPopUp popUp = new MenuPopUp(new String[] {
  790.                     "Save proggie", "Reload data" }, "tools");
  791.                 popUp.addLineListener(new LineListener() {
  792.                 @Override
  793.                 void fireEvent(MouseEvent e, String line) {
  794.                     line = line.toLowerCase().trim();
  795.                     if (e.getID() == MouseEvent.MOUSE_CLICKED) {
  796.                     if (line.contains("save proggie"))
  797.                         paintMenu.saveProggie();
  798.                     else if (line.contains("reload data"))
  799.                         new DataLoader(planker);
  800.                     }
  801.                 }
  802.  
  803.                 @Override
  804.                 boolean hasAction(String line) {
  805.                     line = line.toLowerCase().trim();
  806.                     return (line.contains("save proggie"))
  807.                         || (line.contains("reload data"));
  808.                 }
  809.                 });
  810.                 return popUp;
  811.             }
  812.             });
  813.         paintMenu.add(tools);
  814.  
  815.         paintMenu.compile();
  816.     }
  817.  
  818.     /**
  819.      * Gets the current Goal for the setSkill, or sets all goal variables to
  820.      * -1 if there is no goal
  821.      */
  822.     public void setUpGoal() {
  823.         try {
  824.         for (byte b = 0; b < 10; b++)
  825.             if (game.getCurrentTab() != Game.TAB_STATS) {
  826.             game.openTab(Game.TAB_STATS);
  827.             sleep(1000);
  828.             } else
  829.             break;
  830.  
  831.         RSInterface stats = interfaces.get(320);
  832.         if (stats != null && stats.isValid()) {
  833.             RSComponent mage = stats
  834.                 .getComponent(SKILL_INTERFACES[SkillID]);
  835.             if (mage != null && mage.isValid()
  836.                 && mage.getArea() != null) {
  837.             mouse.move((int) mage.getArea().getCenterX(),
  838.                 (int) mage.getArea().getCenterY());
  839.             sleep(500, 750);
  840.             // Now we see what the popup is doing
  841.             RSComponent pop = stats.getComponent(202);
  842.             if (pop != null && pop.isValid()) {
  843.                 RSComponent def = pop.getComponent(5);
  844.                 if (def != null && def.isValid()) {
  845.                 if (def.getText().trim()
  846.                     .equalsIgnoreCase("Target XP:")) {
  847.                     RSComponent goalXP = pop.getComponent(6);
  848.                     if (goalXP != null && goalXP.isValid()) {
  849.                     goalExp = Integer.valueOf(goalXP
  850.                         .getText().replace(",", "")
  851.                         .trim());
  852.                     goalLevel = -1;
  853.                     }
  854.                 } else {
  855.                     // Proceed
  856.                     RSComponent currExp = pop.getComponent(4);
  857.                     RSComponent goalRemainder = pop
  858.                         .getComponent(12);
  859.                     RSComponent goalLvl = pop.getComponent(10);
  860.                     if (currExp != null && currExp.isValid()
  861.                         && goalRemainder != null
  862.                         && goalRemainder.isValid()
  863.                         && goalLvl != null
  864.                         && goalLvl.isValid()) {
  865.                     goalExp = Integer.valueOf(currExp
  866.                         .getText().replace(",", "")
  867.                         .trim())
  868.                         + Integer.valueOf(goalRemainder
  869.                             .getText()
  870.                             .replace(",", "")
  871.                             .trim());
  872.                     goalLevel = Integer.valueOf(goalLvl
  873.                         .getText().replace(",", "")
  874.                         .trim());
  875.                     }
  876.                 }
  877.                 log.info("Target level: "
  878.                     + (goalLevel > 0 ? goalLevel : "None"));
  879.                 log.info("Target exp: "
  880.                     + (goalExp > 0 ? goalExp : "None"));
  881.                 return;
  882.                 }
  883.             }
  884.             }
  885.         }
  886.         } catch (Exception e) {
  887.         }
  888.         goalExp = -1;
  889.         goalLevel = -1;
  890.     }
  891.  
  892.     /**
  893.      * Renders the current paint to the given graphics context.
  894.      *
  895.      * @param g
  896.      *            as the Graphics2D object to render to
  897.      */
  898.     public void render(Graphics2D g) {
  899.         paintMenu.render(g, mouseLoc);
  900.         int mouseX = mouseLoc.x;
  901.         int mouseY = mouseLoc.y;
  902.         g.setColor(Color.RED);
  903.         g.drawLine(mouseX - 5, mouseY - 5, mouseX + 5, mouseY + 5);
  904.         g.drawLine(mouseX - 5, mouseY + 5, mouseX + 5, mouseY - 5);
  905.     }
  906.  
  907.     /**
  908.      * Fires a MouseEvent in the paintMenu
  909.      *
  910.      * @param e
  911.      *            MouseEvent
  912.      */
  913.     public void fireMouseEvent(MouseEvent e) {
  914.         if (paintMenu.getBoundsFull().contains(e.getPoint()))
  915.         paintMenu.fireMouseEvent(e);
  916.     }
  917.  
  918.     /**
  919.      * Represents a Menu on a PaintInterface
  920.      *
  921.      * @author Equinox_
  922.      *
  923.      */
  924.     public class Menu {
  925.         final int padding = 1;
  926.         Point location;
  927.         PaintInterface parent;
  928.         PaintStyle style;
  929.         List<MenuItem> components = new ArrayList<MenuItem>();
  930.         final Anchor anchor;
  931.         boolean showAllPopups;
  932.         MenuPopUp visiblePopup = null;
  933.         List<MouseListen> mouseListeners;
  934.         LineListener defaultLineListener;
  935.         private FlowType flowType = FlowType.HORIZONTAL;
  936.         public Dimension bounds;
  937.  
  938.         /**
  939.          * Constructs a Menu using the provided PaintInterface, Location,
  940.          * Anchor, and the GameScreen as the bounds
  941.          *
  942.          * @param parent
  943.          *            PaintInterface
  944.          * @param location
  945.          *            Point
  946.          * @param anchor
  947.          *            Anchor
  948.          */
  949.         public Menu(PaintInterface parent, Point location, Anchor anchor) {
  950.         this.parent = parent;
  951.         this.style = parent.style;
  952.         this.location = location;
  953.         this.anchor = anchor;
  954.  
  955.         // Setup dimension
  956.         Rectangle r = interfaces.get(548).getComponent(3).getArea();
  957.         bounds = new Dimension(r.width, r.height);
  958.         }
  959.  
  960.         /**
  961.          * Sets the FlowType and recompiles the menu
  962.          *
  963.          * @param flowType
  964.          *            FlowType
  965.          */
  966.         public void setFlowType(FlowType flowType) {
  967.         this.flowType = flowType;
  968.         this.compile();
  969.         }
  970.  
  971.         /**
  972.          * Gets the FlowType
  973.          *
  974.          * @return FlowType
  975.          */
  976.         public FlowType getFlowType() {
  977.         return flowType;
  978.         }
  979.  
  980.         /**
  981.          * Toggles the showAllPopups state
  982.          * */
  983.         public void toggleShowAll() {
  984.         showAllPopups = !showAllPopups;
  985.         }
  986.  
  987.         /**
  988.          * Constructs a menu using the provided parent and location,
  989.          * assuming Anchor.UP_LEFT
  990.          *
  991.          * @param parent
  992.          *            PaintInterface
  993.          * @param location
  994.          *            Point
  995.          */
  996.         public Menu(PaintInterface parent, Point location) {
  997.         this(parent, location, Anchor.UP_LEFT);
  998.         }
  999.  
  1000.         /**
  1001.          * Adds the specified menu item
  1002.          *
  1003.          * @param i
  1004.          *            MenuItem
  1005.          */
  1006.         public void add(MenuItem i) {
  1007.         i.setIndex(components.size());
  1008.         components.add(i);
  1009.         compile();
  1010.         }
  1011.  
  1012.         /**
  1013.          * Compiles this menu
  1014.          */
  1015.         public void compile() {
  1016.         for (int i = 0; i < components.size(); i++)
  1017.             components.get(i).compile();
  1018.         }
  1019.  
  1020.         /**
  1021.          * Gets position x based on the menu's anchor
  1022.          *
  1023.          * @return int
  1024.          */
  1025.         public int getAbsX() {
  1026.         if (anchor.name().contains("LEFT"))
  1027.             return location.x;
  1028.         else
  1029.             return location.x - getWidth();
  1030.         }
  1031.  
  1032.         /**
  1033.          * Gets position y based on the menu's anchor
  1034.          *
  1035.          * @return int
  1036.          */
  1037.         public int getAbsY() {
  1038.         if (anchor.name().contains("UP"))
  1039.             return location.y;
  1040.         else
  1041.             return location.y - getHeight();
  1042.         }
  1043.  
  1044.         /**
  1045.          * Gets the maximum width of this menu using the menu's FlowType
  1046.          *
  1047.          * @return int
  1048.          */
  1049.         public int getWidth() {
  1050.         if (flowType.equals(FlowType.HORIZONTAL)) {
  1051.             int width = padding * components.size();
  1052.             for (MenuItem m : components)
  1053.             if (m.bounds != null)
  1054.                 width += m.bounds.width;
  1055.             return width + padding;
  1056.         } else {
  1057.             int max = Integer.MIN_VALUE;
  1058.             for (MenuItem m : components)
  1059.             if (m.bounds != null)
  1060.                 if (max < m.bounds.width)
  1061.                 max = (int) m.bounds.width;
  1062.             return max + (2 * padding);
  1063.         }
  1064.         }
  1065.  
  1066.         /**
  1067.          * Gets the maximum height of this menu based of FlowType
  1068.          *
  1069.          * @return int
  1070.          */
  1071.         public int getHeight() {
  1072.         if (flowType.equals(FlowType.HORIZONTAL)) {
  1073.             int max = Integer.MIN_VALUE;
  1074.             for (MenuItem m : components)
  1075.             if (m.bounds != null)
  1076.                 if (max < m.bounds.height)
  1077.                 max = (int) m.bounds.height;
  1078.             return max + (2 * padding);
  1079.         } else {
  1080.             int height = padding * components.size();
  1081.             for (MenuItem m : components)
  1082.             if (m.bounds != null)
  1083.                 height += m.bounds.height;
  1084.             return height + padding;
  1085.         }
  1086.         }
  1087.  
  1088.         /**
  1089.          * Gets the current bounds of this menu, with rounded corners if
  1090.          * specified
  1091.          *
  1092.          * @param rounded
  1093.          *            boolean
  1094.          * @return RoundRectangle2D.Float
  1095.          */
  1096.         public RoundRectangle2D.Float getArea(boolean rounded) {
  1097.         float round = rounded ? style.roundCorner : 0;
  1098.         return new RoundRectangle2D.Float(getAbsX(), getAbsY(),
  1099.             getWidth(), getHeight(), round, round);
  1100.         }
  1101.  
  1102.         public Rectangle getBoundsFull() {
  1103.         RoundRectangle2D r1 = getArea(false);
  1104.         RoundRectangle2D r2 = visiblePopup != null ? visiblePopup.bkg
  1105.             : getArea(false);
  1106.         int x = (int) Math.min(r1.getX(), r2.getX());
  1107.         int y = (int) Math.min(r1.getY(), r2.getY());
  1108.         int width = (int) Math.max(r1.getX() + r1.getWidth(), r2.getX()
  1109.             + r2.getWidth())
  1110.             - x;
  1111.         int height = (int) Math.max(r1.getX() + r1.getHeight(),
  1112.             r2.getX() + r2.getHeight())
  1113.             - y;
  1114.         return new Rectangle(x, y, width, height);
  1115.         }
  1116.  
  1117.         /**
  1118.          * Renders the menu to the specified Graphics object using the
  1119.          * provided mouse location for any popups
  1120.          *
  1121.          * @param g
  1122.          *            Graphics2D
  1123.          * @param mouseLoc
  1124.          *            Point
  1125.          */
  1126.         public void render(Graphics2D g, Point mouseLoc) {
  1127.         g.setColor(style.bgColor);
  1128.         g.fill(getArea(true));
  1129.         MenuPopUp overPopup = null;
  1130.         for (MenuItem m : components) {
  1131.             m.render(g);
  1132.             MenuPopUp p = m.getPopUp();
  1133.             if (p != null) {
  1134.             if (m.bounds.contains(mouseLoc)
  1135.                 || (m.getPopUp().name
  1136.                     .equalsIgnoreCase(visiblePopup != null ? visiblePopup.name
  1137.                         : "") && rectangleContainsApprox(
  1138.                     visiblePopup.bkg, mouseLoc)))
  1139.                 overPopup = m.getPopUp();
  1140.             }
  1141.         }
  1142.         if (showAllPopups)
  1143.             getAllPopups(true).render(g);
  1144.         else if (overPopup != null) {
  1145.             overPopup.render(g);
  1146.         }
  1147.         visiblePopup = overPopup;
  1148.         }
  1149.  
  1150.         /**
  1151.          * Check if the specified point is within sqrt(2) of the Rectangle
  1152.          *
  1153.          * @param r
  1154.          *            RoundRectangle2D
  1155.          * @param p
  1156.          *            Point
  1157.          * @return boolean contains
  1158.          */
  1159.         public boolean rectangleContainsApprox(RoundRectangle2D r, Point p) {
  1160.         for (int oX = -1; oX <= 1; oX++)
  1161.             for (int oY = -1; oY <= 1; oY++)
  1162.             if (r.contains(new Point(p.x + oX, p.y + oY)))
  1163.                 return true;
  1164.         return false;
  1165.         }
  1166.  
  1167.         /**
  1168.          * Gets all popups in frontToBack or backToFront order and excluding
  1169.          * specified names
  1170.          *
  1171.          * @param rightToLeft
  1172.          *            boolean
  1173.          * @param excludeItems
  1174.          *            String...
  1175.          * @return MenuPopUp
  1176.          */
  1177.         public MenuPopUp getAllPopups(boolean backToFront,
  1178.             String... excludeItems) {
  1179.         List<String> lines = new ArrayList<String>();
  1180.         if (components.size() > 0)
  1181.             if (backToFront)
  1182.             for (int i = components.size() - 1; i >= 0; i--) {
  1183.                 boolean ignored = false;
  1184.                 for (String subS : excludeItems)
  1185.                 if (components.get(i).name
  1186.                     .equalsIgnoreCase(subS))
  1187.                     ignored = true;
  1188.                 if (!ignored) {
  1189.                 MenuPopUp sub = components.get(i).getPopUp();
  1190.                 if (sub != null)
  1191.                     for (String line : sub.lines)
  1192.                     if (!containsLine(lines, line))
  1193.                         lines.add(line);
  1194.                 }
  1195.             }
  1196.             else
  1197.             for (int i = 0; i < components.size(); i++) {
  1198.                 boolean ignored = false;
  1199.                 for (String subS : excludeItems)
  1200.                 if (components.get(i).name
  1201.                     .equalsIgnoreCase(subS))
  1202.                     ignored = true;
  1203.                 if (!ignored) {
  1204.                 MenuPopUp sub = components.get(i).getPopUp();
  1205.                 if (sub != null)
  1206.                     for (String line : sub.lines)
  1207.                     if (!containsLine(lines, line))
  1208.                         lines.add(line);
  1209.                 }
  1210.             }
  1211.  
  1212.         String[] linesArr = new String[lines.size()];
  1213.         for (int i = 0; i < lines.size(); i++)
  1214.             linesArr[i] = lines.get(i);
  1215.         MenuPopUp p = new MenuPopUp(linesArr, "allpopups");
  1216.         p.setParent(components.get(components.size() - 1));
  1217.         return p;
  1218.         }
  1219.  
  1220.         /**
  1221.          * Checks if the specified array contains the specified line, just
  1222.          * the tag, not the data if possible
  1223.          *
  1224.          * @param lines
  1225.          *            List of Strings
  1226.          * @param line
  1227.          *            String
  1228.          * @return boolean contains
  1229.          */
  1230.         public boolean containsLine(List<String> lines, String line) {
  1231.         for (String s : lines)
  1232.             if (s.contains(":") && line.contains(":")) {
  1233.             if (s.split(":")[0]
  1234.                 .equalsIgnoreCase(line.split(":")[0]))
  1235.                 return true;
  1236.             } else if (s.equalsIgnoreCase(line))
  1237.             return true;
  1238.         return false;
  1239.         }
  1240.  
  1241.         /**
  1242.          * Gets a proggie as a BufferedImage
  1243.          *
  1244.          * @return BufferedImage proggie
  1245.          */
  1246.         public BufferedImage getProggie() {
  1247.         String[] lines = getAllPopups(true, "tools").lines;
  1248.         Color color = style.FONT_COLOR;
  1249.         Font font = style.FONT;
  1250.         float line_height = font.getLineMetrics(lines[0], Paint.frc)
  1251.             .getHeight();
  1252.         int width = 0;
  1253.         for (String line : lines)
  1254.             if (font.getStringBounds(line, Paint.frc).getWidth() > width)
  1255.             width = (int) font.getStringBounds(line, Paint.frc)
  1256.                 .getWidth();
  1257.  
  1258.         int height = (int) (lines.length * line_height);
  1259.  
  1260.         width += style.roundCorner + 2;
  1261.         height += style.roundCorner + 2;
  1262.  
  1263.         RoundRectangle2D.Float bkg = new RoundRectangle2D.Float(0, 0,
  1264.             width, height,
  1265.             style.roundCorner > 0 ? style.roundCorner + 1 : 0,
  1266.             style.roundCorner > 0 ? style.roundCorner + 1 : 0);
  1267.         RoundRectangle2D.Float fg = new RoundRectangle2D.Float(
  1268.             (float) bkg.getX() + 1, (float) bkg.getY() + 1,
  1269.             width - 2, height - 2, style.roundCorner,
  1270.             style.roundCorner);
  1271.         Rectangle txtBounds = new Rectangle(
  1272.             (int) (fg.getX() + (style.roundCorner / 2)),
  1273.             (int) (fg.getY() + (style.roundCorner / 2)),
  1274.             (int) (width - style.roundCorner - 2), (int) (height
  1275.                 - style.roundCorner - 2));
  1276.         BufferedImage bImg = new BufferedImage(width, height,
  1277.             BufferedImage.TYPE_INT_ARGB);
  1278.         Graphics2D g = (Graphics2D) bImg.getGraphics();
  1279.         g.setColor(style.bgColor);
  1280.         g.fill(bkg);
  1281.         g.setColor(style.fgColor);
  1282.         g.fill(fg);
  1283.         g.setFont(font);
  1284.         g.setColor(color);
  1285.         for (int i = 0; i < lines.length; i++)
  1286.             g.drawString(lines[i], txtBounds.x,
  1287.                 ((i + 1) * (line_height)) + txtBounds.y);
  1288.         return bImg;
  1289.         }
  1290.  
  1291.         /**
  1292.          * Saves a progress report to the Screenshots directory
  1293.          */
  1294.         public void saveProggie() {
  1295.         String name = planker.name
  1296.             + "_"
  1297.             + PaintFormatter.getFormattedTime(
  1298.                 System.currentTimeMillis() - Paint.startTime,
  1299.                 "-", true);
  1300.         final File dir = new File(
  1301.             Configuration.Paths.getScreenshotsDirectory());
  1302.         if (dir.isDirectory() || dir.mkdirs()) {
  1303.             try {
  1304.             int ext = 0;
  1305.             while (new File(dir, name
  1306.                 + (ext > 0 ? ("(" + ext + ")") : "") + ".png")
  1307.                 .exists())
  1308.                 ext++;
  1309.  
  1310.             ImageIO.write(Paint.paintMenu.getProggie(), "png",
  1311.                 new File(dir, name
  1312.                     + (ext > 0 ? ("(" + ext + ")") : "")));
  1313.             log.info("Saved proggie!");
  1314.             log.info(new File(dir, name
  1315.                 + (ext > 0 ? ("(" + ext + ")") : "") + ".png")
  1316.                 .getAbsolutePath());
  1317.             } catch (IOException e) {
  1318.             log.severe("Failed to save proggie!");
  1319.             }
  1320.         }
  1321.         }
  1322.  
  1323.         /**
  1324.          * Adds the specified mouse listener
  1325.          *
  1326.          * @param listen
  1327.          *            MouseListen
  1328.          */
  1329.         public void addMouseListener(MouseListen listen) {
  1330.         if (mouseListeners == null)
  1331.             mouseListeners = new ArrayList<MouseListen>();
  1332.         mouseListeners.add(listen);
  1333.         }
  1334.  
  1335.         /**
  1336.          * Sets the default line listener
  1337.          *
  1338.          * @param listen
  1339.          *            LineListener
  1340.          */
  1341.         public void setDefaultLineListener(LineListener listen) {
  1342.         defaultLineListener = listen;
  1343.         }
  1344.  
  1345.         /**
  1346.          * Fires the MouseEvent in all containing children and this
  1347.          *
  1348.          * @param e
  1349.          *            MouseEvent
  1350.          */
  1351.         public void fireMouseEvent(MouseEvent e) {
  1352.         if (getArea(true).contains(e.getPoint()))
  1353.             if (mouseListeners != null)
  1354.             for (MouseListen m : mouseListeners)
  1355.                 m.MouseAction(e);
  1356.         for (MenuItem m : components)
  1357.             if (m.bounds != null)
  1358.             if (m.bounds.contains(e.getPoint()))
  1359.                 m.fireMouseEvent(e);
  1360.         if (visiblePopup != null)
  1361.             visiblePopup.fireMouseEvent(e);
  1362.  
  1363.         }
  1364.     }
  1365.  
  1366.     /**
  1367.      * Represents a class containing the method for getting the popup
  1368.      *
  1369.      * @author Equinox_
  1370.      *
  1371.      */
  1372.     public abstract class GetPopup {
  1373.         abstract MenuPopUp getPopUp();
  1374.     }
  1375.  
  1376.     /**
  1377.      * Represents a modified MouseListener used in MenuEvents
  1378.      *
  1379.      * @author Equinox_
  1380.      *
  1381.      */
  1382.     public abstract class MouseListen {
  1383.         abstract void MouseAction(MouseEvent e);
  1384.     }
  1385.  
  1386.     /**
  1387.      * An abstract class representing MenuItems
  1388.      *
  1389.      * @author Equinox_
  1390.      *
  1391.      */
  1392.     public abstract class MenuItem {
  1393.         final GetPopup getPopup;
  1394.         Menu parent;
  1395.         RoundRectangle2D.Float bounds;
  1396.         int index;
  1397.         final int width;
  1398.         final int height;
  1399.         List<MouseListen> mouseListeners;
  1400.         final String name;
  1401.  
  1402.         /**
  1403.          * Constructs a MenuItem with the given name, parent, getPopup
  1404.          * method, width and height
  1405.          *
  1406.          * @param name
  1407.          *            String
  1408.          * @param parent
  1409.          *            Menu
  1410.          * @param getPopup
  1411.          *            GetPopup
  1412.          * @param width
  1413.          *            int
  1414.          * @param height
  1415.          *            int
  1416.          */
  1417.         public MenuItem(String name, Menu parent, GetPopup getPopup,
  1418.             int width, int height) {
  1419.         this.name = name;
  1420.         this.height = height;
  1421.         this.width = width;
  1422.         this.getPopup = getPopup;
  1423.         this.parent = parent;
  1424.         this.bounds = new RoundRectangle2D.Float(0, 0, width, height,
  1425.             parent.style.roundCorner, parent.style.roundCorner);
  1426.         }
  1427.  
  1428.         /**
  1429.          * Constructs a MenuItem with the given name, parent, width and
  1430.          * height
  1431.          *
  1432.          * @param name
  1433.          *            String
  1434.          * @param parent
  1435.          *            Menu
  1436.          * @param width
  1437.          *            int
  1438.          * @param height
  1439.          *            int
  1440.          */
  1441.         public MenuItem(String name, Menu parent, int width, int height) {
  1442.         this(name, parent, null, width, height);
  1443.         }
  1444.  
  1445.         /**
  1446.          * sets this item's index
  1447.          *
  1448.          * @param idx
  1449.          *            int
  1450.          */
  1451.         public void setIndex(int idx) {
  1452.         this.index = idx;
  1453.         }
  1454.  
  1455.         /**
  1456.          * renders this item to the given Graphics2D
  1457.          *
  1458.          * @param g
  1459.          *            Graphics2D
  1460.          */
  1461.         abstract void render(Graphics2D g);
  1462.  
  1463.         /**
  1464.          * Compiles this item
  1465.          */
  1466.         public void compile() {
  1467.         this.bounds = new RoundRectangle2D.Float(0, 0, width, height,
  1468.             parent.style.roundCorner, parent.style.roundCorner);
  1469.         bounds.x = getX();
  1470.         bounds.y = getY();
  1471.         }
  1472.  
  1473.         /**
  1474.          * Gets the offset from upper left of parent depending on parent's
  1475.          * FlowType
  1476.          *
  1477.          * @return int offsetY
  1478.          */
  1479.         public int getOffX() {
  1480.         if (parent.getFlowType().equals(FlowType.HORIZONTAL)) {
  1481.             int x = 1;
  1482.             for (int i = 0; i < index; i++)
  1483.             x += 1 + parent.components.get(i).bounds.width;
  1484.  
  1485.             return x;
  1486.         }
  1487.         if (parent.getWidth() > bounds.width)
  1488.             return (int) (parent.getWidth() / 2 - bounds.width / 2);
  1489.         return 1;
  1490.         }
  1491.  
  1492.         /**
  1493.          * Gets the offset from upper left of parent depending on parent's
  1494.          * FlowType
  1495.          *
  1496.          * @return int offsetX
  1497.          */
  1498.         public int getOffY() {
  1499.         if (parent.getFlowType().equals(FlowType.VERTICAL)) {
  1500.             int y = 1;
  1501.             for (int i = 0; i < index; i++)
  1502.             y += 1 + parent.components.get(i).bounds.height;
  1503.  
  1504.             return y;
  1505.         }
  1506.         return 1;
  1507.         }
  1508.  
  1509.         /**
  1510.          * Gets the absolute x
  1511.          *
  1512.          * @return int absolute x
  1513.          */
  1514.         public int getX() {
  1515.         int x = getOffX() + parent.getAbsX();
  1516.         return x;
  1517.         }
  1518.  
  1519.         /**
  1520.          * Gets the absolute y
  1521.          *
  1522.          * @return int absolute y
  1523.          */
  1524.         public int getY() {
  1525.         int y = getOffY() + parent.getAbsY();
  1526.         return y;
  1527.         }
  1528.  
  1529.         /**
  1530.          * Gets this item's popup
  1531.          *
  1532.          * @return MenuPopUp
  1533.          */
  1534.         public MenuPopUp getPopUp() {
  1535.         if (getPopup != null) {
  1536.             MenuPopUp m = getPopup.getPopUp();
  1537.             m.setParent(this);
  1538.             if (parent.defaultLineListener != null)
  1539.             m.addLineListener(parent.defaultLineListener);
  1540.             return m;
  1541.         }
  1542.         return null;
  1543.         }
  1544.  
  1545.         /**
  1546.          * Adds a mouselistener
  1547.          *
  1548.          * @param listen
  1549.          *            MouseListen
  1550.          */
  1551.         public void addMouseListener(MouseListen listen) {
  1552.         if (mouseListeners == null)
  1553.             mouseListeners = new ArrayList<MouseListen>();
  1554.         mouseListeners.add(listen);
  1555.         }
  1556.  
  1557.         /**
  1558.          * Sends the mouse event to all of this item's listeners
  1559.          *
  1560.          * @param e
  1561.          *            MouseEvent
  1562.          */
  1563.         public void fireMouseEvent(MouseEvent e) {
  1564.         if (mouseListeners != null && mouseListeners.size() > 0)
  1565.             for (MouseListen m : mouseListeners)
  1566.             m.MouseAction(e);
  1567.         }
  1568.     }
  1569.  
  1570.     /**
  1571.      * A class representing a mouse over button on the parent menu
  1572.      *
  1573.      * @author Equinox_
  1574.      *
  1575.      */
  1576.     public class MenuButton extends MenuItem {
  1577.         final static int width = 30;
  1578.         final static int height = 30;
  1579.  
  1580.         String imageIcon;
  1581.  
  1582.         /**
  1583.          * Constructs a button using the specified name, parent, imageIcon,
  1584.          * and getPopup method.
  1585.          *
  1586.          * @param name
  1587.          *            String
  1588.          * @param parent
  1589.          *            Menu
  1590.          * @param imageIcon
  1591.          *            String
  1592.          * @param getPopUp
  1593.          *            GetPopup
  1594.          */
  1595.         public MenuButton(String name, Menu parent, String imageIcon,
  1596.             GetPopup getPopUp) {
  1597.         super(name, parent, getPopUp, width, height);
  1598.         this.imageIcon = imageIcon.toLowerCase();
  1599.         }
  1600.  
  1601.         /**
  1602.          * Constructs a button using the specified name, parent, and
  1603.          * imageIcon
  1604.          *
  1605.          * @param name
  1606.          *            String
  1607.          * @param parent
  1608.          *            Menu
  1609.          * @param imageIcon
  1610.          *            String
  1611.          */
  1612.         public MenuButton(String name, Menu parent, String imageIcon) {
  1613.         this(name, parent, imageIcon, null);
  1614.         }
  1615.  
  1616.         /**
  1617.          * Constructs a button using the specified name and parent
  1618.          *
  1619.          * @param name
  1620.          *            String
  1621.          * @param parent
  1622.          *            Menu
  1623.          */
  1624.         public MenuButton(String name, Menu parent) {
  1625.         this(name, parent, "", null);
  1626.         }
  1627.  
  1628.         /**
  1629.          * Renders this MenuButton to the given Graphics2D context
  1630.          */
  1631.         @Override
  1632.         public void render(Graphics2D g) {
  1633.         // Compiling
  1634.         if (parent.parent.icons.containsKey(imageIcon))
  1635.             if (parent.parent.icons.get(imageIcon) != null)
  1636.             if (!parent.parent.icons.containsKey("Button-"
  1637.                 + imageIcon)) {
  1638.                 // Scale the image
  1639.                 int width = (int) (bounds.width - (parent.style.roundCorner));
  1640.                 int height = (int) (bounds.height - (parent.style.roundCorner));
  1641.                 int hints = Image.SCALE_FAST;
  1642.                 parent.parent.icons.put(
  1643.                     "Button-" + imageIcon,
  1644.                     parent.parent.icons.get(imageIcon)
  1645.                         .getScaledInstance(width, height,
  1646.                             hints));
  1647.             }
  1648.  
  1649.         g.setColor(parent.style.fgColor);
  1650.         g.fill(bounds);
  1651.         if (parent.parent.icons.containsKey("Button-" + imageIcon))
  1652.             if (parent.parent.icons.get("Button-" + imageIcon) != null)
  1653.             g.drawImage(
  1654.                 parent.parent.icons.get("Button-" + imageIcon),
  1655.                 (int) (bounds.x + (parent.style.roundCorner / 2)),
  1656.                 (int) (bounds.y + (parent.style.roundCorner / 2)),
  1657.                 null);
  1658.         }
  1659.     }
  1660.  
  1661.     /**
  1662.      * A class representing a progress bar in a menu
  1663.      *
  1664.      * @author Equinox_
  1665.      *
  1666.      */
  1667.     public class MenuProgressBar extends MenuItem {
  1668.         final static int width = 100;
  1669.         final static int height = 30;
  1670.  
  1671.         final GetPercent getPercent;
  1672.         RoundRectangle2D.Float percent;
  1673.         Point textLoc;
  1674.         String prefix;
  1675.  
  1676.         /**
  1677.          * Constructs a MenuProgress bar using the specified name, parent,
  1678.          * getPercent method, text prefix, and getPopup method
  1679.          *
  1680.          * @param name
  1681.          *            String
  1682.          * @param parent
  1683.          *            Menu
  1684.          * @param getPercent
  1685.          *            GetPercent
  1686.          * @param prefix
  1687.          *            String
  1688.          * @param getPopup
  1689.          *            GetPopup
  1690.          */
  1691.         public MenuProgressBar(String name, Menu parent,
  1692.             GetPercent getPercent, String prefix, GetPopup getPopup) {
  1693.         super(name, parent, getPopup, width, height);
  1694.         this.getPercent = getPercent;
  1695.         this.prefix = prefix;
  1696.         }
  1697.  
  1698.         /**
  1699.          * Renders this progress bar to the given Graphics context
  1700.          */
  1701.         @Override
  1702.         public void render(Graphics2D g) {
  1703.         percent.width = getPercent.getPercent();
  1704.         g.setColor(parent.style.progressBarBG);
  1705.         g.fill(bounds);
  1706.         g.setColor(parent.style.progressBarFG);
  1707.         g.fill(percent);
  1708.         String perct = String.valueOf(getPercent.getPercent());
  1709.         if (perct.length() < 2)
  1710.             perct = "0" + perct;
  1711.         g.setFont(style.FONT);
  1712.         g.setColor(style.FONT_COLOR);
  1713.         g.drawString(prefix + ": " + perct + "%", textLoc.x, textLoc.y);
  1714.         }
  1715.  
  1716.         /**
  1717.          * Compiles this progress bar
  1718.          */
  1719.         @Override
  1720.         public void compile() {
  1721.         super.compile();
  1722.         percent = new RoundRectangle2D.Float(bounds.x, bounds.y,
  1723.             getPercent.getPercent(), bounds.height,
  1724.             bounds.arcwidth, bounds.archeight);
  1725.         textLoc = new Point();
  1726.         textLoc.x = (int) bounds.getCenterX();
  1727.         textLoc.y = (int) bounds.getCenterY();
  1728.         textLoc.y += parent.style.FONT.getLineMetrics(prefix + ": 00%",
  1729.             parent.parent.frc).getHeight() / 2f;
  1730.         textLoc.x -= parent.style.FONT.getStringBounds(
  1731.             prefix + ": 00%", parent.parent.frc).getWidth() / 2f;
  1732.         }
  1733.     }
  1734.  
  1735.     /**
  1736.      * Class representing the method for getting the current percentile for
  1737.      * a progress bar
  1738.      *
  1739.      * @author Equinox_
  1740.      *
  1741.      */
  1742.     public abstract class GetPercent {
  1743.         abstract int getPercent();
  1744.     }
  1745.  
  1746.     /**
  1747.      * Class representing the LineListeners in popups
  1748.      *
  1749.      * @author Equinox_
  1750.      *
  1751.      */
  1752.     public abstract class LineListener {
  1753.         abstract void fireEvent(MouseEvent e, String line);
  1754.  
  1755.         abstract boolean hasAction(String line);
  1756.     }
  1757.  
  1758.     /**
  1759.      * A class representing the popups in the paint interface
  1760.      *
  1761.      * @author Equinox_
  1762.      *
  1763.      */
  1764.     public class MenuPopUp {
  1765.         private Font font;
  1766.         private Color color;
  1767.         private PaintStyle style;
  1768.         private RoundRectangle2D bkg;
  1769.         public RoundRectangle2D fg;
  1770.         public Rectangle txtBounds;
  1771.         public MenuItem parent;
  1772.         public final String name;
  1773.         public String[] lines;
  1774.         int width;
  1775.         int height;
  1776.         List<LineListener> lineListeners;
  1777.  
  1778.         /**
  1779.          * Creates a popup using the provided array of strings making up the
  1780.          * lines and name
  1781.          *
  1782.          * @param lines
  1783.          *            as String[]
  1784.          * @param name
  1785.          *            as String
  1786.          */
  1787.         public MenuPopUp(String[] lines, String name) {
  1788.         this.name = name;
  1789.         this.lines = lines;
  1790.         }
  1791.  
  1792.         /**
  1793.          * Set this popup's parent and compiles locations
  1794.          *
  1795.          * @param parent
  1796.          *            MenuItem
  1797.          */
  1798.         public void setParent(MenuItem parent) {
  1799.         this.parent = parent;
  1800.         this.style = parent.parent.style;
  1801.         // Calc dimensions
  1802.         color = name.equals("tools") ? style.TOOLS_FONT_COLOR
  1803.             : style.FONT_COLOR;
  1804.         font = name.equals("tools") ? style.TOOLS_FONT : style.FONT;
  1805.         float line_height = font.getLineMetrics(lines[0], Paint.frc)
  1806.             .getHeight();
  1807.         width = 0;
  1808.         for (String line : lines)
  1809.             if (font.getStringBounds(line, Paint.frc).getWidth() > width)
  1810.             width = (int) font.getStringBounds(line, Paint.frc)
  1811.                 .getWidth();
  1812.  
  1813.         height = (int) (lines.length * line_height);
  1814.  
  1815.         width += style.roundCorner + 2;
  1816.         height += style.roundCorner + 2;
  1817.  
  1818.         int halfPadding = (parent.parent.padding / 2);
  1819.         if (halfPadding < 1 && halfPadding != 0)
  1820.             halfPadding = 1;
  1821.         int x = 0;
  1822.         int y = 0;
  1823.         if (parent.parent.getFlowType().equals(FlowType.HORIZONTAL)) {
  1824.             if (parent.bounds.y - height - parent.parent.padding > 0) {
  1825.             // Above
  1826.             x = (int) (parent.bounds.x - width
  1827.                 + parent.bounds.width + halfPadding);
  1828.             if (x < 0)
  1829.                 x = (int) (parent.bounds.x - halfPadding);
  1830.             y = (int) (parent.parent.getAbsY() - height);
  1831.             } else {
  1832.             // Below
  1833.             x = (int) (parent.bounds.x - halfPadding);
  1834.             if (x + width > parent.parent.bounds.width)
  1835.                 x = (int) (parent.bounds.x - halfPadding - width);
  1836.             y = (int) (parent.parent.getAbsY() + parent.parent
  1837.                 .getHeight());
  1838.             }
  1839.         } else {
  1840.             // Vertical
  1841.             if (parent.bounds.x - width - parent.parent.padding > 0) {
  1842.             // Left
  1843.             x = (int) (parent.parent.getAbsX() - width);
  1844.             if (parent.bounds.y - height + halfPadding
  1845.                 + parent.bounds.height > 0)
  1846.                 y = (int) (parent.bounds.y - height + halfPadding + parent.bounds.height);
  1847.             else
  1848.                 y = (int) (parent.bounds.y - halfPadding);
  1849.             } else {
  1850.             // Right
  1851.             x = (int) (parent.parent.getAbsX() + parent.parent
  1852.                 .getWidth());
  1853.             if (parent.bounds.y - height + halfPadding
  1854.                 + parent.bounds.height > 0)
  1855.                 y = (int) (parent.bounds.y - height + halfPadding + parent.bounds.height);
  1856.             else
  1857.                 y = (int) (parent.bounds.y - halfPadding);
  1858.             }
  1859.         }
  1860.         bkg = new RoundRectangle2D.Float(x, y, width, height,
  1861.             style.roundCorner > 0 ? style.roundCorner + 1 : 0,
  1862.             style.roundCorner > 0 ? style.roundCorner + 1 : 0);
  1863.         fg = new RoundRectangle2D.Float((float) bkg.getX() + 1,
  1864.             (float) bkg.getY() + 1, width - 2, height - 2,
  1865.             style.roundCorner, style.roundCorner);
  1866.         txtBounds = new Rectangle(
  1867.             (int) (fg.getX() + (style.roundCorner / 2)),
  1868.             (int) (fg.getY() + (style.roundCorner / 2)),
  1869.             (int) (width - style.roundCorner - 2), (int) (height
  1870.                 - style.roundCorner - 2));
  1871.         }
  1872.  
  1873.         /**
  1874.          * Paints this popup to using the provided Graphics2D in relation to
  1875.          * it's parent PaintInterface
  1876.          *
  1877.          * @param g
  1878.          *            as Graphics2D
  1879.          */
  1880.         public void render(Graphics2D g) {
  1881.         g.setColor(style.bgColor);
  1882.         g.fill(bkg);
  1883.         g.setColor(style.fgColor);
  1884.         g.fill(fg);
  1885.  
  1886.         float line_height = (txtBounds.height - 4) / lines.length;
  1887.  
  1888.         g.setFont(font);
  1889.         g.setColor(color);
  1890.         for (int i = 0; i < lines.length; i++) {
  1891.             if (new Rectangle(txtBounds.x,
  1892.                 (int) ((i * (line_height)) + txtBounds.y),
  1893.                 txtBounds.width, (int) line_height)
  1894.                 .contains(parent.parent.parent.mouseLoc)
  1895.                 && hasAction(lines[i])) {
  1896.             g.setColor(style.highlightColor);
  1897.             g.fill(new Rectangle(txtBounds.x,
  1898.                 (int) ((i * (line_height)) + 2 + txtBounds.y),
  1899.                 txtBounds.width, (int) line_height));
  1900.             }
  1901.             g.setColor(color);
  1902.             g.drawString(lines[i], txtBounds.x,
  1903.                 ((i + 1) * (line_height)) + txtBounds.y);
  1904.         }
  1905.         }
  1906.  
  1907.         boolean hasAction(String line) {
  1908.         if (lineListeners != null)
  1909.             for (LineListener l : lineListeners)
  1910.             if (l.hasAction(line))
  1911.                 return true;
  1912.         return false;
  1913.         }
  1914.  
  1915.         /**
  1916.          * Adds the specified line listener
  1917.          *
  1918.          * @param l
  1919.          *            LineListener
  1920.          */
  1921.         public void addLineListener(LineListener l) {
  1922.         if (lineListeners == null)
  1923.             lineListeners = new ArrayList<LineListener>();
  1924.         this.lineListeners.add(l);
  1925.         }
  1926.  
  1927.         /**
  1928.          * fires the specified mouse event using this popup's line listeners
  1929.          *
  1930.          * @param e
  1931.          *            MouseEvent
  1932.          */
  1933.         public void fireMouseEvent(MouseEvent e) {
  1934.         if (!bkg.contains(e.getPoint()) || lineListeners == null
  1935.             || lineListeners.size() == 0)
  1936.             return;
  1937.  
  1938.         int line_height = (txtBounds.height - 4) / lines.length;
  1939.  
  1940.         for (int i = 0; i < lines.length; i++) {
  1941.             Rectangle stringRect = new Rectangle(txtBounds.x,
  1942.                 (i * (line_height)) + txtBounds.y, txtBounds.width,
  1943.                 line_height);
  1944.             if (stringRect.contains(e.getPoint())) {
  1945.             for (LineListener lineListener : lineListeners)
  1946.                 lineListener.fireEvent(e, lines[i]);
  1947.             return;
  1948.             }
  1949.         }
  1950.         }
  1951.     }
  1952.  
  1953.     }
  1954.  
  1955.     /**
  1956.      * Used for specifing the way a menu is layed out.
  1957.      *
  1958.      * @author Equinox_
  1959.      *
  1960.      */
  1961.     private enum FlowType {
  1962.     VERTICAL, HORIZONTAL
  1963.     }
  1964.  
  1965.     /**
  1966.      * Used for anchoring the menu bar
  1967.      *
  1968.      * @author Equinox_
  1969.      *
  1970.      */
  1971.     private enum Anchor {
  1972.     UP_LEFT, UP_RIGHT, DOWN_RIGHT, DOWN_LEFT
  1973.     }
  1974.  
  1975.     /**
  1976.      * Used to style the paint
  1977.      *
  1978.      * @author Equinox_
  1979.      *
  1980.      */
  1981.     public static class PaintStyle {
  1982.     public final Color FONT_COLOR = Color.BLACK;
  1983.     public final Font FONT = new Font("Arial", 1, 10)
  1984.         .deriveFont(Font.PLAIN);
  1985.  
  1986.     public final Font TOOLS_FONT = new Font("Arial", 1, 14)
  1987.         .deriveFont(Font.PLAIN);
  1988.     public final Color TOOLS_FONT_COLOR = Color.BLACK;
  1989.  
  1990.     public final float roundCorner = 10f;
  1991.     public final Color progressBarFG = new Color(0f, 1f, 0f, 1f);
  1992.     public final Color progressBarBG = new Color(.3f, .3f, .3f, 1f);
  1993.     public final Color bgColor = new Color(0f, 0f, 0f, 0.75f);
  1994.     final Color fgColor = new Color(.3f, .3f, .3f, 1f);
  1995.     final Color highlightColor = new Color(1f, 0f, 0f, 0.05f);
  1996.     }
  1997.  
  1998.     /**
  1999.      * Modified Copy of DrawMouse
  2000.      */
  2001.     public class ModifiedDrawMouse {
  2002.     private MouseTrailing mouseTrailing = new MouseTrailing();
  2003.     private ArrayList<Mouses> Click = new ArrayList<Mouses>();
  2004.     private long clickLifeTime = 1500;
  2005.  
  2006.     public void onRepaint(final Graphics render) {
  2007.         if (mouse != null) {
  2008.         Point Location = mouse.getLocation();
  2009.         if (mouse.isPressed())
  2010.             if (Click.size() <= 5)
  2011.             Click.add(new Mouses(System.currentTimeMillis(),
  2012.                 Location));
  2013.         mouseTrailing.draw((Graphics2D) render, Color.WHITE);
  2014.         render.setColor(Color.GREEN);
  2015.         render.drawLine(Location.x - 5, Location.y, Location.x + 5,
  2016.             Location.y);
  2017.         render.drawLine(Location.x, Location.y - 5, Location.x,
  2018.             Location.y + 5);
  2019.         if (Click.size() > 1)
  2020.             for (Mouses click : Click) {
  2021.             if (mouse.isPressed())
  2022.                 if (Click.size() <= 10)
  2023.                 Click.add(new Mouses(
  2024.                     System.currentTimeMillis(), Location));
  2025.             float i = ((float) (click.getTime() + clickLifeTime - System
  2026.                 .currentTimeMillis()) / (float) clickLifeTime) + 0.25f;
  2027.             if (i > 0) {
  2028.                 render.setColor(new Color(1, 0, 0, i > 1 ? 1 : i));
  2029.                 render.drawLine(click.getLocation().x - 5,
  2030.                     click.getLocation().y,
  2031.                     click.getLocation().x + 5,
  2032.                     click.getLocation().y);
  2033.                 render.drawLine(click.getLocation().x,
  2034.                     click.getLocation().y - 5,
  2035.                     click.getLocation().x,
  2036.                     click.getLocation().y + 5);
  2037.             } else if (System.currentTimeMillis() - click.getTime() >= 1000) {
  2038.                 Click.remove(click);
  2039.             }
  2040.             }
  2041.  
  2042.         }
  2043.     }
  2044.  
  2045.     /**
  2046.      * @author Baheer (Doout).
  2047.      */
  2048.     public class MouseTrailing {
  2049.         private int LifeTime = 1500;
  2050.         private ArrayList<Mouses> Info = new ArrayList<Mouses>();
  2051.  
  2052.         private void getLocation() {
  2053.         Point m = mouse.getLocation();
  2054.         if (Add(m)) {
  2055.             Info.add(new Mouses(System.currentTimeMillis(), m));
  2056.         }
  2057.         }
  2058.  
  2059.         public boolean Add(Point p) {
  2060.         for (Mouses Trailing : Info)
  2061.             if (Trailing.getLocation().equals(p))
  2062.             return false;
  2063.         return true;
  2064.         }
  2065.  
  2066.         public void draw(Graphics2D g, Color c) {
  2067.         getLocation();
  2068.         if (Info.size() > 1)
  2069.             for (int t = 1; t < Info.size(); t++) {
  2070.             Mouses Trailing1 = Info.get(t);
  2071.             Mouses Trailing2 = Info.get(t - 1);
  2072.             float i = (float) (Trailing1.getTime() + LifeTime - System
  2073.                 .currentTimeMillis()) / (float) LifeTime;
  2074.             if (i > 0) {
  2075.                 g.setColor(new Color(c.getRed() / 255f, c
  2076.                     .getGreen() / 255f, c.getBlue() / 255f, (c
  2077.                     .getAlpha() / 255f) * i));
  2078.                 g.drawLine(Trailing1.getLocation().x,
  2079.                     Trailing1.getLocation().y,
  2080.                     Trailing2.getLocation().x,
  2081.                     Trailing2.getLocation().y);
  2082.             }
  2083.             }
  2084.         if (Info.size() > 1) {
  2085.             if (System.currentTimeMillis() > Info.get(0).getTime()
  2086.                 + LifeTime) {
  2087.             Info.remove(0);
  2088.             }
  2089.         }
  2090.         }
  2091.  
  2092.     }
  2093.  
  2094.     private class Mouses {
  2095.         private long Time;
  2096.         private Point Location;
  2097.  
  2098.         public Mouses(long time, Point loc) {
  2099.         Time = time;
  2100.         Location = loc;
  2101.         }
  2102.  
  2103.         public long getTime() {
  2104.         return Time;
  2105.         }
  2106.  
  2107.         public Point getLocation() {
  2108.         return Location;
  2109.         }
  2110.     }
  2111.     }
  2112.  
  2113.     @Override
  2114.     public void mouseDragged(MouseEvent arg0) {
  2115.     Paint.mouseLoc = arg0.getPoint();
  2116.     }
  2117.  
  2118.     @Override
  2119.     public void mouseMoved(MouseEvent arg0) {
  2120.     Paint.mouseLoc = arg0.getPoint();
  2121.     }
  2122.  
  2123.     @Override
  2124.     public void mouseClicked(MouseEvent arg0) {
  2125.     Paint.fireMouseEvent(arg0);
  2126.     }
  2127.  
  2128.     @Override
  2129.     public void mouseEntered(MouseEvent arg0) {
  2130.  
  2131.     }
  2132.  
  2133.     @Override
  2134.     public void mouseExited(MouseEvent arg0) {
  2135.  
  2136.     }
  2137.  
  2138.     @Override
  2139.     public void mousePressed(MouseEvent arg0) {
  2140.  
  2141.     }
  2142.  
  2143.     @Override
  2144.     public void mouseReleased(MouseEvent arg0) {
  2145.     }
  2146.  
  2147.     /**
  2148.      * Loads script data as the actual script runs. Useful for images that are
  2149.      * non-essential.
  2150.      *
  2151.      * @author Equinox_
  2152.      *
  2153.      */
  2154.     public static class DataLoader extends Thread {
  2155.     EquinoxLunarPlanker planker;
  2156.  
  2157.     /**
  2158.      * Creates a dataloader using the specified EquinoxLunarPlanker instance
  2159.      *
  2160.      * @param planker
  2161.      */
  2162.     public DataLoader(EquinoxLunarPlanker planker) {
  2163.         super("Data Loader");
  2164.         this.planker = planker;
  2165.         this.start();
  2166.     }
  2167.  
  2168.     /**
  2169.      * Gets the icon for a specified image in the runescape online database.
  2170.      *
  2171.      * @param id
  2172.      *            as int
  2173.      * @return Image
  2174.      * @throws MalformedURLException
  2175.      * @throws IOException
  2176.      */
  2177.     public Image getItemImage(int id) throws MalformedURLException,
  2178.         IOException {
  2179.         return ImageIO.read(new URL(
  2180.             "http://services.runescape.com/m=itemdb_rs/3290_obj_sprite.gif?id="
  2181.                 + id));
  2182.     }
  2183.  
  2184.     @Override
  2185.     public void run() {
  2186.         try {
  2187.         if (JOptionPane.NO_OPTION == JOptionPane.showConfirmDialog(
  2188.             null, "Would you like to load some images?",
  2189.             "Equinox_ Data Loader", JOptionPane.YES_NO_OPTION))
  2190.             throw new Exception();
  2191.  
  2192.         long before = System.currentTimeMillis();
  2193.         planker.Paint.putImage(
  2194.             "homeicon",
  2195.             ImageIO.read(new URL(planker.baseURL
  2196.                 + "/images/houseIcon.png")));
  2197.         planker.log("Loaded home image in "
  2198.             + PaintFormatter.getFormattedTime(System
  2199.                 .currentTimeMillis() - before));
  2200.         before = System.currentTimeMillis();
  2201.         planker.Paint.putImage("plankicon", getItemImage(PlankID));
  2202.         planker.log("Loaded plank icon in "
  2203.             + PaintFormatter.getFormattedTime(System
  2204.                 .currentTimeMillis() - before));
  2205.         before = System.currentTimeMillis();
  2206.         planker.Paint.putImage(
  2207.             "toolsicon",
  2208.             ImageIO.read(new URL(planker.baseURL
  2209.                 + "/images/tools.png")));
  2210.         planker.log("Loaded tools icon in "
  2211.             + PaintFormatter.getFormattedTime(System
  2212.                 .currentTimeMillis() - before));
  2213.         } catch (Exception e) {
  2214.         planker.log("Failed to load images");
  2215.         }
  2216.         loadGE();
  2217.     }
  2218.  
  2219.     /**
  2220.      * Loads the GE Item prices
  2221.      */
  2222.     void loadGE() {
  2223.         planker.Paint.astralPrice = planker.getItemPrice(AstralRune);
  2224.         planker.Paint.earthPrice = planker.getItemPrice(EarthRune);
  2225.         planker.Paint.naturePrice = planker.getItemPrice(NatRune);
  2226.         planker.Paint.plankPrice = planker.getItemPrice(PlankID);
  2227.         planker.Paint.logPrice = planker.getItemPrice(LogID);
  2228.     }
  2229.     }
  2230.  
  2231.     /**
  2232.      * gets the item price based on class. Works with all versions of
  2233.      * grandExchange.class
  2234.      *
  2235.      * @param item
  2236.      *            the GEItem to get the price from
  2237.      * @return int the price
  2238.      *
  2239.      * @author Equinox_
  2240.      */
  2241.     public int getItemPrice(int id) {
  2242.     GEItem item = grandExchange.lookup(id);
  2243.     if (item != null) {
  2244.         int price = 0;
  2245.         for (Method m : item.getClass().getMethods())
  2246.         if (m.getName().equals("getGuidePrice")
  2247.             || m.getName().equals("getMinPrice"))
  2248.             try {
  2249.             price = (Integer) (m.invoke(item));
  2250.             break;
  2251.             } catch (Exception e) {
  2252.             }
  2253.         log.info("Price of " + item.getName() + ": " + price);
  2254.         return price;
  2255.     }
  2256.     return 0;
  2257.     }
  2258.  
  2259. }
Advertisement
Add Comment
Please, Sign In to add comment