Advertisement
Guest User

Untitled

a guest
Feb 25th, 2020
239
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //SEMIv0.1.1 by AW.
  2.  
  3. //AldousWatts code section
  4.  
  5. //custom notifications! green background with custom txt, two images, second one optional, main one is add-on icon.
  6. function customNotify(imgsrc="", msg="Custom Notifications!", n=3000) { //outputs a custom notification with optional first image, SEMI icon, and message.
  7.     $.notify(
  8.         {
  9.             message: '<img class="notification-img" src="' + imgsrc + '"><img src="'+ $("#iconImg").attr('src') +'" height="auto" width="auto" style="margin: 4px;"><span class="badge badge-success">' + msg + '</span>'
  10.         },
  11.         {
  12.             type: 'light',
  13.             placement: {
  14.                 from: 'bottom',
  15.                 align: 'center'
  16.             },
  17.             delay: n,
  18.             newest_on_top: true,
  19.             animate: {
  20.                 enter: 'animated fadeInUp',
  21.                 exit: 'animated fadeOut'
  22.             },
  23.             template: '<div data-notify="container" class="col-12 text-center notify-event" role="alert"><span data-notify="message">{2}</span><div class="progress" data-notify="progressbar"><div class="progress-bar progress-bar-{0}" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%;"></div></div><a href="{3}" target="{4}" data-notify="url"></a></div>'
  24.         }
  25.     );
  26. }
  27.  
  28. //toggle SEMI sidebar menu
  29. var semiMenu = true;
  30. $("#semiHeading").append($('<a href="javascript:toggleSemiMenu();"><i class="far fa-eye text-muted ml-1" id="skill-menu-icon2"></i></a>'));
  31. function toggleSemiMenu() {
  32.     semiMenu = !semiMenu;
  33.     for (i=0; i < $("[id^=semi-nav]").length; i++) { $("#semi-nav-" + i).toggleClass("d-none"); } //from 0 to 11 so far.
  34.     $("#skill-menu-icon2").attr("class", "far fa-eye" + ((semiMenu) ? '' : '-slash') + " text-muted ml-1");
  35. }
  36.  
  37. //AutoCook (sorta): insert always-unlocked cooking button.
  38. $("#cook-button-qty-all").parent().append($('<button type="button" id="alwayscookallbut" class="btn btn-warning mb-1" onclick="startCooking(0, false)" style="width: 100%; border: 2px solid red;">Cook All (Permanently Unlocked by SEMI)</button>'));
  39.  
  40. //herblore calc # items needed to level.
  41. $('#herblore-container .col-12 .mr-2 .btn').parent().append('<button type="button" class="btn btn-success m-3" onclick="calcHerbItemsToLvl();">Calculate # Needed to Next Level</button>');
  42. $('#herblore-container .col-12 .mr-2 .btn').parent().append('<p>You need to make <span id="herbCalc">#</span> of this item before leveling up.</p>');
  43. function calcHerbItemsToLvl() {
  44.     if (!selectedHerblore) return;
  45.     var itemsToLvl = Math.round((exp.level_to_xp(skillLevel[19]+1) +1 - skillXP[19])/herbloreItemData[selectedHerblore].herbloreXP)+1 ;
  46.     $("#herbCalc").text(itemsToLvl);
  47. }
  48.  
  49. //not used yet, trying to make more generic, maybe somehow...
  50. function calcToLvl(current=0) {
  51.     var expToLvl = exp.level_to_xp(skillLevel[current]+1) +1 - skillXP[current];
  52.     $("#"+current+"xpCalc").text(itemsToLvl);
  53. }
  54.  
  55. function semiInfo() { $("#modal-semi-info").modal(open); }
  56.  
  57. //Modal for SEMI info popup
  58. $('#modal-account-change').before($(`
  59. <div class="modal" id="modal-semi-info" tabindex="-1" role="dialog" aria-labelledby="modal-block-normal" aria-hidden="true" style="display: none;">
  60.     <div class="modal-dialog" role="document">
  61.         <div class="modal-content">
  62.             <div class="block block-themed block-transparent mb-0">
  63.                 <div class="block-header bg-primary-dark">
  64.                     <img class="nav-img" src="`+ $("#iconImg")[0].src +`">
  65.                     <h3 class="block-title">Scripting Engine for Melvor Idle v0.1.1</h3>
  66.                     <div class="block-options">
  67.                         <button type="button" class="btn-block-option" data-dismiss="modal" aria-label="Close">
  68.                             <i class="fa fa-fw fa-times"></i>
  69.                         </button>
  70.                     </div>
  71.                 </div>
  72.                 <div class="block-content font-size-sm">
  73.                     <p id="semi-info-text"></p>
  74.                    
  75.                     <h2 style="color: white;">SEMI v0.1.1 by Aldous Watts</h2>
  76.                     Various Quality of Life improvements, scripts for automation, and UI tweaks for Melvor.
  77.                     <br><br>
  78.                     Don't forget these features of SEMI that aren't in the sidebar:
  79.                     <ul>
  80.                         <li>Always-unlocked Cook All button in the Cooking page</li>
  81.                         <li>Thieving XP calculators and loot popups in the Thieving page</li>
  82.                         <li>Number of potions until level-up calculator button in the Herblore page</li>
  83.                     </ul>
  84.                     Scripting with Melvor can be done through injected user scripts, either through a browser add-on like this,
  85.                     or another more general-purpose add-on like Tampermonkey to run userscripts.
  86.                     Either way, the end result is extra functionality, like automating a task or adding calculated info to the page.
  87.                     <br><br>
  88.                     Many functions of SEMI are based on these scripts by others:
  89.                     <ul>
  90.                         <li><a href="https://greasyfork.org/en/scripts/394855-melvor-auto-replant" target="_blank">Melvor Auto Replant by Arcanus</a></li>
  91.                         <li><a href="https://discordapp.com/channels/625838709203271680/664637399028072470/669475769671483392" target="_blank">AutoBonfire by Dream</a></li>
  92.                         <li>Auto Mine & Auto Sell Gems from <a href="https://greasyfork.org/en/scripts/395834-melvor-super-control-panel/code" target="_blank">Melvor Super Control Panel by Strutty & others?</a></li>
  93.                         <li><a href="https://greasyfork.org/en/scripts/396400-melvor-auto-slayer" target="_blank">Melvor AutoSlayer by Bubbalova</a></li>
  94.                         <li><a href="https://greasyfork.org/en/scripts/394856-melvor-percent-accuracy" target="_blank">Melvor Percent Accuracy by Arcanus</a></li>
  95.                         <li><a href="https://pastebin.com/wq641Nhx" target="_blank">XPH by Breakit.</a> For now, console only: Ctrl+Shift+K for console, type XPH() for the tool.</li>
  96.                         <li>Thieving Calculator from <a href="https://github.com/RedSparr0w/Melvor-Idle-Helper" target="_blank">Melvor Idle Helper by RedSparr0w</a></li>
  97.                     </ul>
  98.                     <br>
  99.                     I'm definitely eyeballing Katorone's Melvor Idle automation script for extra functionality.
  100.                     <br><br>
  101.                     Source code for SEMI can be found <a href="https://gitlab.com/aldousWatts/SEMI" target="_blank">here.</a>
  102.                     <br><br>
  103.                 </div>
  104.                 <div class="block-content block-content-full text-right border-top">
  105.                     <button type="button" id="semiInfoModalBtn" class="btn btn-sm btn-primary" data-dismiss="modal" onclick=""><i class="fa fa-check mr-1"></i>Cool!</button>
  106.                 </div>
  107.             </div>
  108.         </div>
  109.     </div>
  110. </div>`));
  111.  
  112. //***************************AUTO COMBAT***********************************
  113.     var autocombat;
  114.     var autocombatloop;
  115.     var hp;
  116.     var hpfoox;
  117.     var hpmax;
  118.     var autoEat = true;
  119.     var autoLoot = true;
  120.    
  121. //AutoCombat Main Function
  122. function autocombatfunc() {
  123.     hp = combatData.player.hitpoints; //this number is already multiplied
  124.     hpfood = numberMultiplier * items[equippedFood[currentCombatFood].itemID].healsFor; //numberMultiplier = 10, adjusts hp math
  125.     hpmax = skillLevel[CONSTANTS.skill.Hitpoints] * numberMultiplier; //same here
  126.     if ( (hp < (hpmax-hpfood) || hp<50) && autoEat ) eatFood(); //autoEat toggle here now
  127.     if (equippedFood[currentCombatFood].qty < 1 && autoEat) {
  128.         terminateAutoCombat('food.');
  129.     }
  130.     if ((items[equippedItems[CONSTANTS.equipmentSlot.Weapon]].isRanged || (items[equippedItems[CONSTANTS.equipmentSlot.Weapon]].type === "Ranged Weapon") ) && ammo < 1) {
  131.         terminateAutoCombat('ammo.');
  132.     }
  133.     if (items[equippedItems[CONSTANTS.equipmentSlot.Weapon]].isMagic && !checkRuneCount(selectedSpell) ) {
  134.         terminateAutoCombat('runes.');
  135.     }
  136.     if (!(droppedLoot == "") && autoLoot) lootAll(); //the truth condition was always true. now it ACTUALLY checks when empty and shouldn't run lootAll() every half-second, which caused big issues.
  137. }
  138. //***************************END AUTO COMBAT*******************************
  139. //Autocombat Auxiliaries
  140. function terminateAutoCombat(reason) {
  141.     var today = new Date(); //this and next three lines are date & time function from https://tecadmin.net/get-current-date-time-javascript/
  142.     var date = (today.getMonth()+1)+'-'+today.getDate()+'-'+today.getFullYear();
  143.     var time = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
  144.     var dateTime = date+' @ '+time;
  145.     clearInterval(autocombatloop);
  146.     stopCombat(false, true, true);
  147.     autocombat = false;
  148.     updateACstatus();
  149.     alert('SEMI: Exited Auto Combat @ '+dateTime+' because '+username+' is out of '+reason);//upgrade to jqueryui modal dialog
  150.     autoSlayerEnabled = false; //connecting to auto slayer script by bubbalova from greasefork in tampermonkey
  151.     updateAutoSlayerButtonText(); //yay, automatically turns off auto slayer! kewls
  152. }
  153.  
  154. function updateACstatus() {
  155.     $("#autocombatStatus").text((autocombat) ? 'Enabled' : 'Disabled');
  156.     $("#autocombatStatus").css('color', (autocombat) ? 'gold' : '');
  157. }
  158.  
  159. function toggleautocombat() { //button -> function that enables auto combat
  160.     if (!isInCombat) { terminateAutoCombat("common sense... You aren't in combat!"); return; }
  161.     autocombat = !autocombat;
  162.     updateACstatus();
  163.     if (!autocombat) {
  164.         clearInterval(autocombatloop);
  165.         terminateAutoCombat("orders: you have given the command to stop.");
  166.     } else {
  167.         autocombatloop = setInterval(() => { autocombatfunc(); }, 500);
  168.         customNotify('assets/media/skills/combat/combat.svg','AutoCombat is now running.');
  169.     }
  170. }
  171.  
  172. function toggleAutoEat() {
  173.     autoEat = !autoEat;
  174.     $("#autoEatStatus").text((autoEat) ? 'Enabled' : 'Disabled');
  175. }
  176.  
  177. function toggleAutoLoot() {
  178.     autoLoot = !autoLoot;
  179.     $("#autoLootStatus").text((autoLoot) ? 'Enabled' : 'Disabled');
  180. }
  181. //End of Autocombat Auxiliaries
  182.  
  183. // Imported code section/mostly authored by others. Comments like this //::show the script name & author. Heavy modifications.
  184.  
  185. var autoEquipZone = false;
  186. function toggleAutoEquip() {
  187.     autoEquipZone = !autoEquipZone;
  188.     $("#autoEquipStatus").text( (autoEquipZone) ? 'Enabled' : 'Disabled');
  189. }
  190.  
  191. // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
  192. // Importing Auto Slayer by Bubbalova. Using a modified version of script v1.2.1.
  193. // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
  194.  
  195. var autoSlayerEnabled = false;
  196. var autoSlayerCheck = 0;
  197.  
  198. //Holds values for unequipped equipment
  199.     var originalRing;
  200.     var originalShield;
  201.     var originalCape;
  202.  
  203. var updateAutoSlayerButtonText = function () {
  204.     $('#auto-slayer-button-status').text((autoSlayerEnabled) ? 'Enabled' : 'Disabled');
  205.     $('#auto-slayer-button-status').css('color', (autoSlayerEnabled) ? 'gold' : '');
  206. }
  207.  
  208. var toggleAutoSlayer = function () {
  209.     autoSlayerEnabled = !autoSlayerEnabled; //interesting way to toggle. i like it better than my bs way. seems like the 'right' way. maybe it's just the jqueryui way. nope, all bool way.
  210.     updateAutoSlayerButtonText();
  211.     setTimeout(function() {
  212.         if (!autoSlayerEnabled) {
  213.             stopCombat(false, true, true);
  214.             customNotify('assets/media/skills/slayer/slayer.svg', 'AutoSlayer is now disabled.');
  215.             if (autocombat) terminateAutoCombat('robo-slayer juice. AutoSlayer was disabled, so AutoCombat will follow suit.');
  216.         } else {
  217.             changePage(13)
  218.             customNotify('assets/media/skills/slayer/slayer.svg', 'AutoSlayer is now running.');
  219.         }
  220.     }, 100);
  221. }
  222.  
  223. //Main function
  224. var autoSlayer = function() {
  225.     if (!autoSlayerEnabled) {
  226.         autoSlayerCheck = 0;
  227.         return; //aw: one line
  228.     }
  229.     //Slayer areas that require items
  230.     var strangeCave = 10;
  231.     var highLands = 11;
  232.  
  233.     if (!slayerTask.length) getSlayerTask(); //If there is no slayer task, get one
  234.    
  235.     if(autoSlayerCheck == 0){
  236.         autoSlayerCheck = 1;
  237.         originalCape = equipmentSets[selectedEquipmentSet].equipment[CONSTANTS.equipmentSlot.Cape];
  238.         originalShield = equipmentSets[selectedEquipmentSet].equipment[CONSTANTS.equipmentSlot.Shield];
  239.         originalRing = equipmentSets[selectedEquipmentSet].equipment[CONSTANTS.equipmentSlot.Ring];
  240.     }
  241.  
  242.     //If you are fighting an enemy that isn't your current task, stop combat and switch to the task monster
  243.     if (forcedEnemy !== slayerTask[0].monsterID || !isInCombat) {
  244.         if (isInCombat) stopCombat(false, true, true);
  245.         for(let i=0; i<combatAreas.length; i++){
  246.             if (combatAreas[i].areaName == findEnemyArea(slayerTask[0].monsterID)) {
  247.                 selectedCombatArea = i;
  248.                 break;
  249.             }
  250.         }
  251.         //Equips Slayer Skillcape if owned
  252.         if(skillLevel[CONSTANTS.skill.Slayer] >= 99 && checkBankForItem(CONSTANTS.item.Slayer_Skillcape) || equipmentSets[selectedEquipmentSet].equipment[CONSTANTS.equipmentSlot.Cape] == CONSTANTS.item.Slayer_Skillcape){
  253.             if(equipmentSets[selectedEquipmentSet].equipment[CONSTANTS.equipmentSlot.Cape] != CONSTANTS.item.Slayer_Skillcape){
  254.                 originalCape = equipmentSets[selectedEquipmentSet].equipment[CONSTANTS.equipmentSlot.Cape]
  255.                 for (let i = 0; i < bank.length; i++) {
  256.                     if(typeof(items[bank[i].id].name) == "Slayer Skillcape") {
  257.                         equipItem(i, CONSTANTS.item.Slayer_Skillcape, 1, selectedEquipmentSet)
  258.                         found = true
  259.                         break;
  260.                     }
  261.                 }
  262.             }
  263.         }
  264.         else if( (selectedCombatArea == strangeCave || selectedCombatArea == highLands) && !autoEquipZone ) newSlayerTask(); //aw: ranged & autoslayer: no good. just rerolling when combat area is the cave or highlands. but it costs
  265.         //Equips Mirror Shield for area
  266.         else if(selectedCombatArea == strangeCave && autoEquipZone) {
  267.             if(equipmentSets[selectedEquipmentSet].equipment[CONSTANTS.equipmentSlot.Shield] != CONSTANTS.item.Mirror_Shield) {
  268.                 originalShield = equipmentSets[selectedEquipmentSet].equipment[CONSTANTS.equipmentSlot.Shield];
  269.                 if(equipmentSets[selectedEquipmentSet].equipment[CONSTANTS.equipmentSlot.Shield] == 0) {
  270.                     newSlayerTask();
  271.                     notifyPlayer(CONSTANTS.skill.Slayer, "Skipping task due to 2-handed weapon!");
  272.                 } else {
  273.                     for (let i = 0; i < bank.length; i++) {
  274.                         if(typeof(items[bank[i].id].name) == "Mirror Shield") {
  275.                             equipItem(i, CONSTANTS.item.Mirror_Shield, 1, selectedEquipmentSet)
  276.                             found = true
  277.                             break;
  278.                         }
  279.                     }
  280.                 }
  281.             }
  282.         }
  283.         //Equips Magical Ring for area
  284.         else if(selectedCombatArea == highLands && autoEquipZone) {
  285.             if(equipmentSets[selectedEquipmentSet].equipment[CONSTANTS.equipmentSlot.Ring] != CONSTANTS.item.Magical_Ring) {
  286.                 originalRing = equipmentSets[selectedEquipmentSet].equipment[CONSTANTS.equipmentSlot.Ring];
  287.                 for (let i = 0; i < bank.length; i++) {
  288.                     if(typeof(items[bank[i].id].name) == "Magical Ring") {
  289.                         equipItem(i, CONSTANTS.item.Magical_Ring, 1, selectedEquipmentSet)
  290.                         found = true
  291.                         break;
  292.                     }
  293.                 }
  294.             }
  295.         }
  296.         else if( (selectedCombatArea != strangeCave || selectedCombatArea != highLands) && autoEquipZone){
  297.            
  298.             slayerLockedItem = null; //not sure what this does, added in Auto Slayer 1.2.1
  299.            
  300.             //Equips original shield when not in Area
  301.             if ( (equipmentSets[selectedEquipmentSet].equipment[CONSTANTS.equipmentSlot.Shield] == CONSTANTS.item.Mirror_Shield && originalShield != CONSTANTS.item.Mirror_Shield && originalShield != undefined) && autoEquipZone){
  302.                 for (let i = 0; i < bank.length; i++) {
  303.                     if(typeof(items[bank[i].id].name) == items[originalShield].name) {
  304.                         equipItem(i, originalShield, 1, selectedEquipmentSet)
  305.                         found = true
  306.                         break
  307.                     }
  308.                 }
  309.             }
  310.             //Equips original ring when not in Area
  311.             if ( (equipmentSets[selectedEquipmentSet].equipment[CONSTANTS.equipmentSlot.Ring] == CONSTANTS.item.Magical_Ring && originalRing != CONSTANTS.item.Magical_Ring && originalRing != undefined) && autoEquipZone){
  312.                 for (let i = 0; i < bank.length; i++) {
  313.                     if(typeof(items[bank[i].id].name) == items[originalRing].name) {
  314.                         equipItem(i, originalRing, 1, selectedEquipmentSet)
  315.                         found = true
  316.                         break
  317.                     }
  318.                 }
  319.             }
  320.         }
  321.         selectMonster(slayerTask[0].monsterID);
  322.     }
  323. }
  324.  
  325. var autoSlayerTimer = setInterval(function(){autoSlayer();}, 2000); //idk how i feel about this always being on rn... guess it's ok cuz it will just check if running and return. doesn't seem to be heavy in bg.
  326.  
  327. //AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
  328. // End of AutoSlayer!
  329. //AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
  330.  
  331. //::from Breakit on pastebin, modified for Melvor v0.12: https://pastebin.com/wq641Nhx
  332. function XPH(running,stat) {
  333.   XPH.Stats = [ "Woodcutting","Fishing","Firemaking","Cooking","Mining","Smithing","Attack","Strength","Defence","Hitpoints","Thieving","Farming","Ranged","Fletching","Crafting","Runecrafting","Magic","Prayer","Slayer","Herblore" ]
  334.   if ((running == null) || (stat > 19) || (isNaN(running)) || (isNaN(stat))) {
  335.      for (var i=0; i<XPH.Stats.length; i++) { console.log(i + ': ' + XPH.Stats[i]); }
  336.      console.log('SYNTAX: XPH([1|0],[0-19])');
  337.      console.log(XPH.Stats.toSource());
  338.      console.log('Example to Start/Check Strength XPH(1,7)');
  339.      console.log('Example to Stop Strength XPH(0,7)');
  340.      return
  341.   }
  342.   else {
  343.     if (XPH.running) {
  344.       XPH.rate = Math.floor((skillXP[stat] - XPH.exp) / ((Date.now() - XPH.time) / 1000) * 3600);
  345.       XPH.rate = XPH.rate.toString();
  346.      
  347.       var pattern = /(-?\d+)(\d{3})/;
  348.       while (pattern.test(XPH.rate)) XPH.rate = XPH.rate.replace(pattern, "$1,$2");
  349.       console.log('Current xp/hr rate for ' + XPH.Stats[stat] + ': ' + XPH.rate + '/hr -- Test running for ' + ((Date.now() - XPH.time) / 1000) + ' seconds.');
  350.       if (!running) {
  351.         console.log('Stopping');
  352.         XPH.running = '';
  353.       }
  354.     }
  355.     else {
  356.       XPH.exp = skillXP[stat];
  357.       XPH.time = Date.now();
  358.       XPH.running = 1;
  359.  
  360.       console.log('Starting xp/hr monitoring for: ' + XPH.Stats[stat]);
  361.       console.log('Use XPH(1,' + stat + ') to view current exp/hr.');
  362.       console.log('Use XPH(0,' + stat + ') to stop.');
  363.     }
  364.   }
  365. }
  366. //::what a great utility! to get current page: XPH(1,currentPage);... won't work for combat
  367.  
  368. /* well, i don't like the xph function in this, but this is a good way to create a fresh, working dropdown addon button to the left of the potions header button.
  369. //add xhp... XPH dammit! not x hitpoints... xp hour. feel like it should be xpph...
  370. $("#page-header-potions-dropdown").parent().before($(`
  371. <div class="dropdown d-inline-block ml-2">
  372.     <button type="button" class="btn btn-sm btn-dual" id="page-header-xph-dropdown" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
  373.         XPH
  374.     </button>
  375.     <div class="dropdown-menu dropdown-menu-lg dropdown-menu-right p-0 border-0 font-size-sm" id="header-xph-dropdown" aria-labelledby="page-header-xph-dropdown" x-placement="bottom-end" style="position: absolute; will-change: transform; top: 0px; left: 0px; transform: translate3d(-262px, 33px, 0px);">
  376.         <div class="p-2 bg-primary text-center">
  377.             <h5 class="dropdown-header text-uppercase">
  378.                 <a class="text-white" href="javascript:viewItemStats(0,0,true);">Use the XPH Script (Experience points per hour)</a>
  379.             </h5>
  380.         </div>
  381.         <div class="block-content block-content-full text-center">
  382.             <button id="xphBtn" class="btn btn-sm btn-dual" onclick="xphBtn()">Start</button>
  383.         </div>
  384.     </div>
  385. </div>`));
  386.  
  387. function xphBtn() {
  388.     XPH(1,currentPage); //don't like this actually. sigh.
  389. }
  390. */
  391.  
  392. //:: Scavenging the Thieving calculator from Melvor Idle Helper by RedSparr0w on GitLab: https://github.com/RedSparr0w/Melvor-Idle-Helper
  393. setTimeout( () => { //setup thieving calcs after 10sec, plenty delay for page load... should it be interval or timeout? timeout works fine, no need to repeat.
  394.     thievingCalc();
  395.     $('.js-popover').popover({ // Enable the popovers
  396.         container: 'body',
  397.         animation: false,
  398.         trigger: 'hover focus',
  399.     });
  400. }, 10000); //give it a nice long time to load. this one can throw errors.
  401.  
  402. const addCalcToEl = (el, data = []) => {
  403.     if (!el || !el.appendChild) return;    
  404.     const helper_container = document.createElement('div'); // create our helper elements
  405.     helper_container.className = 'font-size-sm font-w600 text-right text-uppercase text-muted';
  406.     helper_container.style = 'position: absolute; right: 6px; top: 8px;';
  407.     data.forEach((dat, i)=>{
  408.         // Add line break if not first element
  409.         if (i > 0) helper_container.appendChild(document.createElement('br'));
  410.         const el = document.createElement('small');
  411.         el.innerText = dat;
  412.         helper_container.appendChild(el);
  413.     });
  414.     el.classList.add('ribbon', 'ribbon-light', 'ribbon-bookmark', 'ribbon-left'); // Needs these classes for the text to show correctly
  415.     el.appendChild(helper_container);
  416. }
  417.  
  418. const thievingCalc = () => { //this is freshhh - Thieving Calc & Item Popup! SO Handy!
  419.     const seconds = baseThievingInterval / 1000; // Always takes the same amount of time
  420.     thievingNPC.forEach((npc, id) => {
  421.         const xp_ps = +(npc.xp / seconds).toFixed(1);
  422.         // Get the loottable text
  423.         let popoutText = [`<img src='assets/media/main/coins.svg' height='20px'> ${npc.maxCoins} coins (max)`];
  424.         const totalWeight = npc.lootTable.reduce((a,b)=>a + b[1], 0);
  425.         npc.lootTable.forEach(loot => {
  426.             const item = items[loot[0]];
  427.             popoutText.push(`<img src='${item.media}' height='20px'> ${item.name} - ${((loot[1] / totalWeight) * 100).toFixed(1)}%`);
  428.         });
  429.         const npc_el = document.getElementById(`thieving-npc-${id}`).getElementsByClassName('block-content')[0];
  430.         addCalcToEl(npc_el, [xp_ps + ' XP/s']); // Add the xp/s amounts
  431.         npc_el.classList.add('js-popover'); // Add the popovers for the loot
  432.         const npc_el_data = npc_el.dataset;
  433.         npc_el_data.toggle = 'popover';
  434.         npc_el_data.html = 'true';
  435.         npc_el_data.placement = 'bottom';
  436.         npc_el_data.content = popoutText.join('<br/>');
  437.     });
  438. }
  439. //:: end of import of scraps from Melvor Idle Helper
  440.  
  441. //:: importing Melvor Auto Replant 1.6 by Arcanus on Greasyfork: https://greasyfork.org/en/scripts/394855-melvor-auto-replant
  442. function autoReplant() {
  443.     for (let i = 0; i < newFarmingAreas.length; i++) {
  444.         for (let j = 0; j < newFarmingAreas[i].patches.length; j++) {
  445.             if(newFarmingAreas[i].patches[j].hasGrown) {
  446.                 let lastSeed = newFarmingAreas[i].patches[j].seedID
  447.                 let grownID = items[newFarmingAreas[i].patches[j].seedID].grownItemID
  448.                 if(checkBankForItem(grownID) || bankMax+baseBankMax > bank.length) {
  449.                     harvestSeed(i,j)
  450.                     if(checkBankForItem(lastSeed)) {
  451.                         if(farmingMastery[items[lastSeed].masteryID].mastery < 50) {
  452.                             if(equippedItems[CONSTANTS.equipmentSlot.Cape] !== CONSTANTS.item.Farming_Skillcape) {
  453.                                 if(checkBankForItem(CONSTANTS.item.Compost)) {
  454.                                     if(bank[getBankId(CONSTANTS.item.Compost)].qty < 5) {
  455.                                         buyQty = 5 - bank[getBankId(CONSTANTS.item.Compost)].qty
  456.                                         buyCompost()
  457.                                     }
  458.                                 } else {
  459.                                     buyQty = 5
  460.                                     buyCompost()
  461.                                 }
  462.                             }
  463.                             addCompost(i,j,5)
  464.                         }
  465.                         selectedPatch = [i,j]
  466.                         selectedSeed = lastSeed
  467.                         plantSeed()
  468.                     }
  469.                     if (equippedFood.find(food => food.itemID === grownID) && checkBankForItem(grownID))
  470.                         equipFood(getBankId(grownID),grownID,bank[getBankId(grownID)].qty)
  471.                 }
  472.             }
  473.         }
  474.     }
  475. }
  476. var autoReplantLoop = setInterval( () => { autoReplant() }, 5000);
  477. //:: end of import of Melvor Auto Replant. Beautiful script.
  478. //adding togbtn functions, togbtn is injected in setupSEMI()
  479. var autoReplanting = true;
  480. function toggleAutoReplant() {
  481.     autoReplanting = !autoReplanting;
  482.     $("#auto-replant-button-status").text( (autoReplanting) ? 'Enabled' : 'Disabled');
  483.     (autoReplanting) ? autoReplantLoop = setInterval( () => { autoReplant() }, 5000) : clearInterval(autoReplantLoop);
  484. }
  485.  
  486. //:: importing Melvor Percent Accuracy 1.1 by (Not) Arcanus on Greasyfork: https://greasyfork.org/en/scripts/394856-melvor-percent-accuracy
  487. this.setAccuracyPercent = setInterval(() =>{
  488.     if(isInCombat) {
  489.         let playerDodge = combatData.enemy.attackType === CONSTANTS.attackType.Melee ? maximumDefenceRoll : combatData.enemy.attackType === CONSTANTS.attackType.Ranged ? maximumRangedDefenceRoll : maximumMagicDefenceRoll
  490.         let enemyDodge = attackStyle < 3 ? combatData.enemy.maximumDefenceRoll : attackStyle < 6 ? combatData.enemy.maximumRangedDefenceRoll : combatData.enemy.maximumMagicDefenceRoll
  491.         let playerAccuracy = maximumAttackRoll < enemyDodge ? (0.5 * maximumAttackRoll / enemyDodge) * 100 : (1 - 0.5 * enemyDodge / maximumAttackRoll) * 100
  492.         let enemyAccuracy = combatData.enemy.maximumAttackRoll < playerDodge ? (0.5 * combatData.enemy.maximumAttackRoll / playerDodge) * 100 : (1 - 0.5 * playerDodge / combatData.enemy.maximumAttackRoll) * 100
  493.         $("#combat-player-attack-bonus").text(Math.floor(playerAccuracy)+ "%")
  494.         $("#combat-enemy-attack-bonus").text(Math.floor(enemyAccuracy)+ "%")
  495.     }
  496. },1000)
  497. //:: end of %acc
  498.  
  499. //:: simply rewritten autoBonfire by Dream below
  500. function autoBonfire() { if ( $.trim($('#skill-fm-bonfire-status').text()) == 'Inactive') lightBonfire(); } //really
  501. //:: end autoBonfire, adding Auto-Bonfire tog, * button included in setupSEMI() *
  502. var autoBonOn = false;
  503. var bonLoop;
  504. function toggleAutoBonfire() {
  505.     autoBonOn = !autoBonOn;
  506.     $("#auto-bonfire-button-status").text( (autoBonOn) ? 'Enabled' : 'Disabled');
  507.     $("#auto-bonfire-button-status").css('color', (autoBonOn) ? 'red' : '');
  508.     (autoBonOn) ? bonLoop = setInterval( () => { autoBonfire(); }, 500) : clearInterval(bonLoop);
  509. }
  510.  
  511. //:: importing scraps from Melvor Super Control Panel user script by Strutty on Greasefork: https://greasyfork.org/en/scripts/395834-melvor-super-control-panel
  512. //Important Settings
  513. //AutoMine
  514. const copper = 0;
  515. const tin = 1;
  516. const iron = 2;
  517. const coal = 3;
  518. const silver = 4;
  519. const gold = 5;
  520. const mithril = 6;
  521. const addy = 7;
  522. const runite = 8;
  523. const dragonite = 9;
  524. const runeEssence = 10;
  525. var mineArray = ([dragonite, runite, addy, mithril, gold, silver, coal, iron, tin, copper, runeEssence]); //add ui...?
  526. //AutoSellGems
  527. var targetStack = 100; //once it hits this amount, sell all of them.
  528. var gemIdList = [128, 129, 130, 131, 132]; //ruby boobies & such
  529.  
  530. //General Functions
  531. function getBankQty(id) {
  532.     for (let i = 0; i < bank.length; i++) {
  533.       if (bank[i].id === id) {
  534.         return bank[i].qty;
  535.       }
  536.     }
  537.     return 0;
  538. }
  539.  
  540. //SEMI menu setup function -- big fat template literal append
  541. function setupSEMI() { // streamlining/simplicity
  542.     if ($("#auto-replant-button").length) return; //probably smarter than the way i inject a lot of elements
  543.     //Settings menu HTML, attached to the heading anchor set up in SEMI.js content script
  544.     $("#semiHeading").after($(`
  545.    
  546.     <li id="semi-nav-14" class="nav-main-heading">Auto Skills</li>
  547.         <li id="semi-nav-0" class="nav-main-item" title="AutoReplant will automatically farm everything for you, replanting the same seed when it harvests, buying and using compost when it needs to automatically.">
  548.         <a id="auto-replant-button" class="nav-main-link" href="javascript:toggleAutoReplant();">
  549.             <img class="nav-img" src="assets/media/skills/farming/farming.svg">
  550.             <span class="nav-main-link-name">AutoReplant</span>
  551.             <small id="auto-replant-button-status">Enabled</small>
  552.         </a>
  553.     </li>
  554.     <li id="semi-nav-1" class="nav-main-item" title="AutoBonfire will keep a bonfire lit when you have a type of wood selected in Firemaking. The author suggests having an abundance of wood if using this!">
  555.         <a id="auto-bonfire-button" class="nav-main-link" href="javascript:toggleAutoBonfire();">
  556.             <img class="nav-img" src="assets/media/skills/firemaking/bonfire_active.svg">
  557.             <span class="nav-main-link-name">AutoBonfire</span>
  558.             <small id="auto-bonfire-button-status">Disabled</small>
  559.         </a>
  560.     </li>
  561.         <li id="semi-nav-12" class="nav-main-item" title="AutoCook by Unicue will automatically cycle through your fish and cook them all in order.">
  562.         <a id="auto-cook-button" class="nav-main-link" href="javascript:toggleAutoCook();">
  563.             <img class="nav-img" src="assets/media/skills/cooking/cooking.svg">
  564.             <span class="nav-main-link-name">AutoCook</span>
  565.             <small id="auto-cook-status">Disabled</small>
  566.         </a>
  567.     </li>
  568.     <li id="semi-nav-2" class="nav-main-item" title="AutoMine will mine highest XP ore first automatically. DOES NOT MIX WELL WITH AUTOSLAYER.">
  569.         <a id="auto-mine-button" class="nav-main-link" href="javascript:toggleAutoMine();">
  570.             <img class="nav-img" src="assets/media/skills/mining/mining.svg">
  571.             <span class="nav-main-link-name">AutoMine</span>
  572.             <small id="auto-mine-button-status"></small>
  573.         </a>
  574.     </li>    
  575.     <li id="semi-nav-3" class="nav-main-item" title="AutoSell Gems will sell 100 gems once they've reached a stack of 100.">
  576.         <a id="auto-sellgems-button" class="nav-main-link" href="javascript:toggleAutoSellGems();">
  577.             <img class="nav-img" src="assets/media/bank/diamond.svg">
  578.             <span class="nav-main-link-name">AutoSell Gems</span>
  579.             <small id="auto-sellgems-button-status"></small>
  580.         </a>
  581.     </li>
  582.    
  583.    
  584.    
  585.     <li id="semi-nav-14" class="nav-main-heading">Auto Combat</li>
  586.         <li id="semi-nav-5" class="nav-main-item" title="AutoCombat will automatically continue combat until you're either out of food in your equipped food slot, out of ranged ammo, or out of runes if using magic. It will safely exit combat if any of those conditions occur. Options include automatically looting and eating, shown below in the sidebar. Combines well with AutoSlayer.">
  587.         <a class="nav-main-link nav-compact" href="javascript:toggleautocombat();" id="autocombatNavBut">
  588.             <img class="nav-img" src="assets/media/skills/combat/combat.svg" id="autocombatImg">
  589.             <span class="nav-main-link-name">AutoCombat</span>
  590.         <small id="autocombatStatus">Disabled</small></a>
  591.     </li>
  592.         <li id="semi-nav-4" class="nav-main-item" title="aw-AutoSlayer, based on Melvor Auto Slayer by Bubbalova, automatically seeks slayer tasks and sets out to kill that enemy. If you are assigned a monster in a zone that requires special equipment, this version of AutoSlayer will simply reroll your assignment and continue on by default.">
  593.         <a id="auto-slayer-button" class="nav-main-link" href="javascript:toggleAutoSlayer();">
  594.             <img class="nav-img" src="assets/media/skills/slayer/slayer.svg">
  595.             <span class="nav-main-link-name">AutoSlayer</span>
  596.             <small id="auto-slayer-button-status">Disabled</small>
  597.         </a>
  598.     </li>
  599.         <li id="semi-nav-7" class="nav-main-item" title="AutoCombat will, by default, eat your food for you if your HP is less than what your food would heal. This option turns that off, if you'd rather rely on the default in-game Auto Eat, or just don't want it. Be warned that even the tier III in-game Auto Eat will leave you vulnerable to one-hits by very powerful mobs when at just above 40% HP.">
  600.         <a class="nav-main-link nav-compact" href="javascript:toggleAutoEat();" id="autoEatNavBut">
  601.             <img class="nav-img" src="assets/media/shop/autoeat.svg" id="autoEatImg">
  602.             <span class="nav-main-link-name">AC Auto Eat</span>
  603.         <small id="autoEatStatus">Enabled</small></a>
  604.     </li>
  605.     <li id="semi-nav-8" class="nav-main-item" title="Tired of that trash loot while your combat robot does its thing? Try the AutoCombat Auto Loot Option today!">
  606.         <a class="nav-main-link nav-compact" href="javascript:toggleAutoLoot();" id="autoLootNavBut">
  607.             <img class="nav-img" src="assets/media/main/bank_header.svg" id="autoLootImg">
  608.             <span class="nav-main-link-name">AC Auto Loot</span>
  609.         <small id="autoLootStatus">Enabled</small></a>
  610.     </li>
  611.    
  612.  
  613.     <li id="semi-nav-14" class="nav-main-heading">Auto Fish</li>
  614.         <li id="semi-nav-13" class="nav-main-item" title="AutoFish by BreakIt, Aldous Watts, and Jarx will automatically fish for you, either fishing the area with the highest average XP fish, or chasing either chests or highest XP fish in general for maximum efficiency of fishing with potions.">
  615.         <a id="auto-fish-button" class="nav-main-link" href="javascript:toggleAutoFish();">
  616.             <img class="nav-img" src="assets/media/shop/fishing_dragon.svg">
  617.             <span class="nav-main-link-name">AutoFish</span>
  618.             <small id="auto-fish-status">Disabled</small>
  619.         </a>
  620.     </li>
  621.         <li id="semi-nav-15" class="nav-main-item" title="AutoFish by default chases the highest XP fish. This is best for fishing with the fishing potion you can make in herblore. If you'd rather fish in the area with the highest AVERAGE fish XP, then you should turn this option off.">
  622.         <a id="autoFishMaxNavBut" class="nav-main-link nav-compact" href="javascript:toggleAutoFishMax();">
  623.             <img class="nav-img" src="assets/media/skills/fishing/whale.svg" id="autoFishMaxImg">
  624.             <span class="nav-main-link-name">AF Max Mode</span>
  625.         <small id="max-mode-status">Enabled</small></a>
  626.     </li>
  627.     <li id="semi-nav-16" class="nav-main-item" title="Chase those chests! This option will prioritize fishing in areas with chests in them.">
  628.         <a class="nav-main-link nav-compact" href="javascript:toggleAutoFishChest();" id="autoFishChestNavBut">
  629.             <img class="nav-img" src="assets/media/main/bank_header.svg" id="autoFishChestImg">
  630.             <span class="nav-main-link-name">AF Chase Chests</span>
  631.         <small id="chase-chest-status">Enabled</small></a>
  632.     </li>
  633.    
  634.    
  635.    
  636.    
  637.  
  638.    
  639.  
  640.  
  641.    
  642.  
  643.    
  644.    
  645.  
  646.  
  647.  
  648.  
  649.  
  650.  
  651.     <li id="semi-nav-9" class="nav-main-heading">AutoSlayer Options</li>
  652.     <li id="semi-nav-10" class="nav-main-item" title="The original Melvor Auto Slayer script by Bubbalova attempts to equip the Mirror Shield or Magic Ring when assigned a monster in zones that require them to enter. This option, disabled by default in SEMI, turns that functionality back on.">
  653.         <a class="nav-main-link nav-compact" href="javascript:toggleAutoEquip();" id="autoEquipNavBut">
  654.             <img class="nav-img" src="assets/media/bank/mirror_shield.svg" id="autoEquipImg">
  655.             <span class="nav-main-link-name">AS Auto Equip</span>
  656.         <small id="autoEquipStatus">Disabled</small></a>
  657.     </li>
  658.    
  659.     <hr>
  660.    
  661.     <li id="semi-nav-11" class="nav-main-item">
  662.         <a class="nav-main-link nav-compact" href="javascript:semiInfo();" id="semiInfoNavBut">
  663.             <img class="nav-img" src="`+$("#iconImg")[0].src+`">
  664.             <span class="nav-main-link-name">Show SEMI Info</span>
  665.         </a>
  666.     </li>`));
  667.    
  668.     updateAutoSellGemsButtonText();    
  669.     updateAutoMineButtonText();    
  670.     updateAutoSlayerButtonText();
  671. }
  672.  
  673. //AutoSellGems: Will sell gems when they reach the stack amount specified
  674. var autoSellGemsEnabled = false;
  675. var updateAutoSellGemsButtonText = function () {
  676.     $('#auto-sellgems-button-status').text((autoSellGemsEnabled) ? 'Enabled' : 'Disabled');
  677. }
  678. var toggleAutoSellGems = function () {
  679.     autoSellGemsEnabled = !autoSellGemsEnabled;
  680.     updateAutoSellGemsButtonText();
  681.     setTimeout(function() {
  682.         if (!autoSellGemsEnabled) {
  683.             console.log("Auto Sell Gems Disabled!");
  684.         }
  685.     }, 100);
  686. }
  687.  
  688. var autoSellGems = function() {
  689.     if (!autoSellGemsEnabled) {
  690.         return;
  691.     }
  692.     for(const gemId of gemIdList) {
  693.         const curQty = getBankQty(gemId);
  694.         //console.log('GEM ID '+gemId+' you have '+curQty);
  695.         if(curQty > targetStack){
  696.             sellItem(getBankId(gemId), targetStack);
  697.             customNotify('assets/media/main/coins.svg','Auto Sell Gems just sold '+targetStack+' '+ items[gemId].name +'.', 5000);
  698.         }
  699.     }
  700. }
  701. var autoSellGemsTimer = setInterval(function(){autoSellGems();}, 5000);
  702.  
  703. //AutoMine: Will mine based on your or priorities set in mineArray //aw: this still works awesomely!
  704. var autoMineEnabled = false;
  705. var updateAutoMineButtonText = function () { $('#auto-mine-button-status').text((autoMineEnabled) ? 'Enabled' : 'Disabled'); }
  706. var toggleAutoMine = function () {
  707.     autoMineEnabled = !autoMineEnabled;
  708.     updateAutoMineButtonText();
  709.     setTimeout(function() {
  710.         if (!autoMineEnabled) {
  711.             mineRock(currentRock, true);
  712.             console.log("Auto Mine Disabled!");
  713.         }else{
  714.             changePage(10);
  715.             if(!glovesTracker[CONSTANTS.shop.gloves.Mining].isActive){
  716.                 //equipItem(34, 399);
  717.             }
  718.         }
  719.     }, 100);
  720. }
  721. var autoMine = function(rocks) {
  722.     if (!autoMineEnabled) {
  723.         return;
  724.     }
  725.     for(const rock of rocks) {
  726.         if(!rockData[rock].depleted && miningData[rock].level <= skillLevel[CONSTANTS.skill.Mining]) { //added extra condition to make universal
  727.             if(currentRock !== rock) {
  728.                 mineRock(rock);
  729.             }
  730.             return;
  731.         }
  732.     }
  733. }
  734. var autoMineTimer = setInterval(function(){autoMine(mineArray);}, 100);
  735.  
  736. //Super Control Panel Builder (now more semi buttons or whatever)
  737. setTimeout(function() { setupSEMI(); },3000);
  738. //:: end of MSCP
  739.  
  740. //:://Auto Cooking by Unicue on the Melvor discord: https://discordapp.com/channels/625838709203271680/664637399028072470/681397160465661992
  741. let fishTypeCount = 0;
  742. let fishType = [9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
  743.  
  744. function autoCookAll(){
  745.     if(document.getElementById("skill-cooking-food-selected-qty").innerHTML == "x 0"){
  746.         fishTypeCount = (fishTypeCount + 1) % fishType.length;
  747.         selectFood(fishType[fishTypeCount]);
  748.     }
  749.     else if(document.getElementById("cook-count").innerHTML == "-"){
  750.         startCooking(10, false);
  751.     }    
  752. }
  753. var cookInterval;
  754. var autoCook = false;
  755. function toggleAutoCook() {
  756.     autoCook = !autoCook;
  757.     $("#auto-cook-status").text( (autoCook) ? 'Enabled' : 'Disabled');
  758.     if (autoCook) {
  759.         cookInterval = setInterval(autoCookAll, 1000)
  760.         changePage(9);
  761.     } else { clearInterval(cookInterval); }
  762. }
  763. //::end autoCook
  764.  
  765. //:: importing AutoFish by BreakIt, Jarx and me
  766. var chaseChest = true;
  767. var maxMode = true;
  768.  
  769. function autoFish() {
  770.     let fishMax = []; //set to empty each time autoFish iterates to recalculate
  771.     let fishAvg = [];
  772.     let fishZone = 0;
  773.     var maxXP = 0;
  774.    
  775.     if (maxMode) {
  776.         for (let i = 0; i < fishingArea.length; i++) { //for each available fishing area
  777.         if (skillLevel[CONSTANTS.skill.Fishing] > fishingArea[i].level) { //if you can fish it
  778.             maxXP = fishData[Math.max(...fishingArea[i].currentFish)].xp; //find max xp of fish there
  779.             if (chaseChest && Math.max(...fishingArea[i].currentFish) == 12) {
  780.                 console.log("Found a Chest!");
  781.                 console.log($(this));
  782.                 maxXP = 9000;
  783.                 }
  784.             fishMax.push(maxXP); //add that max to the array of fish areas to be max'd again
  785.             }
  786.         }
  787.     fishZone = fishMax.reduce((iMax, x, i, arr) => x > arr[iMax] ? i : iMax, 0); //some maths by BreakIt, calcs max of array and outputs the array position.
  788.     } else {
  789.         $("[id^=fishing-area-fish-]").each(function() {
  790.             var totalexp = 0;
  791.             $(this).children("img").each(function() {
  792.                 totalexp = totalexp + parseInt($(this).attr("data-original-title").split("+")[1].split(" ")[0]);
  793.                 if (chaseChest && parseInt($(this).attr("data-original-title").split("+")[1].split(" ")[0]) == "1") {
  794.                     console.log("Found a Chest!");
  795.                     console.log($(this));
  796.                     totalexp = 9000;
  797.                 }
  798.             });
  799.             var toPush = totalexp / $(this).children("img").length;
  800.             if (toPush == 9000) { toPush = 0; }
  801.             fishAvg.push(toPush);
  802.         });
  803.         fishZone = fishAvg.reduce((iMax, x, i, arr) => x > arr[iMax] ? i : iMax, 0);
  804.     }
  805.    
  806.     let fishActiveZone = 0;
  807.     $("#fishing-container").find("a").each(function() { //sets the zone if max changed.
  808.         if ($(this).hasClass("bg-fishing")) { //if the containers are indeed fishing areas
  809.             if (fishActiveZone != fishZone) { //and if the zone is different from where the max fish is at
  810.                 console.log('Max: '+fishMax+' Avg: '+fishAvg);
  811.                 console.log("Switching from " + fishActiveZone + " to " + fishZone);
  812.                 startFishing(0,false);
  813.                 startFishing(fishZone,false);
  814.             }
  815.         }
  816.     fishActiveZone++;
  817.     });
  818. }
  819. var fishInterval;
  820. var autoFishing = false;
  821. function toggleAutoFish() {
  822.     autoFishing = !autoFishing;
  823.     $("#auto-fish-status").text( (autoFishing) ? 'Enabled' : 'Disabled' );
  824.     if (autoFishing) {
  825.         changePage(7);
  826.         startFishing(0,false);
  827.         //customNotify('assets/media/shop/fishing_dragon.svg', 'AutoFish is enabled.', 5000);
  828.         fishInterval = setInterval( () => { autoFish(); }, 1000); //loop!
  829.     } else {
  830.         clearInterval(fishInterval);
  831.         if (currentlyFishingArea !== null) { startFishing(currentlyFishingArea,false); }
  832.     }
  833. }
  834. function toggleAutoFishMax() {
  835.     maxMode = !maxMode;
  836.     $("#max-mode-status").text( (maxMode) ? 'Enabled' : 'Disabled' );
  837. }
  838. function toggleAutoFishChest() {
  839.     chaseChest = !chaseChest;
  840.     $("#chase-chest-status").text( (chaseChest) ? 'Enabled' : 'Disabled' );
  841. }
  842.  
  843. //:: end autoFish
  844.  
  845. //:: import this soon: https://github.com/Katorone/AutoMelvorIdle/blob/master/melvor.user.js
  846.  
  847. //The end! SEMI loaded custom notification
  848. if(navigator.userAgent.match("Chrome")){
  849.     customNotify('assets/media/monsters/dragon_black.svg','Scripting Engine for Melvor Idle is now loaded and running! Check the bottom of the sidebar.',22000);
  850. } else if(navigator.userAgent.match("Firefox")) {
  851.     customNotify('','Scripting Engine for Melvor Idle is now loaded and running! Check the bottom of the sidebar.',22000);
  852. }
  853.  
  854. /* ~~~~~-----~~~~~-----~~~~~Notes~~~~~-----~~~~~-----~~~~~
  855. TODO
  856. More settings for autocombat: auto re-equip arrows? Auto only-loot bones/etc? neato.
  857. time until done calculators? more items til done calculators? there may already be utils out there. Link to them in info?
  858.     const craftTime = 2; //s
  859.     var numItemsCraftable = math;
  860.     output.text(numItemsCraftable*craftTime+" sec til done");
  861.         UI notes for xp/item calc: sliders. Move a slider to set how many levels you want to move up, then once item is selected, calculate and display XP, gp, whatever.
  862.     craftInterval: game variable for ms that it takes to use crafting to make one item. Halved with skill cape. Could be useful for item/xp time calc. Thief calc does this.
  863.  
  864. add custom settings in localstorage?... keeps variables like autoLoot, autoEat, autoEquipZone, etc. localStorage.SEMI.setItem('test', test)
  865.     idk i like how these scripts kind of reset after reload. so, won't start up with autobon enabled...but that's not really an option
  866.     so much as it is doing some dumb stuff when loaded. so, maybe the AC/slayer option toggles would be fine.
  867.  
  868. make compatible with MICE?... remove all MICE automation and just leave cheats in next ver?
  869.  
  870. FUNKY IDEAS
  871. sound plays when idle is done and no task queued? repeats every minute or so
  872. task queueing
  873. sounds in combat, alert sound for low health
  874.  
  875. //:: //:: //:: More Imported Scripts
  876. //:: average hits to kill enemy from https://repl.it/@Dwake5/TightSpringgreenCosmos
  877. const averageHits = (accuracy, maxHit, enemyHP) => {
  878.     let hits = 0
  879.    
  880.     while (enemyHP > 0) {
  881.       hits++
  882.       if (Math.random()*100 <= accuracy) {
  883.         enemyHP -= Math.floor(Math.random()*maxHit) + 1
  884.       }
  885.     }
  886.  
  887.     return hits
  888. }
  889.  
  890. let total  = 0
  891.  
  892. for (i = 0; i < 10000; i++) {
  893.   total += averageHits(60.4,420,2200)
  894.   // Put your accuracy, maxhit and enemys hp above here
  895. }
  896.  
  897.  
  898. total/10000
  899. //::end hits to kill
  900.  
  901. //::from Bioniclegenius in Melvor discord
  902. var smithingHUD = window.setInterval(function() {
  903.     var xpLeft = exp.level_to_xp(skillLevel[5] + 1) - skillXP[5];
  904.     var smithItemXP = items[smithingItems[selectedSmith].itemID].smithingXP;
  905.     var itemsLeft = Math.ceil(xpLeft / smithItemXP);
  906.     var oldText = numberWithCommas(Math.floor(skillXP[5])) + " / " + numberWithCommas(exp.level_to_xp(skillLevel[5] + 1));
  907.     $("#skill-progress-xp-5").text(oldText + " - " + numberWithCommas(xpLeft) + " - " + numberWithCommas(itemsLeft));
  908. }, 1000 / 60);
  909. //::end smith shit//hmmm... numberWithCommas eh? is this a game function? also, i just kinda hate the way this looks. so unintuitive.
  910.  
  911. //somehow this creates fishing chests at random
  912. //fishingArea[Math.floor(Math.random() * (+fishingArea.length - +0)) + +0].currentFish.push(fishData.length-1); updateFishingVisuals(true);
  913.  
  914. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement