InnominateOne

Mine Guardian

Dec 27th, 2014
100,796
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // ==UserScript==
  2. // @name         Mine Guardian
  3. // @namespace    http://scholtek.com
  4. // @version      0.4
  5. // @description  Various automation options for Mine Defense.
  6. // @author       Innominate
  7. // @match        http://scholtek.com/minedefense
  8. // @run-at       document-end
  9. // @grant        none
  10. // @downloadURL  http://pastebin.com/raw.php?i=w5WLP7bZ
  11. // @updateURL    http://pastebin.com/raw.php?i=w5WLP7bZ
  12. // ==/UserScript==
  13.  
  14. window.inn = {};
  15. var inn = window.inn;
  16.  
  17. inn.debug = false;
  18. inn.debugLog =
  19.     function(message)
  20.     {
  21.         if(inn.debug)
  22.         {
  23.             console.log(message);
  24.         }
  25.     };
  26.  
  27. var _tickers = {};
  28.  
  29. inn.htmlFriendlyName =
  30.     function(string)
  31.     {
  32.         string = string.replace(" ", "");
  33.         string = string.replace(/([a-z][A-Z])/g, function(g) { return g[0] + '-' + g[1].toLowerCase(); });
  34.         return string.toLowerCase();
  35.     };
  36.  
  37. inn.modules = {};
  38. inn.Module =
  39.     function(name, description, ticker, definitions)
  40.     {
  41.         var _enabled = false;
  42.         this.name = name;
  43.         this.checkboxID = "inn-" + inn.htmlFriendlyName(this.name) + "-checkbox";
  44.         this.description = description || "No description.";
  45.         this.settings = {};
  46.         this.ticker = ticker.bind(this.settings);
  47.         this.definitions = definitions || {};
  48.         inn.modules[name] = this;
  49.         Object.defineProperty(this, "enabled",
  50.                 {
  51.                     get:function()
  52.                         {
  53.                             return _enabled;
  54.                         },
  55.                     set:function(value)
  56.                         {
  57.                             _enabled = !!value;
  58.                             if(value)
  59.                             {
  60.                                 _tickers[this.name] = this.ticker;
  61.                             }
  62.                             else
  63.                             {
  64.                                 delete _tickers[this.name];
  65.                             }
  66.                         }
  67.                 });
  68.  
  69.         for(var label in definitions)
  70.         {
  71.             var def = definitions[label];
  72.             try
  73.             {
  74.                 this.settings[label] = def.defaultValue;
  75.             }
  76.             catch(error)
  77.             {
  78.                 console.log("Error setting default value from definition " + label + " (" + error.message + "):");
  79.                 console.log(def);
  80.             }
  81.         }
  82.     };
  83.  
  84. inn.Module.prototype.createModuleSection =
  85.     function()
  86.     {
  87.         this.checkbox = $('<input>', { type:"checkbox", id:this.checkboxID });
  88.         var result = $('<div></div>');
  89.         result.append($('<h1>' + this.name + '</h1>').append(this.checkbox));
  90.         result.append('<p>' + this.description + '</p>');
  91.  
  92.         for(var label in this.definitions)
  93.         {
  94.             result.append(this.createSettingSection(label));
  95.         }
  96.         return result;
  97.     };
  98.  
  99. inn.Module.prototype.createSettingSection =
  100.     function(label)
  101.     {
  102.         var definition = this.definitions[label];
  103.         var result = $('<div></div>');
  104.         result.append('<h3>' + definition.name + '</h3>');
  105.         result.append('<p>' + definition.description + '</p>');
  106.         result.append(this.createSettingComponent(label));
  107.         return result;
  108.     };
  109.  
  110. inn.Module.prototype.createSettingComponent =
  111.     function(label)
  112.     {
  113.         var definition = this.definitions[label];
  114.         definition.componentID = "inn-" + inn.htmlFriendlyName(this.name) + "-" + inn.htmlFriendlyName(definition.name);
  115.         var content = undefined;
  116.         switch(definition.type)
  117.         {
  118.             case "number":
  119.                 content = $('<input>', { type: "text" });
  120.                 definition.retrieve =
  121.                     function()
  122.                     {
  123.                         var result = parseFloat(content.val());
  124.                         if(!isNaN(result))
  125.                         {
  126.                             this[label] = result;
  127.                         }
  128.                     };
  129.                 break;
  130.             case "integer":
  131.                 content = $('<input>', { type: "text" });
  132.                 definition.retrieve =
  133.                     function()
  134.                     {
  135.                         var result = parseInt(content.val(), 10);
  136.                         if(!isNaN(result))
  137.                         {
  138.                             this[label] = result;
  139.                         }
  140.                     };
  141.                 break;
  142.             case "select":
  143.                 content = $('<select></select>'); //falls through to populate
  144.             case "select-multiple":
  145.                 content = content || $('<select></select>', { multiple: "multiple" });
  146.                 for(var optionLabel in definition.options)
  147.                 {
  148.                     var option = $('<option value="' + definition.options[optionLabel] + '">' + optionLabel + '</option>');
  149.                     content.append(option);
  150.                 }
  151.                 break;
  152.             case "boolean":
  153.                 content = $('<input>', { type: "checkbox" });
  154.                 definition.update =
  155.                     function()
  156.                     {
  157.                         content.prop("checked", this[label]);
  158.                     };
  159.                 definition.retrieve =
  160.                     function()
  161.                     {
  162.                         this[label] = content.is(":checked");
  163.                     };
  164.                 break;
  165.             default:
  166.                 content = 'Unable to create a component for this setting.';
  167.                 inn.debugLog("Unable to create a component for setting:");
  168.                 inn.debugLog(definition);
  169.                 break;
  170.         };
  171.         definition.update = (definition.update || //set sensible defaults and bind to settings
  172.             function()
  173.             {
  174.                 content.val(this[label]);
  175.             }).bind(this.settings);
  176.         definition.retrieve = (definition.retrieve ||
  177.             function()
  178.             {
  179.                 this[label] = content.val();
  180.             }).bind(this.settings);
  181.         content.attr("id", definition.componentID);
  182.         definition.component = content;
  183.         return content;
  184.     };
  185.  
  186. inn.Module.prototype.updateModuleSection =
  187.     function()
  188.     {
  189.         this.checkbox.prop("checked", this.enabled);
  190.         inn.debugLog(this.name + " is " + this.enabled);
  191.         for(var label in this.definitions)
  192.         {
  193.             this.definitions[label].update();
  194.         }
  195.     };
  196.  
  197. inn.Module.prototype.retrieveModuleSection =
  198.     function()
  199.     {
  200.         this.enabled = this.checkbox.is(":checked");
  201.         for(var label in this.definitions)
  202.         {
  203.             this.definitions[label].retrieve();
  204.         }
  205.     };
  206.  
  207. inn.Module.prototype.retrieveSettingComponent =
  208.     function(label)
  209.     {
  210.         var definition = this.definitions[label];
  211.     };
  212.    
  213. /* MODIFY DOM TO ALLOW OPTIONS TO BE CHANGED */
  214. inn.showMenu =
  215.     function()
  216.     {
  217.         inn.settingsDialog.dialog("open");
  218.         inn.settingsDialog.css({ height: "500px", overflow: "auto" });
  219.  
  220.         for(var label in inn.modules)
  221.         {
  222.             inn.modules[label].updateModuleSection();
  223.         }
  224.     };
  225.  
  226. inn.updateSettings =
  227.     function()
  228.     {
  229.         for(var label in inn.modules)
  230.         {
  231.             inn.modules[label].retrieveModuleSection();
  232.         }
  233.         inn.settingsDialog.dialog("close");
  234.         inn.save();
  235.     };
  236.  
  237. $("#menu-area").append('<br><button class="btn oval-btn menu-button" onclick="inn.showMenu()">Mine Guardian Settings</button>');
  238.  
  239. inn.settingsDialogID = "inn-mine-guardian-menu";
  240. inn.settingsDialog = $('<div id="' + inn.settingsDialogID + '"></div>');
  241. $("div.ui-dialog:last").after(inn.settingsDialog);
  242.  
  243. inn.initialiseSettingsMenu =
  244.     function()
  245.     {
  246.         for(var label in inn.modules)
  247.         {
  248.             var result = inn.modules[label].createModuleSection();
  249.             inn.settingsDialog.append(result);
  250.         }
  251.         inn.settingsDialog.dialog(
  252.             {
  253.                 autoOpen: false,
  254.                 title: "Mine Guardian Settings",
  255.                 minWidth: 500,
  256.                 buttons: [ { text: "Save Settings", click: inn.updateSettings } ]
  257.             });
  258.     };
  259.  
  260.  
  261. /* UPDATE SETTINGS FROM STORAGE */
  262. inn.storageName = "inndefSettings";
  263. inn.load =
  264.     function()
  265.     {
  266.         var settings = JSON.parse(localStorage.getItem(inn.storageName));
  267.         for(var label in settings)
  268.         {
  269.             var saveSettings = settings[label] || {};
  270.             var module = inn.modules[label];
  271.             $.extend(module.settings, saveSettings);
  272.             module.enabled = saveSettings.enabled;
  273.         }
  274.     };
  275.  
  276. inn.save =
  277.     function()
  278.     {
  279.         var settings = {};
  280.         for(var label in inn.modules)
  281.         {
  282.             settings[label] = {};
  283.             var saveSettings = settings[label];
  284.             var module = inn.modules[label];
  285.             $.extend(saveSettings, module.settings);
  286.             saveSettings.enabled = module.enabled;
  287.         }
  288.         localStorage.setItem(inn.storageName, JSON.stringify(settings));
  289.     };
  290.  
  291. /* AUTO CLICK */
  292. var autoClick = new inn.Module(
  293.     "Mine Clicker",
  294.     "Automatically clicks the mine.",
  295.     function()
  296.     {
  297.         if(this.clickAmount > 0)
  298.         {
  299.             MD.dig(250, 250, this.clickAmount);
  300.         }
  301.     },
  302.     {
  303.         clickAmount:    {
  304.                             name: "Click Amount",
  305.                             description: "The number of times per second to click the mine.",
  306.                             type: "integer",
  307.                             defaultValue: 1
  308.                         }
  309.     });
  310.  
  311. /* MAGE CLICKER */
  312. var mageClick = new inn.Module(
  313.     "Mage Clicker",
  314.     "Automatically powers up your mages to maximum power.",
  315.     function()
  316.     {
  317.         var numMages = Math.ceil(MD.MAGES/5);
  318.         for(var i = 0;i < 6 && i < numMages;++i)
  319.         {
  320.             MD.clickMage(i);
  321.         }
  322.     });
  323.  
  324. /* AUTO COMBINE */
  325. inn.debugLog("TODO: make the gem cap test for the Gem Combiner smarter so that it's more efficient.");
  326. var autoCombine = new inn.Module(
  327.     "Gem Combiner",
  328.     "Combines gems using the \"Combine Up To\" setting on the gems page while maintaining at least enough gems to maximise your discovery gem caches.",
  329.     function()
  330.     {
  331.         var totalGems = Math.round(sumArray(MD.GEMS));
  332.         var gemCap = MD.getStatueGemAmount(MD.CONSTRUCT_LEVELS[4])*200;
  333.         if(totalGems > 8*gemCap)
  334.         {
  335.             MD.combineGems();
  336.         }
  337.     });
  338.  
  339. /* AUTO DISCOVER */
  340. var autoDiscover = new inn.Module(
  341.     "Quarry Discoverer",
  342.     "Automatically checks the quarry when a discovery is found.",
  343.     function()
  344.     {
  345.         if(get("quarry-discovery").style.display !== 'none')
  346.         {
  347.             MD.findQuarryReward();
  348.         }
  349.     });
  350.  
  351. /* AUTO CAMPAIGN */
  352. var autoCampaign = new inn.Module(
  353.     "Campaign Launcher",
  354.     "Automatically launches campaigns when you are a certain proportion stronger than your enemy. Use with caution; it's easy to accidentally make the invading enemies extremely strong.",
  355.     function()
  356.     {
  357.         if(MD.getMilitaryStrength() >= MD.getEnemyStrength()*this.minimumForceRatio)
  358.         {
  359.             MD.launchCampaign();
  360.             if(this.bombEnemies)
  361.             {
  362.                 MD.bombEnemies();
  363.             }
  364.         }
  365.     },
  366.     {
  367.         minimumForceRatio:  {
  368.                                 name: "Minimum Force Ratio",
  369.                                 description: "The minimum ratio of your strength to your enemy's strength for automatic campaigns.",
  370.                                 type: "number",
  371.                                 defaultValue: 1
  372.                             },
  373.         bombEnemies:        {
  374.                                 name: "Bomb Enemies",
  375.                                 description: "If enabled, a bomb will be dropped after every automatically launched campaign.",
  376.                                 type: "boolean",
  377.                                 defaultValue: false
  378.                             }
  379.     });
  380.  
  381. /* AUTO SCHOLAR */
  382. var autoScholar = new inn.Module(
  383.     "Scholar Maker",
  384.     "",
  385.     function()
  386.     {
  387.         if(MD.getPopulation() >= MD.getPopulationMax())
  388.         {
  389.             MD.addScholars();
  390.             $("#construct-dialog-10").dialog("close");
  391.         }
  392.     });
  393.  
  394. /* AUTO BUY */
  395. var autoBuy = new inn.Module(
  396.     "Hireling Buyer",
  397.     "Automatically buys unlocked hirelings up to a certain limit.",
  398.     function()
  399.     {
  400.         var list = this.indexList;
  401.         var limit = this.limit;
  402.         var amount = this.amount;
  403.         for(var index = 0;index < list.length;++index)
  404.         {
  405.             var number = parseInt(list[index], 10);
  406.             var buying = Math.min(limit - MD.HIRELINGS_OWNED[number]);
  407.             for(var i = 0;i < buying;++i)
  408.             {
  409.                 MD.hire(number);
  410.             }
  411.         }
  412.     },
  413.     {
  414.         indexList:  {
  415.                         name: "Hireling Index List",
  416.                         description: "The list of hirelings to automatically buy up to the limit. You can select multiple.",
  417.                         type: "select-multiple",
  418.                         defaultValue: [],
  419.                         options:    {
  420.                                         "Large Ant": 0,
  421.                                         "Woodpecker": 1,
  422.                                         "Bloodhound": 2,
  423.                                         "Sandshrew": 3,
  424.                                         "Goblin": 4,
  425.                                         "Miner": 5,
  426.                                         "Rock Golem": 6,
  427.                                         "Bagger 288": 7,
  428.                                         "Titan of Earth": 8,
  429.                                         "World Eater": 9,
  430.                                         "Hive Queen": 10,
  431.                                         "Wyvern": 11,
  432.                                         "Neurochrysalis": 12,
  433.                                         "Dragon Hunter": 13
  434.                                     }
  435.                     },
  436.         limit:      {
  437.                         name: "Limit",
  438.                         description: "The limit up to which hirelings will be purchased.",
  439.                         type: "number",
  440.                         defaultValue: 1
  441.                     },
  442.         amount:     {
  443.                         name: "Amount",
  444.                         description: "The maximum number of hirelings of each type that will be purchased per tick.",
  445.                         type: "integer",
  446.                         defaultValue: 10
  447.                     }
  448.     });
  449.  
  450. /* AUTO DRAGON */
  451. var essenceSelectID = "dragon-essence-type";
  452. var essenceLabels = ["fire", "water", "earth", "lightning"];
  453. var getEssenceCount =
  454.     function(label)
  455.     {
  456.         return MD[label.toUpperCase() + "_ESSENCE"];
  457.     };
  458. eval('inn.sacrificeDragonSilently = ' + MD.sacrificeDragon.toString().replace(/confirm\("[^()"]*?"\)/, 'true')); //this is an awful hack to eliminate the confirmation, but it's better than hardcoding the function without it
  459.  
  460. var autoDragon = new inn.Module(
  461.     "Dragon Breeder",
  462.     "Automatically feeds dragons up to a limit and sacrifices them when they are above a threshold (preferring to feed before sacrificing).",
  463.     function()
  464.     {
  465.         if(MD.DRAGON_LEVEL < this.feedLimit && $("#dragon-100p.unaffordable").length <= 0)
  466.         {
  467.             if(MD.DRAGONS[MD.CURRENT_DRAGON].name == "Master")
  468.             {
  469.                 var maximum = essenceLabels[0];
  470.                 var maximumValue = getEssenceCount(maximum);
  471.                 for(var index = 1;index < essenceLabels.length;++index)
  472.                 {
  473.                     var label = essenceLabels[index];
  474.                     var value = getEssenceCount(label);
  475.                     if(value > maximumValue)
  476.                     {
  477.                         maximum = label;
  478.                         maximumValue = value;
  479.                     }
  480.                 }
  481.                 $("#" + essenceSelectID).val(maximum);
  482.                 MD.selectEssenceType();
  483.             }
  484.             MD.feedDragon('100P');
  485.         }
  486.         else if(MD.DRAGON_LEVEL >= this.sacrificeThreshold && $("#sacDragonButton.unaffordable").length <= 0)
  487.         {
  488.             inn.sacrificeDragonSilently();
  489.             $("#construct-dialog-23").dialog("close");
  490.         }
  491.     },
  492.     {
  493.         feedLimit:          {
  494.                                 name: "Feeding Limit",
  495.                                 description: "The maximum level to which dragons will be fed.",
  496.                                 type: "number",
  497.                                 defaultValue: 0
  498.                             },
  499.         sacrificeThreshold: {
  500.                                 name: "Sacrifice Threshold",
  501.                                 description: "The minimum level over which dragons will be sacrificed if they cannot be fed any further.",
  502.                                 type: "number",
  503.                                 defaultValue: 1e308
  504.                             }
  505.     });
  506.  
  507. /* AUTO DEFEND */
  508. var autoDefend = new inn.Module(
  509.     "Defender",
  510.     "Automatically clicks enemies attacking the mine to damage them greatly.",
  511.     function()
  512.     {
  513.         for(var index = 0;index < MD.GOBLIN_OBJECT.length;++index)
  514.         {
  515.             if(MD.GOBLIN_OBJECT[index] !== null)
  516.             {
  517.                 MD.clickGoblin(index);
  518.             }
  519.         }
  520.         for(index = 0;index < MD.SPIDER_OBJECT.length;++index)
  521.         {
  522.             if(MD.SPIDER_OBJECT[index] !== null)
  523.             {
  524.                 MD.clickSpider(index);
  525.             }
  526.         }
  527.     });
  528.  
  529. /* AUTO UPGRADE */
  530. var shrineIndices = [15, 17, 19, 21];
  531. inn.simpleConstructUpgrade =
  532.     function(index)
  533.     {
  534.         MD.increaseConstructLevel(index);
  535.         $("#construct-dialog-" + index).dialog("close");
  536.     };
  537.  
  538. var autoUpgrade = new inn.Module(
  539.     "Construct Upgrader",
  540.     "Automatically upgrades some constructs without regard to preserving minimum amounts of resources. Use with caution; you may end up using more resources than you want.",
  541.     function()
  542.     {
  543.         if(this.fletcher)
  544.         {
  545.             inn.simpleConstructUpgrade(14);
  546.         }
  547.         if(this.smelter)
  548.         {
  549.             inn.simpleConstructUpgrade(5);
  550.         }
  551.         if(this.statue)
  552.         {
  553.             inn.simpleConstructUpgrade(4);
  554.         }
  555.         if(this.wall)
  556.         {
  557.             MD.buyWall();
  558.         }
  559.         if(this.shrines)
  560.         {
  561.             var lowest = shrineIndices[0];
  562.             var lowestValue = MD.CONSTRUCT_LEVELS[lowest];
  563.             for(var shrine = 1;shrine < shrineIndices.length;++shrine) //skip 0th, since we assume that's the lowest
  564.             {
  565.                 var index = shrineIndices[shrine];
  566.                 var level = MD.CONSTRUCT_LEVELS[index];
  567.                 if(level < lowestValue)
  568.                 {
  569.                     lowest = index;
  570.                     lowestValue = level;
  571.                 }
  572.             }
  573.             inn.simpleConstructUpgrade(lowest);
  574.         }
  575.     },
  576.     {
  577.         fletcher:   {
  578.                         name: "Fletcher",
  579.                         description: "Upgrades the fletcher automatically.",
  580.                         type: "boolean",
  581.                         defaultValue: false
  582.                     },
  583.         smelter:    {
  584.                         name: "Smelter",
  585.                         description: "Upgrades the smelter automatically.",
  586.                         type: "boolean",
  587.                         defaultValue: false
  588.                     },
  589.         statue:     {
  590.                         name: "Regal Statue",
  591.                         description: "Upgrades the regal statue automatically.",
  592.                         type: "boolean",
  593.                         defaultValue: false
  594.                     },
  595.         wall:       {
  596.                         name: "Wall",
  597.                         description: "Upgrades the wall automatically.",
  598.                         type: "boolean",
  599.                         defaultValue: false
  600.                     },
  601.         shrines:    {
  602.                         name: "Elemental Shrines",
  603.                         description: "Upgrades the elemental shrines automatically. Keeps them the same level so none feel left out.",
  604.                         type: "boolean",
  605.                         defaultValue: false
  606.                     },
  607.     });
  608.  
  609. /* AUTO MACHINIST */
  610. var autoMachinist = new inn.Module(
  611.     "Machinist Manager",
  612.     "Toggles whether the Machinist will auto-build units based on the essence you have compared to a threshold.",
  613.     function()
  614.     {
  615.         var desired = Math.min(MD.FIRE_ESSENCE, MD.WATER_ESSENCE, MD.EARTH_ESSENCE, MD.LIGHTNING_ESSENCE) > this.threshold;
  616.         for(var index = 0;index < this.controlling.length;++index)
  617.         {
  618.            MD.MACHINIST_AUTO[this.controlling[index]] = desired;
  619.         }
  620.         MD.updateMechPage();
  621.     },
  622.     {
  623.         threshold:      {
  624.                             name: "Essence Threshold",
  625.                             description: "Below this threshold all managed auto-builds will be set to off. Above it, they will be set to on.",
  626.                             type: "number",
  627.                             defaultValue: 1e6
  628.                         },
  629.         controlling:    {
  630.                             name: "Controlling",
  631.                             description: "The machinist units to control based on the available essence. You can select multiple.",
  632.                             type: "select-multiple",
  633.                             defaultValue: [],
  634.                             options:    {
  635.                                             "Mage": 0,
  636.                                             "Mason": 1,
  637.                                             "Alchemist": 2
  638.                                         }
  639.                         }
  640.     });
  641.  
  642. /* INITIALISE MASTER TICKER */
  643. inn.initialiseSettingsMenu();
  644.  
  645. inn.tickerInterval = setInterval(
  646.     function()
  647.     {
  648.         for(var label in _tickers)
  649.         {
  650.             _tickers[label]();
  651.         }
  652.     }, 1000);
  653.  
  654. inn.load();
Advertisement
Add Comment
Please, Sign In to add comment