diff --git a/.gitignore b/.gitignore index 5a89515d9..c783fe285 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1 @@ -/sparecode/ -/AutoTrimps.PEM -/https.py -/https2.py -/server.pem -/SIMPLEHTTPSERVER.bat +AutoTrimps2.js \ No newline at end of file diff --git a/.user.js b/.user.js index 1467ea6d0..366490dc0 100644 --- a/.user.js +++ b/.user.js @@ -1,22 +1,22 @@ // ==UserScript== -// @name AutoTrimps-genBTC -// @version 2.1.6.9-genbtc-3-23-2018 -// @namespace https://genbtc.github.io/AutoTrimps -// @updateURL https://genbtc.github.io/AutoTrimps/.user.js +// @name AutoTrimps-Zek +// @version 1.0-Zek +// @namespace https://Zorn192.github.io/AutoTrimps +// @updateURL https://Zorn192.github.io/AutoTrimps/.user.js // @description Automate all the trimps! -// @author zininzinin, spindrjr, Ishkaru, genBTC +// @author zininzinin, spindrjr, Ishkaru, genBTC, Zeker0 // @include *trimps.github.io* // @include *kongregate.com/games/GreenSatellite/trimps -// @connect *genbtc.github.io/AutoTrimps* +// @connect *Zorn192.github.io/AutoTrimps* // @connect *trimps.github.io* // @connect self -// @grant none +// @grant GM_xmlhttpRequest // ==/UserScript== var script = document.createElement('script'); -script.id = 'AutoTrimps-script'; +script.id = 'AutoTrimps-Zek'; //This can be edited to point to your own Github Repository URL. -script.src = 'https://genBTC.github.io/AutoTrimps/AutoTrimps2.js'; +script.src = 'https://Zorn192.github.io/AutoTrimps/AutoTrimps2.js'; //script.setAttribute('crossorigin',"use-credentials"); script.setAttribute('crossorigin',"anonymous"); document.head.appendChild(script); diff --git a/AutoTrimps2.js b/AutoTrimps2.js index 96766fc01..8dd51d941 100644 --- a/AutoTrimps2.js +++ b/AutoTrimps2.js @@ -1,139 +1,102 @@ -// ==UserScript== -// @name AutoTrimpsV2 -// @version 2.1.6.9b-genbtc-4-2-2018 -// @updateURL https://github.com/genbtc/AutoTrimps/AutoTrimps2.js -// @description Automate all the trimps! -// @author zininzinin, spindrjr, belaith, ishakaru, genBTC, Unihedron, coderPatsy -// @include *trimps.github.io* -// @include *kongregate.com/games/GreenSatellite/trimps -// @grant none -// ==/UserScript== -var ATversion = '2.1.6.9b-genbtc-4-2-2018'; - -//////////////////////////////////////////////////////////////////////////////// -//Main Loader Initialize Function (loads first, load everything else)/////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////// -var atscript = document.getElementById('AutoTrimps-script') - , basepath = 'https://genBTC.github.io/AutoTrimps/' - , modulepath = 'modules/' - ; -//This should redirect the script to wherever its being mirrored from. -if (atscript !== null) { - basepath = atscript.src.replace(/AutoTrimps2\.js$/, ''); -} -//This could potentially do something one day. like: read localhost url from tampermonkey. -// AKA do certain things when matched on a certain url. -//if (atscript.src.includes('localhost')) {;}; +var ATversion = 'Zek v5.1.0', + atscript = document.getElementById('AutoTrimps-script'), + basepath = 'https://Zorn192.github.io/AutoTrimps/', //Link to your own Github here if you forked! + modulepath = 'modules/'; +null !== atscript && (basepath = atscript.src.replace(/AutoTrimps2\.js$/, '')); -//Script can be loaded like this: ATscriptLoad(modulepath, 'utils.js'); function ATscriptLoad(pathname, modulename) { if (modulename == null) debug("Wrong Syntax. Script could not be loaded. Try ATscriptLoad(modulepath, 'example.js'); "); var script = document.createElement('script'); if (pathname == null) pathname = ''; script.src = basepath + pathname + modulename + '.js'; script.id = modulename + '_MODULE'; - //script.setAttribute('crossorigin',"use-credentials"); - //script.setAttribute('crossorigin',"anonymous"); document.head.appendChild(script); } -//Scripts can be unloaded like this: ATscriptUnload('scryer'); -function ATscriptUnload(id) { - var $link = document.getElementById(id + '_MODULE'); - if (!$link) return; - document.head.removeChild($link); - debug("Removing " + id + "_MODULE","other"); + +function ATscriptUnload(a) { + var b = document.getElementById(a + "_MODULE"); + b && (document.head.removeChild(b), debug("Removing " + a + "_MODULE", "other")) } -ATscriptLoad(modulepath, 'utils'); //Load stuff needed to load other stuff: +ATscriptLoad(modulepath, 'utils'); -//This starts up after 2.5 seconds. function initializeAutoTrimps() { - loadPageVariables(); //get autoTrimpSettings - ATscriptLoad('','SettingsGUI'); //populate Settings GUI - ATscriptLoad('','Graphs'); //populate Graphs - //Load modules: - ATmoduleList = ['query', 'portal', 'upgrades', 'heirlooms', 'buildings', 'jobs', 'equipment', 'gather', 'stance', 'battlecalc', 'maps', 'breedtimer', 'dynprestige', 'fight', 'scryer', 'magmite', 'other', 'import-export', 'client-server', 'perks', /* 'perky', */ 'fight-info', 'performance']; + loadPageVariables(); + ATscriptLoad('', 'SettingsGUI'); + var script = document.createElement('script'); + script.src = 'https://Quiaaaa.github.io/AutoTrimps/Graphs.js'; + document.head.appendChild(script); + ATmoduleList = ['import-export', 'query', 'calc', 'portal', 'upgrades', 'heirlooms', 'buildings', 'jobs', 'equipment', 'gather', 'stance', 'mapfunctions', 'maps', 'breedtimer', 'dynprestige', 'fight', 'scryer', 'magmite', 'nature', 'other', 'perks', 'fight-info', 'performance', 'ab', 'MAZ']; for (var m in ATmoduleList) { ATscriptLoad(modulepath, ATmoduleList[m]); } - // - debug('AutoTrimps v' + ATversion + ' Loaded!', '*spinner3'); + debug('AutoTrimps - Zek Fork Loaded!', '*spinner3'); } var changelogList = []; -//changelogList.push({date: " ", version: " ", description: "", isNew: true}); //TEMPLATE -changelogList.push({date: "4/2", version: "v2.1.6.9b", description: "Import Export, Modules Load code Improvements. Multiple Buttons/Settings Were Combined. AutoPerks code was changed but still functions the same, except for a new algorithm that reduces the time to allocate for high helium players to near-instantaneous. Please test new algo with MODULES[\"perks\"].useAlgo2=true; .You can also clear all perks then allocate and have it work now. AutoMaps no longer considered as being in Lead challenge during Chall^2. ", isNew: true}); -changelogList.push({date: "3/23", version: "v2.1.6.9", description: "Game's Map at Zone can be used with AT now, to run maps forever. AutoMaps setting was combined with RunUniqueMaps (variable has changed from boolean false,true to a value 0,1,2). Settings file has been migrated as such. New: Map SpecialMod is sort of working, at least. Geneticist Infinity bugfix. New AGU Settings for 60% Void (fixed). Many Graphs fixes. AutoMaps changes. Equipment Cap, see README at GitHub DarkTheme fix. Scientists Fix. Zek450 Perks Preset Changed. Ongoing Development...", isNew: true}); -changelogList.push({date: "3/22", version: "v2.1.6.8", description: "Settings GUI, make better. Import/export improved. Graph buttons: Cycle Up/Down. Internal code fixes. New Graph: Nurseries", isNew: false}); -changelogList.push({date: "3/24", version: "v2.1.6.5-stable", description: "Set up Stable Repository for the faint of heart.", isNew: true}); -//changelogList.push({date: "3/20", version: "v2.1.6.7", description: "Entirely Re-Arranged Settings Layout. Enjoy! New: Display Tab: EnhanceGrid + Go AFK Mode. GUI: Pinned AT Tab menu bar to top when scrolling. Minimize/Maxi/Close Buttons. ShowChangeLog Button. New Graph: FluffyXP&Xp/Hr (starts@300)", isNew: false}); -//changelogList.push({date: "3/13", version: "v2.1.6.6", description: "Geneticist management changes. Equipment code improvements. ATscriptLoad improvements. attempt to track errors.", isNew: false}); -//changelogList.push({date: "3/7", version: "v2.1.6.5", description: "Save/Reload Profiles in Import/Export. Magmamancer graph. Magmite/Magma Spam disableable.", isNew: false}); - -function assembleChangelog(date,version,description,isNew) { - return (isNew) - ? (`${date} ${version} New: ${description}
`) - : (`${date} ${version} ${description}
`); +changelogList.push({ + date: "11/02/2023", + version: "v5.2.0", + description: "Trimps v5.9.0 Added Frigid to calc. Added Desolation AutoDeso. Added mutations to calc. ", + isNew: true +}); +changelogList.push({ + date: "13/11/2022", + version: "v5.2.1", + description: "Trimps v5.8.0 Added Smithy farming. Changed Scryer stuff. U1 Calc slightly more accurate. Changed some colours and setting descriptions like AutoHeirlooms. Let me know if something is broken. ", + isNew: false +}); +changelogList.push({ + date: "28/10/2022", + version: "v5.2.0", + description: "Trimps v5.8.0 Changed U2 Automaps so there might be problems, let me know if there is. Autogiga, Better stance swap, U1 Calc fixed. ", + isNew: false +}); + +function assembleChangelog(a, b, c, d) { + return d ? `${a} ${b} New: ${c}
` : `${a} ${b} ${c}
` } + function printChangelog() { - var body=""; + var body = ""; for (var i in changelogList) { var $item = changelogList[i]; - var result = assembleChangelog($item.date,$item.version,$item.description,$item.isNew); - body+=result; - }; + var result = assembleChangelog($item.date, $item.version, $item.description, $item.isNew); + body += result; + } var footer = - 'Ongoing Development - Report any bugs/problems please!\ -
Talk with the dev: genr8_#8163 @ AutoTrimps Discord Channel\ -
SeeReadMe Or check the commit history (if you want).' - , action = 'cancelTooltip()' - , title = 'Script Update Notice
' + ATversion - , acceptBtnText = "Thank you for playing AutoTrimps. Accept and Continue." - , hideCancel = true; - tooltip('confirm', null, 'update', body+footer, action, title, acceptBtnText, null, hideCancel); -} -function printLowerLevelPlayerNotice() { - tooltip('confirm', null, 'update', 'The fact that it works at all is misleading new players into thinking its perfect. Its not. If your highest zone is under z60, you have not unlocked the stats required, and have not experienced the full meta with its various paradigm shifts. If you are just starting, my advice is to play along naturally and use AutoTrimps as a tool, not a crutch. Play with the settings as if it was the game, Dont expect to go unattended, if AT chooses wrong, and make the RIGHT choice yourself. Additionally, its not coded to run one-time challenges for you, only repeatable ones for helium. During this part of the game, content is king - automating literally removes the fun of the game. If you find that many flaws in the automation exist for you, level up. Keep in mind the challenge of maintaining the code is that it has to work for everyone. AT cant see the future and doesnt run simulations, it exists only in the present moment. Post any suggestions on how it can be better, or volunteer to adapt the code, or produce some sort of low-level player guide with what youve learned.
Happy scripting! -genBTC','cancelTooltip()', 'LowLevelPlayer Notes:
PSA: AutoTrimps was not designed for new/low-level players.', "I understand I am on my own and I Accept and Continue.", null, true); + 'ZӘK Fork - Report any bugs/problems please!\ +
Talk with the dev: Zek#0647 @ Zeks Discord Channel\ +
Talk with the other Trimpers: Trimps Discord Channel\ +
See ReadMe Or check the commit history (if you want).', + action = 'cancelTooltip()', + title = 'Script Update Notice
' + ATversion, + acceptBtnText = "Thank you for playing AutoTrimps. Accept and Continue.", + hideCancel = true; + tooltip('confirm', null, 'update', body + footer, action, title, acceptBtnText, null, hideCancel); } -//////////////////////////////////////// -//Main DELAY Loop/////////////////////// -//////////////////////////////////////// -//Magic Numbers -var runInterval = 100; //How often to loop through logic -var startupDelay = 2500; //How long to wait for everything to load +var runInterval = 100; +var startupDelay = 4000; -//Start Loops setTimeout(delayStart, startupDelay); + function delayStart() { initializeAutoTrimps(); printChangelog(); setTimeout(delayStartAgain, startupDelay); } -function delayStartAgain(){ - if (game.achievements.zones.finished < 8) //z60 - printLowerLevelPlayerNotice(); - //Set some game ars after we load. + +function delayStartAgain() { game.global.addonUser = true; game.global.autotrimps = true; - //Actually Start mainLoop and guiLoop MODULESdefault = JSON.parse(JSON.stringify(MODULES)); setInterval(mainLoop, runInterval); - setInterval(guiLoop, runInterval*10); - if (autoTrimpSettings.PrestigeBackup !== undefined && autoTrimpSettings.PrestigeBackup.selected != "") - document.getElementById('Prestige').value = autoTrimpSettings.PrestigeBackup.selected; - if (document.getElementById('Prestige').value === "") - document.getElementById('Prestige').value = "Off"; - + setInterval(guiLoop, runInterval * 10); } -//////////////////////////////////////// -//Global Main vars ///////////////////// -//////////////////////////////////////// -//////////////////////////////////////// -var ATrunning = true; //status var -var ATmessageLogTabVisible = true; //show an AutoTrimps tab after Story/Loot/Unlocks/Combat message Log Container -var enableDebug = true; //Spam console.log with debug info +var ATrunning = true; +var ATmessageLogTabVisible = true; +var enableDebug = true; var autoTrimpSettings = {}; var MODULES = {}; @@ -143,11 +106,15 @@ var ATmoduleList = []; var bestBuilding; var scienceNeeded; +var RscienceNeeded; var breedFire = false; var shouldFarm = false; +var RshouldFarm = false; var enoughDamage = true; +var RenoughDamage = true; var enoughHealth = true; +var RenoughHealth = true; var baseDamage = 0; var baseBlock = 0; @@ -161,127 +128,272 @@ var preBuymaxSplit; var currentworld = 0; var lastrunworld = 0; var aWholeNewWorld = false; -var needGymystic = true; //used in setScienceNeeded, buildings.js, equipment.js +var needGymystic = true; var heirloomFlag = false; +var daily3 = false; var heirloomCache = game.global.heirloomsExtra.length; var magmiteSpenderChanged = false; +var lastHeliumZone = 0; +var lastRadonZone = 0; + +//Get Gamma burst % value +gammaBurstPct = (getHeirloomBonus("Shield", "gammaBurst") / 100) > 0 ? (getHeirloomBonus("Shield", "gammaBurst") / 100) : 1; +shieldEquipped = game.global.ShieldEquipped.id; -//////////////////////////////////////// -//Main LOGIC Loop/////////////////////// -//////////////////////////////////////// -//////////////////////////////////////// function mainLoop() { if (ATrunning == false) return; - if(getPageSetting('PauseScript') || game.options.menu.pauseGame.enabled || game.global.viewingUpgrades) return; + if (getPageSetting('PauseScript') || game.options.menu.pauseGame.enabled || game.global.viewingUpgrades) return; ATrunning = true; - if(game.options.menu.showFullBreed.enabled != 1) toggleSetting("showFullBreed"); //more detail - addbreedTimerInsideText.innerHTML = parseFloat(game.global.lastBreedTime/1000).toFixed(1) + 's'; //add hidden next group breed timer; - addToolTipToArmyCount(); //Add hidden tooltip for army count (SettingsGUI.js @ end) - //Heirloom: - if (mainCleanup() // Z1 new world - || portalWindowOpen // in the portal screen (for manual portallers) - || (!heirloomsShown && heirloomFlag) // closed heirlooms screen - || (heirloomCache != game.global.heirloomsExtra.length)) { // inventory size changed (a drop appeared) - // also pre-portal: portal.js:111 - if (getPageSetting('AutoHeirlooms2')) autoHeirlooms2(); //"Auto Heirlooms 2" (heirlooms.js) - else if (getPageSetting('AutoHeirlooms')) autoHeirlooms();//"Auto Heirlooms" (") - if (getPageSetting('AutoUpgradeHeirlooms') && !heirloomsShown) autoNull(); //"Auto Upgrade Heirlooms" (heirlooms.js) - + if (getPageSetting('showbreedtimer') == true) { + if (game.options.menu.showFullBreed.enabled != 1) toggleSetting("showFullBreed"); + addbreedTimerInsideText.innerHTML = ((game.jobs.Amalgamator.owned > 0) ? Math.floor((new Date().getTime() - game.global.lastSoldierSentAt) / 1000) : Math.floor(game.global.lastBreedTime / 1000)) + 's'; //add breed time for next army; + addToolTipToArmyCount(); + } + if (mainCleanup() || portalWindowOpen || (!heirloomsShown && heirloomFlag) || (heirloomCache != game.global.heirloomsExtra.length)) { heirloomCache = game.global.heirloomsExtra.length; } heirloomFlag = heirloomsShown; - //Stuff to do Every new Zone if (aWholeNewWorld) { - // Auto-close dialogues. switch (document.getElementById('tipTitle').innerHTML) { - case 'The Improbability': // Breaking the Planet - case 'Corruption': // Corruption / True Corruption - case 'Spire': // Spire - case 'The Magma': // Magma + case 'The Improbability': + case 'Corruption': + case 'Spire': + case 'The Magma': cancelTooltip(); } if (getPageSetting('AutoEggs')) easterEggClicked(); - setTitle(); // Set the browser title + setTitle(); + } + if (game.global.world != autoTrimpSettings.zonetracker) { + autoTrimpSettings.zonetracker = game.global.world; + } + + //Universal Logic + if (getPageSetting('AutoBoneChargeMax') != 0) autoBoneChargeWhenMax(); + + //Logic for Universe 1 + if (game.global.universe == 1) { + + //Offline Progress + if (!usingRealTimeOffline) { + setScienceNeeded(); + autoLevelEquipment(); + } + + //Heirloom Shield Swap Check + if (shieldEquipped !== game.global.ShieldEquipped.id) HeirloomShieldSwapped(); + + //Core + if (getPageSetting('AutoMaps') > 0 && game.global.mapsUnlocked) autoMap(); + if (getPageSetting('automapsalways') == true && autoTrimpSettings.AutoMaps.value != 1) autoTrimpSettings.AutoMaps.value = 1; + if (getPageSetting('showautomapstatus') == true) updateAutoMapsStatus(); + if (getPageSetting('ManualGather2') == 1) manualLabor2(); + if (getPageSetting('TrapTrimps') && game.global.trapBuildAllowed && game.global.trapBuildToggled == false) toggleAutoTrap(); + if (getPageSetting('ManualGather2') == 2) autogather3(); + if (getPageSetting('ATGA2') == true) ATGA2(); + if (aWholeNewWorld && getPageSetting('AutoRoboTrimp')) autoRoboTrimp(); + if (game.global.challengeActive == "Daily" && getPageSetting('buyheliumy') >= 1 && getDailyHeliumValue(countDailyWeight()) >= getPageSetting('buyheliumy') && game.global.b >= 100 && !game.singleRunBonuses.heliumy.owned) purchaseSingleRunBonus('heliumy'); + if (aWholeNewWorld && getPageSetting('FinishC2') > 0 && game.global.runningChallengeSquared) finishChallengeSquared(); + if (getPageSetting('spendmagmite') == 2 && !magmiteSpenderChanged) autoMagmiteSpender(); + if (getPageSetting('AutoNatureTokens') && game.global.world > 229) autoNatureTokens(); + if (getPageSetting('autoenlight') && game.global.world > 229 && game.global.uberNature == false) autoEnlight(); + if (getPageSetting('BuyUpgradesNew') != 0) buyUpgrades(); + if ((getPageSetting('Hshrine') == true) || (getPageSetting('Hdshrine') == 1) || (getPageSetting('Hdshrine') == 2)) autoshrine(); + + //Buildings + if (!usingRealTimeOffline) { + if (getPageSetting('BuyBuildingsNew') === 0 && getPageSetting('hidebuildings') == true) buyBuildings(); + else if (getPageSetting('BuyBuildingsNew') == 1) { + buyBuildings(); + buyStorage(); + } else if (getPageSetting('BuyBuildingsNew') == 2) buyBuildings(); + } + else if (getPageSetting('BuyBuildingsNew') == 3) buyStorage(); + if (getPageSetting('UseAutoGen') == true && game.global.world > 229) autoGenerator(); + + //Jobs + if (getPageSetting('BuyJobsNew') == 1) { + workerRatios(); + buyJobs(); + } else if (getPageSetting('BuyJobsNew') == 2) buyJobs(); + + //Portal + if (autoTrimpSettings.AutoPortal.selected != "Off" && game.global.challengeActive != "Daily" && !game.global.runningChallengeSquared) autoPortal(); + if (getPageSetting('AutoPortalDaily') > 0 && game.global.challengeActive == "Daily") dailyAutoPortal(); + if (getPageSetting('c2runnerstart') == true && getPageSetting('c2runnerportal') > 0 && game.global.runningChallengeSquared && game.global.world > getPageSetting('c2runnerportal')) c2runnerportal(); + + //Combat + if (getPageSetting('ForceAbandon') == true || getPageSetting('fuckanti') > 0) trimpcide(); + if (getPageSetting('trimpsnotdie') == true && game.global.world > 1) helptrimpsnotdie(); + if (!game.global.fighting) { + if (getPageSetting('fightforever') == 0) fightalways(); + else if (getPageSetting('fightforever') > 0 && calcHDratio() <= getPageSetting('fightforever')) fightalways(); + else if (getPageSetting('cfightforever') == true && (challengeActive("Electricty") || challengeActive("Toxicity") || challengeActive("Nom"))) fightalways(); + else if (getPageSetting('dfightforever') == 1 && game.global.challengeActive == "Daily" && typeof game.global.dailyChallenge.empower == 'undefined' && typeof game.global.dailyChallenge.bloodthirst == 'undefined' && (typeof game.global.dailyChallenge.bogged !== 'undefined' || typeof game.global.dailyChallenge.plague !== 'undefined' || typeof game.global.dailyChallenge.pressure !== 'undefined')) fightalways(); + else if (getPageSetting('dfightforever') == 2 && game.global.challengeActive == "Daily" && (typeof game.global.dailyChallenge.bogged !== 'undefined' || typeof game.global.dailyChallenge.plague !== 'undefined' || typeof game.global.dailyChallenge.pressure !== 'undefined')) fightalways(); + } + if (getPageSetting('BetterAutoFight') == 1) betterAutoFight(); + if (getPageSetting('BetterAutoFight') == 2) betterAutoFight3(); + var forcePrecZ = (getPageSetting('ForcePresZ') < 0) || (game.global.world < getPageSetting('ForcePresZ')); + if (getPageSetting('DynamicPrestige2') > 0 && forcePrecZ) prestigeChanging2(); + else autoTrimpSettings.Prestige.selected = document.getElementById('Prestige').value; + if (game.global.world > 5 && game.global.challengeActive == "Daily" && getPageSetting('avoidempower') == true && typeof game.global.dailyChallenge.empower !== 'undefined' && !game.global.preMapsActive && !game.global.mapsActive && game.global.soldierHealth > 0) avoidempower(); + if (getPageSetting('buywepsvoid') == true && ((getPageSetting('VoidMaps') == game.global.world && game.global.challengeActive != "Daily") || (getPageSetting('DailyVoidMod') == game.global.world && game.global.challengeActive == "Daily")) && game.global.mapsActive && getCurrentMapObject().location == "Void") buyWeps(); + if ((getPageSetting('darmormagic') > 0 && typeof game.global.dailyChallenge.empower == 'undefined' && typeof game.global.dailyChallenge.bloodthirst == 'undefined' && (typeof game.global.dailyChallenge.bogged !== 'undefined' || typeof game.global.dailyChallenge.plague !== 'undefined' || typeof game.global.dailyChallenge.pressure !== 'undefined')) || (getPageSetting('carmormagic') > 0 && (challengeActive("Toxicity") || challengeActive("Nom")))) armormagic(); + + //Stance + if ((getPageSetting('UseScryerStance') == true) || (getPageSetting('scryvoidmaps') == true && game.global.challengeActive != "Daily") || (getPageSetting('dscryvoidmaps') == true && game.global.challengeActive == "Daily")) useScryerStance(); + else if ((getPageSetting('AutoStance') == 3) || (getPageSetting('use3daily') == true && game.global.challengeActive == "Daily")) windStance(); + else if (getPageSetting('AutoStance') == 1) autoStance(); + else if (getPageSetting('AutoStance') == 2) autoStance2(); + + //Spire + if (getPageSetting('ExitSpireCell') > 0 && game.global.challengeActive != "Daily" && getPageSetting('IgnoreSpiresUntil') <= game.global.world && game.global.spireActive) exitSpireCell(); + if (getPageSetting('dExitSpireCell') >= 1 && game.global.challengeActive == "Daily" && getPageSetting('dIgnoreSpiresUntil') <= game.global.world && game.global.spireActive) dailyexitSpireCell(); + if (getPageSetting('SpireBreedTimer') > 0 && getPageSetting('IgnoreSpiresUntil') <= game.global.world) ATspirebreed(); + if (getPageSetting('spireshitbuy') == true && (isActiveSpireAT() || disActiveSpireAT())) buyshitspire(); + + //Raiding + if ((getPageSetting('PraidHarder') == true && getPageSetting('Praidingzone').length > 0 && game.global.challengeActive != "Daily") || (getPageSetting('dPraidHarder') == true && getPageSetting('dPraidingzone').length > 0 && game.global.challengeActive == "Daily")) PraidHarder(); + else { + if (getPageSetting('Praidingzone').length && game.global.challengeActive != "Daily") Praiding(); + if (getPageSetting('dPraidingzone').length && game.global.challengeActive == "Daily") dailyPraiding(); + } + if (((getPageSetting('BWraid') && game.global.challengeActive != "Daily") || (getPageSetting('Dailybwraid') && game.global.challengeActive == "Daily"))) { + BWraiding(); + } + if ((getPageSetting('BWraid') == true || getPageSetting('DailyBWraid') == true) && bwraidon) buyWeps(); + if (game.global.mapsActive && getPageSetting('game.global.universe == 1 && BWraid') == true && game.global.world == getPageSetting('BWraidingz') && getCurrentMapObject().level <= getPageSetting('BWraidingmax')) buyWeps(); + + //Golden + var agu = getPageSetting('AutoGoldenUpgrades'); + var dagu = getPageSetting('dAutoGoldenUpgrades'); + var cagu = getPageSetting('cAutoGoldenUpgrades'); + if (agu && agu != 'Off' && (!game.global.runningChallengeSquared && game.global.challengeActive != "Daily")) autoGoldenUpgradesAT(agu); + if (dagu && dagu != 'Off' && game.global.challengeActive == "Daily") autoGoldenUpgradesAT(dagu); + if (cagu && cagu != 'Off' && game.global.runningChallengeSquared) autoGoldenUpgradesAT(cagu); + } + + //Logic for Universe 2 + if (game.global.universe == 2) { + + //Offline Progress + if (!usingRealTimeOffline) { + RsetScienceNeeded(); + } + + //Heirloom Shield Swap Check + if (shieldEquipped !== game.global.ShieldEquipped.id) HeirloomShieldSwapped(); + + if (!(game.global.challengeActive == "Quest" && game.global.world > 5 && game.global.lastClearedCell < 90 && ([14, 24].indexOf(questcheck()) >= 0))) { + if (getPageSetting('RBuyUpgradesNew') != 0) RbuyUpgrades(); + } + + //RCore + if (getPageSetting('RAutoMaps') > 0 && game.global.mapsUnlocked) RautoMap(); + if (getPageSetting('Rshowautomapstatus') == true) RupdateAutoMapsStatus(); + if (getPageSetting('Rautomapsalways') == true && autoTrimpSettings.RAutoMaps.value != 1) autoTrimpSettings.RAutoMaps.value = 1; + if (getPageSetting('RManualGather2') == 1) RmanualLabor2(); + if (getPageSetting('RTrapTrimps') && game.global.trapBuildAllowed && game.global.trapBuildToggled == false) toggleAutoTrap(); + if (game.global.challengeActive == "Daily" && getPageSetting('buyradony') >= 1 && getDailyHeliumValue(countDailyWeight()) >= getPageSetting('buyradony') && game.global.b >= 100 && !game.singleRunBonuses.heliumy.owned) purchaseSingleRunBonus('heliumy'); + if ((getPageSetting('Rshrine') == true) || (getPageSetting('Rdshrine') == 1) || (getPageSetting('Rdshrine') == 2)) autoshrine(); + + //AB + if (game.stats.highestRadLevel.valueTotal() >= 75 && getPageSetting('RAB') == true) { + if (getPageSetting('RABpreset') == true) ABswitch(); + if (getPageSetting('RABdustsimple') == 1) ABdustsimple(); + else if (getPageSetting('RABdustsimple') == 2) ABdustsimplenonhid(); + if (getPageSetting('RABfarm') == true) ABfarmsave(); + if (getPageSetting('RABfarmswitch') == true) ABfarmswitch(); + if (getPageSetting('RABsolve') == true) ABsolver(); + } + + //RBuildings + if (getPageSetting('RBuyBuildingsNew') == true) { + RbuyBuildings(); + } + + //RJobs + if (!(game.global.challengeActive == "Quest" && game.global.world > 5) && getPageSetting('RBuyJobsNew') == 1) { + RworkerRatios(); + RbuyJobs(); + } else if (!(game.global.challengeActive == "Quest" && game.global.world > 5) && getPageSetting('RBuyJobsNew') == 2) { + RbuyJobs(); + } + if (game.global.challengeActive == "Quest" && game.global.world > 5 && getPageSetting('RBuyJobsNew') > 0) { + RquestbuyJobs(); + } + + //RPortal + if (autoTrimpSettings.RAutoPortal.selected != "Off" && game.global.challengeActive != "Daily" && !game.global.runningChallengeSquared) RautoPortal(); + if (getPageSetting('RAutoPortalDaily') > 0 && game.global.challengeActive == "Daily") RdailyAutoPortal(); + + //RChallenges + if (getPageSetting('Rarchon') == true && game.global.challengeActive == "Archaeology") { + archstring(); + } + + //RCombat + if (getPageSetting('Requipon') == true && (!(game.global.challengeActive == "Quest" && game.global.world > 5 && game.global.lastClearedCell < 90 && ([11, 12, 21, 22].indexOf(questcheck()) >= 0)))) RautoEquip(); + if (getPageSetting('BetterAutoFight') == 1) betterAutoFight(); + if (getPageSetting('BetterAutoFight') == 2) betterAutoFight3(); + if (game.global.world > 5 && game.global.challengeActive == "Daily" && getPageSetting('Ravoidempower') == true && typeof game.global.dailyChallenge.empower !== 'undefined' && !game.global.preMapsActive && !game.global.mapsActive && game.global.soldierHealth > 0) Ravoidempower(); + if (!game.global.fighting) { + if (getPageSetting('Rfightforever') == 0) Rfightalways(); + else if (getPageSetting('Rfightforever') > 0 && RcalcHDratio() <= getPageSetting('Rfightforever')) Rfightalways(); + else if (getPageSetting('Rdfightforever') == 1 && game.global.challengeActive == "Daily" && typeof game.global.dailyChallenge.empower == 'undefined' && typeof game.global.dailyChallenge.bloodthirst == 'undefined' && (typeof game.global.dailyChallenge.bogged !== 'undefined' || typeof game.global.dailyChallenge.plague !== 'undefined' || typeof game.global.dailyChallenge.pressure !== 'undefined')) Rfightalways(); + else if (getPageSetting('Rdfightforever') == 2 && game.global.challengeActive == "Daily" && (typeof game.global.dailyChallenge.bogged !== 'undefined' || typeof game.global.dailyChallenge.plague !== 'undefined' || typeof game.global.dailyChallenge.pressure !== 'undefined')) Rfightalways(); + } + if ((getPageSetting('Rdarmormagic') > 0 && typeof game.global.dailyChallenge.empower == 'undefined' && typeof game.global.dailyChallenge.bloodthirst == 'undefined' && (typeof game.global.dailyChallenge.bogged !== 'undefined' || typeof game.global.dailyChallenge.plague !== 'undefined' || typeof game.global.dailyChallenge.pressure !== 'undefined')) || (getPageSetting('Rcarmormagic') > 0 && (game.global.challengeActive == 'Toxicity' || game.global.challengeActive == 'Nom'))) Rarmormagic(); + if (getPageSetting('Rmanageequality') == true && game.global.fighting) Rmanageequality(); + + //RHeirlooms + if ((getPageSetting('Rhs') == true && game.global.challengeActive != 'Daily') || (getPageSetting('Rdhs') == 2 && game.global.challengeActive == 'Daily')) { + Rheirloomswap(); + } + if (getPageSetting('Rdhs') == 1 && game.global.challengeActive == 'Daily') { + Rdheirloomswap(); + } + + //RGolden + var Ragu = getPageSetting('RAutoGoldenUpgrades'); + var Rdagu = getPageSetting('RdAutoGoldenUpgrades'); + var Rcagu = getPageSetting('RcAutoGoldenUpgrades'); + if (Ragu && Ragu != 'Off' && (!game.global.runningChallengeSquared && game.global.challengeActive != "Daily")) RautoGoldenUpgradesAT(Ragu); + if (Rdagu && Rdagu != 'Off' && game.global.challengeActive == "Daily") RautoGoldenUpgradesAT(Rdagu); + if (Rcagu && Rcagu != 'Off' && game.global.runningChallengeSquared) RautoGoldenUpgradesAT(Rcagu); } - setScienceNeeded(); //determine how much science is needed - - //EXECUTE CORE LOGIC - if (getPageSetting('ExitSpireCell') >0) exitSpireCell(); //"Exit Spire After Cell" (other.js) - if (getPageSetting('WorkerRatios')) workerRatios(); //"Auto Worker Ratios" (jobs.js) - if (getPageSetting('BuyUpgrades')) buyUpgrades(); //"Buy Upgrades" (upgrades.js) - var agu = getPageSetting('AutoGoldenUpgrades'); - if (agu && agu!='Off') autoGoldenUpgradesAT(agu); //"Golden Upgrades" (other.js) - if (getPageSetting('BuyStorage')) buyStorage(); //"Buy Storage" (buildings.js) - if (getPageSetting('BuyBuildings')) buyBuildings(); //"Buy Buildings" (buildings.js) - if (getPageSetting('BuyJobs')) buyJobs(); //"Buy Jobs" (jobs.js) - if (getPageSetting('ManualGather2')<=2) manualLabor(); //"Auto Gather/Build" (gather.js) - else if (getPageSetting('ManualGather2')==3) manualLabor2(); //"Auto Gather/Build #2" (") - getPageSetting('AutoMaps') > 0 ? autoMap() : updateAutoMapsStatus(); //"Auto Maps" (automaps.js) - if (getPageSetting('GeneticistTimer') >= 0) autoBreedTimer(); //"Geneticist Timer" / "Auto Breed Timer" (autobreedtimer.js) - if (autoTrimpSettings.AutoPortal.selected != "Off") autoPortal(); //"Auto Portal" (hidden until level 40) (portal.js) - if (getPageSetting('TrapTrimps') && game.global.trapBuildAllowed && game.global.trapBuildToggled == false) toggleAutoTrap(); //"Trap Trimps" - if (aWholeNewWorld && getPageSetting('AutoRoboTrimp')) autoRoboTrimp(); //"AutoRoboTrimp" (other.js) - if (aWholeNewWorld && getPageSetting('FinishC2')>0 && game.global.runningChallengeSquared) finishChallengeSquared(); // "Finish Challenge2" (other.js) - autoLevelEquipment(); //"Buy Armor", "Buy Armor Upgrades", "Buy Weapons", "Buy Weapons Upgrades" (equipment.js) - if (getPageSetting('UseScryerStance')) useScryerStance(); //"Use Scryer Stance" (scryer.js) - else if (getPageSetting('AutoStance')<=1) autoStance(); //"Auto Stance" (autostance.js) - else if (getPageSetting('AutoStance')==2) autoStance2(); //"Auto Stance #2" (") - if (getPageSetting('UseAutoGen')) autoGenerator(); //"Auto Generator ON" (magmite.js) - ATselectAutoFight(); // pick the right version of Fight/AutoFight/BetterAutoFight/BAF2 (fight.js) - var forcePrecZ = (getPageSetting('ForcePresZ')<0) || (game.global.world0 && forcePrecZ) prestigeChanging2(); //"Dynamic Prestige" (dynprestige.js) - else autoTrimpSettings.Prestige.selected = document.getElementById('Prestige').value; //just make sure the UI setting and the internal setting are aligned. - if (getPageSetting('AutoMagmiteSpender2')==2 && !magmiteSpenderChanged) autoMagmiteSpender(); //Auto Magmite Spender (magmite.js) - if (getPageSetting('AutoNatureTokens')) autoNatureTokens(); //Nature (other.js) - // - //Runs any user provided scripts, see line 253 below - if (userscriptOn) userscripts(); - // - //rinse, repeat, done - return; } -//GUI Updates happen on this thread, every 1000ms function guiLoop() { - updateCustomButtons(); - //MODULESdefault = JSON.parse(JSON.stringify(MODULES)); - //Store the diff of our custom MODULES vars in the localStorage bin. - safeSetItems('storedMODULES', JSON.stringify(compareModuleVars())); - //Swiffy UI/Display tab - if(getPageSetting('EnhanceGrids')) - MODULES["fightinfo"].Update(); - if(typeof MODULES !== 'undefined' && typeof MODULES["performance"] !== 'undefined' && MODULES["performance"].isAFK) - MODULES["performance"].UpdateAFKOverlay(); + updateCustomButtons(), safeSetItems('storedMODULES', JSON.stringify(compareModuleVars())), getPageSetting('EnhanceGrids') && MODULES.fightinfo.Update(), 'undefined' != typeof MODULES && 'undefined' != typeof MODULES.performance && MODULES.performance.isAFK && MODULES.performance.UpdateAFKOverlay() } -//reset stuff that may not have gotten cleaned up on portal function mainCleanup() { lastrunworld = currentworld; currentworld = game.global.world; aWholeNewWorld = lastrunworld != currentworld; - //run once per portal: - if (currentworld == 1 && aWholeNewWorld) { + if (game.global.universe == 1 && currentworld == 1 && aWholeNewWorld) { lastHeliumZone = 0; zonePostpone = 0; - //for the dummies like me who always forget to turn automaps back on after portaling - if(getPageSetting('AutoMaps')==1 && !game.upgrades.Battle.done && getPageSetting('AutoMaps') == 0) - settingChanged("AutoMaps"); - return true; // Do other things + if (getPageSetting('automapsportal') == true && getPageSetting('AutoMaps') == 0 && !game.upgrades.Battle.done) + autoTrimpSettings["AutoMaps"].value = 1; + return true; } + if (game.global.universe == 2 && currentworld == 1 && aWholeNewWorld) { + lastRadonZone = 0; + zonePostpone = 0; + if (getPageSetting('Rautomapsportal') == true && getPageSetting('RAutoMaps') == 0 && !game.upgrades.Battle.done) + autoTrimpSettings["RAutoMaps"].value = 1; + return true; + } + autoTrimpSettings.zonetracker = 1; } -// Userscript loader. write your own! -//Copy and paste this function named userscripts() into the JS Dev console. (F12) -var userscriptOn = true; //controls the looping of userscripts and can be self-disabled -var globalvar0,globalvar1,globalvar2,globalvar3,globalvar4,globalvar5,globalvar6,globalvar7,globalvar8,globalvar9; -//left blank intentionally. the user will provide this. blank global vars are included as an example -function userscripts() -{ - //insert code here: -} - -//test. function throwErrorfromMain() { - throw new Error("We have successfully read the thrown error message out of the main file"); + throw new Error("We have successfully read the thrown error message out of the main file") } + +if (document.getElementById('tooltipDiv').classList.contains('tooltipExtraLg') === false) + document.getElementById('tooltipDiv').style.overflowY = ''; diff --git a/FastPriorityQueue.js b/FastPriorityQueue.js index 37058aaad..b8ddff2d9 100644 --- a/FastPriorityQueue.js +++ b/FastPriorityQueue.js @@ -1,130 +1,11 @@ -/** - * FastPriorityQueue.js : a fast heap-based priority queue in JavaScript. - * (c) the authors - * Licensed under the Apache License, Version 2.0. - * - * Speed-optimized heap-based priority queue for modern browsers and JavaScript engines. - * - * Usage : - Installation (in shell, if you use node): - $ npm install fastpriorityqueue - - Running test program (in JavaScript): - - // var FastPriorityQueue = require("fastpriorityqueue");// in node - var x = new FastPriorityQueue(); - x.add(1); - x.add(0); - x.add(5); - x.add(4); - x.add(3); - x.peek(); // should return 0, leaves x unchanged - x.size; // should return 5, leaves x unchanged - while(!x.isEmpty()) { - console.log(x.poll()); - } // will print 0 1 3 4 5 - */ 'use strict'; - -var defaultcomparator = function(a, b) { - return a < b; -}; - -// the provided comparator function should take a, b and return *true* when a < b -function FastPriorityQueue(comparator) { - this.array = []; - this.size = 0; - this.compare = comparator || defaultcomparator; -} - - -// Add an element the the queue -// runs in O(log n) time -FastPriorityQueue.prototype.add = function(myval) { - var i = this.size; - this.array[this.size++] = myval; - while ( i > 0) { - var p = (i - 1) >> 1; - var ap = this.array[p]; - if(!this.compare(myval, ap )) break; - this.array[i] = ap; - i = p; - } - this.array[i] = myval; -}; - -// replace the content of the heap by provided array and "heapifies it" -FastPriorityQueue.prototype.heapify = function(arr) { - this.array = arr; - this.size = arr.length; - for (var i = (this.size >> 1); i >= 0; i--) { - this._percolateDown(i); - } -}; - -// for internal use -FastPriorityQueue.prototype._percolateUp = function(i) { - var myval = this.array[i]; - while ( i > 0) { - var p = (i - 1) >> 1; - var ap = this.array[p]; - if(!this.compare(myval, ap )) break; - this.array[i] = ap; - i = p; - } - this.array[i] = myval; -}; - - -// for internal use -FastPriorityQueue.prototype._percolateDown = function(i) { - var size = this.size; - var hsize = this.size >>> 1; - var ai = this.array[i]; - while (i < hsize) { - var l = (i << 1) + 1; - var r = l + 1; - var bestc = this.array[l]; - if (r < size) { - if (this.compare(this.array[r], bestc)) { - l = r; - bestc = this.array[r]; - } - } - if (!this.compare(bestc,ai)) { - break; - } - this.array[i] = bestc; - i = l; - } - this.array[i] = ai; -}; - -//Look at the top of the queue (a smallest element) -// executes in constant time -FastPriorityQueue.prototype.peek = function(t) { - return this.array[0]; -}; - -// remove the element on top of the heap (a smallest element) -// runs in logarithmic time -FastPriorityQueue.prototype.poll = function(i) { - var ans = this.array[0]; - if(this.size > 1) { - this.array[0] = this.array[--this.size]; - this._percolateDown(0 | 0); - } - else if (this.size == 0) --this.size; - return ans; -}; - - -// recover unused memory (for long-running priority queues) -FastPriorityQueue.prototype.trim = function() { - this.array = this.array.slice(0,this.size); -}; - -// Check whether the heap is empty -FastPriorityQueue.prototype.isEmpty = function(i) { - return this.size == 0; -}; \ No newline at end of file +var defaultcomparator=function(a,b){return a>1,d=this.array[c];if(!this.compare(a,d))break;this.array[b]=d,b=c}this.array[b]=a}; +FastPriorityQueue.prototype.heapify=function(a){this.array=a,this.size=a.length;for(var b=this.size>>1;0<=b;b--)this._percolateDown(b)}; +FastPriorityQueue.prototype._percolateUp=function(a){for(var b=this.array[a];0>1,d=this.array[c];if(!this.compare(b,d))break;this.array[a]=d,a=c}this.array[a]=b}; +FastPriorityQueue.prototype._percolateDown=function(a){for(var b=this.size,c=this.size>>>1,d=this.array[a];aDISCLAIMER: Takes quite a long time to generate.\")\' onmouseout=\'tooltip(\"hide\")\'>Export your Graph Database\ -
\ -
\ -
'; -//TODO: make the overall hover tooltip better and seperate individual help into each button tooltip. -document.getElementById("graphFooterLine2").innerHTML += '\ -Tips: Hover for usage tips.\ -\ -Try to Remember Which Portals are Selected when switching between Graphs:\ -\ -Black Graphs:'; -//handle the locking mechanism checkbox for the Clear all previous data button: -function toggleClearButton() { - document.getElementById('clrAllDataBtn').disabled=!document.getElementById('clrChkbox').checked; + +// Save Portal Data to history, or current only +function savePortalData(saveAll = true) { + var currentPortal = getportalID(); + if (saveAll) { + safeLocalStorage("portalDataHistory", LZString.compressToBase64(JSON.stringify(portalSaveData))) + } + else { + let portalObj = {} + portalObj[currentPortal] = portalSaveData[currentPortal]; + safeLocalStorage("portalDataCurrent", portalObj) + } } -//Dark graphs by Unihedron -//game.options.menu.darkTheme.enabled == 2 (also ok 0==black) -// if (MODULES["graphs"].useDarkAlways) - // addDarkGraphs(); -//Theme Changer is below -function addDarkGraphs() { - var $oldlink = document.getElementById("dark-graph.css"); - if ($oldlink) return; - var $link = document.createElement('link'); - $link.rel = "stylesheet"; - $link.type = "text/css"; - $link.id = 'dark-graph.css'; - //basepath ref comes from the userscripts - $link.href = basepath + 'dark-graph.css'; - document.head.appendChild($link); - debug("Adding dark-graph.css file","graphs"); +// Save settings, with or without updating a key +function saveSetting(key, value) { + if (key !== null && value !== null) GRAPHSETTINGS[key] = value; + safeLocalStorage("GRAPHSETTINGS", GRAPHSETTINGS); } -function removeDarkGraphs() { - var $link = document.getElementById("dark-graph.css"); - if (!$link) return; - document.head.removeChild($link); - debug("Removing dark-graph.css file","graphs"); + +// returns _d _h _m _s or _._s +function formatDuration(timeSince) { + let timeObj = { + d: Math.floor(timeSince / 86400), + h: Math.floor(timeSince / 3600) % 24, + m: Math.floor(timeSince / 60) % 60, + s: Math.floor(timeSince % 60), + } + let milliseconds = Math.floor(timeSince % 1 * 10) + let timeString = ""; + let unitsUsed = 0 + for (const [unit, value] of Object.entries(timeObj)) { + if (value === 0 && timeString === "") continue; + unitsUsed++; + if (value) timeString += value.toString() + unit + " "; + } + if (unitsUsed <= 1) { + timeString = [timeObj.s.toString().padStart(1, "0"), milliseconds.toString(), "s"].join("."); + } + return timeString } -function toggleDarkGraphs() { - if (game) { - var $link = document.getElementById("dark-graph.css"); - var blackCB = document.getElementById('blackCB').checked; - if ((!$link && (game.options.menu.darkTheme.enabled == 0 || game.options.menu.darkTheme.enabled == 2)) || MODULES["graphs"].useDarkAlways || blackCB) - addDarkGraphs(); - else if ($link && (game.options.menu.darkTheme.enabled == 1 || game.options.menu.darkTheme.enabled == 3 || !blackCB)) - removeDarkGraphs(); + +function loadGraphData() { + var loadedData = LZString.decompressFromBase64(localStorage.getItem("portalDataHistory")); + var currentPortal = JSON.parse(localStorage.getItem("portalDataCurrent")); + if (loadedData != "") { + var loadedData = JSON.parse(loadedData); + if (currentPortal) { loadedData[Object.keys(currentPortal)[0]] = Object.values(currentPortal)[0] } + console.log("Graphs: Found portalSaveData") + // remake object structure + for (const [portalID, portalData] of Object.entries(loadedData)) { + portalSaveData[portalID] = new Portal(); + for (const [k, v] of Object.entries(portalData)) { + portalSaveData[portalID][k] = v; + } } -} -//Runs once on startup to color the graph footer elements Black. -//Then every time the theme is changed. Called out of updateCustomButtons() loop in SettingsGUI. -var lastTheme=-1; -MODULES["graphs"].themeChanged = function() { - //Everything else in Settings, (for now: all Inputs, Dropdowns) - if (game && game.options.menu.darkTheme.enabled != lastTheme) { - //GRAPHS: - toggleDarkGraphs(); - debug("Theme change - AutoTrimps styles updating..."); - function color1(el,i,arr) { - if(game.options.menu.darkTheme.enabled != 2) - el.style.color = "black"; - else - el.style.color = ""; - }; - //GRAPHS: - function color2(el,i,arr) { - if (el.id == 'graphSelection') { - if(game.options.menu.darkTheme.enabled != 2) - el.style.color = "black"; - return; - } - }; - var inpts1 = document.getElementsByTagName("input"); - var drops2 = document.getElementsByTagName("select"); - var footer3 = document.getElementById("graphFooterLine1").children; - for (let el of inpts1) { color1(el); }; - for (let el of drops2) { color1(el); }; - for (let el of footer3) { color1(el); }; - for (let el of footer3) { color2(el); }; + } + var loadedSettings = JSON.parse(localStorage.getItem("GRAPHSETTINGS")); + if (loadedSettings !== null) { + for (const [k, v] of Object.entries(loadedSettings)) { + GRAPHSETTINGS[k] = v; } - if (game) - lastTheme = game.options.menu.darkTheme.enabled; -}; -MODULES["graphs"].themeChanged(); - - -function GraphsImportExportTooltip(what, isItIn, event) { - if (game.global.lockTooltip) - return; - var elem = document.getElementById("tooltipDiv"); - swapClass("tooltipExtra", "tooltipExtraNone", elem); - var ondisplay = null; // if non-null, called after the tooltip is displayed - var tooltipText; - var costText = ""; - if (what == "ExportGraphs"){ - tooltipText = "This is your GRAPH DATABASE save string. There are many like it but this one is yours. Save this save somewhere safe so you can save time next time.

"; - costText = "
Got it
"; - if (document.queryCommandSupported('copy')){ - costText += "
Copy to Clipboard
"; - ondisplay = function(){ - document.getElementById('exportArea').select(); - document.getElementById('clipBoardBtn').addEventListener('click', function(event) { - document.getElementById('exportArea').select(); - try { - document.execCommand('copy'); - } catch (err) { - document.getElementById('clipBoardBtn').innerHTML = "Error, not copied"; - } - }); - }; - } - else { - ondisplay = function(){ - document.getElementById('exportArea').select(); - }; - } - costText += "
"; + } + // initialize save space for the toggles + if (GRAPHSETTINGS.toggles == null) GRAPHSETTINGS.toggles = {}; + for (const graph of graphList) { + if (graph.toggles) { + if (GRAPHSETTINGS.toggles[graph.id] === undefined) { GRAPHSETTINGS.toggles[graph.id] = {} } + graph.toggles.forEach((toggle) => { + if (GRAPHSETTINGS.toggles[graph.id][toggle] === undefined) { GRAPHSETTINGS.toggles[graph.id][toggle] = false } + }) } - if (what == "ImportGraphs"){ - //runs the loadGraphs() function. - tooltipText = "Replaces your GRAPH DATABASE with this save string! It'll be fine, I promise.

"; - costText="
Import
Cancel
"; - ondisplay = function () { - document.getElementById('importBox').focus(); - }; + } + GRAPHSETTINGS.open = false; + MODULES.graphs = {} + MODULES.graphs.useDarkAlways = false +} + +function clearData(keepN, clrall = false) { + let changed = false; + let currentPortalNumber = getTotalPortals(); + if (clrall) { + for (const [portalID, portalData] of Object.entries(portalSaveData)) { + if (portalData.totalPortals != currentPortalNumber) { + delete portalSaveData[portalID]; + changed = true; + } } - if (what == "AppendGraphs"){ - //runs the appendGraphs() function. - tooltipText = "Appends to your GRAPH DATABASE with this save string (combines them)! It'll be fine, I hope.

"; - costText="
Import
Cancel
"; - ondisplay = function () { - document.getElementById('importBox').focus(); - }; + } else { + let totalSaved = Object.keys(portalSaveData).length; + for (const [portalID, portalData] of Object.entries(portalSaveData)) { + if (totalSaved > keepN && portalData.totalPortals <= currentPortalNumber - keepN) { + delete portalSaveData[portalID]; + totalSaved--; + changed = true; + } } - game.global.lockTooltip = true; - elem.style.left = "33.75%"; - elem.style.top = "25%"; - document.getElementById("tipTitle").innerHTML = what; - document.getElementById("tipText").innerHTML = tooltipText; - document.getElementById("tipCost").innerHTML = costText; - elem.style.display = "block"; - if (ondisplay !== null) - ondisplay(); + } + if (changed) { + savePortalData(true) + showHideUnusedGraphs(); + } } -//function to take the text string, and use it to load and overwrite your saved data (for graphs) -function loadGraphs() { - var thestring = document.getElementById("importBox").value.replace(/(\r\n|\n|\r|\s)/gm,""); - var tmpset = JSON.parse(thestring); - if (tmpset == null) - return; - //should have done more error checking with at least an error message. - allSaveData = tmpset; - //refresh - drawGraph(); +function deleteSpecific() { + let portalNum = Number(document.getElementById("deleteSpecificTextBox").value); + if (parseInt(portalNum) < 0) { clearData(Math.abs(portalNum)); } + else { + for (const [portalID, portalData] of Object.entries(portalSaveData)) { + if (portalData.totalPortals === portalNum) delete portalSaveData[portalID]; + } + } + savePortalData(true) + showHideUnusedGraphs(); } -//function to take the text string, and use it to load and append your saved data (for graphs) to the old database -function appendGraphs() { - //currently overwrites: - /* - var thestring = document.getElementById("importBox").value.replace(/(\r\n|\n|\r|\s)/gm,""); - var tmpset = JSON.parse(thestring); - if (tmpset == null) - return; - //should have done more error checking with at least an error message. - allSaveData = tmpset; - */ - //refresh - drawGraph(); +// Custom Function Helpers +// diff between x and x-1, or x and initial +function diff(dataVar, initial) { + return function (portal, i) { + let e1 = portal.perZoneData[dataVar][i]; + let e2 = initial ? initial : portal.perZoneData[dataVar][i - 1]; + if (e1 === null || e2 === null) return null; + return e1 - e2 + } } -//Remember Checkbox -var rememberSelectedVisible = []; -function saveSelectedGraphs() { - rememberSelectedVisible = []; - for (var i=0; i < chart1.series.length; i++){ - var run = chart1.series[i]; - rememberSelectedVisible[i] = run.visible; - } -} -function applyRememberedSelections() { - for (var i=0; i < chart1.series.length; i++){ - var run = chart1.series[i]; - if (rememberSelectedVisible[i] == false) - run.hide(); - } +const formatters = { + datetime: function () { + let ser = this.series; + return ' ' + ser.name + ": " + formatDuration(this.y / 1000) + "
"; + }, + defaultPoint: function () { + var ser = this.series; // 'this' being the highcharts object that uses formatter() + return ' ' + ser.name + ": " + prettify(this.y) + "
"; + }, + defaultAxis: function () { + // These are Trimps format functions for durations(modified) and numbers, respectively + if (this.dateTimeLabelFormat) return formatDuration(this.value / 1000) + else return prettify(this.value); + } } -//Invert graph selections -function toggleSpecificGraphs() { - for (var i=0; i < chart1.series.length; i++){ - var run = chart1.series[i]; - run.visible ? run.hide() : run.show(); - } +function last(arr) { + return arr[arr.length - 1] } -//Turn all graphs on/off (to the opposite of which one we are closer to) -function toggleAllGraphs() { - var count = 0; - for (var i=0; i < chart1.series.length; i++){ - var run = chart1.series[i]; - if (run.visible) - count++; - } - for (var i=0; i < chart1.series.length; i++){ - var run = chart1.series[i]; - if (count > chart1.series.length/2) - run.hide(); - else - run.show(); +// --------- User Interface --------- + +// Create all of the UI elements and load in scripts needed +// TODO reduce screaming +function createUI() { + var head = document.getElementsByTagName("head")[0] + + var chartscript = document.createElement("script"); + chartscript.type = "text/javascript"; + chartscript.src = "https://code.highcharts.com/highcharts.js"; + head.appendChild(chartscript); + + var graphsButton = document.createElement("TD"); + graphsButton.appendChild(document.createTextNode("Graphs")) + graphsButton.setAttribute("class", "btn btn-default") + graphsButton.setAttribute("onclick", "escapeATWindows(false); drawGraph(); swapGraphUniverse();"); + + var settingbarRow = document.getElementById("settingsTable").firstElementChild.firstElementChild; + settingbarRow.insertBefore(graphsButton, settingbarRow.childNodes[10]) + + document.getElementById("settingsRow").innerHTML += ` + + `; + + function createSelector(id, sourceList, textMod = "", onchangeMod = "") { + let selector = document.createElement("select"); + selector.id = id; + selector.setAttribute("style", ""); + selector.setAttribute("onchange", "saveSetting(this.id, this.value); drawGraph();" + onchangeMod); + for (var item of sourceList) { + let opt = document.createElement("option"); + opt.value = item; + opt.text = textMod + item; + selector.appendChild(opt); } -} + selector.value = GRAPHSETTINGS[selector.id] + return selector; + } -function clearData(portal,clrall) { - //clear data of runs with portalnumbers prior than X (15) away from current portal number. (or 0 = clear all) - if(!portal) - portal = 0; - if (!clrall) { - while(allSaveData[0].totalPortals < game.global.totalPortals - portal) { - allSaveData.shift(); - } - } else { - while(allSaveData[0].totalPortals != game.global.totalPortals) { - allSaveData.shift(); - } + // Create Universe and Graph selectors + var universeFooter = document.getElementById("graphFooterLine1"); + [ + ["universeSelection", [1, 2], "Universe ", " swapGraphUniverse();"], + ["u1graphSelection", graphList.filter((g) => g.universe == 1 || !g.universe).map((g) => g.selectorText)], + ["u2graphSelection", graphList.filter((g) => g.universe == 2 || !g.universe).map((g) => g.selectorText)] + ].forEach((opts) => universeFooter.appendChild(createSelector(...opts))) + + universeFooter.innerHTML += ` +
+
+
+
+
+
+
+
+
+
` + + // AAAAAAAAAAAAAAAAAAAAAAAAAAAA (Setting the inner HTML of the parent element resets the value of these? what the fuck) + document.querySelector("#universeSelection").value = GRAPHSETTINGS.universeSelection + document.querySelector("#u1graphSelection").value = GRAPHSETTINGS.u1graphSelection + document.querySelector("#u2graphSelection").value = GRAPHSETTINGS.u2graphSelection + + let tipsText = "You can zoom by dragging a box around an area. You can turn portals off by clicking them on the legend. Quickly view the last portal by clicking it off, then Invert Selection. Or by clicking All Off, then clicking the portal on. To delete a portal, Type its portal number in the box and press Delete Specific. Using negative numbers in the Delete Specific box will KEEP that many portals (starting counting backwards from the current one), ie: if you have Portals 1000-1015, typing -10 will keep 1005-1015." + document.getElementById("graphFooterLine2").innerHTML += ` + Tips: Hover for usage tips. + Live Updates + Show Portals + + Black Graphs: + `; + + // Add a header with negative float hanging down on the top of the graph, for toggle buttons + var toggleDiv = document.createElement("div"); + toggleDiv.id = "toggleDiv"; + toggleDiv.setAttribute("style", "position: absolute; top: 1rem; left: 3rem; z-index: 1;") + toggleDiv.innerText = "" + document.querySelector("#graphParent").appendChild(toggleDiv); + + + // Handle Dark Graphs? Old code + MODULES.graphs.themeChanged = function () { + if (game && game.options.menu.darkTheme.enabled != lastTheme) { + function f(h) { + h.style.color = 2 == game.options.menu.darkTheme.enabled ? "" : "black"; + } + function g(h) { + if ("graphSelection" == h.id) return void (2 != game.options.menu.darkTheme.enabled && (h.style.color = "black")); + } + toggleDarkGraphs(); + var c = document.getElementsByTagName("input"); + var d = document.getElementsByTagName("select"); + var e = document.getElementById("graphFooterLine1").children; + for (let h of c) f(h); + for (let h of d) f(h); + for (let h of e) f(h); + for (let h of e) g(h); } + game && (lastTheme = game.options.menu.darkTheme.enabled); + } + + MODULES.graphs.themeChanged(); + document.querySelector("#blackCB").checked = GRAPHSETTINGS.darkTheme; + document.querySelector("#portalCountTextBox").value = GRAPHSETTINGS.portalsDisplayed; } -//delete a specific portal number's graphs. use negative numbers to keep that many portals. -function deleteSpecific() { - var txtboxvalue = document.getElementById('deleteSpecificTextBox').value; - if (txtboxvalue == "") - return; - if (parseInt(txtboxvalue) < 0) { - clearData(Math.abs(txtboxvalue)); - } else { - for (var i = allSaveData.length-1; i >= 0; i--) { - if (allSaveData[i].totalPortals == txtboxvalue) - allSaveData.splice(i, 1); - } - } +// Show/hide the universe-specific graph selectors +function swapGraphUniverse() { + let universe = GRAPHSETTINGS.universeSelection; + let active = `u${universe}` + let inactive = `u${universe == 1 ? 2 : 1}` + document.getElementById(`${active}graphSelection`).style.display = ''; + document.getElementById(`${inactive}graphSelection`).style.display = 'none'; } -function addGraphNoteLabel() { - debug("GOTCHA This feature is not actually written, yet..."); +function toggleClearButton() { + document.getElementById("clrAllDataBtn").disabled = !document.getElementById("clrChkbox").checked; } -function autoToggleGraph() { - if (game.options.displayed) toggleSettingsMenu(); - var $item = document.getElementById('autoSettings'); - if ($item) { - if ($item.style.display === 'block') $item.style.display = 'none'; +function toggleDarkGraphs() { + function removeDarkGraphs() { + var darkcss = document.getElementById("dark-graph.css"); + darkcss && (document.head.removeChild(darkcss), debug("Removing dark-graph.css file", "graphs")); + } + function addDarkGraphs() { + var darkcss = document.getElementById("dark-graph.css"); + if (!darkcss) { + var b = document.createElement("link"); + (b.rel = "stylesheet"), (b.type = "text/css"), (b.id = "dark-graph.css"), (b.href = basepath + "dark-graph.css"), document.head.appendChild(b), debug("Adding dark-graph.css file", "graphs"); } - var $item = document.getElementById('autoTrimpsTabBarMenu'); - if ($item) { - if ($item.style.display === 'block') $item.style.display = 'none'; + } + if (game) { + var darkcss = document.getElementById("dark-graph.css") + var dark = document.getElementById("blackCB").checked; + saveSetting("darkTheme", !dark) + if ((!darkcss && (0 == game.options.menu.darkTheme.enabled || 2 == game.options.menu.darkTheme.enabled)) || MODULES.graphs.useDarkAlways || dark) { + addDarkGraphs() } - var $graph = document.getElementById('graphParent'); - if ($graph.style.display === 'block') $graph.style.display = 'none'; else { - $graph.style.display = 'block'; - setGraph(); + if (darkcss && (1 == game.options.menu.darkTheme.enabled || 3 == game.options.menu.darkTheme.enabled || !dark)) { + removeDarkGraphs(); + } } + } } -function escapeATWindows() { - var $tooltip = document.getElementById("tooltipDiv"); - if ($tooltip.style.display != 'none') { - cancelTooltip(); - return; +// Toggle AT windows with UI, or force close with Esc +function escapeATWindows(escPressed = true) { + var a = document.getElementById("tooltipDiv"); + if (a.style.display != "none") return void cancelTooltip(); // old code, uncertain what it's for or why it's here. + for (elemId of ["autoSettings", "autoTrimpsTabBarMenu", "graphParent"]) { + var elem = document.getElementById(elemId); + if (!elem) continue; + if (elemId === "graphParent") { // toggle Graphs window + var open = elem.style.display === "block"; + if (escPressed) open = true; // override to always close + elem.style.display = open ? "none" : "block"; + GRAPHSETTINGS.open = !open; + trimpStatsDisplayed = !open; // HACKS disable hotkeys without touching Trimps settings } - //Turn off "Settings"/"AutoTrimpsSettings"/"Graphs" Menu on escape. - if (game.options.displayed) toggleSettingsMenu(); - var $item = document.getElementById('autoSettings'); - if ($item.style.display === 'block') $item.style.display = 'none'; - var $item = document.getElementById('autoTrimpsTabBarMenu'); - if ($item.style.display === 'block') $item.style.display = 'none'; - var $graph = document.getElementById('graphParent'); - if ($graph.style.display === 'block') $graph.style.display = 'none'; -} -document.addEventListener("keydown",function (event) { - //Hotkeys have to be enabled, and all these conditions have to be met or else we cant use the hotkey. - if (game.options.menu.hotkeys.enabled == 1 && !game.global.preMapsActive && !game.global.lockTooltip && !ctrlPressed && !heirloomsShown && event.keyCode == 27) //27 == escape - escapeATWindows(); - //TODO this currently escapes out of both tooltips and the settings and its already checking for locked tooltips. Maybe if there IS a tooltip open we should just close that first. - //Turn off "Settings"/"AutoTrimpsSettings"/"Graphs" Menu on escape. -}, true); - - -function getTotalDarkEssenceCount() { - var purchased = 10 * (Math.pow(3, countPurchasedTalents()) - 1) / (3 - 1); - return game.global.essence + purchased; + else { elem.style.display = "none"; } // close other windows + } } -function pushData() { - debug('Starting Zone ' + game.global.world, "graphs"); - //helium/hour % of totalHE, and currentRun/totalLifetime HE - var getPercent = (game.stats.heliumHour.value() / (game.global.totalHeliumEarned - (game.global.heliumLeftover + game.resources.helium.owned)))*100; - var lifetime = (game.resources.helium.owned / (game.global.totalHeliumEarned-game.resources.helium.owned))*100; - - allSaveData.push({ - totalPortals: game.global.totalPortals, - heliumOwned: game.resources.helium.owned, - currentTime: new Date().getTime(), - portalTime: game.global.portalTime, - world: game.global.world, - challenge: game.global.challengeActive, - voids: game.global.totalVoidMaps, - heirlooms: {"value": game.stats.totalHeirlooms.value, "valueTotal":game.stats.totalHeirlooms.valueTotal}, - nullifium: recycleAllExtraHeirlooms(true), - gigas: game.upgrades.Gigastation.done, - gigasleft: game.upgrades.Gigastation.allowed - game.upgrades.Gigastation.done, - trimps: game.resources.trimps.realMax(), - coord: game.upgrades.Coordination.done, - lastwarp: game.global.lastWarp, - essence: getTotalDarkEssenceCount(), - hehr: getPercent.toFixed(4), - helife: lifetime.toFixed(4), - overkill: GraphsVars.OVKcellsInWorld, - zonetime: GraphsVars.ZoneStartTime, - mapbonus: GraphsVars.MapBonus, - magmite: game.global.magmite, - magmamancers: game.jobs.Magmamancer.owned, - fluffy: game.global.fluffyExp, - nursery: game.buildings.Nursery.purchased - }); - //only keep 15 portals worth of runs to prevent filling storage - clearData(15); - safeSetItems('allSaveData', JSON.stringify(allSaveData)); -} +// Listen for Esc key presses, somehow. This is ancient eldritch mess, but it works? +document.addEventListener( + "keydown", + function (a) { + 1 != game.options.menu.hotkeys.enabled || game.global.preMapsActive || game.global.lockTooltip + || ctrlPressed || heirloomsShown || 27 != a.keyCode || escapeATWindows(); + }, + true +); -//TODO: Cloud Analytics - Experimental function to start tracking graphing data on the cloud server. -// we want this to be small so we don't transmit the whole 10MB graph-data. -var graphAnal = []; -function trackHourlyGraphAnalytics() { - graphAnal.push({ - currentTime: new Date().getTime(), - totalPortals: game.global.totalPortals, - heliumOwned: game.resources.helium.owned, - highzone: game.global.highestLevelCleared, - bones: game.global.b - //ratio: document.getElementById("ratioPreset").value - }); - safeSetItems('graphAnal', JSON.stringify(graphAnal)); -} -//Run once. -trackHourlyGraphAnalytics(); -//then set Timer loop for 1 hour; -setInterval(trackHourlyGraphAnalytics, 3600000); - -function initializeData() { - //initialize fresh with a blank array if needed - if (allSaveData === null) { - allSaveData = []; - } - //fill the array with the first data point - if (allSaveData.length === 0) { - pushData(); - } -} +// --------- Graph handling --------- -var GraphsVars = {}; -function InitGraphsVars() { - GraphsVars.currentPortal = 0; - GraphsVars.OVKcellsInWorld = 0; - GraphsVars.lastOVKcellsInWorld = 0; - GraphsVars.currentworld = 0; - GraphsVars.lastrunworld = 0; - GraphsVars.aWholeNewWorld = false; - GraphsVars.lastZoneStartTime = 0; - GraphsVars.ZoneStartTime = 0; - GraphsVars.MapBonus = 0; - GraphsVars.aWholeNewPortal = 0; - GraphsVars.currentPortal = 0; -} -InitGraphsVars(); +function Graph(dataVar, universe, selectorText, additionalParams = {}) { + // graphTitle, customFunction, useAccumulator, xTitle, yTitle, formatter, xminFloor, yminFloor, yType + this.dataVar = dataVar + this.universe = universe; // false, 1, 2 + this.selectorText = selectorText ? selectorText : dataVar; + this.id = selectorText.replace(/ /g, "_") + this.graphTitle = this.selectorText; + this.graphType = "line" + this.customFunction; + this.useAccumulator; + this.xTitle = "Zone"; + this.yTitle = this.selectorText; + this.formatter = formatters.defaultPoint; + this.xminFloor = 1; + this.yminFloor; + this.yType = "Linear"; + this.graphData = []; + this.typeCheck = "number" + this.conditional = () => { return true }; + for (const [key, value] of Object.entries(additionalParams)) { + this[key] = value; + } + this.baseGraphTitle = this.graphTitle; -//main function of the graphs script - runs every second. -function gatherInfo() { - //dont push updates if the game is paused. fix import on pause Clear Time problem - if (game.options.menu.pauseGame.enabled) return; - //make sure data structures are ready - initializeData(); - //Track portal. - GraphsVars.aWholeNewPortal = GraphsVars.currentPortal != game.global.totalPortals; - if (GraphsVars.aWholeNewPortal) { - GraphsVars.currentPortal = game.global.totalPortals; - //clear filtered loot data upon portaling. < 5 check to hopefully throw out bone portal shenanigans - filteredLoot = { - 'produced': {metal: 0, wood: 0, food: 0, gems: 0}, - 'looted': {metal: 0, wood: 0, food: 0, gems: 0} + // create an object to pass to Highcharts.Chart + this.createHighChartsObj = function () { + return { + chart: { + renderTo: "graph", + zoomType: "xy", + animation: false, + resetZoomButton: { + position: { + align: "right", + verticalAlign: "top", + x: -20, + y: 15, + }, + relativeTo: "chart", + }, + }, + colors: ["#e60049", "#0bb4ff", "#50e991", "#e6d800", "#9b19f5", "#ffa300", "#dc0ab4", "#b3d4ff", "#00bfa0"], + title: { + text: this.graphTitle, + x: -20, + }, + plotOptions: { + series: { + lineWidth: 1, + animation: false, + marker: { + enabled: false, + }, + }, + }, + xAxis: { + floor: this.xminFloor, + title: { + text: this.xTitle, + }, + }, + yAxis: { + floor: this.yminFloor, + title: { + text: this.yTitle, + }, + plotLines: [ + { + value: 0, + width: 1, + color: "#808080", + }, + ], + type: this.yType, + labels: { + formatter: formatters.defaultAxis + }, + endOnTick: false, + maxPadding: .05, + }, + tooltip: { + pointFormatter: this.formatter, + }, + legend: { + layout: "vertical", + align: "right", + verticalAlign: "middle", + borderWidth: 0, + }, + series: this.graphData, + additionalParams: {}, + } + } + // Main Graphing function + this.updateGraph = function () { + var HighchartsObj; + if (this.graphType == "line") HighchartsObj = this.lineGraph(); + if (this.graphType == "column") HighchartsObj = this.columnGraph(); + saveSelectedGraphs(); + chart1 = new Highcharts.Chart(HighchartsObj); + applyRememberedSelections(); + } + // prepares data series for Highcharts, and optionally transforms it with toggled options, customFunction and useAccumulator + this.lineGraph = function () { + var highChartsObj = this.createHighChartsObj() // make default object, to be customized as needed + var item = this.dataVar; + this.graphData = []; + this.useAccumulator = false; // HACKS ( only one set of graphs uses an accumulator and it's on a toggle ) + var maxS3 = Math.max(...Object.values(portalSaveData).map((portal) => portal.s3).filter((s3) => s3)); + var activeToggles = []; + if (this.toggles) { + // Modify the chart area based on the toggles active + activeToggles = Object.keys(toggledGraphs).filter(toggle => GRAPHSETTINGS.toggles[this.id][toggle]) + activeToggles.forEach(toggle => toggledGraphs[toggle].graphMods(this, highChartsObj)); // + } + // parse data per portal + let portalCount = 0; + for (const portal of Object.values(portalSaveData).reverse()) { + if (!(item in portal.perZoneData)) continue; // ignore blank + if (portal.universe != GRAPHSETTINGS.universeSelection) continue; // ignore inactive universe + let cleanData = []; + // parse the requested datavar + for (const index in portal.perZoneData[item]) { + let x = portal.perZoneData[item][index]; + let time = portal.perZoneData.currentTime[index]; + if (typeof this.customFunction === "function") { + x = this.customFunction(portal, index); + if (x < 0) x = null; } + // TOGGLES + if (activeToggles.includes("perZone")) { // must always be first + [x, time] = toggledGraphs.perZone.customFunction(portal, item, index, x); + } + for (toggle of activeToggles.filter(x => x != "perZone")) { + try { x = toggledGraphs[toggle].customFunction(portal, item, index, x, time, maxS3); } + catch (e) { + x = 0; + debug(`Error graphing data on: ${item} ${toggle}, ${e.message}`) + } + } + if (this.useAccumulator) { x += last(cleanData) !== undefined ? last(cleanData)[1] : 0; } + if (this.typeCheck && typeof x != this.typeCheck) x = null; + cleanData.push([Number(index), x]) // highcharts expects number, number, not str, number + } + if (activeToggles.includes("perZone") && ["fluffy", "scruffy"].includes(item)) { + cleanData.splice(cleanData.length - 1); // current zone is too erratic to include due to weird order of granting fluffy exp + } + this.graphData.push({ + name: `Portal ${portal.totalPortals}: ${portal.challenge}`, + data: cleanData, + }) + portalCount++; + if (portalCount >= GRAPHSETTINGS.portalsDisplayed) break; } - //Track zone. - GraphsVars.aWholeNewWorld = GraphsVars.currentworld != game.global.world; - if (GraphsVars.aWholeNewWorld) { - GraphsVars.currentworld = game.global.world; - //if we have reached a new zone, push a new data point (main) - if (allSaveData.length > 0 && allSaveData[allSaveData.length - 1].world != game.global.world) { - pushData(); + this.graphData = this.graphData.reverse(); + highChartsObj.series = this.graphData; + return highChartsObj; + } + // prepares multi-column data series from per-portal data. + this.columnGraph = function () { + var highChartsObj = this.createHighChartsObj() // make default object, to be customized as needed + highChartsObj.xAxis.title.text = "Portal" + highChartsObj.plotOptions.series = { groupPadding: .2, pointPadding: 0, animation: false, } + // set up axes for each column so they scale independently + var activeColumns = this.columns.filter(column => !(column.universe && column.universe != GRAPHSETTINGS.universeSelection)); + if (GRAPHSETTINGS.toggles[this.id].perHr) { // disable time when comparing things over time. x/x is not interesting data. + toggledGraphs.perHr.graphMods(false, highChartsObj) + activeColumns = activeColumns.filter(column => column.dataVar !== "currentTime") + } + // all of the yaxes showing is just visual noise, all invisible hurts me, but I have no good alternatives + var axes = activeColumns.map(column => { return { visible: false, endOnTick: false } }); + + this.graphData = []; + var yAxis = 0; + for (const column of activeColumns) { + let cleanData = [] + for (const portal of Object.values(portalSaveData)) { + if (portal.universe != GRAPHSETTINGS.universeSelection) continue; + let data; + if (portal[column.dataVar]) data = portal[column.dataVar]; + if (portal.perZoneData[column.dataVar]) data = last(portal.perZoneData[column.dataVar]); + if (column.customFunction) data = column.customFunction(portal, data); + if (GRAPHSETTINGS.toggles[this.id].perHr) { // HACKS a headache for future me if other toggles are wanted here. + data = data / (last(portal.perZoneData.currentTime) / 3600000); } - //reset stuff,prepare tracking variables. - GraphsVars.OVKcellsInWorld = 0; - GraphsVars.ZoneStartTime = 0; - GraphsVars.MapBonus = 0; + cleanData.push([portal.totalPortals, data]) + } + let series = { + name: column.title, + data: cleanData, + type: "column", + yAxis: yAxis, + color: column.color, + } + if (column.dataVar === "currentTime") { // HACKS override formatter for time vars + series["tooltip"] = { "pointFormatter": formatters.datetime } + } + this.graphData.push(series); + yAxis += 1; } - //Overkill cell tracking: - if (game.options.menu.overkillColor.enabled == 0) toggleSetting('overkillColor'); //make sure the setting is on. - //Detecting the liquification through liquimp - Crude attempt at this, need to store/track more data. - if (game.options.menu.liquification.enabled && game.talents.liquification.purchased && !game.global.mapsActive && game.global.gridArray && game.global.gridArray[0] && game.global.gridArray[0].name == "Liquimp") - GraphsVars.OVKcellsInWorld = 100; - //if (game.stats.zonesLiquified.value > oldzonesLiquified) //may come in handy; goes up by 1 each zone you liqui-kill. - else - //track how many overkill world cells we have beaten in the current level. (game.stats.cellsOverkilled.value for the entire run) - GraphsVars.OVKcellsInWorld = document.getElementById("grid").getElementsByClassName("cellColorOverkill").length; - //track time in each zone for better graphs - GraphsVars.ZoneStartTime = new Date().getTime() - game.global.zoneStarted; - //track MapBonus - GraphsVars.MapBonus = game.global.mapBonus; -} -var dataBase = {} -var databaseIndexEntry = { - Index: 0, - Portal: 0, - Challenge: 0, - World: 0 + highChartsObj.yAxis = axes; + highChartsObj.series = this.graphData; + return highChartsObj; + } } -var databaseDirtyEntry = { - State: false, - Reason: "", - Index: -1 + +function lookupGraph(selectorText) { + for (const graph of graphList) { + if (graph.selectorText === selectorText) return graph; + } } -var portalExistsArray = []; -var portalRunArray = []; -var portalRunIndex = 0; - -function chkdsk() { - rebuildDataIndex(); - checkIndexConsistency(); - checkWorldSequentiality(); - if (databaseDirtyEntry.State == true) { - // + +// Draws the graph currently selected by the user +function drawGraph() { + // TOGGLES + function makeCheckbox(graph, toggle) { + // create checkbox element labeled with the toggle + var container = document.createElement("span") + var checkbox = document.createElement("input"); + var label = document.createElement("span"); + + container.style.padding = "0rem .5rem"; + + checkbox.type = "checkbox"; + checkbox.id = toggle; + // initialize the checkbox to saved value + checkbox.checked = GRAPHSETTINGS.toggles[graph][toggle]; + // create a godawful inline function to set saved value on change, apply exclusions, and update the graph + let funcString = ""; + if (toggledGraphs[toggle] && toggledGraphs[toggle].exclude) { + toggledGraphs[toggle].exclude.forEach(exTog => funcString += `GRAPHSETTINGS.toggles.${graph}.${exTog} = false; `) } + funcString += `GRAPHSETTINGS.toggles.${graph}.${toggle} = this.checked; drawGraph();` + checkbox.setAttribute("onclick", funcString); -} + label.innerText = toggle; + label.style.color = "#757575"; -function rebuildDataIndex() { - for (var i = 0; i < allSaveData.length-1; i++) { - //database - dataBase[i] ={ - Index: i, - Portal: allSaveData[i].totalPortals, - Challenge: allSaveData[i].challenge, - World: allSaveData[i].world - } - //reverse lookup quickArray - portalRunArray.push({Index: i, Portal: allSaveData[i].totalPortals , Challenge: allSaveData[i].challenge}); - - if (typeof portalExistsArray[allSaveData[i].totalPortals] == "undefined") - portalExistsArray[allSaveData[i].totalPortals] = {Exists: true, Row: portalRunIndex, Index: i, Challenge: allSaveData[i].challenge}; - else { - databaseDirtyFlag.State = true; - databaseDirtyFlag.Reason = 'oreoportal'; - databaseDirtyFlag.Index = i; - row = portalExistsArray[allSaveData[i].totalPortals].Row; - } - portalRunIndex++; + container.appendChild(checkbox) + container.appendChild(label) + return container; + } + pushData(); // update current zone data on request + updateGraph(); + let universe = GRAPHSETTINGS.universeSelection; + let selectedGraph = document.getElementById(`u${universe}graphSelection`); + if (selectedGraph.value) { + // draw the graph + let graph = lookupGraph(selectedGraph.value); + // create toggle elements + toggleDiv = document.querySelector("#toggleDiv") + toggleDiv.innerHTML = ""; + if (graph.toggles) { + for (const toggle of graph.toggles) { + toggleDiv.appendChild(makeCheckbox(graph.id, toggle)) + } } + } + showHideUnusedGraphs(); } -function checkIndexConsistency() { - for (var i = 0; i < dataBase.length-1; i++) { - if (dataBase[i].Index != i) { - databaseDirtyFlag = [true,'index',i]; - break; +function updateGraph() { + let universe = GRAPHSETTINGS.universeSelection; + let selectedGraph = document.getElementById(`u${universe}graphSelection`); + if (selectedGraph.value) { + // draw the graph + let graph = lookupGraph(selectedGraph.value); + graph.updateGraph(); + } +} + +// Hide graphs that have no collected data +function showHideUnusedGraphs() { + let activeUniverses = []; + for (const graph of graphList) { + if (graph.graphType != "line") continue; // ignore column graphs (pure laziness, the only two always exist anyways) + const universes = graph.universe ? [graph.universe] : [1, 2] + for (const universe of universes) { + let style = "none" + for (portal of Object.values(portalSaveData)) { + if (portal.perZoneData[graph.dataVar] && portal.universe === universe // has collected data, in the right universe + && new Set(portal.perZoneData[graph.dataVar].filter(x => x)).size > 1) { // and there is nonzero, variable data + style = "" + if (!activeUniverses.includes(universe)) activeUniverses.push(universe); + break; } + } + // hide unused graphs + document.querySelector(`#u${universe}graphSelection [value="${graph.selectorText}"]`).style.display = style; } + } + // hide universe selector if graphs are only in one universe + let universeSel = document.querySelector(`#universeSelection`); + if (activeUniverses.length === 1) { + universeSel.style.display = "none"; + GRAPHSETTINGS.universeSelection = activeUniverses[0]; + swapGraphUniverse() + } + else { + universeSel.style.display = ""; + } } -function checkWorldSequentiality() { - var lastworld,currentworld,nextworld; - for (var i = 1; i < dataBase.length-1; i++) { - lastworldEntry = dataBase[i-1]; - currentworldEntry = dataBase[i]; - nextworldEntry = dataBase[i+1]; - lastworld = lastworldEntry.World; - currentworld = currentworldEntry.World; - nextworld = nextworldEntry.World - if (lastworld > currentworld && currentworld != 1) { - databaseDirtyFlag.State = true; - databaseDirtyFlag.Reason = 'descending'; - databaseDirtyFlag.Index = i; - break; - } - if (lastworld > currentworld && currentworld == 1 && lastworld == nextworld) { - databaseDirtyFlag.State = true; - databaseDirtyFlag.Reason = 'badportal'; - databaseDirtyFlag.Index = i; - break; - } +// Graph Selection + +function saveSelectedGraphs() { + if (!chart1) return; + for (let i = 0; i < chart1.series.length; i++) { + GRAPHSETTINGS.rememberSelected[i] = chart1.series[i].visible; + } + saveSetting(); +} +function applyRememberedSelections() { + if (chart1.series.length !== GRAPHSETTINGS.rememberSelected.length) { + GRAPHSETTINGS.rememberSelected = [] // if the graphlist changes, order is no longer guaranteed + } + for (let i = 0; i < chart1.series.length; i++) { + if (GRAPHSETTINGS.rememberSelected[i] === false) { chart1.series[i].hide(); } + } +} +function toggleSpecificGraphs() { + for (const chart of chart1.series) { + chart.visible ? chart.hide() : chart.show(); + } +} +// toggle all graphs to the opposite of the average visible/hidden state +function toggleAllGraphs() { + let visCount = 0; + chart1.series.forEach(chart => visCount += chart.visible) + for (const chart of chart1.series) { + visCount > chart1.series.length / 2 ? chart.hide() : chart.show(); + } +} + +// --------- Portal and Game data handling --------- + +// Stores and updates data for an individual portal +function Portal() { + this.universe = getGameData.universe(); + this.totalPortals = getTotalPortals(); + this.challenge = getGameData.challengeActive() === 'Daily' + ? getCurrentChallengePane().split('.')[0].substr(13).slice(0, 16) // names dailies by their start date, only moderately cursed + : getGameData.challengeActive(); + this.initialNullifium = game.global.nullifium; + this.totalNullifium = getGameData.nullifium(); + this.totalVoidMaps = getGameData.totalVoids(); + this.cinf = getGameData.cinf(); + if (this.universe === 1) { + this.totalHelium = game.global.totalHeliumEarned; + this.initialFluffy = getGameData.fluffy() - game.stats.bestFluffyExp.value; // adjust for mid-run graph start + this.initialDE = getGameData.essence(); + } + if (this.universe === 2) { + this.totalRadon = game.global.totalRadonEarned; + this.initialScruffy = getGameData.scruffy() - game.stats.bestFluffyExp2.value; // adjust for mid-run graph start + this.initialMutes = getGameData.mutatedSeeds(); + this.s3 = getGameData.s3(); + } + // create an object to collect only the relevant data per zone, without fromEntries because old JS + this.perZoneData = {}; + var perZoneItems = graphList.filter((graph) => + (graph.universe == this.universe || !graph.universe) // only save data relevant to the current universe + && graph.conditional() && graph.dataVar) // and for relevant challenges, with datavars + .map((graph) => graph.dataVar) + .concat(["currentTime", "mapCount", "timeOnMap"]); // always graph time vars + perZoneItems.forEach((name) => this.perZoneData[name] = []); + + // update per zone data and special totals + this.update = function (fromMap) { // check source of the update + const world = getGameData.world(); + this.totalNullifium = game.global.nullifium - this.initialNullifium + getGameData.nullifium(); + this.totalVoidMaps = getGameData.totalVoids(); + for (const [name, data] of Object.entries(this.perZoneData)) { + if (world + 1 < data.length) { // FENCEPOSTING (zones are 1 indexed) + data.splice(world + 1) // trim 'future' zones on reload + } + if (name === "timeOnMap") { + let timeOnMap = getGameData.timeOnMap(); + if (fromMap) { data[world] = data[world] + timeOnMap || timeOnMap; } // additive per map within a zone + continue; + } + if (name === "mapCount") { + if (fromMap && game.global.mapsActive) { data[world] = data[world] + 1 || 1; } // start at 1 because the hook in is before the map is started/finished + continue; + } + data[world] = getGameData[name](); } + } } -////////////////////////////////////// -//MAIN GRAPHING FUNCTION - the meat.// -////////////////////////////////////// -function drawGraph(minus,plus) { - var $item = document.getElementById('graphSelection'); - //Cycle Through Graphs with GUI Up/Down Arrow Buttons - if (minus) { - $item.selectedIndex--; - if ($item.selectedIndex < 0) - $item.selectedIndex = 0; +function getportalID() { return `u${getGameData.universe()} p${getTotalPortals()}` } + +function pushData(fromMap) { + //debug("Starting Zone " + getGameData.world(), "graphs"); + const portalID = getportalID(); + if (!portalSaveData[portalID] || getGameData.world() === 1) { // reset portal data if restarting a portal + savePortalData(true) // save old portal to history + portalSaveData[portalID] = new Portal(); + } + portalSaveData[portalID].update(fromMap); + clearData(GRAPHSETTINGS.maxGraphs); + savePortalData(false) // save current portal + if (GRAPHSETTINGS.live && GRAPHSETTINGS.open) { + updateGraph(); + } +} + +const getGameData = { + currentTime: () => { return getGameTime() - game.global.portalTime }, // portalTime changes on pause, 'when a portal started' is not a static concept + timeOnMap: () => { + // TODO this time is wrong if the player sits in map chamber. Then again, they might want that time included in 'map' time. + let annoyingRemainder = 0; + if (game.global.mapStarted < game.global.zoneStarted) { + annoyingRemainder = getGameTime() - game.global.mapStarted; + } + return getGameTime() - game.global.mapStarted - annoyingRemainder; + }, + world: () => { return game.global.world }, + challengeActive: () => { return game.global.challengeActive }, + voids: () => { return game.global.totalVoidMaps }, + totalVoids: () => { return game.stats.totalVoidMaps.value }, + nullifium: () => { return recycleAllExtraHeirlooms(true) }, + coord: () => { return game.upgrades.Coordination.allowed - game.upgrades.Coordination.done }, + overkill: () => { + // overly complex check for Liq, overly fragile check for overkill cells. please rewrite this at some point. + if (game.options.menu.overkillColor.enabled == 0) toggleSetting("overkillColor"); + if (game.options.menu.liquification.enabled && game.talents.liquification.purchased && !game.global.mapsActive && game.global.gridArray && game.global.gridArray[0] && game.global.gridArray[0].name == "Liquimp") + return 100; + else return document.getElementById("grid").getElementsByClassName("cellColorOverkill").length; + }, + zoneTime: () => { return Math.round((getGameTime() - game.global.zoneStarted) * 100) / 100 }, // rounded to x.xs, not used + mapbonus: () => { return game.global.mapBonus }, + empower: () => { return game.global.challengeActive == "Daily" && typeof game.global.dailyChallenge.empower !== "undefined" ? game.global.dailyChallenge.empower.stacks : 0 }, + lastWarp: () => { return game.global.lastWarp }, + essence: () => { return game.global.spentEssence + game.global.essence }, + heliumOwned: () => { return game.resources.helium.owned }, + //magmite: () => { return game.global.magmite }, + //magmamancers: () => { return game.jobs.Magmamancer.owned }, + fluffy: () => { + // cap exp at maximum for an evo, because Trimps doesn't do it and it causes horrible horrible bugs + let maxExp = Math.floor((1000 * Math.pow(5, Fluffy.getCurrentPrestige())) * ((Math.pow(4, 10) - 1) / (4 - 1))) + let exp = Math.min(game.global.fluffyExp, maxExp); + //sum of all previous evo costs + current exp, because Trimps doesn't store this + for (var evo = 0; evo < Fluffy.getCurrentPrestige(); evo++) { + exp += Math.floor((1000 * Math.pow(5, evo)) * ((Math.pow(4, 10) - 1) / (4 - 1)));; } - else if (plus) { - if ($item.selectedIndex != ($item.options.length-1)) - $item.selectedIndex++; + return exp + }, + //nursery: () => { return game.buildings.Nursery.purchased }, + amals: () => { return game.jobs.Amalgamator.owned }, + wonders: () => { return game.challenges.Experience.wonders }, + scruffy: () => { return game.global.fluffyExp2 }, + smithies: () => { return game.buildings.Smithy.owned }, + radonOwned: () => { return game.resources.radon.owned }, + worshippers: () => { return game.jobs.Worshipper.owned }, + bonfires: () => { return game.challenges.Hypothermia.bonfires }, + embers: () => { return game.challenges.Hypothermia.embers }, + cruffys: () => { return game.challenges.Nurture.level }, + universe: () => { return game.global.universe }, + s3: () => { return game.global.lastRadonPortal }, + u1hze: () => { return game.global.highestLevelCleared }, + u2hze: () => { return game.global.highestRadonLevelCleared }, + c23increase: () => { + if (game.global.challengeActive !== "" && game.global.runningChallengeSquared) { + return Math.max(0, getIndividualSquaredReward(game.global.challengeActive, game.global.world) - getIndividualSquaredReward(game.global.challengeActive)); } - setGraphData($item.value); + else { return 0; } + }, + cinf: () => { return countChallengeSquaredReward(false, false, true) }, + mutatedSeeds: () => { return game.global.mutatedSeedsSpent + game.global.mutatedSeeds } } -function setGraphData(graph) { - var title, xTitle, yTitle, yType, valueSuffix, series, formatter, xminFloor=1, yminFloor=null; - var precision = 0; - var oldData = JSON.stringify(graphData); - valueSuffix = ''; - - switch (graph) { - case 'Helium - He/Hr Instant': - var currentPortal = -1; - var currentZone = -1; - graphData = []; - var nowhehr=0;var lasthehr=0; - for (var i in allSaveData) { - if (allSaveData[i].totalPortals != currentPortal) { - graphData.push({ - name: 'Portal ' + allSaveData[i].totalPortals + ': ' + allSaveData[i].challenge, - data: [] - }); - currentPortal = allSaveData[i].totalPortals; - if(allSaveData[i].world == 1 && currentZone != -1 ) - graphData[graphData.length -1].data.push(0); - - if(currentZone == -1 || allSaveData[i].world != 1) { - var loop = allSaveData[i].world; - while (loop > 0) { - graphData[graphData.length -1].data.push(0); - loop--; - } - } - nowhehr = 0; lasthehr = 0; - } - if(currentZone < allSaveData[i].world && currentZone != -1) { - nowhehr = Math.floor((allSaveData[i].heliumOwned - allSaveData[i-1].heliumOwned) / ((allSaveData[i].currentTime - allSaveData[i-1].currentTime) / 3600000)); - graphData[graphData.length - 1].data.push(nowhehr); - } - currentZone = allSaveData[i].world; - - } - title = 'Helium/Hour Instantaneous - between current and last zone.'; - xTitle = 'Zone'; - yTitle = 'Helium/Hour per each zone'; - yType = 'Linear'; - yminFloor=null; - break; - - case 'Helium - He/Hr Delta': - var currentPortal = -1; - var currentZone = -1; - graphData = []; - var nowhehr=0;var lasthehr=0; - for (var i in allSaveData) { - if (allSaveData[i].totalPortals != currentPortal) { - graphData.push({ - name: 'Portal ' + allSaveData[i].totalPortals + ': ' + allSaveData[i].challenge, - data: [] - }); - currentPortal = allSaveData[i].totalPortals; - if(allSaveData[i].world == 1 && currentZone != -1 ) - graphData[graphData.length -1].data.push(0); - - if(currentZone == -1 || allSaveData[i].world != 1) { - var loop = allSaveData[i].world; - while (loop > 0) { - graphData[graphData.length -1].data.push(0); - loop--; - } - } - nowhehr = 0; lasthehr = 0; - } - if(currentZone < allSaveData[i].world && currentZone != -1) { - nowhehr = Math.floor(allSaveData[i].heliumOwned / ((allSaveData[i].currentTime - allSaveData[i].portalTime) / 3600000)); - if (lasthehr == 0) - lasthehr = nowhehr; - graphData[graphData.length - 1].data.push(nowhehr-lasthehr); - } - currentZone = allSaveData[i].world; - lasthehr = nowhehr; - - } - title = 'Helium/Hour Delta(Difference) - between current and last zone.'; - xTitle = 'Zone'; - yTitle = 'Difference in Helium/Hour'; - yType = 'Linear'; - yminFloor=null; - break; - - case 'Run Time': - var currentPortal = -1; - var theChallenge = ''; - graphData = []; - for (var i in allSaveData) { - if (allSaveData[i].totalPortals != currentPortal) { - if(currentPortal == -1) { - theChallenge = allSaveData[i].challenge; - currentPortal = allSaveData[i].totalPortals; - graphData.push({ - name: 'Run Time', - data: [], - type: 'column' - }); - continue; - } - var theOne = allSaveData[i-1]; - var runTime = theOne.currentTime - theOne.portalTime; - graphData[0].data.push([theOne.totalPortals, runTime]); - theChallenge = allSaveData[i].challenge; - currentPortal = allSaveData[i].totalPortals; - } - } - title = 'Total Run Time'; - xTitle = 'Portal'; - yTitle = 'Time'; - yType = 'datetime'; - formatter = function () { - var ser = this.series; - return ' ' + - ser.name + ': ' + - Highcharts.dateFormat('%H:%M:%S', this.y) + '
'; - - }; - break; - - case 'Void Maps': - var currentPortal = -1; - var totalVoids = 0; - var theChallenge = ''; - graphData = []; - for (var i in allSaveData) { - if (allSaveData[i].totalPortals != currentPortal) { - if(currentPortal == -1) { - theChallenge = allSaveData[i].challenge; - currentPortal = allSaveData[i].totalPortals; - graphData.push({ - name: 'Void Maps', - data: [], - type: 'column' - }); - continue; - } - graphData[0].data.push([allSaveData[i-1].totalPortals, totalVoids]); - theChallenge = allSaveData[i].challenge; - totalVoids = 0; - currentPortal = allSaveData[i].totalPortals; - } - if(allSaveData[i].voids > totalVoids) { - totalVoids = allSaveData[i].voids; - } - } - title = 'Void Maps (completed)'; - xTitle = 'Portal'; - yTitle = 'Number of Void Maps'; - yType = 'Linear'; - break; - - case 'Nullifium Gained': - var currentPortal = -1; - var totalNull = 0; - var theChallenge = ''; - graphData = []; - var averagenulli = 0; - var sumnulli = 0; - var count = 0; - for (var i in allSaveData) { - if (allSaveData[i].totalPortals != currentPortal) { - if(currentPortal == -1) { - theChallenge = allSaveData[i].challenge; - currentPortal = allSaveData[i].totalPortals; - graphData.push({ - name: 'Nullifium Gained', - data: [], - type: 'column' - }); - continue; - } - graphData[0].data.push([allSaveData[i-1].totalPortals, totalNull]); - count++; - sumnulli += totalNull; - //console.log("nulli was: " + totalNull + " " + count + " @ " + allSaveData[i].totalPortals); //debug - theChallenge = allSaveData[i].challenge; - totalNull = 0; - currentPortal = allSaveData[i].totalPortals; - - } - if(allSaveData[i].nullifium > totalNull) { - totalNull = allSaveData[i].nullifium; - } - } - averagenulli = sumnulli / count; - //console.log("Average nulli was: " + averagenulli); - title = 'Nullifium Gained Per Portal'; - if (averagenulli) - title = "Average " + title + " = " + averagenulli; - xTitle = 'Portal'; - yTitle = 'Nullifium Gained'; - yType = 'Linear'; - break; - - case 'Loot Sources': - graphData = []; - graphData[0] = {name: 'Metal', data: lootData.metal}; - graphData[1] = {name: 'Wood', data: lootData.wood}; - graphData[2] = {name: 'Food', data: lootData.food}; - graphData[3] = {name: 'Gems', data: lootData.gems}; - title = 'Current Loot Sources (of all resources gained) - for the last 15 minutes'; - xTitle = 'Time (every 15 seconds)'; - yTitle = 'Ratio of looted to gathered'; - valueSuffix = '%'; - formatter = function () { - return Highcharts.numberFormat(this.y,3); - }; - break; - - //all use the same function: allPurposeGraph() - case 'Clear Time #2': - graphData = allPurposeGraph('cleartime2',true,null, - function specialCalc(e1,e2) { - return Math.round(e1.zonetime/1000); - }); - title = '(#2) Time to Clear Zone'; - xTitle = 'Zone'; - yTitle = 'Clear Time'; - yType = 'Linear'; - valueSuffix = ' Seconds'; - break; - case 'Clear Time': - graphData = allPurposeGraph('cleartime1',true,null, - function specialCalc(e1,e2) { - return Math.round(((e1.currentTime - e2.currentTime)-(e1.portalTime - e2.portalTime)) / 1000); - }); - title = 'Time to clear zone'; - xTitle = 'Zone'; - yTitle = 'Clear Time'; - yType = 'Linear'; - valueSuffix = ' Seconds'; - yminFloor=0; - break; - case 'Cumulative Clear Time #2': - graphData = allPurposeGraph('cumucleartime2',true,null, - function specialCalc(e1,e2) { - return Math.round(e1.zonetime); - },true); - title = '(#2) Cumulative Time (at END of zone#)'; - xTitle = 'Zone'; - yTitle = 'Cumulative Clear Time'; - yType = 'datetime'; - formatter = function () { - var ser = this.series; - return ' ' + - ser.name + ': ' + - Highcharts.dateFormat('%H:%M:%S', this.y) + '
'; - - }; - yminFloor=0; - break; - case 'Cumulative Clear Time': - graphData = allPurposeGraph('cumucleartime1',true,null, - function specialCalc(e1,e2) { - return Math.round((e1.currentTime - e2.currentTime)-(e1.portalTime - e2.portalTime)); - },true); - title = 'Cumulative Time (at END of zone#)'; - xTitle = 'Zone'; - yTitle = 'Cumulative Clear Time'; - yType = 'datetime'; - formatter = function () { - var ser = this.series; - return ' ' + - ser.name + ': ' + - Highcharts.dateFormat('%H:%M:%S', this.y) + '
'; - - }; - yminFloor=0; - break; - case 'Helium - He/Hr': - graphData = allPurposeGraph('heliumhr',true,null, - function specialCalc(e1,e2) { - return Math.floor(e1.heliumOwned / ((e1.currentTime - e1.portalTime) / 3600000)); - }); - title = 'Helium/Hour (Cumulative)'; - xTitle = 'Zone'; - yTitle = 'Helium/Hour'; - yType = 'Linear'; - yminFloor=0; - break; - case 'Helium - Total': - graphData = allPurposeGraph('heliumOwned',true,null, - function specialCalc(e1,e2) { - return Math.floor(e1.heliumOwned); - }); - title = 'Helium (Lifetime Total)'; - xTitle = 'Zone'; - yTitle = 'Helium'; - yType = 'Linear'; - break; - case 'HeHr % / LifetimeHe': - graphData = allPurposeGraph('hehr',true,"string"); - title = 'He/Hr % of LifetimeHe'; - xTitle = 'Zone'; - yTitle = 'He/Hr % of LifetimeHe'; - yType = 'Linear'; - precision = 4; - break; - case 'He % / LifetimeHe': - graphData = allPurposeGraph('helife',true,"string"); - title = 'He % of LifetimeHe'; - xTitle = 'Zone'; - yTitle = 'He % of LifetimeHe'; - yType = 'Linear'; - precision = 4; - break; - case 'Void Map History': - graphData = allPurposeGraph('voids',true,"number"); - title = 'Void Map History (voids finished during the same level acquired (with RunNewVoids) are not counted/tracked)'; - xTitle = 'Zone'; - yTitle = 'Number of Void Maps'; - yType = 'Linear'; - break; - case 'Map Bonus': - graphData = allPurposeGraph('mapbonus',true,"number"); - title = 'Map Bonus History'; - xTitle = 'Zone'; - yTitle = 'Map Bonus Stacks'; - yType = 'Linear'; - break; - case 'Coordinations': - graphData = allPurposeGraph('coord',true,"number"); - title = 'Coordination History'; - xTitle = 'Zone'; - yTitle = 'Coordination'; - yType = 'Linear'; - break; - case 'GigaStations': - graphData = allPurposeGraph('gigas',true,"number"); - title = 'Gigastation History'; - xTitle = 'Zone'; - yTitle = 'Number of Gigas'; - yType = 'Linear'; - break; - case 'Unused Gigas': - graphData = allPurposeGraph('gigasleft',true,"number"); - title = 'Unused Gigastations'; - xTitle = 'Zone'; - yTitle = 'Number of Gigas'; - yType = 'Linear'; - break; - case 'Last Warpstation': - graphData = allPurposeGraph('lastwarp',true,"number"); - title = 'Warpstation History'; - xTitle = 'Zone'; - yTitle = 'Previous Giga\'s Number of Warpstations'; - yType = 'Linear'; - break; - case 'Trimps': - graphData = allPurposeGraph('trimps',true,"number"); - title = 'Total Trimps Owned'; - xTitle = 'Zone'; - yTitle = 'Cumulative Number of Trimps'; - yType = 'Linear'; - break; - case 'Magmite': - graphData = allPurposeGraph('magmite',true,"number"); - title = 'Total Magmite Owned'; - xTitle = 'Zone (starting at 230)'; - yTitle = 'Magmite'; - yType = 'Linear'; - xminFloor = 230; - break; - case 'Magmamancers': - graphData = allPurposeGraph('magmamancers',true,"number"); - title = 'Total Magmamancers Owned'; - xTitle = 'Zone (starting at 230)'; - yTitle = 'Magmamancers'; - yType = 'Linear'; - xminFloor = 230; - break; - case 'Dark Essence': - graphData = allPurposeGraph('essence',true,"number"); - title = 'Total Dark Essence Owned'; - xTitle = 'Zone'; - yTitle = 'Dark Essence'; - yType = 'Linear'; - xminFloor = 181; - break; - case 'Dark Essence PerHour': - var currentPortal = -1; - var currentZone = -1; - var startEssence = 0; - graphData = []; - for (var i in allSaveData) { - if (allSaveData[i].totalPortals != currentPortal) { - graphData.push({ - name: 'Portal ' + allSaveData[i].totalPortals + ': ' + allSaveData[i].challenge, - data: [] - }); - currentPortal = allSaveData[i].totalPortals; - currentZone = 0; - startEssence = allSaveData[i].essence; - } - //runs extra checks for mid-run imports, and pushes 0's to align to the right zone properly. - if (currentZone != allSaveData[i].world - 1) { - var loop = allSaveData[i].world - 1 - currentZone; - while (loop > 0) { - graphData[graphData.length - 1].data.push(0); - loop--; - } - } - //write datapoint (one of 3 ways) - if (currentZone != 0) { - graphData[graphData.length - 1].data.push(Math.floor((allSaveData[i].essence - startEssence) / ((allSaveData[i].currentTime - allSaveData[i].portalTime) / 3600000))); - } - currentZone = allSaveData[i].world; - } - title = 'Dark Essence/Hour (Cumulative)'; - xTitle = 'Zone'; - yTitle = 'Dark Essence/Hour'; - yType = 'Linear'; - xminFloor = 181; - break; - case 'Nurseries': - graphData = allPurposeGraph('nursery',true,"number"); - title = 'Nurseries Bought (Total)'; - xTitle = 'Zone';// (starting at your NoNurseriesUntil setting)'; - yTitle = 'Nursery'; - yType = 'Linear'; - // if (getPageSetting('NoNurseriesUntil')) - // xminFloor = getPageSetting('NoNurseriesUntil'); - break; - case 'Fluffy XP': - graphData = allPurposeGraph('fluffy',true,"number"); - title = 'Fluffy XP (Lifetime Total)'; - xTitle = 'Zone (starts at 300)'; - yTitle = 'Fluffy XP'; - yType = 'Linear'; - xminFloor = 300; - break; - case 'Fluffy XP PerHour': - var currentPortal = -1; - var currentZone = -1; - var startFluffy = 0; - graphData = []; - for (var i in allSaveData) { - if (allSaveData[i].totalPortals != currentPortal) { - graphData.push({ - name: 'Portal ' + allSaveData[i].totalPortals + ': ' + allSaveData[i].challenge, - data: [] - }); - currentPortal = allSaveData[i].totalPortals; - currentZone = 0; - startFluffy = allSaveData[i].fluffy; - } - //runs extra checks for mid-run imports, and pushes 0's to align to the right zone properly. - /*if (currentZone != allSaveData[i].world - 1) { - var loop = allSaveData[i].world - 1 - currentZone; - while (loop > 0) { - graphData[graphData.length - 1].data.push(0); - loop--; - } - }*/ - if (currentZone != allSaveData[i].world - 1) { - //console.log(allSaveData[i].totalPortals + " / " + allSaveData[i].world); - var loop = allSaveData[i].world - 1 - currentZone; - while (loop > 0) { - graphData[graphData.length - 1].data.push(allSaveData[i-1][item]*1); - loop--; - } - } - //write datapoint (one of 3 ways) - if (currentZone != 0) { - graphData[graphData.length - 1].data.push(Math.floor((allSaveData[i].fluffy - startFluffy) / ((allSaveData[i].currentTime - allSaveData[i].portalTime) / 3600000))); - } - currentZone = allSaveData[i].world; - } - title = 'Fluffy XP/Hour (Cumulative)'; - xTitle = 'Zone (starts at 300)'; - yTitle = 'Fluffy XP/Hour'; - yType = 'Linear'; - xminFloor = 300; - break; - case 'OverkillCells': - var currentPortal = -1; - graphData = []; - for (var i in allSaveData) { - if (allSaveData[i].totalPortals != currentPortal) { - graphData.push({ - name: 'Portal ' + allSaveData[i].totalPortals + ': ' + allSaveData[i].challenge, - data: [] - }); - currentPortal = allSaveData[i].totalPortals; - if(allSaveData[i].world == 1 && currentZone != -1 ) - graphData[graphData.length -1].data.push(0); - - if(currentZone == -1 || allSaveData[i].world != 1) { - var loop = allSaveData[i].world; - while (loop > 0) { - graphData[graphData.length -1].data.push(0); - loop--; - } - } - } - if(currentZone < allSaveData[i].world && currentZone != -1) { - var num = allSaveData[i].overkill; - if (num) - graphData[graphData.length - 1].data.push(num); - } - currentZone = allSaveData[i].world; - } - title = 'Overkilled Cells'; - xTitle = 'Zone'; - yTitle = 'Overkilled Cells'; - yType = 'Linear'; - break; - }//end of switch(graph) - - //(internal) default function used to draw non-specific graphs (and some specific ones) - function allPurposeGraph(item,extraChecks,typeCheck,funcToRun,useAccumulator) { - var currentPortal = -1; - var currentZone = 0; - var accumulator = 0; - graphData = []; - //begin iterating: - for (var i in allSaveData) { - //acts as an "exists" check (for lack of data) - if (typeCheck && typeof allSaveData[i][item] != typeCheck) - continue; - if (allSaveData[i].totalPortals != currentPortal) { - graphData.push({ - name: 'Portal ' + allSaveData[i].totalPortals + ': ' + allSaveData[i].challenge, - data: [] - }); - currentPortal = allSaveData[i].totalPortals; - currentZone = 0; - if (funcToRun) { - accumulator = 0; - //push a 0 to index 0 so that clear times line up with x-axis numbers - graphData[graphData.length -1].data.push(0); - } - continue; - } - //maybe not?runs extra checks for mid-run imports, and pushes 0's to align to the right zone properly. - if (extraChecks) { - if (currentZone != allSaveData[i].world - 1) { - //console.log(allSaveData[i].totalPortals + allSaveData[i].world); - var loop = allSaveData[i].world - 1 - currentZone; - while (loop > 0) { - graphData[graphData.length - 1].data.push(allSaveData[i-1][item]*1); - loop--; - } - } - } - //write datapoint (one of 3 ways) - if (funcToRun && !useAccumulator && currentZone != 0) { - var num = funcToRun(allSaveData[i],allSaveData[i-1]); - if (num < 0) num = 1; - graphData[graphData.length - 1].data.push(num); - } - else if (funcToRun && useAccumulator && currentZone != 0) { - accumulator += funcToRun(allSaveData[i],allSaveData[i-1]); - if (accumulator < 0) accumulator = 1; - graphData[graphData.length - 1].data.push(accumulator); - } - else { - if (allSaveData[i][item] >= 0) - graphData[graphData.length - 1].data.push(allSaveData[i][item]*1); - else if (extraChecks) - graphData[graphData.length - 1].data.push(-1); - } - currentZone = allSaveData[i].world; - } - return graphData; +// --------- Data structures --------- + +// Create all the Graph objects +// Graph(dataVar, universe, selectorText, additionalParams) +// additionalParams include graphTitle, conditional, customFunction, useAccumulator, toggles, xTitle, yTitle, formatter + +// To add a new graph, add it to graphList with the desired options, +// If using a new dataVar, add that to getGameData +// To make a new toggle, add the required logic to togglesProperties + +const graphList = [ + new Graph("currentTime", false, "Clear Time", { + yType: "datetime", + formatter: formatters.datetime, + toggles: ["perZone", "mapTime", "mapCount"], + // , "mapPct" TODO having issues with accumulators on this one, more trouble than it's worth given nobody asked for it + }), + // U1 Graphs + new Graph("heliumOwned", 1, "Helium", { + toggles: ["perHr", "perZone", "lifetime"] + }), + new Graph("fluffy", 1, "Fluffy Exp", { + conditional: () => { return getGameData.u1hze() >= 299 && getGameData.fluffy() < 3413330078125000 }, // pre unlock, post E10L10 + customFunction: (portal, i) => { return diff("fluffy", portal.initialFluffy)(portal, i) }, + toggles: ["perHr", "perZone",] + }), + new Graph("essence", 1, "Dark Essence", { + conditional: () => { return getGameData.essence() < 5.826e+39 }, + customFunction: (portal, i) => { return diff("essence", portal.initialDE)(portal, i) }, + toggles: ["perHr", "perZone",], + xminFloor: 181, + }), + new Graph("lastWarp", 1, "Warpstations", { + graphTitle: "Warpstations built on previous Giga", + conditional: () => { return getGameData.u1hze() >= 59 && ((game.global.totalHeliumEarned - game.global.heliumLeftover) < 10 ** 10) }, // Warp unlock, less than 10B He allocated + xminFloor: 60, + }), + new Graph("amals", 1, "Amalgamators"), + new Graph("wonders", 1, "Wonders", { + conditional: () => { return getGameData.challengeActive() === "Experience" }, + xminFloor: 300, + }), + + // U2 Graphs + new Graph("radonOwned", 2, "Radon", { + toggles: ["perHr", "perZone", "lifetime", "s3normalized"] + }), + new Graph("scruffy", 2, "Scruffy Exp", { + customFunction: (portal, i) => { return diff("scruffy", portal.initialScruffy)(portal, i) }, + toggles: ["perHr", "perZone",] + }), + new Graph("mutatedSeeds", 2, "Mutated Seeds", { + conditional: () => { return getGameData.u2hze() >= 200 }, + customFunction: (portal, i) => { return diff("mutatedSeeds", portal.initialMutes)(portal, i) }, + toggles: ["perHr", "perZone"], + xminFloor: 200, + }), + new Graph("worshippers", 2, "Worshippers", { + conditional: () => { return getGameData.u2hze() >= 49 }, + xminFloor: 50, + }), + new Graph("smithies", 2, "Smithies"), + new Graph("bonfires", 2, "Bonfires", { + graphTitle: "Active Bonfires", + conditional: () => { return getGameData.challengeActive() === "Hypothermia" } + }), + new Graph("embers", 2, "Embers", { + conditional: () => { return getGameData.challengeActive() === "Hypothermia" } + }), + new Graph("cruffys", 2, "Cruffys", { + conditional: () => { return getGameData.challengeActive() === "Nurture" } + }), + + // Generic Graphs + new Graph("c23increase", false, "C2 Bonus", { + conditional: () => { return game.global.runningChallengeSquared }, + toggles: ["perHr", "perZone", "lifetime"] + }), + new Graph("voids", false, "Void Map History", { + graphTitle: "Void Map History (voids finished during the same level acquired are not counted/tracked)", + yTitle: "Number of Void Maps", + }), + new Graph("coord", false, "Coordinations", { + graphTitle: "Unbought Coordinations", + }), + new Graph("overkill", false, "Overkill Cells", { + // Overkill unlock zones (roughly) + conditional: () => { + return ((getGameData.universe() == 1 && getGameData.u1hze() >= 169) + || (getGameData.universe() == 2 && getGameData.u2hze() >= 200)) + } + }), + new Graph("mapbonus", false, "Map Bonus"), + new Graph("empower", false, "Empower", { + conditional: () => { return getGameData.challengeActive() === "Daily" && typeof game.global.dailyChallenge.empower !== "undefined" } + }), + new Graph(false, false, "Portal Stats", { + graphTitle: "Portal Stats", + graphType: "column", + toggles: ["perHr"], + columns: [ + { dataVar: "totalVoidMaps", title: "Voids", color: "#4d0e8c" }, + { dataVar: "totalNullifium", title: "Nu", color: "#8a008a" }, + { dataVar: "heliumOwned", universe: 1, title: "Helium", color: "#5bc0de" }, + { dataVar: "radonOwned", universe: 2, title: "Radon", color: "#5bc0de" }, + { dataVar: "fluffy", universe: 1, title: "Pet Exp", color: "green", customFunction: (portal, x) => { return x - portal.initialFluffy } }, + { dataVar: "scruffy", universe: 2, title: "Pet Exp", color: "green", customFunction: (portal, x) => { return x - portal.initialScruffy } }, + { dataVar: "currentTime", title: "Run Time", type: "datetime", color: "#928DAD" }, // TODO some vars should be on shared axes... woo + //{ dataVar: "timeOnMap", title: "Mapping Time", type: "datetime", customFunction: () => { } }, // TODO should be sum not max + ], + }), +] + +// rules for toggle based graphs +const toggledGraphs = { + mapCount: { + exclude: ["mapTime", "mapPct"], + graphMods: (graph, highChartsObj) => { + highChartsObj.tooltip = { pointFormatter: formatters.defaultPoint }; + highChartsObj.yAxis.type = "Linear"; + highChartsObj.title.text = "Maps Run" + highChartsObj.yAxis.title.text = "Maps Run" + graph.useAccumulator = true; + }, + customFunction: (portal, item, index, x) => { + x = portal.perZoneData.mapCount[index] || 0; + return x + } + }, + mapTime: { + exclude: ["mapCount", "mapPct"], + graphMods: (graph, highChartsObj) => { + highChartsObj.title.text = "Time in Maps"; + graph.useAccumulator = true; + }, + customFunction: (portal, item, index, x) => { + x = portal.perZoneData.timeOnMap[index] || 0; + return x; } - //default formatter used (can define a decimal precision, and a suffix) - formatter = formatter || function () { - var ser = this.series; - return ' ' + - ser.name + ': ' + - Highcharts.numberFormat(this.y, precision,'.', ',') + valueSuffix + '
'; - }; - var additionalParams = {}; - //Makes everything happen. - if (oldData != JSON.stringify(graphData)) { - saveSelectedGraphs(); - setGraph(title, xTitle, yTitle, valueSuffix, formatter, graphData, yType, xminFloor, yminFloor, additionalParams); + }, + mapPct: { // not used + exclude: ["mapCount", "mapTime"], + graphMods: (graph, highChartsObj) => { + highChartsObj.tooltip = { pointFormatter: formatters.defaultPoint }; + highChartsObj.yAxis.type = "Linear" + highChartsObj.title.text = "% of Clear time spent Mapping" + highChartsObj.yAxis.title.text = "% Clear Time" + graph.useAccumulator = true; + }, + customFunction: (portal, item, index, x) => { + x = portal.perZoneData.timeOnMap[index] / x || 0; + return x; } - //put finishing touches on this graph. - if (graph == 'Helium - He/Hr Delta') { - var plotLineoptions = { - value: 0, - width: 2, - color: 'red' - }; - chart1.yAxis[0].addPlotLine(plotLineoptions); + }, + perZone: { + graphMods: (graph, highChartsObj) => { + highChartsObj.title.text += " each Zone" + graph.useAccumulator = false // HACKS this might be incredibly stupid, find out later when you use this option for a different case! + }, + customFunction: (portal, item, index, x) => { + if (portal.perZoneData[item][index - 1] && portal.perZoneData[item][index]) { // check for missing data, or start of data + var x = portal.perZoneData[item][index] - portal.perZoneData[item][index - 1] + var time = portal.perZoneData.currentTime[index] - portal.perZoneData.currentTime[index - 1] + } + else { + x = 0 + time = 0 + } + return [x, time]; } - //put finishing touches on this graph. - if (graph == 'Loot Sources') { - chart1.xAxis[0].tickInterval = 1; - chart1.xAxis[0].minorTickInterval = 1; + }, + perHr: { + graphMods: (graph, highChartsObj) => { + highChartsObj.title.text += " / Hour" + }, + customFunction: (portal, item, index, x, time) => { + if (x) { x = x / (time / 3600000) } + return x; } - //remember what we had (de)selected, if desired. - if (document.getElementById('rememberCB').checked) { - applyRememberedSelections(); + }, + lifetime: { + graphMods: (graph, highChartsObj) => { + highChartsObj.title.text += " % of Lifetime Total"; + highChartsObj.yAxis.title.text += " % of lifetime" + }, + customFunction: (portal, item, index, x) => { + let initial; + if (item === "heliumOwned") { initial = portal.totalHelium; } + if (item === "radonOwned") { initial = portal.totalRadon; } + if (item === "c23increase") { initial = portal.cinf; } + if (!initial) { + debug("Attempted to calc lifetime percent of an unknown type:" + item); + return 0; + } + if (item === "c23increase") { + let totalBonus = (1 + (initial[1] / 100)) * initial[0]; // calc initial cinf + let c2 = initial[0]; + let c3 = initial[1]; + portal.universe == 1 ? c2 += x : c3 += x; + let newBonus = (1 + (c3 / 100)) * c2; // calc final cinf + x = ((newBonus - totalBonus) / (totalBonus ? totalBonus : 1)); + } + else { x = x / (initial ? initial : 1) } + return x; } + }, + s3normalized: { + graphMods: (graph, highChartsObj) => { + var maxS3 = Math.max(...Object.values(portalSaveData).map((portal) => portal.s3).filter((s3) => s3)); + highChartsObj.title.text += `, Normalized to z${maxS3} S3` + }, + customFunction: (portal, item, index, x, time, maxS3) => { + x = x / 1.03 ** portal.s3 * 1.03 ** maxS3 + return x; + } + }, } + +// --------- Runtime --------- + var chart1; -function setGraph(title, xTitle, yTitle, valueSuffix, formatter, series, yType, xminFloor, yminFloor, additionalParams) { - chart1 = new Highcharts.Chart({ - chart: { - renderTo: 'graph', - zoomType: 'xy', - //move reset button out of the way. - resetZoomButton: { - position: { - align: 'right', - verticalAlign: 'top', - x: -20, - y: 15 - }, - relativeTo: 'chart' - } - }, - title: { - text: title, - x: -20 //center - }, - plotOptions: { - series: { - lineWidth: 1, - animation: false, - marker: { - enabled: false - } - } - }, - xAxis: { - floor: xminFloor, - title: { - text: xTitle - }, - }, - yAxis: { - floor: yminFloor, - title: { - text: yTitle - }, - plotLines: [{ - value: 0, - width: 1, - color: '#808080' - }], - type: yType, - dateTimeLabelFormats: { //force all formats to be hour:minute:second - second: '%H:%M:%S', - minute: '%H:%M:%S', - hour: '%H:%M:%S', - day: '%H:%M:%S', - week: '%H:%M:%S', - month: '%H:%M:%S', - year: '%H:%M:%S' - } - }, - tooltip: { - pointFormatter: formatter, - valueSuffix: valueSuffix - }, - legend: { - layout: 'vertical', - align: 'right', - verticalAlign: 'middle', - borderWidth: 0 - }, - series: series, - additionalParams - }); +var lastSave = new Date() +var GRAPHSETTINGS = { + universeSelection: 1, + u1graphSelection: null, + u2graphSelection: null, + rememberSelected: [], + toggles: {}, + darkTheme: true, + maxGraphs: 60, // Highcharts gets a bit angry rendering more graphs, 30 is the maximum you can fit on the legend before it splits into pages. + portalsDisplayed: 30 } +var portalSaveData = {} -function setColor(tmp) { - for (var i in tmp) { - tmp[i].color = (i == tmp.length - 1) ? '#FF0000' //Current run is in red - : '#90C3D4'; //Old runs are in blue - } - return tmp; -} +// load and initialize the UI +loadGraphData(); +createUI() +showHideUnusedGraphs() +var lastTheme = -1; -var filteredLoot = { - 'produced': {metal: 0, wood: 0, food: 0, gems: 0}, - 'looted': {metal: 0, wood: 0, food: 0, gems: 0} -} -var lootData = { - metal: [], wood:[], food:[], gems:[] -}; -//track loot gained. jest == from jest/chronoimp -function filterLoot (loot, amount, jest, fromGather) { - if(loot != 'wood' && loot != 'metal' && loot != 'food' && loot != 'gems') return; - if(jest) { - filteredLoot.produced[loot] += amount; - //subtract from looted because this loot will go through addResCheckMax which will add it to looted - filteredLoot.looted[loot] -= amount; - } - else if (fromGather) filteredLoot.produced[loot] += amount; - else filteredLoot.looted[loot] += amount; - //console.log('item is: ' + loot + ' amount is: ' + amount); -} -function getLootData() { - var loots = ['metal', 'wood', 'food', 'gems']; - for(var r in loots){ - var name = loots[r]; - //avoid /0 NaN - if(filteredLoot.produced[name]) - lootData[name].push(filteredLoot.looted[name]/filteredLoot.produced[name]); - if(lootData[name].length > 60)lootData[name].shift(); - } +// --------- Trimps Wrappers --------- + +//On Zone transition +var originalnextWorld = nextWorld; +nextWorld = function () { + try { + if (game.options.menu.pauseGame.enabled) return; + if (null === portalSaveData) portalSaveData = {}; + if (getGameData.world()) { pushData(); } + } + catch (e) { debug("Gather info failed: " + e) } + originalnextWorld(...arguments); } -setInterval(getLootData, 15000); +//On Portal +var originalactivatePortal = activatePortal; +activatePortal = function () { + try { pushData(); } + catch (e) { debug("Gather info failed: " + e) } + originalactivatePortal(...arguments) +} -//BEGIN overwriting default game functions!!!!!!!!!!!!!!!!!!!!!! -//(dont panic, this is done to insert the tracking function "filterLoot" in) -(function(){ - var resAmts; +//On Map start +// This unfortunately loses the last map, since we grab map time at the creation of the map +var originalbuildMapGrid = buildMapGrid; +buildMapGrid = function () { + try { pushData(true); } + catch (e) { debug("Gather info failed: " + e) } + originalbuildMapGrid(...arguments) +} - function storeResAmts() { - resAmts = {}; - for (let item in lootData) { - resAmts[item] = game.resources[item].owned; - } - } +//On leaving maps for world +// this captures the last map when you switch away from maps +var originalmapsSwitch = mapsSwitch; +mapsSwitch = function () { + originalmapsSwitch(...arguments) + try { if (!game.global.mapsActive) pushData(true); } + catch (e) { debug("Gather info failed: " + e) } - const oldJestimpLoot = game.badGuys.Jestimp.loot; - game.badGuys.Jestimp.loot = - function() { - storeResAmts(); - var toReturn = oldJestimpLoot.apply(this, arguments); - for (let item in resAmts) { - var gained = game.resources[item].owned - resAmts[item]; - if (gained > 0) { - filterLoot(item, gained, true); - } - } - return toReturn; - }; - - const oldChronoimpLoot = game.badGuys.Chronoimp.loot; - game.badGuys.Chronoimp.loot = - function () { - storeResAmts(); - var toReturn = oldChronoimpLoot.apply(this, arguments); - for (let item in resAmts) { - var gained = game.resources[item].owned - resAmts[item]; - if (gained > 0) { - filterLoot(item, gained, true); - } - } - return toReturn; - }; - - // who even thought copying the code was a good idea? - const oldFunction = window.addResCheckMax; - window.addResCheckMax = (a, b, c, d, e) => filterLoot(a, b, null, d) || oldFunction(a, b, c, d, e); -})(); -//END overwriting default game functions!!!!!!!!!!!!!!!!!!!!!! - -function lookUpZoneData(zone,portal) { - if (portal == null) - portal = game.global.totalPortals; - for (var i=allSaveData.length-1,end=0; i >= 0; i--) { - if (allSaveData[i].totalPortals != portal) continue; - if (allSaveData[i].world != zone) continue; - return allSaveData[i]; - } -} -//run the main gatherInfo function 1 time every second -setInterval(gatherInfo, 100); +} \ No newline at end of file diff --git a/GraphsOnly.js b/GraphsOnly.js new file mode 100644 index 000000000..40ab8b358 --- /dev/null +++ b/GraphsOnly.js @@ -0,0 +1,28 @@ +var basepath = 'https://Quiaaaa.github.io/AutoTrimps/' //Link to your own Github here if you forked! + +//var isSteam = false; + +function ATscriptLoad(path, module) { + if (module == null) debug('Wrong Syntax. Script could not be loaded.') + if (path == null) path = ''; + var scriptElem = document.createElement('script'); + scriptElem.src = basepath + path + module + '.js' + scriptElem.id = module + '_MODULE' + document.head.appendChild(scriptElem) +} + +function initializeGraphs() { + ATscriptLoad('', 'Graphs'); + debug('AutoTrimps - Zek Graphs Only Fork Loaded!', '*spinner3'); +} + +var enableDebug = false; +function debug(message, type, lootIcon) { + if (enableDebug) + console.debug(0 + ' ' + message); +} + +var MODULES = {} +var startupDelay = 1000; +setTimeout(initializeGraphs, startupDelay); + diff --git a/GraphsOnly.user.js b/GraphsOnly.user.js index 30f097dec..fdf9eaa2f 100644 --- a/GraphsOnly.user.js +++ b/GraphsOnly.user.js @@ -1,30 +1,16 @@ // ==UserScript== -// @name AutoTrimpsV2+genBTC-GraphsOnly -// @namespace https://github.com/genbtc/AutoTrimps -// @version 2.1.6.9-genbtc-3-23-2018 -// @updateURL https://github.com/genbtc/AutoTrimps/GraphsOnly.user.js +// @name AT-Quia-GraphsOnly +// @namespace https://github.com/Quiaaaa/AutoTrimps +// @version 3.0-Quia +// @updateURL https://github.com/Quiaaaa/AutoTrimps/GraphsOnly.user.js // @description Graphs Module (only) from AutoTrimps -// @author zininzinin, spindrjr, belaith, ishakaru, genBTC +// @author zininzinin, spindrjr, belaith, ishakaru, genBTC, Zek, Quia // @include *trimps.github.io* // @include *kongregate.com/games/GreenSatellite/trimps // @grant none // ==/UserScript== -//this comes from AutoTrimps/modules/utils.js , then we dont need to load everything from that file. -function safeSetItems(name,data) { - try { - localStorage.setItem(name, data); - } catch(e) { - if (e.code == 22) { - // Storage full, maybe notify user or do some clean-up - debug("Error: LocalStorage is full, or error. Attempt to delete some portals from your graph or restart browser."); - } - } -} -//This can be edited to point to your own Github Repository URL. -var basepath = 'https://genbtc.github.io/AutoTrimps/'; var script = document.createElement('script'); script.id = 'AutoTrimps-Graphs'; -script.src = basepath + 'Graphs.js'; -//script.setAttribute('crossorigin',"use-credentials"); -script.setAttribute('crossorigin',"anonymous"); -document.head.appendChild(script); \ No newline at end of file +script.src = 'https://Quiaaaa.github.io/AutoTrimps/GraphsOnly.js'; +script.setAttribute('crossorigin', "anonymous"); +document.head.appendChild(script); diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..f288702d2 --- /dev/null +++ b/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/README.md b/README.md index d495e29df..7c3e30984 100644 --- a/README.md +++ b/README.md @@ -1,327 +1,119 @@ -# AutoTrimps + genBTC -![Donate](https://blockchain.info/Resources/buttons/donate_64.png) -1genbtcPLjAEk6RnfC66chYniFKfP7vASNo one has donated bitcoin yet - be the first and I will be ever eternally grateful
-Automation script for the idle incremental game Trimps, originally based on the zininzinin fork and modified by genBTC (genr8_ on discord)
+# AutoTrimps - Zek Fork + + -[![Join the chat at https://gitter.im/AutoTrimps/Lobby](https://badges.gitter.im/AutoTrimps/Lobby.svg)](https://gitter.im/AutoTrimps/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) ## Discussion / Discord Channel - -Discord is a chat program. Come to talk about AutoTrimps, for help, or suggestions for new features : https://discord.gg/0VbWe0dxB9kIfV2C (same one as zininzinin) - -## Current Version (full changes below) - Ongoing Development! -- This version has beta changes by genBTC, forked from GenBTC. Including Autostance 3, Update to Swiffy Overlay, and Merging of buttons. Please tell me about bugs on Discord -- Mar 24, BATTLECALC CHANGES: -- BattleCalc.js - getBattleStats() updated for the stuff added to AutoStance 1 a while ago, Life,C2,StillRowing, Copied from game code. -- Mar 24, EQUIPMENT CHANGES: -- Equip.js - Now supports higher cap numbers such as 200. Lower cap for liquified and overkilled zones: -- If a zone is liquified its 10% of your cap. -- If its a quick zone that you might complete in under 25 seconds its also 10% of your cap (based on last zone). -- hidden variable MODULES["equipment"].capDivisor = 10; //number to divide your normal cap by -- Spire is explicitly leveled to your full 100% cap. -- Also above MaxMapBonusAfterZone the armor equip is leveled to full cap as well, as an attempt to get more Armor (working on it). -- Sorry for any bugs or undocumenteds in the meantime. -- Old Original Zeker450 AutoPerk Preset was changed 2 days ago without notice also. This is your notice That is now called #2, And there is a new one called #3 That it his latest change. -- v2.1.6.5-stable - Mar 24, Set up Stable Repository for the faint of heart. Equipment changes, see README at GitHub and check commit history; Sorry for any breakages. -- v2.1.6.9 - March 23, New: AutoMaps setting combined with RunUniqueMaps. Be advised, the variable has changed from boolean false,true to a value 0,1,2. Settings file has been migrated as such. New: Map SpecialMod is extremely beta and can break your game. Geneticist Infinity fixed. New AGU Settings for 60% Void. Graphs fixes. AutoMaps changes. Equipment level cap improvements. -- v2.1.6.8 - March 22, Settings GUI, make better. Up/Down graph buttons. Warning notices on import/export. Internal code fixes, gameplay unchanged. -- v2.1.6.7 - March 20, Moved all the Settings around on you :) Enjoy the new layout. Display Tab: EnhanceGrid + Go AFK Mode. Pinned AT Tab menu bar to top when scrolling. Graph: Graph: FluffyXP . Continue Development on long TODO list... -- v2.1.6.6 - March 13, Geneticist management changes. Equipment code improvements. scriptLoad improvements. attempt to track errors. -- v2.1.6.5 - March 7, Save/Reload Profiles in Import/Export. Magmamancer graph. Magmite/Magma Spam disableable. -- v2.1.6.4 - March 4, 2018 Basic Analytics are now being collected. Read about it in the tooltip of the new button on the Import/Export tab . Overkill Graph fixed for Liquification. Setting Max Explorers to infinity as they are not that useless anymore. Update battlecalc for Fluffy & Ice on Autostance2. -- v2.1.6.3 - March 3, 2018 AutoPerks: Capable/Curious/Cunning, BaseDamageCalc: C2,StillRowing,Strength in Health,Ice,Fluffy,Magmamancer - Fix bugs in autoperks around capable/fluffy allocating looting + more bugs -- v2.1.6.2 - March 2, 2018 -- v2.1.6.1 - March 1, 2018 -- v2.1.6.0 - December 23, 2018 -- v2.1.5.7 - November 7,2017 = Merge in DerSkagg's GoldenUpgrades Mod (Pull request #90) (thanks Derskagg) -- v2.1.5.6 - August 26, 2017 = Merge ALL of Unihedro branch back into genBTC branch. (thanks UniHedro) -- v2.1.5.4 - August 26, 2017 = Added AutoDimGen + little fixes (FirenX) -took a break -- v2.1.5.3 - January 10, 2017 genbtc-1-10-2016+Modular (meant 2017 lol) - -## Script Installation -**Please backup your game via export before and during use to prevent losing your save due to corruption!** - -***Option 1***: Install TamperMonkey (Chrome) or GreaseMonkey (Firefox) - -**EASY INSTALL click here: https://github.com/genbtc/AutoTrimps/raw/gh-pages/.user.js** (the Monkeys will detect this and prompt you to install it) - -Overly detailed Chrome/TamperMonkey Instructions: -- Open the TamperMonkey dashboard and go to utilities – in the URL box paste https://github.com/genbtc/AutoTrimps/raw/gh-pages/.user.js and click IMPORT -- Alternatively, paste the contents of `.user.js` into a user script (pay attention, it says .user.js - this contains 4 lines of code that loads AutoTrimps2.js) -- The script should automatically load everytime you go to https://trimps.github.io or the game on Kongregate -- You will know you have the script loaded if you see the Automation and Graphs buttons in the game menu at the bottom -- DO NOT PASTE THE FULL 2000+ line contents of the script into TamperMonkey! It will not work properly! -- The .user.js file is a "stub" or "loader" that references the AutoTrimps2.js file which is where the actual script is located. -- The purpose of .user.js is so that you don't have to rely on TamperMonkey's update functionality - instead it will automaticaly download the updated copy from the URL provided everytime its loaded. - -FireFox/GreaseMonkey instructions: -- GreaseMonkey identifies userscripts by visiting a URL that ends with ".user.js" in them: -- Visit this URL, and Agree to install the userscript: https://github.com/genbtc/AutoTrimps/raw/gh-pages/.user.js - -***Option 2***: Via a Bookmark (does not work with Kongregate - maybe it does now that I added an include kongregate line to the file) -- Create new bookmark and set its target to: -```js -javascript:with(document)(head.appendChild(createElement('script')).src='https://genbtc.github.io/AutoTrimps/AutoTrimps2.js')._ + +Discord is a chat program. Come to talk about AutoTrimps, for help, or suggestions for new features : https://discord.gg/Ztcnfjr + + + +## Current Version - Ongoing Development! +- Zek Fork. All changes made by Zek using GenBTC as base. Currently up-to-date as of 06/2022. + + + +## AT Script Installation +### Browser +Step 1: +Install TamperMonkey: +https://www.tampermonkey.net/ + +Step 2: +Click this link: https://github.com/Zorn192/AutoTrimps/raw/gh-pages/.user.js +If clicking the link does not work, copy the contents of user.js into a new script inside tampermonkey. +If you are unsure how to do that, copy this: +``` +var script = document.createElement('script'); +script.id = 'AutoTrimps-Zek'; +script.src = 'https://Zorn192.github.io/AutoTrimps/AutoTrimps2.js'; +script.setAttribute('crossorigin',"anonymous"); +document.head.appendChild(script); +``` +Press F12 inside the game, this opens the console, and paste the text into it and hit enter, this will load the script. You will have to do this everytime you refresh the game though so I recommend getting tampermonkey to do it for you! + +Step 3: +Configure settings. Will NOT work as intended with default settings. + +### Steam +Step 1: +Go to this link to open the mods.js file on Github: mods.js +Then, right click the Raw button, hit Save link as, and save the mods.js file somewhere to your computer where you can find it, like desktop. +![Download mods.js](https://i.imgur.com/opuO6yd.png) + +Step 2: +In your Steam Library (where you see all your games in the Steam app), right click on Trimps, go to Manage, then Browse local files. +A folder where Trimps is installed inside Steam should open. +![Go to Trimps directory](https://imgur.com/cr35LK2.png) + +Inside this folder, navigate to the mods folder (you should be in Steam\steamapps\common\Trimps\mods), and place the mods.js file there, like so: +![Insert mods.js](https://imgur.com/muW6cUh.png) + +Advanced users: If you have other mods installed then just copy the text in AT's mods.js and place it somewhere in your existing mods.js file. + +Step 3: +Restart the game, or if the game is already running, hit F5 to refresh. + +Step 4: +Configure your settings. AT will not work properly if they are not configured! + +## Graphs only Script Installation +### Browser +Step 1: +Install TamperMonkey: +https://www.tampermonkey.net/ + +Step 2: +Click this link: https://github.com/Zorn192/AutoTrimps/blob/gh-pages/GraphsOnly.user.js +If clicking the link does not work, copy the contents of GraphsOnly.user.js into a new script inside tampermonkey. +If you are unsure how to do that, copy this: ``` -- This bookmark button has to be clicked manually after you go to https://trimps.github.io - -***Option 3***: Paste into console (last resort for debugging, dont do this) - -Chrome Instructions -- You can copy and paste the entire contents of AutoTrimps2.js into the Dev Console (F12 in chrome) of the page. (make sure the dropdown box to the left of "Preserve Log" is set to "top" - or "mainFrame (indexKong.html)" for kongregate. - -Firefox Instructions -- Push Ctrl+Shift+K to go into console and look for the "Select an iframe" icon, and choose http://trimps.github.io/indexKong.html - -Notes: -If you would like to use only the graphs module, replace `AutoTrimps2.js` with `Graphs.js` in the bookmark or your userscript. -Feel free to submit any bugs/suggestions as issues here on github. - -***LowLevelPlayer Notes:*** - -***PSA: AutoTrimps was not designed for new/low-level players.*** - -The fact that it works at all is misleading new players into thinking its perfect. Its not. If your highest zone is under z60, you have not unlocked the stats required, and have not experienced the full meta with its various paradigm shifts. If you are just starting, my advice is to play along naturally and use AutoTrimps as a tool, not a crutch. Play with the settings as if it was the game, Dont expect to go unattended, if AT chooses wrong, and make the RIGHT choice yourself. Additionally, its not coded to run one-time challenges for you, only repeatable ones for helium. During this part of the game, content is king - automating literally removes the fun of the game. If you find that many flaws in the automation exist for you, level up. Keep in mind the challenge of maintaining the code is that it has to work for everyone. AT cant see the future and doesnt run simulations, it exists only in the present moment. Post any suggestions on how it can be better, or volunteer to adapt the code, or produce some sort of low-level player guide with what youve learned. Happy scripting! -genBTC - -## Current feature changes by genBTC -- Current as of : -- *** 11/7/2017, v2.1.5.7 Merge DerSkagg PullRequest In*** -- New AutoGoldenUpgrades - After max void golden upgrades, alternate between buying helium and battle upgrades. Or Choose a Zone to switch over completely at. -- *** 8/26/2017, v2.1.5.6 Merge Unihedro Branch In*** -- Uni changes include: Dont buy Coords, Trimple Z#, Scryer Suicide Z#, Safety First, Forced Prestige Z#, Prefer Metal Maps, Nursery Count Pre-Spire, Finish Challenge2, DontCare/PowerSaving/DontRushVoids, Prestige Skip 2, Auto Eggs. -- See his branch here @ https://github.com/Unihedro/AutoTrimps -- Past Changes: -- *** April Unihedro Branch Changes *** -- 4/17 v2.1.5.5u3 - fix improvedautostorage hijack -- Fixed a certain specific stupid bug caused by how graph overwrites some functions unnecessarily -- 4/16 v2.1.5.5u2 - do more map stacks if not enoughHealth -- No longer forces Buy Storage off -- 4/15 v2.1.5.5u1 - new settings BuyOvclock -- 4/14 v2.1.5.4u6 - Improved nurseries map and betterautostorage -- 4/14 v2.1.5.4u5 - Auto Eggs, some more 4.3 support -- 4/12 v2.1.5.4u4 - AutoTrimps lifecycle changes -- 4/11 v2.1.5.4u3 - fixed spire farming, autogen supply zone -- 4/10 v2.1.5.4u2 - PrestigeSkip2 -- 4/09 v2.1.5.4u1 - Magma: AutoGen, AutoGen2 -- 4/08 v2.1.5.3u6 - ForcePresZ -- 4/07 + 4/06: -- U5: FinishC2, PowerSaving -- U4: PreferMetal, PreSpireNurseries -- U3: LinearZ, SupplyWall, OneTimeOnly -- U2: TrimpleZ, ScryerDieZ, IgnoreCrits -- U1: Don't buy Coords / Skip challenge maps -- ***1/10/2017*** -- new setting Buy Warp to Hit Coord (genbtc page) -- AutoStance support for Plague/Bogged Daily -- Update Map Sliders decisions - less loot% reduction -- ***12/23/2016*** -- v2.1.5.2-genbtc-12-23-2016+Modular -- ***12/20*** -- Gear tab to Settings UI. Customize your equip level cap. -- Internally Disable Farm mode if we have nothing left to farm for (no prestiges,capped equip) to prevent infinite farming. -- ***12/19*** -- Skip prestige if >=2 unbought prestiges (maps settings) -- Bug Fixes + redo geneticists buying again. -- NEW: Add Map Bonus Graph -- ***12/18*** -- Fixed: dynamic prestige not reverting to dagger after the target zone is reached -- Graphs - clear time, removed #2s, (essence graph might be messed up but its fixed now) -- Change forceAbandonTrimps "sitting around breeding forever when not on full anti stacks" from 60 seconds to 31. -- Fix BAF2 #4 for players without geneticists. -- Buildings cost efficiency + jobs low level fixes -- Some low level jobs and Buildings fixes. -- ***12/14*** -- NEW: AutoAllocatePerks (genbtc settings) - uses AutoPerks ratio system to Auto Spend Helium during AutoPortal -- ***12/12*** -- Fix: HeHrBuffer will now portal midzone if you exceed 5x your buffer -- ***12/10*** -- New: AutoStartDaily option (read tooltip) -- New way to buy geneticists (fast) -- ***12/9*** -- Fixed: DynamicPrestige=-1 wasnt disabling it -- Fixed: needPrestige conflicting with needFarmSpire -- ***12/8*** -- FarmWithNomStacks changes (read tooltip) -- Nom stacks now calced by Autostance1 -- Default VoidDifficultyCheck is now defaulting to 6 -- ***12/6*** -- AutoMagmiteSpender now has a new cost efficiency algorithm.(read new tooltip) -- AT now does its Nursery map for Blacksmithery owners at z50 not z60, to prevent breeding time-stalls.(+fixed bug) -- ***12/4*** -- Completely rewrite lots of the Graphs.js code. -- Converted the codebase into individual files, to help people find stuff. -- For automaps, Not enough Health doesnt do 10 maps anymore, it only does 1. -- Adjust enoughHealth calculation for people without D stance. -- Add a farm lower level zones option (maps settings tab). -- ***12/2*** -- Changed Automaps farming/damage/health calculations. AutoMaps farms above 16x now. (10x in Lead, 10x in Nom with the Farm on >7 NOMstacks option). -- Hover over the Farming/Advancing/WantMoreDamage status area to see the precise number now. Read the AutoMaps tooltip in settings for slightly more information. -- Add dailymods: weakness, rampage, oddtrimpnerf, eventrimpbuff, badStrength, badMapStrength, bloodthirst to Autostance1. (and AS2 has minDmg, maxDmg too) -- ***11/29*** -- Puts a 5 second pause in between cycling AutoMagmiteSpender from "on portal" to "always" so you can switch it to "off" without it spending all your magmite. -- Make multi-toggle tooltip title give the name of all 3 options to be more descriptive. -- new calcBadGuyDmg function, used in DynamicGyms. -- stop using stopScientistsatFarmers and use MaxScientists instead. -- hire 1 miner,farmer,lumber each cycle even if our breed timer is low to do something tiny, so earlygame isnt stuck on 0 -- fix/re-arrange lazy Trainers duplicate code -- exit autostance if Formations isnt done (like level <60) -- Lead damage stacks were wrongly on 0.0005, its 0.0003. -- Trimpicide Mod #1: consider Titimp = forceAbandon and kill titimp if theres less than 5 seconds left on it or, we stand to gain more than 5 antistacks. -- Trimpicide Mod #2: if we're sitting around breeding for >60s while being over 5 anti stacks away from target. -- Include beta autostance2 code that im working on so I dont have a bunch of crazy local commits. -- ***11/26*** -- Patch corruption detection, and Scryer tooltips -- Dynamic Gyms - dont buy gyms if your block is higher than enemy attack -- Auto Magmamancer management after 10 mins -- Auto Finish Daily on portal (genbtc settings) -- Gym Wall (genbtc settings) -- ***11/23*** -- Auto Magmite Spender can now be toggled to Always Run -- AutoTrimpicide/Force-Abandon is now toggleable -- New Better AutoFight #2(optional) -- New Hover tooltips: Screenshot beta0.1, more to come -- ***11/22*** -- Auto Spend Magmite before portaling - (setting in genBTC page)- Part 1 buys any permanent one-and-done upgrades in order from most expensive to least. Part 2 then finds/buys the cheapest non-permanent multi-upgrade and repeats itself until you cant buy anymore. -- Buy 2 buildings instead of 1 if we have the mastery -- Entirely remove high lumberjack ratio during Spire. -- During Magma with 3000+ Tributes, switch to 1/12/12 auto-worker-ratios instead of 1/2/22. -- Add a 10 second timeout Popup window that can postpone Autoportal when clicked. -- Added a No Nurseries Until setting, in genBTC page -- ***11/20*** -- Fixed spire map bug -- Added new ratios to AutoPerks (ZXV3,truth_late) -- AutoFight if timer is <0.5 not <0.1 now -- ***11/19*** -- Doesnt run the 10 maps for Mapbonus before Spire now. Please increase/adjust your MinutesBeforeSpire Timer accordingly (the 10 maps were never accounted for in that timer). -- Re-arranged all the categories in the settings window and updated tooltips -- Kill your trimps (AutoTrimpicide) for Anti-Stacks more often - -## Gap in Changelog exists here. - -## Prior feature changes by genBTC (up to date as of 8/5/2016): -- Minutes to Farm Before Spire - force some time to be spent so you can for sure complete Spire (recommended: 3-10 minutes) -- Auto Upgrade Heirlooms - spends ALL your nullifium on the recommended upgrades -- Auto Golden Upgrades = Buys all the Golden Helium, Battle, or Voids when available. -- Always Runs 10 maps for 200% map bonus before attempting Spire (happens after the first death if you don't select "Map At Spire" in regular Trimps settings) -- AutoHeirlooms2 - new algorithm to sort/carry/recycle the Heirlooms (the original had a bug) -- Cap Trainers to a % of Tributes - Only buy a trainer when its cost is less than X% of the cost of a tribute. Prevents from competing with food resources, if you care. -- Run Bionic Before Spire - meant as a one time function (like max tox is) to farm the Bionic Wonderland maps for a LONG time(2 hours-ish) before entering Spire. (not HE/hr efficient) -- Dynamic Prestige: Skip prestiges at the beginning of the run which saves time, and delay them until the end when you need them most and can provide resources from farming too) -- Helium per Hour Portal "Buffer" - now you can customize how much He/Hr is allowed to drop before portaling -- Auto Robo Trimp - activate the MagnetoShriek ability on the bosses every 5 levels starting from the level you specify. (recommended set to 60) - -## Individual changes (from pinned messages on the Discord channel) -- 7/30 Patch heirlooms2 not carrying all protected heirlooms due to some indexing bug -- 7/28 Add 3 new graphs. Update Graphs, fix He/hr shifted by 1 bug. -- 7/27 Works on level 1 fresh new games a lot better, and added a new function Auto Upgrade Heirlooms which spends ALL your nullifium on the advised upgrade automatically -Also bugfix Adjust storage buying so that the script cannot buy a storage building before it is unlocked at level 1 and 70% -- 7/23 Important Fix for Heirloom2 and fix tooltips. -Reason: It was trying too hard to maintain equal shield/staff amounts, now it will not leave any better heirlooms (rarity/mods) in the temporary "extras" pile. -- 7/23 ~~Automatically gets 10 map stacks During Spire.~~ -- 7/22 Add new feature: Auto Golden Upgrades (in genBTC advanced settings) -- 7/22 Brand new AutoHeirlooms2 algorithm & Dynamic Prestige Algorithm (by Hyppy) -There is a new setting in the genBTC settings called "AutoHeirlooms2" and this will override the original. -I have not immediately switched over because Heirlooms are sensitive and I dont want to be responsible for anyone's heirlooms losses -So when you enable this new setting for the new algorithm, Take notice of what is going on, and manually "Protect" button any heirlooms you need to before portal-recycling -This image is a quick documentation of the heirloom carry bug, and the fix: https://puu.sh/qb6zj/903364c3d2.png -- 7/21 Fix helium per hour portal bug. -- 7/20 Dynamic Prestige now works with Helium Per Hour Autoportal setting! It uses the Last Run's portal zone in this situation. -- 7/17 Add Corruption handling for 2 of the corruption types (Strong and Tough). -- 7/16 Dynamic Prestige has been altered, if you are having a bug, reload, toggle your prestige dropdown setting to something else, and back, and portal to start a fresh run. -- 7/16 Added a new "Protect Heirloom" button in the Heirlooms dialog: Mark certain heirlooms from being auto-recycled on portal if/when a better one is found by the AutoHeirloom script. -- 7/6 New EasyMode Worker Ratios, >1000 tributes = 1/1/10 and >1500 tributes = 1/2/22 - -## Feature changes added by genBTC since before 4/27/2016 and Trimps version 3.22: -- Change Genetecist Timer to 10 sec instead of 11sec. (was commonly showing 11.4s because it rounds. that is too much) -- 'Farm on >7 NomStacks': During Nom, take precautions not to get too many stacks. (On Improbability(cell 100). Meant to be used with DisableFarming (otherwise farming would take care of this, but its slower). If Improbability already has 5 NomStacks, stack 30 Anticipation. If the Improbability has >7 NomStacks on it, get +200% dmg from MapBonus. If we still cant kill it, enter Farming mode at 30 stacks, Even with DisableFarming On!') -- Dynamic Siphonology - only when needed based on (Enemyhealth / baseDamage) -Created a new setting in the advanced options. "Dynamic Siphonology". -It will switch to the proper Map-level as soon as the current map is completed. -So you can choose original behavior of always using the lowest level map, -or the modified behavior, which increases the map level based on your damage. -The old behavior of "no siphonology at all when using DisableFarming" is no longer applied, under any circumstance. -- Skip Gear Level 58&59: Dont Buy Gear during level 58 and 59, wait till level 60, when cost drops down to 10%. -- Cap Equip to 10: Do not level equipment past 10. Similar to LimitEquipment, Helps for early game when the script wants to level your tier2s to 40+, but unlike LimitEquipment, should not impact Zone 60+. -- Delay Armor When needed: Delay buying armor prestige upgrades during Want More Damage or Farming automap-modes. -- Add console debug messages to the map selection/buying/running section. -- Put a numerical status on the "Farming"&"Want more Damage" UI indicator. -This way you can see things progressing, instead of wondering what is going on. -The number pertains to Enemy Health / Base Damage(non-stance). Above 16 means farm. Below 10 means stop farming. -- Farm @ cell 61 (megamining) not 82 (megafarming). -- Farm if enemyHealth divided by baseDamage (in X stance) is between 10 and 16. (Used to be 10 and 15). -Means it will farm very slightly less. -- Take Map Bonus +%Damage into account for farming decisions. (so you can farm less.) -- Stop from firing all scientists when it reaches the threshhold. (250k farmers) -Farmers will be maintained at the current level, not fired entirely. I -- Add WarpStation Cap (deltaGiga+baseWarp) feature. -Stop making warpstations if we are past the deltagiga + base -warpstations (and no giga upgrade is available). Will also remove the -green highlight around the icon. This will save you metal to use on -weapons,armor, etc. -NOTE: (the cap will ONLY work on incremental buys, it will not come into -effect when the game uses a gigastation and immediately BULK-buys as -many warpstations as it can afford. In this way it can buy over the cap. I think this is actually preferrable.) -- Add an Export/Import/Reset AutoTrimps settings buttons. -- Add a seperate "genBTC's settings UI" button, -- Better Tooltip Help - -**Voidmaps and Toxicity changes:** - -- Voidmaps: Do voids @ cell 96 Instead of 98. (to prevent overkill). Before, it only applied to Tox runs. -- Voidmap + Max-Tox runs: If we need to do a voidmap and have already more than 1415 stacks, (smallest voidmap is 85 cells) consider tox-stack finished. -- For normal-tox: Instead of starting the voidmap at 1400 stacks, start at (1500-theVoidmap.size) in case its an 85 cell voidmap. -- Regular Tox-Run: Avoid another non-unique map cycle due to having the amount of tox stacks we need. -- Max-Tox Run: During a Toxicity + Max Tox run AutoPortal, unset the MaxTox setting from the settings page, so we dont' run 2 Max-Tox's in a row (will go back to normal Tox run). - -## Original zininzinin version's historical changes -See changelog at the original version's github page: https://github.com/zininzinin/AutoTrimps/blob/c8eac4c80d0a1a5ebe36bc44c7655c335a2dea7b/README.md#recent-changes - - -## Easy explanation of Colors for EquipUpgrades / prestiges highlights -- white - Upgrade is not available -- yellow - Upgrade is not affordable -- orange - Upgrade is affordable, but will lower stats -- red - Yes, do it now! - -## Confusing original explanation of colors, (gl trying to understand this!) -- Red text on Equip - it's best in its category in terms of stat per resource. This also compares Gyms with Shields. -- Orange text - Upgrade is available and improving this will make the upgrade actually reduce stat in question and it's best in its category in terms of stat per resource. -- Yellow text - Upgrade is available and improving this will make the upgrade actually reduce stat in question -- White border - upgrade is not yet available -- Yellow border - upgrade is available, but not affordable -- Orange border - upgrade is available, affordable, but will actually reduce stat in question -- Red border - you have enough resources to level equip after upgrade to surpass it's current stats. -- Green border on buildings - Best for gems - - -## Detailed Code Documentation: -Read docs/main-doc.txt or docs/TODO.md for more complete info, the below is somewhat outdated. - -Since javascript is easily human readable, Much can be learned by reading the source code, starting with this knowledge: - -The script was faux-modularized on 12/4/2016, with the modules residing in the '/modules/' dir. This means that although the files are seperate, they are all still required for the script to run. In addition, the interoperability of the modules is still undocumented, and some(most) rely on other modules. Sometime in the future, you will be able to load/use different verisons of the various modules. -AutoTrimps2.js is the main file that loads the modules, and then runs its mainLoop. - -The mainLoop() consists of the following subroutine functions, all of which are enable-able/disable-able by their buttons.: -- exitSpireCell(); //"Exit Spire After Cell" (other.js) -- workerRatios(); //"Auto Worker Ratios" -- buyUpgrades(); //"Buy Upgrades" -- autoGoldenUpgrades(); //"AutoGoldenUpgrades" (genBTC settings area) -- buyStorage(); //"Buy Storage" -- buyBuildings(); //"Buy Buildings" -- buyJobs(); //"Buy Jobs" -- manualLabor(); //"Auto Gather/Build" -- autoMap(); //"Auto Maps" -- autoBreedTimer(); //"Genetecist Timer" / "Auto Breed Timer" -- autoPortal(); //"Auto Portal" (hidden until level 40) -- autoHeirlooms2(); or autoHeirlooms(); //"Auto Heirlooms 2" (genBTC settings area) or //"Auto Heirlooms" -- autoNull(); //"Auto Upgrade Heirlooms" (genBTC settings area) -- toggleAutoTrap(); //"Trap Trimps" -- autoRoboTrimp(); //"AutoRoboTrimp" (genBTC settings area) -- autoLevelEquipment(); //"Buy Armor", "Buy Armor Upgrades", "Buy Weapons","Buy Weapons Upgrades" -- autoStance(); //"Auto Stance" -- betterAutoFight(); //"Better Auto Fight" -- prestigeChanging2(); //"Dynamic Prestige" (genBTC settings area) -- userscripts(); //Runs any user provided scripts - by copying and pasting a function named userscripts() into the Chrome Dev console. (F12) - -Once you have determined the function you wish to examine, CTRL+F to find it and read its code. There are lots of comments. In this way you can determine why AutoTrimps is acting a certain way. +var script = document.createElement('script'); +script.id = 'AutoTrimps-Graphs'; +script.src = 'https://Zorn192.github.io/AutoTrimps/GraphsOnly.js'; +script.setAttribute('crossorigin',"anonymous"); +document.head.appendChild(script); +``` +Press F12 inside the game, this opens the console, and paste the text into it and hit enter, this will load the script. You will have to do this everytime you refresh the game though so I recommend getting tampermonkey to do it for you! + +Step 3: +Enjoy your Graphs! + +### Steam +Step 1: +Go to this link to open the modsGRAPH.js file on Github: modsGRAPH.js +Then, right click the Raw button, hit Save link as, and save the modsGRAPH.js file somewhere to your computer where you can find it, like desktop. +![Download mods.js](https://i.imgur.com/opuO6yd.png) + +Step 2: +Rename the modsGRAPH.js file to mods.js (Right click the file, rename, then remove GRAPH). Sorry but I can't have 2 mods.js named the same so Graphs Only users have to deal with it :( + +Step 3: +In your Steam Library (where you see all your games in the Steam app), right click on Trimps, go to Manage, then Browse local files. +A folder where Trimps is installed inside Steam should open. +![Go to Trimps directory](https://imgur.com/cr35LK2.png) + +Inside this folder, navigate to the mods folder (you should be in Steam\steamapps\common\Trimps\mods), and place the mods.js file that we renamed earlier there, like so: +![Insert mods.js](https://imgur.com/muW6cUh.png) + +Advanced users: If you have other mods installed then just copy the text in AT's mods.js and place it somewhere in your existing mods.js file. + +Step 4: +Restart the game, or if the game is already running, hit F5 to refresh. + +Step 5: +Enjoy your Graphs! + +## Equipment && Upgrade's colour explaination: + +White - Upgrade is not available + +Yellow - Upgrade is not affordable + +Orange - Upgrade is affordable, but will lower stats + +Red - Will buy next + +## Troubleshooting + +**Combat won't start** - Make sure you have enabled the Better Auto Fight/Vanilla setting in Combat & Stance Settings. If you're not on dark theme, you may see a tiny thin black bar in combat, click it to show this setting. diff --git a/SettingsGUI.js b/SettingsGUI.js index 8b88d2df2..28282b67b 100644 --- a/SettingsGUI.js +++ b/SettingsGUI.js @@ -1,16 +1,9 @@ -//AutoTrimps Settings GUI - Current Version 2.1.6.9 -//maintained by genBTC, current as of 3/20/2018 - -//create the Automation icon in the game bar (self-executing) -//This creates the entire DOM-structure for this page. function automationMenuInit() { var settingBtnSrch = document.getElementsByClassName("btn btn-default"); - //Change Settings button handler to go through AutoTrimps Settings for (var i = 0; i < settingBtnSrch.length; i++) { if (settingBtnSrch[i].getAttribute("onclick") === "toggleSettingsMenu()") settingBtnSrch[i].setAttribute("onclick", "autoPlusSettingsMenu()"); } - //create the AutoTrimps Script button (bottom toolbar) var newItem = document.createElement("TD"); newItem.appendChild(document.createTextNode("AutoTrimps")); newItem.setAttribute("class", "btn btn-default"); @@ -18,9 +11,7 @@ function automationMenuInit() { var settingbarRow = document.getElementById("settingsTable").firstElementChild.firstElementChild; settingbarRow.insertBefore(newItem, settingbarRow.childNodes[10]); - //create automaps button (in the world sidebar) var newContainer = document.createElement("DIV"); - //newContainer.setAttribute("class", "battleSideBtnContainer"); newContainer.setAttribute("style", "margin-top: 0.2vw; display: block; font-size: 1.1vw; height: 1.5em; text-align: center; border-radius: 4px"); newContainer.setAttribute("id", "autoMapBtn"); newContainer.setAttribute("class", "noselect settingsBtn"); @@ -28,38 +19,42 @@ function automationMenuInit() { newContainer.setAttribute("onmouseover", 'tooltip(\"Toggle Automapping\", \"customText\", event, \"Toggle automapping on and off.\")'); newContainer.setAttribute("onmouseout", 'tooltip("hide")'); var abutton = document.createElement("SPAN"); - abutton.appendChild(document.createTextNode("Auto Maps")); + abutton.appendChild(document.createTextNode("Auto Maps")); abutton.setAttribute("id", "autoMapLabel"); var fightButtonCol = document.getElementById("battleBtnsColumn"); newContainer.appendChild(abutton); fightButtonCol.appendChild(newContainer); - //create automaps status (in the world sidebar) newContainer = document.createElement("DIV"); newContainer.setAttribute("style", "display: block; font-size: 1.1vw; text-align: center; background-color: rgba(0,0,0,0.3);"); - newContainer.setAttribute("onmouseover", 'tooltip(\"Health to Damage ratio\", \"customText\", event, \"This status box displays the current mode Automaps is in. The number usually shown here during Farming or Want more Damage modes is the \'HDratio\' meaning EnemyHealth to YourDamage Ratio (in X stance). Above 16 will trigger farming, above 4 will trigger going for Map bonus up to 10 stacks.

enoughHealth: \" + enoughHealth + \"
enoughDamage: \" + enoughDamage +\"
shouldFarm: \" + shouldFarm +\"
H:D ratio = \" + HDratio + \"
\")'); + if (game.global.universe == 1) { + newContainer.setAttribute("onmouseover", 'tooltip(\"Health to Damage ratio\", \"customText\", event, \"This status box displays the current mode Automaps is in. The number usually shown here during Farming or Want more Damage modes is the \'HDratio\' meaning EnemyHealth to YourDamage Ratio (in X stance). Above 16 will trigger farming, above 4 will trigger going for Map bonus up to 10 stacks.

enoughHealth: \" + enoughHealth + \"
enoughDamage: \" + enoughDamage +\"
shouldFarm: \" + shouldFarm +\"
H:D ratio = \" + calcHDratio() + \"
\")'); + } + if (game.global.universe == 2) { + newContainer.setAttribute("onmouseover", 'tooltip(\"Health to Damage ratio\", \"customText\", event, \"This status box displays the current mode Automaps is in. The number usually shown here during Farming or Want more Damage modes is the \'HDratio\' meaning EnemyHealth to YourDamage Ratio (in X stance). Above 16 will trigger farming, above 4 will trigger going for Map bonus up to 10 stacks.

enoughHealth: \" + RenoughHealth + \"
enoughDamage: \" + RenoughDamage +\"
shouldFarm: \" + RshouldFarm +\"
H:D ratio = \" + RcalcHDratio() + \"
\")'); + } newContainer.setAttribute("onmouseout", 'tooltip("hide")'); abutton = document.createElement("SPAN"); abutton.id = 'autoMapStatus'; newContainer.appendChild(abutton); fightButtonCol.appendChild(newContainer); - //create hiderStatus - He/hr percent (in world sidebar) newContainer = document.createElement("DIV"); newContainer.setAttribute("style", "display: block; font-size: 1vw; text-align: center; margin-top: 2px; background-color: rgba(0,0,0,0.3);"); - newContainer.setAttribute("onmouseover", 'tooltip(\"Helium/Hr Info\", \"customText\", event, \"1st is Current He/hr % out of Lifetime He(not including current+unspent).
0.5% is an ideal peak target. This can tell you when to portal...
2nd is Current run Total He earned / Lifetime He(not including current)
\" + getDailyHeHrStats())'); + if (game.global.universe == 1) + newContainer.setAttribute("onmouseover", 'tooltip(\"Helium/Hr Info\", \"customText\", event, \"1st is Current He/hr % out of Lifetime He(not including current+unspent).
0.5% is an ideal peak target. This can tell you when to portal...
2nd is Current run Total He earned / Lifetime He(not including current)
\" + getDailyHeHrStats())'); + else if (game.global.universe == 2) + newContainer.setAttribute("onmouseover", 'tooltip(\"Radon/Hr Info\", \"customText\", event, \"1st is Current Rn/hr % out of Lifetime Rn(not including current+unspent).
0.5% is an ideal peak target. This can tell you when to portal...
2nd is Current run Total Rn earned / Lifetime Rn(not including current)
\" + getDailyRnHrStats())'); newContainer.setAttribute("onmouseout", 'tooltip("hide")'); abutton = document.createElement("SPAN"); abutton.id = 'hiderStatus'; newContainer.appendChild(abutton); fightButtonCol.appendChild(newContainer); - //make timer clock toggle paused mode when clicked (bottom right) var $portalTimer = document.getElementById('portalTimer'); $portalTimer.setAttribute('onclick', 'toggleSetting(\'pauseGame\')'); $portalTimer.setAttribute('style', 'cursor: default'); - //shrink padding for fight buttons to help fit automaps button/status var btns = document.getElementsByClassName("fightBtn"); for (var x = 0; x < btns.length; x++) { btns[x].style.padding = "0.01vw 0.01vw"; @@ -67,127 +62,172 @@ function automationMenuInit() { } automationMenuInit(); -//create container for settings buttons (this is seperate because it needs to -// be re-run seperately to reset when importing) +function modifyParentNode(setting, id) { + var elem = document.getElementById(id).parentNode.parentNode.children; + for (i = 0; i < elem.length; i++) { + if (document.getElementById(id).parentNode.parentNode.children[i].children[0] === undefined) { + continue + } else { + if (document.getElementById(id).parentNode.parentNode.children[i].children[0].id === id) { + if (autoTrimpSettings[setting].enabled) { + if (elem.length > (i + 1)) { + if (document.getElementById(id).parentNode.parentNode.children[(i + 1)].style.length == 0) { + document.getElementById(id).parentNode.parentNode.children[(i + 1)].remove() + break; + } + } + } else { + document.getElementById(id).parentNode.parentNode.children[i].insertAdjacentHTML('afterend', '
'); + } + } + + } + } +} + function automationMenuSettingsInit() { - var settingsrow = document.getElementById("settingsRow"); - var autoSettings = document.createElement("DIV"); - autoSettings.id = "autoSettings"; - autoSettings.setAttribute("style", "display: none; max-height: 92.5vh;overflow: auto;"); - autoSettings.setAttribute("class","niceScroll"); - settingsrow.appendChild(autoSettings); + var a = document.getElementById("settingsRow"), + b = document.createElement("DIV"); + b.id = "autoSettings", b.setAttribute("style", "display: none; max-height: 92.5vh;overflow: auto;"), b.setAttribute("class", "niceScroll"), a.appendChild(b) } automationMenuSettingsInit(); +var link1 = document.createElement("link"); +link1.rel = "stylesheet", link1.type = "text/css", link1.href = basepath + "tabs.css", document.head.appendChild(link1); -//prepare CSS for new Tab interface -var link1 = document.createElement('link'); -link1.rel = "stylesheet"; -link1.type = "text/css"; -link1.href = basepath + 'tabs.css'; -document.head.appendChild(link1); - -//Tab make helperfunctions -function createTabs(name, description) { - var li_0 = document.createElement('li'); - var a_0 = document.createElement('a'); - a_0.className = "tablinks"; - a_0.setAttribute('onclick', 'toggleTab(event, \'' + name + '\')'); - a_0.href = "#"; - a_0.appendChild(document.createTextNode(name)); - li_0.id = 'tab' + name; - li_0.appendChild(a_0); - addtabsUL.appendChild(li_0); - createTabContents(name, description); +function createTabs(a, b) { + var c = document.createElement("li"), + d = document.createElement("a"); + d.className = "tablinks", d.setAttribute("onclick", "toggleTab(event, '" + a + "')"), d.href = "#", d.appendChild(document.createTextNode(a)), c.id = "tab" + a, c.appendChild(d), addtabsUL.appendChild(c), createTabContents(a, b) } -function createTabContents(name, description) { - var div_0 = document.createElement('div'); - div_0.className = "tabcontent"; - div_0.id = name; - var div_1 = document.createElement('div'); - div_1.setAttribute("style", "margin-left: 1vw; margin-right: 1vw;"); - var h4_0 = document.createElement('h4'); - h4_0.setAttribute('style', 'font-size: 1.2vw;'); - h4_0.appendChild(document.createTextNode(description)); - div_1.appendChild(h4_0); - div_0.appendChild(div_1); - addTabsDiv.appendChild(div_0); +function createTabContents(a, b) { + var c = document.createElement('div'); + c.className = 'tabcontent', c.id = a; + var d = document.createElement('div'); + d.setAttribute('style', 'margin-left: 1vw; margin-right: 1vw;'); + var e = document.createElement('h4'); + e.setAttribute('style', 'font-size: 1.2vw;'), e.appendChild(document.createTextNode(b)), d.appendChild(e), c.appendChild(d), addTabsDiv.appendChild(c) } -//Toggle handler (onclick) -function toggleTab(evt, tabName) { - if (evt.currentTarget.className.indexOf(" active") > -1) { - document.getElementById(tabName).style.display = "none"; - evt.currentTarget.className = evt.currentTarget.className.replace(" active", ""); - } else { - document.getElementById(tabName).style.display = "block"; - evt.currentTarget.className += " active"; - } +function toggleTab(a, b) { + -1 < a.currentTarget.className.indexOf(" active") ? (document.getElementById(b).style.display = "none", a.currentTarget.className = a.currentTarget.className.replace(" active", "")) : (document.getElementById(b).style.display = "block", a.currentTarget.className += " active") } -//Minimize button handler function minimizeAllTabs() { - // Get all elements with class="tabcontent" and hide them - var tabcontent = document.getElementsByClassName("tabcontent"); - for (var i = 0,len = tabcontent.length; i < len ; i++) { - tabcontent[i].style.display = "none"; - } - // Get all elements with class="tablinks" and remove the class "active" - var tablinks = document.getElementsByClassName("tablinks"); - for (var i = 0,len = tablinks.length; i < len ; i++) { - // if (!(tablinks[i].className.includes('minimize') || tablinks[i].className.includes('maximize') || tablinks[i].className.includes('tabclose') || tablinks[i].parentNode.id.includes('tabCore'))) - // tablinks[i].style.display = "none"; - tablinks[i].className = tablinks[i].className.replace(" active", ""); - } + for (var a = document.getElementsByClassName("tabcontent"), b = 0, c = a.length; b < c; b++) a[b].style.display = "none"; + for (var d = document.getElementsByClassName("tablinks"), b = 0, c = d.length; b < c; b++) d[b].className = d[b].className.replace(" active", "") } -//Minimize button handler function maximizeAllTabs() { - // Get all elements with class="tabcontent" and show them - var tabcontent = document.getElementsByClassName("tabcontent"); - for (var i = 0,len = tabcontent.length; i < len ; i++) { - tabcontent[i].style.display = "block"; - } - // Get all elements with class="tablinks" and add the class "active" - var tablinks = document.getElementsByClassName("tablinks"); - for (var i = 0,len = tablinks.length; i < len ; i++) { - tablinks[i].style.display = "block"; - if (!tablinks[i].className.includes(' active')) - tablinks[i].className += " active"; + for (var a = document.getElementsByClassName("tabcontent"), b = 0, c = a.length; b < c; b++) a[b].style.display = "block"; + for (var d = document.getElementsByClassName("tablinks"), b = 0, c = d.length; b < c; b++) d[b].style.display = "block", d[b].className.includes(" active") || (d[b].className += " active") +} + +function nuloom(slot) { + var nuloom = getPageSetting('heirloomnu'); + if (game.global.ShieldEquipped.name == nuloom) { + selectHeirloom(-1, 'ShieldEquipped', true); + if (slot == 0) { + return game.global.ShieldEquipped.mods[0][0]; + } + if (slot == 1) { + return game.global.ShieldEquipped.mods[1][0]; + } + if (slot == 2) { + return game.global.ShieldEquipped.mods[2][0]; + } + if (slot == 3) { + return game.global.ShieldEquipped.mods[3][0]; + } + if (slot == 4) { + return game.global.ShieldEquipped.mods[4][0]; + } + if (slot == 5) { + return game.global.ShieldEquipped.mods[5][0]; + } + } + + if (game.global.StaffEquipped.name == nuloom) { + selectHeirloom(-1, 'StaffEquipped', true); + if (slot == 0) { + return game.global.StaffEquipped.mods[0][0]; + } + if (slot == 1) { + return game.global.StaffEquipped.mods[1][0]; + } + if (slot == 2) { + return game.global.StaffEquipped.mods[2][0]; + } + if (slot == 3) { + return game.global.StaffEquipped.mods[3][0]; + } + if (slot == 4) { + return game.global.StaffEquipped.mods[4][0]; + } + if (slot == 5) { + return game.global.StaffEquipped.mods[5][0]; + } + } + + if (game.global.StaffEquipped.name != nuloom && game.global.ShieldEquipped.name != nuloom) { + for (var loom of game.global.heirloomsCarried) { + if (loom.name == getPageSetting('heirloomnu')) { + selectHeirloom(game.global.heirloomsCarried.indexOf(loom), "heirloomsCarried", true); + if (slot == 0) { + return loom.mods[0][0]; + } + if (slot == 1) { + return loom.mods[1][0]; + } + if (slot == 2) { + return loom.mods[2][0]; + } + if (slot == 3) { + return loom.mods[3][0]; + } + if (slot == 4) { + return loom.mods[4][0]; + } + if (slot == 5) { + return loom.mods[5][0]; + } + } + } } } var addTabsDiv; var addtabsUL; -//Actually Make the Tabs + function initializeAllTabs() { - //CREATE TABS + CONTENT addTabsDiv = document.createElement('div'); addtabsUL = document.createElement('ul'); addtabsUL.className = "tab"; addtabsUL.id = 'autoTrimpsTabBarMenu'; addtabsUL.style.display = "none"; - //Pin settings Tab Bar to the top like the other bar? var sh = document.getElementById("settingsRow") sh.insertBefore(addtabsUL, sh.childNodes[2]); - //addTabsDiv.appendChild(addtabsUL); - //Then it has to be maintained and toggled on off. - //Make Tabs. createTabs("Core", "Core - Main Controls for the script"); createTabs("Buildings", "Building Settings"); createTabs("Jobs", "Jobs - Worker Settings"); createTabs("Gear", "Gear - Equipment Settings"); createTabs("Maps", "Maps - AutoMaps & VoidMaps Settings"); + createTabs("Spire", "Spire - Settings for Spires"); + createTabs("Raiding", "Raiding - Settings for Raiding"); + createTabs("Daily", "Dailies - Settings for Dailies"); + createTabs("C2", "C2 - Settings for C2s"); + createTabs("Challenges", "Challenges - Settings for Specific Challenges"); createTabs("Combat", "Combat & Stance Settings"); + createTabs("Windstacking", "Windstacking Settings"); + createTabs("ATGA", "Geneticassist Settings"); createTabs("Scryer", "Scryer Settings"); createTabs("Magma", "Dimensional Generator & Magmite Settings"); createTabs("Heirlooms", "Heirloom Settings"); createTabs("Golden", "Golden Upgrade Settings"); + createTabs("SA", "SA Settings"); createTabs("Nature", "Nature Settings"); createTabs("Display", "Display & Spam Settings"); - //createTabs("Modules", "Load/Unload Modules & Settings"); createTabs("Import Export", "Import & Export Settings"); - //add a minimize button: var li_0 = document.createElement('li'); var a_0 = document.createElement('a'); a_0.className = "tablinks minimize"; @@ -196,9 +236,8 @@ function initializeAllTabs() { a_0.appendChild(document.createTextNode("-")); li_0.appendChild(a_0); li_0.setAttribute("style", "float:right!important;"); - li_0.setAttribute("onmouseover",'tooltip("Minimize all tabs", "customText", event, "Minimize all AT settings tabs.")'); + li_0.setAttribute("onmouseover", 'tooltip("Minimize all tabs", "customText", event, "Minimize all AT settings tabs.")'); li_0.setAttribute("onmouseout", 'tooltip("hide")'); - //add a maximize button: var li_1 = document.createElement('li'); var a_1 = document.createElement('a'); a_1.className = "tablinks maximize"; @@ -207,9 +246,8 @@ function initializeAllTabs() { a_1.appendChild(document.createTextNode("+")); li_1.appendChild(a_1); li_1.setAttribute("style", "float:right!important;"); - li_1.setAttribute("onmouseover",'tooltip("Maximize all tabs", "customText", event, "Maximize all AT settings tabs.")'); + li_1.setAttribute("onmouseover", 'tooltip("Maximize all tabs", "customText", event, "Maximize all AT settings tabs.")'); li_1.setAttribute("onmouseout", 'tooltip("hide")'); - //add a minimize button: var li_2 = document.createElement('li'); var a_2 = document.createElement('a'); a_2.className = "tablinks tabclose"; @@ -218,245 +256,916 @@ function initializeAllTabs() { a_2.appendChild(document.createTextNode("x")); li_2.appendChild(a_2); li_2.setAttribute("style", "float:right!important;"); - li_2.setAttribute("onmouseover",'tooltip("Exit (duplicate)", "customText", event, "Closes/toggles/hides AutoTrimps (just a UI shortcut)")'); + li_2.setAttribute("onmouseover", 'tooltip("Exit (duplicate)", "customText", event, "Closes/toggles/hides AutoTrimps (just a UI shortcut)")'); li_2.setAttribute("onmouseout", 'tooltip("hide")'); - addtabsUL.appendChild(li_2); //close - addtabsUL.appendChild(li_1); //max - addtabsUL.appendChild(li_0); //min - //Insert tabs into the game area + addtabsUL.appendChild(li_2); + addtabsUL.appendChild(li_1); + addtabsUL.appendChild(li_0); document.getElementById("autoSettings").appendChild(addTabsDiv); - //pretend click to make first tab active. document.getElementById("Core").style.display = "block"; document.getElementsByClassName("tablinks")[0].className += " active"; } initializeAllTabs(); -//Actually Make the Settings Buttons function initializeAllSettings() { - //START MAKING BUTTONS IN THE TABS: - - - -//CORE: - //Line1: - createSetting('ManualGather2', ['Gather/Build OFF', 'Auto Gather/Build', 'Science Research OFF', 'Auto Gather/Build #2'], '4-Way Button. Auto Gathering of Food,Wood,Metal(w/turkimp) & Science. Auto speed-Builds your build queue. Now able to turn science researching off for the achievement Reach Z120 without using manual research. The decision between AutoGather 1 or 2 is up to your own discretion and they should be similar.', 'multitoggle', 1, null, "Core"); - createSetting('BuyUpgrades', 'Buy Upgrades', 'Autobuy non equipment Upgrades', 'boolean', true, null, "Core"); - createSetting('TrapTrimps', 'Trap Trimps', 'Automatically trap trimps when needed, including building traps. (when you turn off, make sure you also turn off the ingame AutoTraps button)', 'boolean', true, null, "Core"); - createSetting('ManageBreedtimer', 'Auto Breed Timer', 'Genetecist management is controlled by the Timer setting box to the right, not this.
Explanation:
[ON](Green): All this does is auto-choose the appropriate timer for various challenges (0, 3.5s, 10s, 30s).
[OFF](Red): You set the Timer yourself! Even if this is red, it still tampers with genetecists if the timer is >= 0.
Note: Using AutoStance is recommended to survive the full 30 seconds or else Auto will probably be undesirable.', 'boolean', true, null, "Core"); - createSetting('UsePatience', 'Enable Patience', 'Sets the default breed timer to 45 seconds if you have the Patience mastery.', 'boolean', true, null, 'Core'); - createSetting('GeneticistTimer', 'Geneticist Timer', 'Manages the breed timer by hiring/firing Geneticists for the purpose of setting the ideal anticpation stacks. Disable with -1 to disable the Hiring/Firing of geneticists.
Info: Potency and Nursery buying behavior is adjusted dynamically (and disabling no longer disables potency). The Automatic Genetecist Hiring Process can best be summarized by: Buy/Wait/Die,Repeat. (if you do not die, no action is taken). Also self-kills (trimpicide) aka force abandon when your anti-stacks arent maxed out (conservatively).

Controlled automatically (locked) when Auto Breed Timer is on.', 'value', '30', null, "Core"); - createSetting('SpireBreedTimer', 'Spire Breed Timer', 'Set a different breed timer target for the Spire. Use -1 to disable this special setting.', 'value', -1, null, 'Core'); - //Line2 - createSetting('AutoAllocatePerks', 'Auto Allocate Perks', 'Uses the AutoPerks ratio based preset system to automatically allocate your perks to spend whatever helium you have when you AutoPortal. ', 'boolean', false, null, 'Core'); - createSetting('AutoStartDaily', 'Auto Start Daily', 'With this on, the Auto Portal options will portal you into and auto-start the daily whenever available. Does Yesterday first, followed by Today. Falls back to selected challenge when both are complete.', 'boolean', false, null, 'Core'); - createSetting('AutoFinishDaily', 'Auto Finish Daily', 'With this on, the He/Hr Portal and Custom Auto Portal options will auto-finish the daily whenever they trigger and THEN portal you.', 'boolean', true, null, 'Core'); - createSetting('AutoFinishDailyZone', 'Finish Daily Zone Mod', 'Finish Daily by this # of zones earlier/later than your regular Custom AutoPortal zone or your Helium Dont Portal Before zone. When Auto Finish Daily is on. Tip: Tune your value of He/HrDontPortalBefore to suit the daily, and then tune this. Can accept negative numbers for earlier, ie: -7 means portal 7 zones earlier than normal. Can also use positive numbers to DELAY portaling for later. When used with He/Hr AutoPortal, the number of zones early does not FORCE end the daily at that zone, only ALLOW it to end that early: it will Always end when your HE/hr drops enough to trigger the portal. Use 0 to disable.', 'valueNegative', 0, null, 'Core'); - createSetting('FinishC2', 'Finish Challenge2', 'Finish / Abandon Challenge2 (any) when this zone is reached, if you are running one. For manual use. Recommended: Zones ending with 0 for most challenges. Disable with -1.', 'value', -1, null, 'Core'); - if (game.worldUnlocks.easterEgg) + + //Core + + //Line 1 + createSetting('ManualGather2', ['Manual Gather/Build', 'Auto Gather/Build', 'Mining/Building Only', 'Science Research OFF'], 'Controls what you gather/build do. Manual does nothing
Auto Gathering of Food,Wood,Metal(w/turkimp) & Science. Auto speed-Builds your build queue.
Mining/Building only does exactly what it says. Only use if you are passed the early stages of the game and have the mastery foremany unlocked (No longer need to trap, food and wood are useless).
You can disable science researching for the achievement: Reach Z120 without using manual research.', 'multitoggle', 1, null, "Core"); + createSetting('gathermetal', 'Metal Only', 'For use with Mining/Gather Only. Only gathers Metal if you have foremany unlocked. ', 'boolean', false, null, "Core"); + createSetting('BuyUpgradesNew', ['Manual Upgrades', 'Buy All Upgrades', 'Upgrades no Coords'], 'Autobuys non-equipment upgrades (equipment is controlled in the Gear tab). The second option does NOT buy coordination (use this ONLY if you know what you\'re doing).', 'multitoggle', 1, null, "Core"); + createSetting('amalcoord', 'Amal Boost', 'Boost your Amal count for more Mi. Will not buy coords until your H:D ratio is below a certain value. This means that you will get amals quicker. Will not activate higher than your Amal Boost End Zone Setting! ', 'boolean', false, null, "Core"); + createSetting('amalcoordt', 'Amal Target', 'Set the amount of Amals you wish to aim for. Once this target is reached, it will buy coords below your Amal ratio regardless of your H:D, just enough to keep the Amal. -1 to disable and use H:D for entire boost. ', 'value', -1, null, "Core"); + createSetting('amalcoordhd', 'Amal Boost H:D', 'Set your H:D for Amal Boost here. The higher it is the less coords AT will buy. 0.0000025 is the default. ', 'value', 0.0000025, null, "Core"); + createSetting('amalcoordz', 'Amal Boost End Z', 'Amal Boost End Zone. Set the zone you want to stop Amal Boosting. -1 to do it infinitely. ', 'value', -1, null, "Core"); + createSetting('AutoAllocatePerks', ['Auto Allocate Off', 'Auto Allocate On', 'Dump into Looting II'], 'Uses the AutoPerks ratio based preset system to automatically allocate your perks to spend whatever helium you have when you AutoPortal. Does not change Fixed Perks: siphonology, anticipation, meditation, relentlessness, range, agility, bait, trumps, packrat, capable. NEW: Dump into Looting II, dumps all loot gained from previous portal at specified zone', 'multitoggle', 0, null, 'Core'); + + //Line 2 + createSetting('fastallocate', 'Fast Allocate', 'Turn on if your helium is above 500Qa. Not recommended for low amounts of helium. ', 'boolean', false, null, 'Core'); + createSetting('TrapTrimps', 'Trap Trimps', 'Automatically trap trimps when needed, including building traps. (when you turn this off, you may aswell turn off the in-game autotraps button, think of the starving trimps that could eat that food!)', 'boolean', true, null, "Core"); createSetting('AutoEggs', 'AutoEggs', 'Click easter egg if it exists, upon entering a new zone. Warning: Quite overpowered. Please solemnly swear that you are up to no good.', 'boolean', false, null, 'Core'); - createSetting('ManualCoords', 'Don\'t buy Coords', 'Enable it if you know what you\'re doing, disable it if you don\'t know what you\'re doing. For when manually handling coords means a lot on challenges like Trapper.', 'boolean', false, null, 'Core'); - //NewLine3 - document.getElementById('ManualCoords').parentNode.insertAdjacentHTML('afterend','
'); - createSetting('AutoPortal', 'Auto Portal', 'Automatically portal. Will NOT auto-portal if you have a challenge active, the challenge setting dictates which challenge it will select for the next run. All challenge settings will portal right after the challenge ends, regardless. Helium Per Hour only portals at cell 1 of the first level where your He/Hr went down even slightly compared to the current runs Best He/Hr. Take note, there is a Buffer option, which is like a grace percentage of how low it can dip without triggering. Setting a buffer will portal mid-zone if you exceed 5x of the buffer. CAUTION: Selecting He/hr may immediately portal you if its lower-(use Pause AutoTrimps button to pause the script first to avoid this)', 'dropdown', 'Off', ['Off', 'Helium Per Hour', 'Balance', 'Decay', 'Electricity', 'Life', 'Crushed', 'Nom', 'Toxicity', 'Watch', 'Lead', 'Corrupted', 'Custom'], "Core"); - //document.getElementById("AutoPortal").style="font-size: 1.0vw;"; //fit it on 1 line. - createSetting('HeliumHourChallenge', 'Portal Challenge', 'Automatically portal into this challenge when using helium per hour or custom autoportal. Custom portals after cell 100 of the zone specified. ', 'dropdown', 'None', ['None', 'Balance', 'Decay', 'Electricity', 'Life', 'Crushed', 'Nom', 'Toxicity', 'Watch', 'Lead', 'Corrupted'], "Core"); - //document.getElementById("HeliumHourChallengeLabel").innerHTML = "Portal Challenge:"; //fit it on 1 line. + createSetting('AutoBoneChargeMax', ['Manual Bone Charge', 'Bone Charge When Max', 'Bone Charge (Daily Only)'], 'Automatically uses a Bone Charge from the Bone Shrine if you are at max charges. The start zone can be configured under Bone Charge Start Z.

Bone Charge (Daily Only) as the name suggests; will only use a Bone Charge when at max and if on a daily challenge.

Default: Off (Manual Bone Charge).', 'multitoggle', 0, null, "Core"); + createSetting('AutoBoneChargeMaxStartZone', 'Bone Charge Start Z', 'Enter the zone number at which you wish to start using Bone Charges.

Alternatively, set it to -1 to automatically update the zone to 10% of your highest zone cleared. For example, if your highest zone cleared was 400, bone charges would be automatically used from zone 360 onwards.

Default: Automated (-1).', 'value', -1, null, "Core"); + document.getElementById('AutoEggs').parentNode.insertAdjacentHTML('afterend', '
'); + + //RCore + + //Line 1 + createSetting('RManualGather2', ['Manual Gather/Build', 'Auto Gather/Build', 'Mining/Building Only'], 'Controls what you gather/build do. Manual does nothing
Auto Gathering of Food,Wood,Metal(w/turkimp) & Science. Auto speed-Builds your build queue.
Mining/Building only does exactly what it says. Only use if you are passed the early stages of the game and have the mastery foremany unlocked (No longer need to trap, food and wood are useless). ', 'multitoggle', 1, null, "Core"); + createSetting('RTrapTrimps', 'Trap Trimps', 'Automatically trap trimps when needed, including building traps. (when you turn this off, you may aswell turn off the in-game autotraps button, think of the starving trimps that could eat that food!)', 'boolean', true, null, "Core"); + createSetting('RBuyUpgradesNew', ['Manual Upgrades', 'Buy All Upgrades', 'Upgrades no Coords'], 'Autobuys non-equipment upgrades (equipment is controlled in the Gear tab). The second option does NOT buy coordination (use this ONLY if you know what you\'re doing).', 'multitoggle', 1, null, "Core"); + createSetting('RAutoAllocatePerks', ['Auto Allocate Off', 'Auto Allocate On', 'Dump into Looting'], 'Uses the AutoPerks ratio based preset system to automatically allocate your perks to spend whatever helium you have when you AutoPortal. Does not change Fixed Perks: siphonology, anticipation, meditation, relentlessness, range, agility, bait, trumps, packrat, capable. NEW: Dump into Looting, dumps all loot gained from previous portal at specified zone', 'multitoggle', 0, null, 'Core'); + createSetting('Rdumpgreed', 'Greed Dump', 'Dump Radon into Greed instead. ', 'boolean', false, null, "Core"); + + + //Portal + createSetting('AutoPortal', 'AutoPortal', 'Automatically portal. Will NOT auto-portal if you have a challenge active, the challenge setting dictates which challenge it will select for the next run. All challenge settings will portal right after the challenge ends, regardless. Helium Per Hour only portals at cell 1 of the first level where your He/Hr went down even slightly compared to the current runs Best He/Hr. Take note, there is a Buffer option, which is like a grace percentage of how low it can dip without triggering. Setting a buffer will portal mid-zone if you exceed 5x of the buffer. CAUTION: Selecting He/hr may immediately portal you if its lower-(use Pause AutoTrimps button to pause the script first to avoid this)', 'dropdown', 'Off', ['Off', 'Helium Per Hour', 'Balance', 'Decay', 'Electricity', 'Life', 'Crushed', 'Nom', 'Toxicity', 'Watch', 'Lead', 'Corrupted', 'Domination', 'Experience', 'Custom'], "Core"); + createSetting('HeliumHourChallenge', 'Portal Challenge', 'Automatically portal into this challenge when using helium per hour or custom autoportal. Custom portals after cell 100 of the zone specified. Do not choose a challenge if you havent unlocked it. ', 'dropdown', 'None', ['None', 'Balance', 'Decay', 'Electricity', 'Life', 'Crushed', 'Nom', 'Toxicity', 'Watch', 'Lead', 'Corrupted', 'Domination', 'Experience'], "Core"); + document.getElementById("HeliumHourChallengeLabel").innerHTML = "Portal Challenge:"; createSetting('CustomAutoPortal', 'Custom Portal', 'Automatically portal AFTER clearing this level.(ie: setting to 200 would portal when you first reach level 201)', 'value', '999', null, "Core"); createSetting('HeHrDontPortalBefore', 'Don\'t Portal Before', 'Do NOT allow Helium per Hour AutoPortal setting to portal BEFORE this level is reached. It is an additional check that prevents drops in helium/hr from triggering autoportal. Set to 0 or -1 to completely disable this check. (only shows up with Helium per Hour set)', 'value', '999', null, "Core"); createSetting('HeliumHrBuffer', 'He/Hr Portal Buffer %', 'IMPORTANT SETTING. When using the He/Hr Autoportal, it will portal if your He/Hr drops by this amount of % lower than your best for current run, default is 0% (ie: set to 5 to portal at 95% of your best). Now with stuck protection - Allows portaling midzone if we exceed set buffer amount by 5x. (ie a normal 2% buffer setting would now portal mid-zone you fall below 10% buffer).', 'value', '0', null, 'Core'); - createSetting('PauseScript', 'Pause AutoTrimps', 'Pause AutoTrimps Script (not including the graphs module)', 'boolean', null, null, 'Core'); - //code to locate the pause button at lower right - var $pauseScript = document.getElementById('PauseScript'); - $pauseScript.parentNode.style.setProperty('float','right'); - $pauseScript.parentNode.style.setProperty('margin-right','1vw'); - $pauseScript.parentNode.style.setProperty('margin-left','0'); - + //RPortal + document.getElementById('Rdumpgreed').parentNode.insertAdjacentHTML('afterend', '
'); + createSetting('RAutoPortal', 'AutoPortal', 'Automatically portal. Will NOT auto-portal if you have a challenge active, the challenge setting dictates which challenge it will select for the next run. All challenge settings will portal right after the challenge ends, regardless. Radon Per Hour only portals at cell 1 of the first level where your Rn/Hr went down even slightly compared to the current runs Best Rn/Hr. Take note, there is a Buffer option, which is like a grace percentage of how low it can dip without triggering. Setting a buffer will portal mid-zone if you exceed 5x of the buffer. CAUTION: Selecting Rn/hr may immediately portal you if its lower-(use Pause AutoTrimps button to pause the script first to avoid this)', 'dropdown', 'Off', ['Off', 'Radon Per Hour', 'Bublé', 'Melt', 'Quagmire', 'Archaeology', 'Insanity', 'Nurture', 'Alchemy', 'Hypothermia', 'Custom'], "Core"); + createSetting('RadonHourChallenge', 'Portal Challenge', 'Automatically portal into this challenge when using radon per hour or custom autoportal. Custom portals after cell 100 of the zone specified. Do not choose a challenge if you havent unlocked it. ', 'dropdown', 'None', ['None', 'Bublé', 'Melt', 'Quagmire', 'Archaeology', 'Insanity', 'Nurture', 'Alchemy', 'Hypothermia'], "Core"); + createSetting('RCustomAutoPortal', 'Custom Portal', 'Automatically portal AFTER clearing this level.(ie: setting to 200 would portal when you first reach level 201)', 'value', '999', null, "Core"); + createSetting('RnHrDontPortalBefore', 'Don\'t Portal Before', 'Do NOT allow Radon per Hour AutoPortal setting to portal BEFORE this level is reached. It is an additional check that prevents drops in radon/hr from triggering autoportal. Set to 0 or -1 to completely disable this check. (only shows up with Radon per Hour set)', 'value', '999', null, "Core"); + createSetting('RadonHrBuffer', 'Rn/Hr Portal Buffer %', 'IMPORTANT SETTING. When using the Rn/Hr Autoportal, it will portal if your Rn/Hr drops by this amount of % lower than your best for current run, default is 0% (ie: set to 5 to portal at 95% of your best). Now with stuck protection - Allows portaling midzone if we exceed set buffer amount by 5x. (ie a normal 2% buffer setting would now portal mid-zone you fall below 10% buffer).', 'value', '0', null, 'Core'); -//Buildings - createSetting('BuyStorage', 'Buy Storage', 'Will buy storage when resource is almost full. (like AutoStorage, even anticipates Jestimp)', 'boolean', true, null, "Buildings"); - createSetting('BuyBuildings', 'Buy Buildings', 'Will buy non storage buildings as soon as they are available', 'boolean', true, null, "Buildings"); + //Pause + Switch + createSetting('PauseScript', 'Pause AutoTrimps', 'Pause AutoTrimps Script (not including the graphs module)', 'boolean', null, null, 'Core'); + var $pauseScript = document.getElementById('PauseScript'); + $pauseScript.parentNode.style.setProperty('float', 'right'); + $pauseScript.parentNode.style.setProperty('margin-right', '1vw'); + $pauseScript.parentNode.style.setProperty('margin-left', '0'); + createSetting('radonsettings', ['Helium', 'Radon'], 'Switch between Helium (U1) and Radon (U2) settings. ', 'multitoggle', 0, null, 'Core'); + var $radonsettings = document.getElementById('radonsettings'); + $radonsettings.parentNode.style.setProperty('float', 'right'); + $radonsettings.parentNode.style.setProperty('margin-right', '1vw'); + $radonsettings.parentNode.style.setProperty('margin-left', '0'); + + + + //Daily + + //Line 1 + createSetting('buyheliumy', 'Buy Heliumy %', 'Buys the Heliumy bonus for 100 bones when Daily bonus is above the value set in this setting. Recommend anything above 475. Will not buy if you cant afford to, or value is -1. ', 'value', -1, null, 'Daily'); + createSetting('dfightforever', ['DFA: Off', 'DFA: Non-Empowered', 'DFA: All Dailies'], 'Daily Fight Always. Sends trimps to fight if they\'re not fighting in Daily challenges similar to Toxicity/Nom but not on Bloodthirst/Plagued/Bogged Dailies, regardless of BAF. Non-Empowered will only send to fight if the Daily is not Empowered. Essenitally the same as the one in combat, can use either if you wish, except this will only activate in these daily challenges (duh) ', 'multitoggle', '0', null, 'Daily'); + createSetting('avoidempower', 'Avoid Empower', 'Tries to avoid Empower stacks in Empower Dailies. No harm in this being on, so default is On. ', 'boolean', true, null, 'Daily'); + createSetting('darmormagic', ['Daily Armor Magic Off', 'DAM: Above 80%', 'DAM: H:D', 'DAM: Always'], 'Will buy Armor to try and prevent death on Bleed/Plague/Bogged Dailies under the 3 conditions.
Above 80%: Will activate at and above 80% of your HZE.
H:D: Will activate at and above the H:D you have defined in maps.
Always Will activate always.
All options will activate at or below 25% of your health. ', 'multitoggle', 0, null, "Daily"); + createSetting('dscryvoidmaps', 'Daily VM Scryer', 'Only use in Dailies if you have Scryhard II, for er, obvious reasons. Works without the scryer options. ', 'boolean', false, null, 'Daily'); + + //Spire + document.getElementById('dscryvoidmaps').parentNode.insertAdjacentHTML('afterend', '
'); + createSetting('dIgnoreSpiresUntil', 'Daily Ignore Spires Until', 'Spire specific settings like end-at-cell are ignored until at least this zone is reached in Dailies (0 to disable). ', 'value', '200', null, 'Daily'); + createSetting('dExitSpireCell', 'Daily Exit Spire Cell', 'What cell to exit spire in dailys. ', 'value', -1, null, 'Daily'); + createSetting('dPreSpireNurseries', 'Daily Nurseries pre-Spire', 'Set the maximum number of Nurseries to build for Spires in Dailies. Overrides No Nurseries Until z and Max Nurseries so you can keep them seperate! Disable with -1.', 'value', -1, null, 'Daily'); + + //Windstacking + document.getElementById('dPreSpireNurseries').parentNode.insertAdjacentHTML('afterend', '
'); + createSetting('use3daily', 'Daily Windstacking', ' This must be on for Daily windstacking settings to appear! Overrides your Autostance settings to use the WS stance on Dailies. Make sure Windstack HD is set otherwise this does nothing. ', 'boolean', false, null, 'Daily'); + createSetting('dWindStackingMin', 'Daily Windstack Min Zone', 'For use with Windstacking Stance, enables windstacking in zones above and inclusive of the zone set for dailys. (Get specified windstacks then change to D, kill bad guy, then repeat). This is designed to force S use until you have specified stacks in wind zones, overriding scryer settings. All windstack settings apart from Daily WS MAX work off this setting. ', 'value', '-1', null, 'Daily'); + createSetting('dWindStackingMinHD', 'Daily Windstack H:D', 'For use with Windstacking Stance in Dailies, fiddle with this to maximise your stacks in wind zones for Dailies. If H:D is above this setting it will not use W stance. If it is below it will. Use something like 10 decillion if you just want to use W stance. ', 'value', '1e33', null, 'Daily'); + createSetting('dWindStackingMax', 'Daily Windstack Stacks', 'For use with Windstacking Stance in Dailies. Amount of windstacks to obtain before switching to D stance. Default is 200, but I recommend anywhere between 175-190. In Wind Enlightenment it will add 100 stacks to your total automatically. So if this setting is 200 It will assume you want 300 stacks instead during enlightenment. ', 'value', '200', null, 'Daily'); + createSetting('dwindcutoff', 'Daily Wind Damage Cutoff', 'Set this value to optimise your windstacking in dailys. Can work without Windstacking Stance, but not recommended. AT normally uses 4 as its cutoff. I.e if the cutoff is above 4 it will buy max equipment. If you set this to 160, it will not get more damage till you are above x160. Essentially, the higher the value, the less damage AT wants to get, this will enable you to windstack to incredibly high amounts. -1 to disable/go back to default. Must set your windstacking min zone to use. ', 'value', '-1', null, 'Daily'); + createSetting('dwindcutoffmap', 'Daily Wind Map Cutoff', 'Set this value to optimise your windstacking in dailys. Can work without Windstacking Stance, but not recommended. AT normally uses 4 as its cutoff. I.e if the cutoff is above 4 it will do map bonus. If you set this to 160, it will not do maps till you are above x160. Essentially, the higher the value, the less damage AT wants to get, this will enable you to windstack to incredibly high amounts. -1 to disable/go back to default. Must set your windstacking min zone to use. ', 'value', '-1', null, 'Daily'); + createSetting('liqstack', 'Stack Liquification', 'Stack Wind zones during Wind Enlight during Liquification. ', 'boolean', false, null, 'Daily'); + createSetting('dwsmax', 'Daily WS MAX', 'For maximising Windstacking an entire Daily. Withholds damage to try and get your max windstacks every wind zone. Not recommended for terrible Dailies. ', 'value', '-1', null, 'Daily'); + createSetting('dwsmaxhd', 'Daily WSM H:D', 'Fiddle with this to maximise your DWSM settings. Default is 0.00025. ', 'value', '-1', null, 'Daily'); + + //Raiding + document.getElementById('dwsmaxhd').parentNode.insertAdjacentHTML('afterend', '
'); + createSetting('dPraidingzone', 'Daily P Raiding Z', 'Raids Maps for prestiges at zone specified in Dailies. Example: 495, will raid Maps at 501. Once all gear is obtained from the map, it will revert back to regular farming. Extremely helpful for spire. Best used in poison zones. You can use multiple values like this 495,506,525! ', 'multiValue', [-1], null, 'Daily'); + createSetting('dPraidingcell', 'Daily P Raiding Cell', 'What Cell to start P Raiding at. Recommend below your BW Raiding cell if used together. -1 to Raid at cell 1. ', 'value', -1, null, 'Daily'); + createSetting('dPraidingHD', 'Daily P Raiding HD', 'Checks if you can raid the map. If your HD value (calculated using the maps you will raid) is below this value it will not buy the map and you will stop raiding. The higher this value the higher zones it will raid. Can raid up to +10 depending on the zone. -1 or 0 to remove this check.', 'value', -1, null, 'Daily'); + createSetting('dPraidingP', 'Daily P Raiding Poison', 'Maximum level of map to P Raid at in Poison. If this value is 10 it will be able to go to +10 maps in Poison. You should use this instead of the HD function if you feel the calculations are off, but you can use both if needed. -1 or 0 to have no max. ', 'value', -1, null, 'Daily'); + createSetting('dPraidingI', 'Daily P Raiding Ice', 'Maximum level of map to P Raid at in Ice. If this value is 10 it will be able to go to +10 maps in Ice. You should use this instead of the HD function if you feel the calculations are off, but you can use both if needed. -1 or 0 to have no max. ', 'value', -1, null, 'Daily'); + createSetting('dPraidHarder', 'Daily Hardcore P Raiding', '(EXPERIMENTAL) P Raid Harder: When enabled, always buys the highest prestige map we can afford when P raiding, with option to farm fragments for highest available prestige level.', 'boolean', false, null, 'Daily'); + createSetting('dMaxPraidZone', 'Daily Max P Raid Z', 'List of maximum zones to Praid on Dailies corresponding to the list specified in Daily Praiding Z. e.g. if Daily P raiding Z setting is 491,495 and this setting is 495,505, AT will P raid up to 495 from 491, and 505 from 495. Set to -1 to always buy highest available prestige map. If no corrsponding value, or value is invalid, defaults to max available (up to +10)', 'multiValue', [-1], null, 'Daily'); + createSetting('dPraidFarmFragsZ', 'Daily Farm Frags Z', 'P Raiding harder: List of zones where we should farm fragments until we can afford the highest or target prestige map for P raiding. Set to -1 to never farm fragments.', 'multiValue', [-1], null, 'Daily'); + createSetting('dPraidBeforeFarmZ', 'Dy Raid bef farm Z', 'P Raiding harder: List of zones where we should P Raid as far as we can afford before trying to farm fragments to Praid the highest or target prestige map. Only occasionally useful, e.g. if it picks up a Speedexplorer or farming fragments is slow due to low damage. Set to -1 to never raid prestiges before farming fragents.', 'multiValue', [-1], null, 'Daily'); + createSetting('Dailybwraid', 'Daily BW Raid', 'Toggle for Daily BW Raid settings. Turn off Climb BW. ', 'boolean', false, null, 'Daily'); + createSetting('dbwraidcell', 'Daily BW Raiding Cell', 'What Cell to start BW Raiding at. Recommend above your P Raiding cell if used together. -1 to Raid at cell 1. ', 'value', -1, null, 'Daily'); + createSetting('dBWraidingz', 'Daily Z to BW Raid', 'Raids BWs at zone specified in dailys. Example: 495, will raid all BWs for all gear starting from 495. Will skip lower BWs if you have enough damage. Once all gear is obtained, will return to regular farming. Accepts comma separated lists, and raids up to the value in the corrsponding position in the Max BW to raid setting. So if this is set to 480,495 and Daily Max BW to Raid is set to 500,515 AT will BW raid up to 500 from 480, and 515 from 495. Make sure these lists are the same length or BW raiding may fail.', 'multiValue', [-1], null, 'Daily'); + createSetting('dBWraidingmax', 'Daily Max BW to raid', 'Raids BWs until zone specified in dailys. Example: 515, will raid all BWs for all gear until 515. Will skip lower BWs if you have enough damage. Once all gear is obtained, will return to regular farming. Now accepts comma separated lists - see description of Daily Z to BW raid setting for details.', 'multiValue', [-1], null, 'Daily'); + + //Shrine - U1 (Daily) + document.getElementById('dBWraidingmax').parentNode.insertAdjacentHTML('afterend', '
'); + createSetting('Hdshrine', ['Daily AutoShrine Off', 'Daily AutoShrine On', 'DAS: Normal'], 'Turn this on if you want to use Shrines automatically in Dailies. Use DAS: Normal if you want to use the settings in the Maps tab if do not wish to copy them here. ', 'multitoggle', 0, null, 'Daily'); + createSetting('Hdshrinemaz', 'Daily AutoShrine Settings', 'Click to open Daily AutoShrine settings.
Zone: What zone to use Bone Shrine charges.
Cell: What cell to use Bone Shrine charges at, if you use it after cell 80 you will get the benefit of all the books. to use.
Amount: How many Bone Shrine charges you wish to use.
Example: If you put Zone: 40\, Cell: 10\, Amount: 3\, you will use 3 Bone Shrine Charges at zone 40 at cell 10 in a Daily. ', 'infoclick', false, null, 'Daily'); + createSetting('Hdshrinezone', 'AutoShrine: Zone', 'zone', 'multiValue', [-1], null, 'Daily'); + createSetting('Hdshrinecell', 'AutoShrine: Cell', 'cell', 'multiValue', [-1], null, 'Daily'); + createSetting('Hdshrineamount', 'AutoShrine: Amount', 'amount', 'multiValue', [-1], null, 'Daily'); + + //RDaily + + //Line 1 + createSetting('buyradony', 'Buy Radonculous %', 'Buys the Radonculous bonus for 100 bones when Daily bonus is above the value set in this setting. Recommend anything above 475. Will not buy if you cant afford to, or value is -1. ', 'value', -1, null, 'Daily'); + createSetting('Rdfightforever', ['DFA: Off', 'DFA: Non-Empowered', 'DFA: All Dailies'], 'Daily Fight Always. Sends trimps to fight if they\'re not fighting in Daily challenges similar to Toxicity/Nom but not on Bloodthirst/Plagued/Bogged Dailies, regardless of BAF. Non-Empowered will only send to fight if the Daily is not Empowered. Essenitally the same as the one in combat, can use either if you wish, except this will only activate in these daily challenges (duh) ', 'multitoggle', '0', null, 'Daily'); + createSetting('Ravoidempower', 'Avoid Empower', 'Tries to avoid Empower stacks in Empower Dailies. No harm in this being on, so default is On. ', 'boolean', true, null, 'Daily'); + createSetting('Rdarmormagic', ['Daily Armor Magic Off', 'DAM: Above 80%', 'DAM: H:D', 'DAM: Always'], 'Will buy Armor to try and prevent death on Bleed/Plague/Bogged Dailies under the 3 conditions.
Above 80%: Will activate at and above 80% of your HZE.
H:D: Will activate at and above the H:D you have defined in maps.
Always Will activate always.
All options will activate at or below 25% of your health. ', 'multitoggle', 0, null, "Daily"); + + //dRaiding + document.getElementById('Rdarmormagic').parentNode.insertAdjacentHTML('afterend', '
'); + createSetting('RdAMPraid', ['Daily Praiding Off', 'Daily Praiding On', 'DPR: Normal'], 'MASTER BUTTON
Toggle Daily Prestige Raiding. Use DPR: Zone, DPR: Raid and DPR: Cell to Raid Prestiges in higher Maps.
I.e: World is 95, DPR: Zone is [95,105], DPR: Raid is [105,115], DPR: Cell is 1. Will go into map creation at cell 1, create maps 101, 102, 103, 104, 105 with Prestige option. If you can\'t afford P maps, it will try without. If still unable to afford will buy the highest maps first without buying 101 and 102 for example. Raiding will take longer if you can\'t afford it. Once all maps are created it will run the lowest created then move onto the next till all created maps are finished. If you have enabled DPR: Recycle it will then recycle those maps. DPR: Normal will use the settings in Raiding tab so if they are the same you do not have to copy them over. ', 'multitoggle', 0, null, 'Daily'); + createSetting('RdAMPraidmaz', 'Daily Praiding Settings', 'Click to open the Daily Praiding settings. ', 'infoclick', false, null, 'Daily'); + createSetting('RdAMPraidzone', 'DPR: Zone', 'Zones to Prestige Raid. Can use 95,105,115! ', 'multiValue', [-1], null, 'Daily'); + createSetting('RdAMPraidraid', 'DPR: Raid', 'What Maps to Raid. Corrosponds to PR: Zone, so first value will corrospond to first value in PR: Zone. Can use 105,115,125! ', 'multiValue', [-1], null, 'Daily'); + createSetting('RdAMPraidcell', 'DPR: Cell', 'What Cell to start Prestige Raiding at. -1 to Raid at cell 1. ', 'multiValue', [-1], null, 'Daily'); + createSetting('RdAMPraidfrag', ['DPR: Frag', 'DPR: Frag Min', 'DPR: Frag Max'], 'Farm for fragments to afford the maps you want to create. DPR: Frag Min is used for absolute minimum frag costs (which includes no Prestige special, perfect sliders, random map and the difficulty and size options, however it will try to afford those options first!) and prioritises buying the most maps for a smoother sequential raid. DPR: Frag Max is used for the ultimate Raiding experience. This option will probably take the most time to farm but may save you time in the actual raid. I would recommend using Min Mode if you don\'t have frag drop or explorer effic on your heirloom and Max if you are confident in your Fragment gains. ', 'multitoggle', 0, null, 'Daily'); + createSetting('RdAMPraidrecycle', 'DPR: Recycle', 'Recycle maps created in Daily Prestige Raiding. ', 'boolean', false, null, 'Daily'); + + //dTimefarm + document.getElementById('RdAMPraidrecycle').parentNode.insertAdjacentHTML('afterend', '
'); + createSetting('Rdtimefarm', ['Daily Time Farm Off', 'Daily Time Farm On', 'DTF: Normal'], 'Turn this on if you want to use Daily Time Farming. Use DTF: Normal if you want to use the settings in the Maps tab if do not wish to copy them here. ', 'multitoggle', 0, null, 'Daily'); + createSetting('Rdtimefarmmaz', 'DTM Settings', 'Click to open the Daily Time Farm settings. It will also put all your workers into what you are gathering.
Zone: What zone to start time farming.
Cell: What cell to start time farming at.
Time: How much time in Minutes to farm.
Level: How many map levels above your zone to use.
Map: What kind of map you want to use.
Special: What type of special you want to use.
Gather: What resource you would like to gather.
Example: If you put Zone: 60\, Cell: 10\, Time: 3\, Level: 5\, Map: Gardens\, Special: Large Metal Cache\, Gather: Metal\, while in a Daily you will farm at zone 60 at cell 10 for 3 minutes in a +5 Gardens map that has a Large Metal Cache while gathering metal. ', 'infoclick', false, null, 'Daily'); + createSetting('Rdtimefarmzone', 'DTF: Zone', 'zone', 'multiValue', [-1], null, 'Daily'); + createSetting('Rdtimefarmcell', 'DTF: Cell', 'cell', 'multiValue', [-1], null, 'Daily'); + createSetting('Rdtimefarmtime', 'DTF: Time', 'time', 'multiValue', [-1], null, 'Daily'); + createSetting('Rdtimefarmlevel', 'DTF: Map Level', 'level', 'multiValue', [0], null, 'Daily'); + createSetting('Rdtimefarmmap', 'DTF: Map Selection', 'map', 'textValue', 'undefined', null, 'Daily'); + createSetting('Rdtimefarmspecial', 'DTF: Special Selection', 'special', 'textValue', 'undefined', null, 'Daily'); + createSetting('Rdtimefarmgather', 'DTF: Gather Selection', 'gather', 'textValue', 'undefined', null, 'Daily'); + + + //Heirloom + createSetting('dhighdmg', 'DHS: High Damage', 'HIGH DAMAGE HEIRLOOM

Enter the name of your high damage heirloom. This is your heirloom that you will use normally in dailies. ', 'textValue', 'undefined', null, 'Daily'); + createSetting('dlowdmg', 'DHS: Low Damage', 'LOW DAMAGE HEIRLOOM

Enter the name of your low damage heirloom. This is the heirloom that you will use for windstacking in dailies. ', 'textValue', 'undefined', null, 'Daily'); + + + //RHeirloom + document.getElementById('dlowdmg').parentNode.insertAdjacentHTML('afterend', '
'); + createSetting('Rdhs', ['DHS: Off', 'DHS: On', 'DHS: Normal'], 'Heirloom swapping master button for Dailies. Turn this on to allow heirloom swapping and its associated settings. Use DHS: Normal to use the non-daily settings. ', 'multitoggle', 0, null, 'Daily'); + + //DShield Swapping + document.getElementById('Rdhs').parentNode.insertAdjacentHTML('afterend', '
'); + createSetting('Rdhsshield', 'Daily Shields', 'Toggle to swap Shields in Dailies', 'boolean', false, null, 'Daily'); + createSetting('Rdhsz', 'DHSh: Zone', 'Which zone to swap from your first heirloom you have defined to your second heirloom you have defined. I.e if this value is 75 it will switch to the second heirloom on z75', 'value', '-1', null, 'Daily'); + createSetting('Rdhs1', 'DHSh: First', 'First Heirloom to use

Enter the name of your first heirloom. This is the heirloom that you will use before swapping to the second heirloom at the zone you have defined in the HS: Zone. ', 'textValue', 'undefined', null, 'Daily'); + createSetting('Rdhs2', 'DHSh: Second', 'Second Heirloom to use

Enter the name of your second heirloom. This is the heirloom that you will use after swapping from the first heirloom at the zone you have defined in the HS: Zone. ', 'textValue', 'undefined', null, 'Daily'); + + //DStaff Swapping + document.getElementById('Rdhs2').parentNode.insertAdjacentHTML('afterend', '
'); + createSetting('Rdhsstaff', 'Daily Staffs', 'Toggle to swap Staffs', 'boolean', false, null, 'Daily'); + createSetting('Rdhsworldstaff', 'DHSt: World', 'World Staff

Enter the name of your world staff for Dailies.', 'textValue', 'undefined', null, 'Daily'); + createSetting('Rdhsmapstaff', 'DHSt: Map', 'Mapping staff

Enter the name of your mapping staff for Dailies.', 'textValue', 'undefined', null, 'Daily'); + createSetting('Rdhstributestaff', 'DHSt: Tribute', 'Tribute farming staff

Enter the name of the staff you would like to equip during tribute farming for Dailies', 'textValue', 'undefined', null, 'Daily'); + + //Shrine - U2 (Daily) + document.getElementById('Rdhstributestaff').parentNode.insertAdjacentHTML('afterend', '
'); + createSetting('Rdshrine', ['Daily AutoShrine Off', 'Daily AutoShrine On', 'DAS: Normal'], 'Turn this on if you want to use Shrines automatically in Dailies. Use DAS: Normal if you want to use the settings in the Maps tab if do not wish to copy them here. ', 'multitoggle', 0, null, 'Daily'); + createSetting('Rdshrinemaz', 'Daily AutoShrine Settings', 'Click to open Daily AutoShrine settings.
Zone: What zone to use Bone Shrine charges.
Cell: What cell to use Bone Shrine charges at, if you use it after cell 80 you will get the benefit of all the books. to use.
Amount: How many Bone Shrine charges you wish to use.
Example: If you put Zone: 40\, Cell: 10\, Amount: 3\, you will use 3 Bone Shrine Charges at zone 40 at cell 10 in a Daily. ', 'infoclick', false, null, 'Daily'); + createSetting('Rdshrinezone', 'AutoShrine: Zone', 'zone', 'multiValue', [-1], null, 'Daily'); + createSetting('Rdshrinecell', 'AutoShrine: Cell', 'cell', 'multiValue', [-1], null, 'Daily'); + createSetting('Rdshrineamount', 'AutoShrine: Amount', 'amount', 'multiValue', [-1], null, 'Daily'); + + //Portal Line + document.getElementById('Rdshrineamount').parentNode.insertAdjacentHTML('afterend', '
'); + createSetting('AutoStartDaily', 'Auto Start Daily', 'Starts Dailies for you. When you portal with this on, it will select the oldest Daily and run it. Use the settings in this tab to decide whats next. ', 'boolean', false, null, 'Daily'); + createSetting('u2daily', 'Daily in U2', 'If this is on, you will do your daily in U2. ', 'boolean', false, null, 'Daily'); + createSetting('AutoPortalDaily', ['Daily Portal Off', 'DP: He/Hr', 'DP: Custom'], 'DP: He/Hr: Portals when your world zone is above the minium you set (if applicable) and the buffer falls below the % you have defined.
DP: Custom: Portals after clearing the zone you have defined in Daily Custom Portal. ', 'multitoggle', '0', null, "Daily"); + createSetting('dHeliumHourChallenge', 'DP: Challenge', 'Automatically portal into this challenge when using helium per hour or custom autoportal in dailies when there are none left. Custom portals after cell 100 of the zone specified. Do not choose a challenge if you havent unlocked it. ', 'dropdown', 'None', ['None', 'Balance', 'Decay', 'Electricity', 'Life', 'Crushed', 'Nom', 'Toxicity', 'Watch', 'Lead', 'Corrupted', 'Domination', 'Experience'], "Daily"); + createSetting('dCustomAutoPortal', 'Daily Custom Portal', 'Automatically portal AFTER clearing this level in dailies. (ie: setting to 200 would portal when you first reach level 201)', 'value', '999', null, "Daily"); + createSetting('dHeHrDontPortalBefore', 'D: Don\'t Portal Before', 'Do NOT allow Helium per Hour Daily AutoPortal setting to portal BEFORE this level is reached in dailies. It is an additional check that prevents drops in helium/hr from triggering autoportal in dailies. Set to 0 or -1 to completely disable this check. (only shows up with Helium per Hour set in dailies)', 'value', '999', null, "Daily"); + createSetting('dHeliumHrBuffer', 'D: He/Hr Portal Buffer %', 'IMPORTANT SETTING. When using the Daily He/Hr Autoportal, it will portal if your He/Hr drops by this amount of % lower than your best for current run in dailies, default is 0% (ie: set to 5 to portal at 95% of your best in dailies). Now with stuck protection - Allows portaling midzone if we exceed set buffer amount by 5x. (ie a normal 2% buffer setting would now portal mid-zone you fall below 10% buffer).', 'value', '0', null, 'Daily'); + createSetting('DailyVoidMod', 'Daily Void Zone', 'What zone to do void maps in dailies. Disable with -1', 'value', -1, null, 'Daily'); + createSetting('dvoidscell', 'Daily Voids Cell', 'Run Voids at this Cell. -1 to run them at the default value, which is 70. ', 'value', '-1', null, 'Daily'); + createSetting('dRunNewVoidsUntilNew', 'Daily New Voids Mod', '0 to disable. Positive numbers are added to your Void Map zone. -1 for no cap. This allows you to run new Void Maps in Dailies obtained after your Void Map zone by adding this number to your Void Map zone.
Example Void map zone=187 and This setting=10. New Voids run until 197).
This means that any new void maps gained until Z197. CAUTION: May severely slow you down by trying to do too-high level void maps. Default 0 (OFF).', 'value', '0', null, 'Daily'); + createSetting('drunnewvoidspoison', 'New Voids Poison', 'Only run new voids in poison zones.', 'boolean', false, null, 'Daily'); + + //RPortal Line + document.getElementById('dlowdmg').parentNode.insertAdjacentHTML('afterend', '
'); + createSetting('RAutoStartDaily', 'Auto Start Daily', 'Starts Dailies for you. When you portal with this on, it will select the oldest Daily and run it. Use the settings in this tab to decide whats next. ', 'boolean', false, null, 'Daily'); + createSetting('u1daily', 'Daily in U1', 'If this is on, you will do your daily in U1. ', 'boolean', false, null, 'Daily'); + createSetting('RAutoPortalDaily', ['Daily Portal Off', 'DP: Rn/Hr', 'DP: Custom'], 'DP: Rn/Hr: Portals when your world zone is above the minium you set (if applicable) and the buffer falls below the % you have defined.
DP: Custom: Portals after clearing the zone you have defined in Daily Custom Portal. ', 'multitoggle', '0', null, "Daily"); + createSetting('RdHeliumHourChallenge', 'DP: Challenge', 'Automatically portal into this challenge when using radon per hour or custom autoportal in dailies when there are none left. Custom portals after cell 100 of the zone specified. Do not choose a challenge if you havent unlocked it. ', 'dropdown', 'None', ['None', 'Bublé', 'Melt', 'Quagmire', 'Archaeology', 'Insanity', 'Nurture', 'Alchemy', 'Hypothermia'], "Daily"); + createSetting('RdCustomAutoPortal', 'Daily Custom Portal', 'Automatically portal AFTER clearing this level in dailies. (ie: setting to 200 would portal when you first reach level 201)', 'value', '999', null, "Daily"); + createSetting('RdHeHrDontPortalBefore', 'D: Don\'t Portal Before', 'Do NOT allow Radon per Hour Daily AutoPortal setting to portal BEFORE this level is reached in dailies. It is an additional check that prevents drops in radon/hr from triggering autoportal in dailies. Set to 0 or -1 to completely disable this check. (only shows up with Radon per Hour set in dailies)', 'value', '999', null, "Daily"); + createSetting('RdHeliumHrBuffer', 'D: Rn/Hr Portal Buffer %', 'IMPORTANT SETTING. When using the Daily Rn/Hr Autoportal, it will portal if your Rn/Hr drops by this amount of % lower than your best for current run in dailies, default is 0% (ie: set to 5 to portal at 95% of your best in dailies). Now with stuck protection - Allows portaling midzone if we exceed set buffer amount by 5x. (ie a normal 2% buffer setting would now portal mid-zone you fall below 10% buffer).', 'value', '0', null, 'Daily'); + createSetting('RDailyVoidMod', 'Daily Void Zone', 'What zone to do void maps in dailies. Disable with -1', 'value', -1, null, 'Daily'); + createSetting('RdRunNewVoidsUntilNew', 'Daily New Voids Mod', '0 to disable. Positive numbers are added to your Void Map zone. -1 for no cap. This allows you to run new Void Maps in Dailies obtained after your Void Map zone by adding this number to your Void Map zone.
Example Void map zone=187 and This setting=10. New Voids run until 197).
This means that any new void maps gained until Z197. CAUTION: May severely slow you down by trying to do too-high level void maps. Default 0 (OFF).', 'value', '0', null, 'Daily'); + + + + //C2 + + //Line 1 + createSetting('FinishC2', 'Finish Challenge2', 'DONT USE THIS WITH C2 RUNNER
Finish / Abandon Challenge2 (any) when this zone is reached, if you are running one. For manual use. Recommended: Zones ending with 0 for most Challenge2. Disable with -1. Does not affect Non-Challenge2 runs.', 'value', -1, null, 'C2'); + createSetting('buynojobsc', 'No F/L/M in C2', 'Buys No Farmers, Lumberjacks or Miners in the C2 challenges Watch and Trapper. ', 'boolean', 'false', null, "C2"); + createSetting('cfightforever', 'Tox/Nom Fight Always', 'Sends trimps to fight if they\'re not fighting in the Toxicity and Nom Challenges, regardless of BAF. Essenitally the same as the one in combat, can use either if you wish, except this will only activate in these challenges (duh) ', 'boolean', 'false', null, 'C2'); + createSetting('carmormagic', ['C2 Armor Magic Off', 'CAM: Above 80%', 'CAM: H:D', 'CAM: Always'], 'Will buy Armor to try and prevent death on Nom/Tox Challenges under the 3 conditions.
Above 80%: Will activate at and above 80% of your HZE and when your health is sufficiently low.
H:D: Will activate at and above the H:D you have defined in maps.
Always Will activate always.
All options will activate at or below 25% of your health. ', 'multitoggle', 0, null, "C2"); + createSetting('mapc2hd', 'Mapology H:D', 'Set your H:D ratio for Mapology. Will not go into maps unless your H:D ratio is above this. -1 to use normal behaviour. ', 'value', '-1', null, 'C2'); + createSetting('novmsc2', 'No VMs', 'Turn off VM running for C2s. Handy for the C2 Runner. ', 'boolean', 'false', null, "C2"); + + //C2 Runner Line + document.getElementById('novmsc2').parentNode.insertAdjacentHTML('afterend', '
'); + createSetting('c2runnerstart', 'C2 Runner', 'Runs the normal C2s in sequence according to difficulty. See C2Table for list. Once zone you have defined has been reached, will portal into next. I will advise you not to touch the challenges (abandoning, doing a different one, etc) if you are running this, it could break it. Only runs challenges that need updating, will not run ones close-ish to your HZE. ', 'boolean', false, null, 'C2'); + createSetting('c2runnerportal', 'C2 Runner Portal', 'Automatically portal AFTER clearing this level in C2 Runner. (ie: setting to 200 would portal when you first reach level 201)', 'value', '999', null, "C2"); + createSetting('c2runnerpercent', 'C2 Runner %', 'What percent Threshhold you want C2s to be over. E.g 85, will only run C2s with HZE% below this number. Default is 85%. Must have a value set for C2 Runner to... well, run. ', 'value', '85', null, "C2"); + createSetting('c2table', 'C2 Table', 'Display your C2s and C3s in a convenient table which is colour coded.
Green = Not worth updating.
Yellow = Consider updating.
Red = Updating this C2/C3 is worth doing.
Blue = You have not yet done/unlocked this C2/C3 challenge. ', 'infoclick', 'c2table', null, 'C2'); + + + + //Buildings + + //Line 1 + createSetting('hidebuildings', 'Hide Buildings', 'If you have unlocked Autostructure and Decabuild, this setting will appear and enable you to hide the now obsolete building settings, so please use AutoStructure instead. The settings will only disappear if you disable the buy buildings button and turn this on. It will not hide the Gym settings as Autostructure does not allow you to customize how you buy them. ', 'boolean', false, null, "Buildings"); + createSetting('BuyBuildingsNew', ['Buy Neither', 'Buy Buildings & Storage', 'Buy Buildings', 'Buy Storage'], 'AutoBuys Storage when it is almost full (it even anticipates Jestimp) and Non-Storage Buildings (As soon as they are available). Takes cost efficiency into account before buying Non-Storage Buildings.', 'multitoggle', 1, null, "Buildings"); createSetting('WarpstationCap', 'Warpstation Cap', 'Do not level Warpstations past Basewarp+DeltaGiga **. Without this, if a Giga wasnt available, it would level infinitely (wastes metal better spent on prestiges instead.) **The script bypasses this cap each time a new giga is bought, when it insta-buys as many as it can afford (since AT keeps available metal/gems to a low, overbuying beyond the cap to what is affordable at that first moment is not a bad thing). ', 'boolean', true, null, 'Buildings'); createSetting('WarpstationCoordBuy', 'Buy Warp to Hit Coord', 'If we are very close to hitting the next coordination, and we can afford the warpstations it takes to do it, Do it! (even if we are over the Cap/Wall). Recommended with WarpCap/WarpWall. (has no point otherwise) ', 'boolean', true, null, 'Buildings'); createSetting('MaxHut', 'Max Huts', 'Huts', 'value', '100', null, "Buildings"); createSetting('MaxHouse', 'Max Houses', 'Houses', 'value', '100', null, "Buildings"); createSetting('MaxMansion', 'Max Mansions', 'Mansions', 'value', '100', null, "Buildings"); createSetting('MaxHotel', 'Max Hotels', 'Hotels', 'value', '100', null, "Buildings"); - //Line2 + + //Line 2 createSetting('MaxResort', 'Max Resorts', 'Resorts', 'value', '100', null, "Buildings"); - createSetting('MaxGateway', 'Max Gateways', 'WARNING: Not recommended to raise above 25', 'value', '25', null, "Buildings"); + createSetting('MaxGateway', 'Max Gateways', 'Gateways', 'value', '25', null, "Buildings"); createSetting('MaxWormhole', 'Max Wormholes', 'WARNING: Wormholes cost helium! Values below 0 do nothing.', 'value', '0', null, "Buildings"); createSetting('MaxCollector', 'Max Collectors', 'recommend: -1', 'value', '-1', null, "Buildings"); createSetting('MaxGym', 'Max Gyms', 'Advanced. recommend: -1', 'value', '-1', null, "Buildings"); createSetting('MaxTribute', 'Max Tributes', 'Advanced. recommend: -1 ', 'value', '-1', null, "Buildings"); - createSetting('GymWall', 'Gym Wall', 'Conserves Wood. Only buys 1 Gym when you can afford X gyms wood cost (at the first one\'s price, simple math). -1 or 0 to disable. In other words, only allows gyms that cost less than 1/nth your currently owned wood. (to save wood for nurseries for new z230+ Magma nursery strategy). Takes decimal numbers. (Identical to the Warpstation wall setting which is why its called that). Setting to 1 does nothing besides stopping gyms from being bought 2 at a time due to the mastery.', 'value', -1, null, 'Buildings'); - //Line3 + createSetting('GymWall', 'Gym Wall', 'Conserves Wood. Only buys 1 Gym when you can afford X gyms wood cost (at the first one\'s price, simple math). -1 or 0 to disable. In other words, only allows gyms that cost less than 1/nth your currently owned wood. (to save wood for nurseries for new z230+ Magma nursery strategy). Takes decimal numbers. (Identical to the Warpstation wall setting which is why its called that). Setting to 1 does nothing besides stopping gyms from being bought 2 at a time due to the mastery.', 'value', -1, null, 'Buildings'); //remove? + + //Line 3 createSetting('FirstGigastation', 'First Gigastation', 'How many warpstations to buy before your first gigastation', 'value', '20', null, "Buildings"); - createSetting('DeltaGigastation', 'Delta Gigastation', 'How many extra warpstations to buy for each gigastation. Supports decimal values. For example 2.5 will buy +2/+3/+2/+3...', 'value', '2', null, "Buildings"); + createSetting('DeltaGigastation', 'Delta Gigastation', 'YOU MUST HAVE BUY UPGRADES ENABLED!
How many extra warpstations to buy for each gigastation. Supports decimal values. For example 2.5 will buy +2/+3/+2/+3...', 'value', '2', null, "Buildings"); + createSetting('AutoGigas', 'Auto Gigas', "Advanced.
If enabled, AT will buy its first Gigastation if:
A) Has more than 2 Warps &
B) Can't afford more Coords &
C) (Only if Custom Delta Factor > 20) Lacking Health or Damage &
D) (Only if Custom Delta Factor > 20) Has run at least 1 map stack or
E) If forced to by using the firstGiga(true) command in the console.
Then, it'll calculate the delta based on your Custom Delta Factor and your Auto Portal/VM zone (whichever is higher), or Daily Auto Portal/VM zone, or C2 zone, or Custom AutoGiga Zone.", 'boolean', 'true', null, 'Buildings'); + createSetting('CustomTargetZone', 'Custom Target Zone', 'To be used with Auto Gigas.
The zone to be used as a the target zone when calculating the Auto Gigas delta.
Values below 60 will be discarded.', 'value', '-1', null, "Buildings"); + createSetting('CustomDeltaFactor', 'Custom Delta Factor', 'Advanced. To be used with Auto Gigas.
This setting is used to calculate a better Delta. Think of this setting as how long your target zone takes to complete divided by the zone you bought your first giga in.
Basically, a higher number means a higher delta. Values below 1 will default to 10.
Recommended: 1-2 for very quick runs. 5-10 for regular runs where you slow down at the end. 20-100+ for very pushy runs.', 'value', '-1', null, "Buildings"); createSetting('WarpstationWall3', 'Warpstation Wall', 'Conserves Metal. Only buys 1 Warpstation when you can afford X warpstations metal cost (at the first one\'s price, simple math). -1, 0, 1 = disable. In other words, only allows warps that cost less than 1/nth your currently owned metal. (to save metal for prestiges)', 'value', -1, null, 'Buildings'); createSetting('MaxNursery', 'Max Nurseries', 'Advanced. Recommend: -1 until you reach Magma (z230+)', 'value', '-1', null, "Buildings"); - createSetting('NoNurseriesUntil', 'No Nurseries Until z', 'For Magma z230+ purposes. Nurseries get shut down, and wasting nurseries early on is probably a bad idea. Might want to set this to 230+ for now. Can use combined with the old Max Nurseries cap setting.', 'value', -1, null, 'Buildings'); - createSetting('PreSpireNurseries', 'Nurseries pre-Spire', 'Set the maximum number of Nurseries to build for Spires. Overrides No Nurseries Until z and Max Nurseries so you can keep them seperate! Will build nurseries before z200 for Spire 1, but only on the zone of Spires 2+ to avoid unnecessary burning. Disable with -1.', 'value', -1, null, 'Buildings'); + //Line 4 + createSetting('NurseryWall', 'Nursery Wall', 'Only spends N% of resources on nurseries. N being this setting. ', 'value', -1, null, 'Buildings'); + createSetting('NoNurseriesUntil', 'No Nurseries Until z', 'Builds Nurseries starting from this zone. -1 to build from when they are unlocked. ', 'value', '-1', null, 'Buildings'); + + //RBuildings + + //Line 1 + createSetting('RBuyBuildingsNew', 'AutoBuildings', 'Buys buildings in an efficient way. Also enables Vanilla AutoStorage if its off. ', 'boolean', 'true', null, "Buildings"); + createSetting('RMaxHut', 'Max Huts', 'Huts', 'value', '100', null, "Buildings"); + createSetting('RMaxHouse', 'Max Houses', 'Houses', 'value', '100', null, "Buildings"); + createSetting('RMaxMansion', 'Max Mansions', 'Mansions', 'value', '100', null, "Buildings"); + createSetting('RMaxHotel', 'Max Hotels', 'Hotels', 'value', '100', null, "Buildings"); + createSetting('RMaxResort', 'Max Resorts', 'Resorts', 'value', '100', null, "Buildings"); + createSetting('RMaxGateway', 'Max Gateways', 'Gateways', 'value', '25', null, "Buildings"); + + //Line 2 + createSetting('RMaxCollector', 'Max Collectors', 'recommend: -1', 'value', '-1', null, "Buildings"); + createSetting('RMaxTribute', 'Max Tributes', 'Advanced. recommend: -1 ', 'value', '-1', null, "Buildings"); + createSetting('RMaxLabs', 'Max Labs', 'It is about 10 labs per level at level 10 plus. ', 'value', '0', null, "Buildings"); + createSetting('Rmeltsmithy', 'Melt Smithy', 'Run the Melting Point Map to gain one extra Smithy when at or above this value. ', 'value', '-1', null, "Buildings"); + createSetting('Rsmithylogic', 'Smithy Savings', 'ABSOLUTELY WILL NOT WORK IN TESTING!
Uses Smithy Saving logic when this is turned on. Make sure every SS setting is set above 0 or it wont work. This feature will stop using resources on items needed for Smithy when you have reached the targets you have selected.', 'boolean', 'false', null, "Buildings"); + createSetting('Rsmithynumber', 'SS: Number', 'Start SS at this number of Smithys. I.e 9, will buy anything regardless of Smithy before having 9 Smithys. After 9 has been reached will start to save up for them. ', 'value', '-1', null, "Buildings"); + createSetting('Rsmithypercent', 'SS: Percent', 'If you have SS enabled this value will allow items below this value to be purchased. I.e if this is set to 1, it will only buy items if that item is 1% of Smithys cost or lower. ', 'value', '-1', null, "Buildings"); + createSetting('Rsmithyseconds', 'SS: Seconds', 'How many seconds SS starts activating at. I.e 120, if your Smithy is 120 seconds away from being purchased SS will kick in. ', 'value', '-1', null, "Buildings"); -//Jobs - createSetting('BuyJobs', 'Buy Jobs', 'Buys jobs based on ratios configured below. CAUTION: you cannot manually assign jobs with this. Toggle if you need to.', 'boolean', true, null, "Jobs"); - createSetting('WorkerRatios', 'Auto Worker Ratios', 'Automatically changes worker ratios based on current progress. WARNING: overrides worker ratio settings. Settings: 1/1/1 up to 300k trimps, 3/3/5 up to 3mil trimps, then 3/1/4 above 3 mil trimps, then 1/1/10 above 1000 tributes, then 1/2/22 above 1500 tributes, then 1/12/12 above 3000 tributes.', 'boolean', true, null, "Jobs"); + //Jobs + + //Line 1 + createSetting('fuckjobs', 'Hide Jobs', 'Hides obsolete settings when you have obtained the AutoJobs Mastery. It should be far better to use than AT, Especially on c2 Challenges like Watch. ', 'boolean', 'false', null, "Jobs"); + createSetting('BuyJobsNew', ['Don\'t Buy Jobs', 'Auto Worker Ratios', 'Manual Worker Ratios'], 'Manual Worker Ratios buys jobs for your trimps according to the ratios below, Make sure they are all different values, if two of them are the same it might causing an infinite loop of hiring and firing! Auto Worker ratios automatically changes these ratios based on current progress, overriding your ratio settings.
AutoRatios: 1/1/1 up to 300k trimps, 3/3/5 up to 3mil trimps, then 3/1/4 above 3 mil trimps, then 1/1/10 above 1000 tributes, then 1/2/22 above 1500 tributes, then 1/12/12 above 3000 tributes.
CAUTION: You cannot manually assign jobs with this, turn it off if you have to', 'multitoggle', 1, null, "Jobs"); createSetting('AutoMagmamancers', 'Auto Magmamancers', 'Auto Magmamancer Management. Hires Magmamancers when the Current Zone time goes over 10 minutes. Does a one-time spend of at most 10% of your gem resources. Every increment of 10 minutes after that repeats the 10% hiring process. Magmamancery mastery is accounted for, with that it hires them at 5 minutes instead of 10. Disclaimer: May negatively impact Gem count.', 'boolean', true, null, 'Jobs'); createSetting('FarmerRatio', 'Farmer Ratio', '', 'value', '1', null, "Jobs"); createSetting('LumberjackRatio', 'Lumberjack Ratio', '', 'value', '1', null, "Jobs"); createSetting('MinerRatio', 'Miner Ratio', '', 'value', '1', null, "Jobs"); - createSetting('MaxScientists', 'Max Scientists', 'Enable or disable hiring of scientists or Cap your scientists. (This is NOT a ratio, it is an absolute number). Recommend: -1 (infinite cap, hiring controls itself). 0 means Dont Hire Scientists at all. Any other number sets the population cap, not the ratio. Scientist ratio can be controlled by internal variable: MODULES[\\"jobs\\"].scientistRatio = 25; Example Math Behind It: ScientistRatio=(FarmerRatio+LumberjackRatio+MinerRatio)/25.', 'value', '-1', null, "Jobs"); - //Line2 - createSetting('MaxExplorers', 'Max Explorers', 'Advanced. Cap your explorers. recommend: -1', 'value', '-1', null, "Jobs"); - createSetting('MaxTrainers', 'Max Trainers', 'Advanced. Cap your trainers. recommend: -1', 'value', '-1', null, "Jobs"); - createSetting('TrainerCaptoTributes', 'Cap Trainers %', 'Only Buy a Trainer when its cost is LESS than X% of cost of a tribute. This setting can work in combination with the other one, or set the other one to -1 and this will take full control. Default: -1 (Disabled). 50% is close to the point where the cap does nothing. You can go as low as you want but recommended is 10% to 1%. (example: Trainer cost of 5001, Tribute cost of 100000, @ 5%, it would NOT buy the trainer.)', 'value', '-1', null, 'Jobs'); - createSetting('BreedFire', 'Breed Fire', 'OPTIONAL. Fire Lumberjacks and Miners to speed up breeding when needed. Basically trades wood/metal to cut the wait between deaths down. Disclaimer: May heavily negatively impact wood-gathering. ', 'boolean', false, null, 'Jobs'); + createSetting('MaxScientists', 'Max Scientists', 'Advanced. Cap your scientists (This is an absolute number not a ratio). recommend: -1 (infinite still controls itself)', 'value', '-1', null, "Jobs"); + createSetting('MaxExplorers', 'Max Explorers', 'Advanced. Cap your explorers (This is an absolute number not a ratio). recommend: -1', 'value', '-1', null, "Jobs"); + //Line 2 + createSetting('MaxTrainers', 'Max Trainers', 'Advanced. Cap your trainers (This is an absolute number not a ratio). recommend: -1', 'value', '-1', null, "Jobs"); + //RJobs -//GEAR: - createSetting('BuyArmor', 'Buy Armor Levels', 'Auto-Buy/Level-Up the most cost efficient armor available. ', 'boolean', true, null, "Gear"); - createSetting('BuyArmorUpgrades', 'Buy Armor Prestiges', '(Prestiges) & Gymystic. Will buy the most efficient armor upgrade available. ', 'boolean', true, null, "Gear"); - createSetting('BuyWeapons', 'Buy Weapon Levels', 'Auto-Buy/Level-Up the most cost efficient weapon available. ', 'boolean', true, null, "Gear"); - createSetting('BuyWeaponUpgrades', 'Buy Weapon Prestiges', '(Prestiges) Will buy the most efficient weapon upgrade available. ', 'boolean', true, null, "Gear"); - createSetting('CapEquip2', 'Cap Equip to', 'Do not level equipment past this number. Helps stop wasting metal when the script levels-up equip High, only to prestige right after. Recommended value: earlygame 10, lategame: 100. Disable with -1 or 0. NEW: Also sub-caps to 10% of your number during liquified or overkilled(under 25sec) zones. This does not mean the script always hits the cap. Your Equip will now always be leveled to at least 2 since its the most effective level. It will only be leveled however if you dont have enoughHealth or enoughDamage. But During Spire, everything will be leveled up to the cap.
Hidden var: MODULES[\\"equipment\\"].capDivisor = 10; //number to divide your normal cap by.', 'value', 10, null, 'Gear'); - createSetting('DynamicPrestige2', 'Dynamic Prestige z', 'Dynamic Prestige: Set Target Zone number: Z #. (disable with 0 or -1)
Skip getting prestiges at first, and Gradually work up to the desired Prestige setting you have set (set the Prestige dropdown to the highest weapon you want to end up on at the target zone you set here). Runs with Dagger to save a significant amount of time until we need better gear, then starts increasing the prestige setting near the end of the run. Examines which prestiges you have, how many missing ones youd need to achieve the desired target and starts running maps every zone (more maps for higher settings), Until the target prestige is reached. ', 'value', -1, null, 'Gear'); - createSetting('Prestige', 'Prestige', 'Acquire prestiges through the selected item (inclusive) as soon as they are available in maps. Forces equip first mode. Automap must be enabled. THIS IS AN IMPORTANT SETTING related to speed climbing and should probably always be on something. If you find the script getting stuck somewhere, particularly where you should easily be able to kill stuff, setting this to an option lower down in the list will help ensure you are more powerful at all times, but will spend more time acquiring the prestiges in maps.', 'dropdown', 'Polierarm', ['Off', 'Supershield', 'Dagadder', 'Bootboost', 'Megamace', 'Hellishmet', 'Polierarm', 'Pantastic', 'Axeidic', 'Smoldershoulder', 'Greatersword', 'Bestplate', 'Harmbalest', 'GambesOP'], "Gear"); - //Make a backup of the prestige setting: backup setting grabs the actual value of the primary setting any time it is changed, (line 784 of the function settingChanged()) - var lastSetting = autoTrimpSettings["PrestigeBackup"]; - autoTrimpSettings["PrestigeBackup"] = { - selected: (lastSetting != undefined ? lastSetting.selected : autoTrimpSettings["Prestige"].selected ) || "Off", - id: "PrestigeBackup", - name: "PrestigeBackup" - }; - //Line2: - createSetting('ForcePresZ', 'Force Prestige Z', 'On and after this zone is reached, always try to prestige for everything immediately, ignoring Dynamic Prestige settings and overriding that of Linear Prestige. Prestige Skip mode will exit this. Disable with -1.', 'value', -1, null, 'Gear'); - createSetting('PrestigeSkipMode', 'Prestige Skip Mode', 'If there are more than 2 Unbought Prestiges (besides Shield), ie: sitting in your upgrades window but you cant afford them, AutoMaps will not enter Prestige Mode, and/or will exit from it. The amount of unboughts can be configured with this variable MODULES[\\"maps\\"].SkipNumUnboughtPrestiges = 2;', 'boolean', false, null, "Gear"); - createSetting('PrestigeSkip2', 'Prestige Skip 2', 'If there are 2 or fewer Unobtained Weapon Prestiges in maps, ie: there are less than 2 types to run for, AutoMaps will not enter Prestige Mode, and/or will exit from it. For users who tends to not need the last few prestiges due to resource gain not keeping up. The amount of unboughts can be configured with MODULES.maps.UnearnedPrestigesRequired. If PrestigeSkipMode is enabled, both conditions need to be reached before exiting.', 'boolean', false, null, 'Gear'); - createSetting('DelayArmorWhenNeeded', 'Delay Armor Prestige', 'Delays buying armor prestige-upgrades during Want More Damage or Farming automap-modes, Although if you need health AND damage, it WILL buy armor prestiges tho. NOTE: Applies to Prestiges only', 'boolean', false, null, 'Gear'); - createSetting('BuyShieldblock', 'Buy Shield Block', 'Will buy the shield block upgrade. CAUTION: If you are progressing past zone 60, you probably don\'t want this :)', 'boolean', false, null, "Gear"); + //Line 1 + createSetting('RBuyJobsNew', ['Don\'t Buy Jobs', 'Auto Worker Ratios', 'Manual Worker Ratios'], 'Manual Worker Ratios buys jobs for your trimps according to the ratios below, Make sure they are all different values, if two of them are the same it might causing an infinite loop of hiring and firing! Auto Worker ratios automatically changes these ratios based on current progress, overriding your ratio settings.
AutoRatios: 1/1/1 up to 300k trimps, 3/3/5 up to 3mil trimps, then 3/1/4 above 3 mil trimps, then 1/1/10 above 1000 tributes, then 1/2/22 above 1500 tributes, then 1/12/12 above 3000 tributes.
CAUTION: You cannot manually assign jobs with this, turn it off if you have to', 'multitoggle', 1, null, "Jobs"); + createSetting('RFarmerRatio', 'Farmer Ratio', '', 'value', '1', null, "Jobs"); + createSetting('RLumberjackRatio', 'Lumberjack Ratio', '', 'value', '1', null, "Jobs"); + createSetting('RMinerRatio', 'Miner Ratio', '', 'value', '1', null, "Jobs"); + createSetting('RMaxExplorers', 'Max Explorers', 'Advanced. Cap your explorers (This is an absolute number not a ratio). recommend: -1', 'value', '-1', null, "Jobs"); + + //Ships + document.getElementById('RMaxExplorers').parentNode.insertAdjacentHTML('afterend', '
'); + createSetting('Rshipfarmon', 'Ship Farming', 'Turn Ship Farming off or on. You need to have unlocked Large Savory Cache to use this. If you have not I would recommend Time Farm instead. ', 'boolean', 'false', null, "Jobs"); + createSetting('Rshipfarmzone', 'SF: Zone', 'Farms for specified worshippers in SF: Amount at zone according to this settings value. Can use 59,61,62. ', 'multiValue', [-1], null, 'Jobs'); + createSetting('Rshipfarmcell', 'SF: Cell', 'Ship Farm at this Cell. -1 to run them at the default value, which is 1. ', 'value', '-1', null, 'Jobs'); + createSetting('Rshipfarmamount', 'SF: Amount', 'How many Worshippers to farm up to at zone specified in SF. Can use 50,45,40. These values should match up to your SF zones. If using SF and SF: Amount examples (59 and 50 respectively) it will farm at z59 up to 50 Worshippers. Just use one 50 if you want it to farm to 50 everytime. ', 'multiValue', [-1], null, 'Jobs'); + createSetting('Rshipfarmlevel', 'SF: Map Level', 'What map level to use for SF. Can use -1,1,2. -1 to use a level down from world (Map Reducer mastery gives loot equal to world one level down), 0 to use world, 1 etc to use +maps. Using 0 by itself will use global level for all maps. ', 'multiValue', [0], null, 'Jobs'); + createSetting('Rshipfarmfrag', 'SF: Frags', '**Ship farming will create infinite maps if this isnt on**
Turn this on to farm fragments if you cannot afford the map you have selected for SF. ', 'boolean', 'false', null, 'Jobs'); + //Gear + //Line 1 + createSetting('BuyArmorNew', ['Armor: Buy Neither', 'Armor: Buy Both', 'Armor: Prestiges', 'Armor: Levels'], 'AutoBuys Prestiges and Levels up the most cost efficient Armor available. Gymystic buying is controlled under this setting\'s prestige option', 'multitoggle', 1, null, "Gear"); //This should replace the two below + createSetting('BuyWeaponsNew', ['Weapons: Buy Neither', 'Weapons: Buy Both', 'Weapons: Prestiges', 'Weapons: Levels'], 'AutoBuys Prestiges and Levels up the most cost efficient Weapon available.', 'multitoggle', 1, null, "Gear"); //This should replace the two below + createSetting('CapEquip2', 'Weapon Level Cap', 'Do not level Weapons past this number. Helps stop wasting metal when the script levels-up equip High, only to prestige right after. Recommended value: earlygame 10, lategame: 100. Disable with -1 or 0. NEW: Also sub-caps to 10% of your number during liquified or overkilled(under 25sec) zones. This does not mean the script always hits the cap. Your Equip will now always be leveled to at least 2 since its the most effective level. It will only be leveled however if you dont have enoughDamage. But During Spire, everything will be leveled up to the cap.
Hidden var: MODULES[\\"equipment\\"].capDivisor = 10; //number to divide your normal cap by.', 'value', 10, null, 'Gear'); + createSetting('CapEquiparm', 'Armor Level Cap', 'Do not level Armor past this number. Helps stop wasting metal when the script levels-up equip High, only to prestige right after. Recommended value: earlygame 10, lategame: 100. Disable with -1 or 0. NEW: Also sub-caps to 10% of your number during liquified or overkilled(under 25sec) zones. This does not mean the script always hits the cap. Your Equip will now always be leveled to at least 2 since its the most effective level. It will only be leveled however if you dont have enoughHealth. But During Spire, everything will be leveled up to the cap.
Hidden var: MODULES[\\"equipment\\"].capDivisor = 10; //number to divide your normal cap by.', 'value', 10, null, 'Gear'); + createSetting('dmgcuntoff', 'Equipment Cut Off', 'Decides when to buy gear. 4 is default. This means it will take 1 hit to kill an enemy if in D stance. ', 'value', '4', null, 'Gear'); + createSetting('DynamicPrestige2', 'Dynamic Prestige z', 'Dynamic Prestige: Set Target Zone number: Z #. (disable with 0 or -1)
Skip getting prestiges at first, and Gradually work up to the desired Prestige setting you have set (set the Prestige dropdown to the highest weapon you want to end up on at the target zone you set here). Runs with Dagger to save a significant amount of time until we need better gear, then starts increasing the prestige setting near the end of the run. Examines which prestiges you have, how many missing ones youd need to achieve the desired target and starts running maps every zone (more maps for higher settings), Until the target prestige is reached. Use Dagger or else', 'value', -1, null, 'Gear'); + createSetting('Prestige', 'Prestige', 'Acquire prestiges through the selected item (inclusive) as soon as they are available in maps. Forces equip first mode. Automap must be enabled. THIS IS AN IMPORTANT SETTING related to speed climbing and should probably always be on something. If you find the script getting stuck somewhere, particularly where you should easily be able to kill stuff, setting this to an option lower down in the list will help ensure you are more powerful at all times, but will spend more time acquiring the prestiges in maps.', 'dropdown', 'Polierarm', ['Off', 'Supershield', 'Dagadder', 'Bootboost', 'Megamace', 'Hellishmet', 'Polierarm', 'Pantastic', 'Axeidic', 'Smoldershoulder', 'Greatersword', 'Bestplate', 'Harmbalest', 'GambesOP'], "Gear"); -//AutoMaps + VoidMaps settings: -//Could combine automaps and run unique maps into one 3 way toggle: Automaps on, Non-unique maps only, Automaps off. - createSetting('AutoMaps', ["Auto Maps Off","Auto Maps","Auto Maps No Unique"], 'Recommended. Automatically run maps to progress. Very Important. Has multiple modes: Prestige, Voids, Want more Damage, Want more Health, Want Health & Damage, and Farming.Prestige takes precedence and does equal level maps until it gets what is needed as per Autotrimps Prestige dropdown setting. Voids is self explanatory: use the Void Difficulty Check setting to control the amount of farming. If \'want more damage\', it will only do 10 maps for 200% mapbonus damage bonus. If \'Farming\', it does maps beyond 10 if the displayed number is over >16x. \'Want more health[or and damage]\' is basically just a status message telling you need more health, theres not much that can be done besides tell AutoLevelEquipment to keep buying stuff. If you \'want health\' but your damage is OK to continue, invest in more HP perks.


Unique Maps are run automatically unless disabled.
Uniques Required to auto-run The Wall and Dimension of Anger. Also Required for challenges: Electricity, Mapocalypse, Meditate, and Crushed (etc) to complete their AutoPortal.

Maps/Levels:
The Block - 12
The Wall - 16
Dimension of Anger - 21
Trimple Of Doom - 34
The Prison - 82
Bionic Wonderland (only during Crushed) @ 127
NOTE: This should generally be on.
NOTE: Run Bionic Before Spire prevents the setting of Unique.
NOTICE: This does NOT auto-run all your Bionics according to your lack of Robotrimp status or whether you pass a certain level (yet).', 'multitoggle', 1, null, "Maps"); + //Line 2 + createSetting('ForcePresZ', 'Force Prestige Z', 'On and after this zone is reached, always try to prestige for everything immediately, ignoring Dynamic Prestige settings and overriding that of Linear Prestige. Prestige Skip mode will exit this. Disable with -1.', 'value', -1, null, 'Gear'); + createSetting('PrestigeSkip1_2', ['Prestige Skip Off', 'Prestige Skip 1 & 2', 'Prestige Skip 1', 'Prestige Skip 2'], 'Prestige Skip 1: If there are more than 2 Unbought Prestiges (besides Shield), ie: sitting in your upgrades window but you cant afford them, AutoMaps will not enter Prestige Mode, and/or will exit from it. The amount of unboughts can be configured with this variable MODULES[\\"maps\\"].SkipNumUnboughtPrestiges = 2;
Prestige Skip 2: If there are 2 or fewer Unobtained Weapon Prestiges in maps, ie: there are less than 2 types to run for, AutoMaps will not enter Prestige Mode, and/or will exit from it. For users who tends to not need the last few prestiges due to resource gain not keeping up. The amount of unboughts can be configured with MODULES.maps.UnearnedPrestigesRequired. If PrestigeSkipMode is enabled, both conditions need to be reached before exiting.', 'multitoggle', 0, null, "Gear"); + createSetting('DelayArmorWhenNeeded', 'Delay Armor Prestige', 'Delays buying armor prestige-upgrades during Want More Damage or Farming automap-modes, Although if you need health AND damage, it WILL buy armor prestiges tho. NOTE: Applies to Prestiges only', 'boolean', false, null, 'Gear'); + createSetting('BuyShieldblock', 'Buy Shield Block', 'Will buy the shield block upgrade. CAUTION: If you are progressing past zone 60, you probably don\'t want this :)', 'boolean', false, null, "Gear"); + createSetting('trimpsnotdie', 'Buy Armor on Death', 'Buys 10 levels of Armor when Trimps die. Useful when your trimps die frequentely. ', 'boolean', false, null, "Gear"); + createSetting('gearamounttobuy', 'Gear Levels to Buy', 'Set the amount of Gear Levels to buy for AT. I.e if set to 1 will buy 1 level at a time. Recommended value 1. MUST ALWAYS HAVE A VALUE GREATER THAN 0! ', 'value', 1, null, "Gear"); + createSetting('always2', 'Always Level 2', 'Always buys level 2 of weapons and armor regardless of efficiency', 'boolean', false, null, "Gear"); + + + //RGear + + //Line 1 + createSetting('Requipon', 'AutoEquip', 'AutoEquip. Buys Prestiges and levels equipment according to various settings. Will only buy prestiges if it is worth it. Levels all eqiupment according to best efficiency. ', 'boolean', false, null, "Gear"); + createSetting('Rdmgcuntoff', 'AE: Cut-off', 'Decides when to buy gear. 1 is default. This means it will take 1 hit to kill an enemy. If zone is below the zone you have defined in AE: Zone then it will only buy equips when needed. ', 'value', '1', null, 'Gear'); + createSetting('Requipamount', 'AE: Amount', 'How much equipment to level per time. ', 'value', 1, null, "Gear"); + createSetting('Requipcapattack', 'AE: Weapon Cap', 'What level to stop buying Weapons at. ', 'value', 50, null, "Gear"); + createSetting('Requipcaphealth', 'AE: Armour Cap', 'What level to stop buying Armour at. ', 'value', 50, null, "Gear"); + createSetting('Requipzone', 'AE: Zone', 'What zone to stop caring about H:D and buy as much prestiges and equipment as possible. ', 'value', -1, null, "Gear"); + createSetting('Requippercent', 'AE: Percent', 'What percent of resources to spend on equipment before the zone you have set in AE: Zone', 'value', 1, null, "Gear"); + createSetting('Requip2', 'AE: 2', 'Always buys level 2 of weapons and armor regardless of efficiency', 'boolean', true, null, "Gear"); + document.getElementById('Requip2').parentNode.insertAdjacentHTML('afterend', '
'); + createSetting('Requipfarmon', 'AE: Farm', 'AutoEquip Farm. Calculates metal needed to reach the target you have defined in the AEF settings. Will try to buy the best map you can make. Will never make a plus map as this is intended for us on deep push runs. ', 'boolean', false, null, "Gear"); + createSetting('Requipfarmzone', 'AEF: Zone', 'What zone to start AEF: H:D and AEF: Multiplier. ', 'value', '-1', null, 'Gear'); + createSetting('RequipfarmHD', 'AEF: H:D', 'What H:D to use for AEF target. ', 'value', '-1', null, 'Gear'); + createSetting('Requipfarmmult', 'AEF: Multiplier', 'Starting from the zone above AEF: Zone, this setting will multiply the H:D you have set in AEF: H:D. So if AEF: Zone was 100, AEF: H:D was 10, AEF: Multiplier was 1.2, at z101 your H:D target will be 12, then at z102 it will be 14.4 and so on. This way you can account for the zones getting stronger and you will not waste time farming for a really low H:D. ', 'value', '-1', null, 'Gear'); + createSetting('Requipfarmhits', 'AEF: Hits', 'How many hits do you want to kill an enemy in a AEF map. ', 'value', '-1', null, 'Gear'); + + + + //Maps + + //Line 1 + createSetting('AutoMaps', ["Auto Maps Off", "Auto Maps On", "Auto Maps: Unique"], 'Automaps. Recommended ON. Do not use MaZ, it will not work. Automaps: Unique will unlock settings for each unique map. Select which unique maps you would like to run\, but otherwise functions the same. ', 'multitoggle', 1, null, "Maps"); + createSetting('AMUblock', 'AMU: The Block', 'Turn on to run this map every run. ', 'boolean', false, null, 'Maps'); + createSetting('AMUwall', 'AMU: The Wall', 'Turn on to run this map every run. ', 'boolean', false, null, 'Maps'); + createSetting('AMUanger', 'AMU: Dimension of Anger', 'Turn on to run this map every run. ', 'boolean', false, null, 'Maps'); + createSetting('AMUtrimple', 'AMU: Trimple', 'Turn on to run this map every run. ', 'boolean', false, null, 'Maps'); + createSetting('AMUprison', 'AMU: Prison', 'Turn on to run this map every run. ', 'boolean', false, null, 'Maps'); + createSetting('AMUbw', 'AMU: BW', 'Turn on to run this map every run. ', 'boolean', false, null, 'Maps'); + createSetting('AMUstar', 'AMU: Imploding Star', 'Turn on to run this map every run. ', 'boolean', false, null, 'Maps'); + createSetting('automapsportal', 'AM Portal', 'Makes sure Auto Maps is on on portal. ', 'boolean', false, null, 'Maps'); + createSetting('automapsalways', 'AM Always', 'Makes sure Auto Maps is on always. ', 'boolean', false, null, 'Maps'); + document.getElementById('automapsportal').parentNode.insertAdjacentHTML('afterend', '
'); + + //Line 2 createSetting('DynamicSiphonology', 'Dynamic Siphonology', 'Recommended Always ON. Use the right level of siphonology based on your damage output. IE: Only uses siphonology if you are weak. With this OFF it means it ALWAYS uses the lowest siphonology map you can create. Siphonology is a perk you get at level 115-125ish, and means you receive map bonus stacks for running maps below your current zone - Up to 3 zones below (1 per perk level).', 'boolean', true, null, 'Maps'); - createSetting('PreferMetal', 'Prefer Metal Maps', 'ADVANCED: Always prefer metal maps, intended for manual use, such as pre-spire farming. Remember to turn it back off after you\'re done farming! Usually helps for pre-spire. Use on x90-x99 zones.', 'boolean', false, null, 'Maps'); + createSetting('PreferMetal', 'Prefer Metal Maps', 'Always prefer metal maps, intended for manual use, such as pre-spire farming. Remember to turn it back off after you\'re done farming!', 'boolean', false, null, 'Maps'); + createSetting('mapselection', 'Map Selection', 'Select which you prefer to use. Recommend Plentiful (Gardens) if you have unlocked it. ', 'dropdown', 'Mountain', ["Random", "Mountain", "Forest", "Sea", "Depths", "Gardens"], 'Maps'); createSetting('MaxMapBonusAfterZone', 'Max MapBonus After', 'Always gets Max Map Bonus from this zone on. (inclusive and after).
NOTE: Set -1 to disable entirely (default). Set 0 to use it always.
Advanced:User can set a lower number than the default 10 maps with the AT hidden console command: MODULES[\\"maps\\"].maxMapBonusAfterZ = 9;', 'value', '-1', null, 'Maps'); - createSetting('DisableFarm', 'Disable Farming', 'Disables the extended farming algorithm of the AutoMaps part of the script. Always returns to the world after reaching 10 map stacks. Use at your own risk. (No need to refresh anymore)', 'boolean', false, null, 'Maps'); + createSetting('MaxMapBonuslimit', 'Max MapBonus Limit', 'Limit the amount of Map Bonuses you get. Default is 10. ', 'value', '10', null, 'Maps'); + createSetting('MaxMapBonushealth', 'Max MapBonus Health', 'Limit the amount of map bonuses you get when AutoMaps requires more health. Default is 10. ', 'value', '10', null, 'Maps'); + createSetting('mapcuntoff', 'Map Cut Off', 'Decides when to get max map bonus. 4 is default. This means it will take 1 hit to kill an enemy if in D stance. ', 'value', '4', null, 'Maps'); + + //Line 3 + createSetting('DisableFarm', 'Farming H:D', 'If H:D goes above this value, it will farm for Damage & Health. The lower this setting, the more it will want to farm. Default is 16. -1 to disable farming!', 'value', -1, null, 'Maps'); createSetting('LowerFarmingZone', 'Lower Farming Zone', 'Lowers the zone used during Farming mode. Uses the dynamic siphonology code, to Find the minimum map level you can successfully one-shot, and uses this level for any maps done after the first 10 map stacks. The difference being it goes LOWER than what Siphonology gives you map-bonus for, but after 10 stacks you dont need bonus, you just want to do maps that you can one-shot. Goes as low as 10 below current zone if your damage is that bad, but this is extreme and indicates you should probably portal.', 'boolean', true, null, 'Maps'); - //Line2 - createSetting('MaxStacksForSpire', 'Max Map Bonus for Spire', 'Get max map bonus before running the Spire.', 'boolean', false, null, 'Maps'); - createSetting('MinutestoFarmBeforeSpire', 'Farm Before Spire', 'Farm level 200/199(or BW) maps for X minutes before continuing onto attempting Spire.
NOTE: Set 0 to disable entirely (default).
Setting to -1/Infinite does not work here, set a very high number instead.', 'value', '0', null, 'Maps'); - createSetting('IgnoreSpiresUntil', 'Ignore Spires Until', 'Spire specific settings like end-at-cell are ignored until at least this zone is reached (0 to disable).
Does not work with Run Bionic Before Spire.', 'value', '200', null, 'Maps'); - createSetting('RunBionicBeforeSpire', 'Run Bionic Before Spire', 'CAUTION: Runs Bionic Wonderlands and repeatedly farms Bionic VI @ level 200 before attempting Spire, for the purpose of resource farming. Then it attempts the spire. The Minutes-Before-Spire timer runs concurrently to this, and needs to be set. If not set, it will exit without doing any Bionics... You can un-toggle it on the fly.
NOTE: Turning this on also mandates that AutoMaps + Unique Maps be on.
WARNING: These 100 square maps take ~3x longer than normal maps.
WARNING: If you dont have Bionic Magnet mastery, this will run the 5 pre-requisites and take longer.
NOTE: In fact, it may not be what you want at all.', 'boolean', false, null, 'Maps'); - createSetting('ExitSpireCell', 'Exit Spire After Cell', 'Optional/Rare. Exits the Spire early, after completing cell X. example: 40 for Row 4. (use 0 or -1 to disable)', 'value', '-1', null, 'Maps'); - createSetting('CorruptionCalc', 'Corruption Farm Mode', 'Recommended. Enabling this will cause the Automaps routine to take amount of corruption in a zone into account, to decide whether it should do maps first for map bonus. ONLY in Zone 181+ (or Headstart 1,2,3 zone: 176,166,151) ', 'boolean', true, null, 'Maps'); createSetting('FarmWhenNomStacks7', 'Farm on >7 NOMstacks', 'Optional. If Improbability already has 5 NOMstacks, stack 30 Anticipation. If the Improbability has >7 NOMstacks on it, get +200% dmg from MapBonus. If we still cant kill it, enter Farming mode at 30 stacks, Even with DisableFarming On! (exits when we get under 10x). Farms if we hit 100 stacks in the world. If we ever hit (100) nomstacks in a map (likely a voidmap), farm, (exit the voidmap) and (prevent void from running, until situation is clear). Restarts any voidmaps if we hit 100 stacks. ', 'boolean', false, null, 'Maps'); - //Line3 - createSetting('VoidMaps', 'Void Maps', 'The zone at which you want all your void maps to be cleared (Cell 96). 0 is off', 'value', '0', null, "Maps"); - createSetting('RunNewVoids', 'Run New Voids', 'Run new void maps acquired after the set void map zone. Runs them at Cell 95 by default, unless you set a decimal value indicating the cell, like: 187.75 CAUTION: May severely slow you down by trying to do too-high level voidmaps. Use the adjacent RunNewVoidsUntil setting to limit this.', 'boolean', false, null, 'Maps'); - createSetting('RunNewVoidsUntil', 'New Voids Until', 'Run New Voids Until: Put a cap on what zone new voids will run at, until this zone, inclusive. ', 'value', '-1', null, 'Maps'); - //createSetting('VoidsPerZone', 'Voids per Zone', 'Run a max of this many Voids per zone, if you have a lot of Voids saved up. Then moves onto the next zone and does more voids.', 'value', '-1', null, 'Maps'); - createSetting('VoidCheck', 'Void Difficulty Check', 'How many hits to be able to take from a void map boss in X stance before we attempt the map. Higher values will get you stronger (by farming maps for health) before attempting. Disabling this with 0 or -1 translates into a default of surviving 2 hits. I recommend somewhere between 2 and 12 (default is now 6).', 'value', '6', null, 'Maps'); - createSetting('MaxTox', 'Max Toxicity Stacks', 'Get maximum toxicity stacks before killing the improbability in each zone 60 and above. Generally only recommended for 1 run to maximize bone portal value. This setting will revert to disabled after a successful Max-Tox run + Toxicity Autoportal.', 'boolean', false, null, 'Maps'); + createSetting('VoidMaps', 'Void Maps', '0 to disable The zone at which you want all your void maps to be cleared inclusive of the zone you type. Runs them at Cell 70. Use odd zones on Lead.
', 'value', '0', null, "Maps"); + createSetting('voidscell', 'Voids Cell', 'Run Voids at this Cell. -1 to run them at the default value, which is 70. ', 'value', '-1', null, 'Maps'); + createSetting('RunNewVoidsUntilNew', 'New Voids Mod', '0 to disable. Positive numbers are added to your Void Map zone. -1 for no cap. This allows you to run new Void Maps obtained after your Void Map zone by adding this number to your Void Map zone.
Example Void map zone=187 and This setting=10. New Voids run until 197).
This means that any new void maps gained until Z197. CAUTION: May severely slow you down by trying to do too-high level void maps. Default 0 (OFF).', 'value', '0', null, 'Maps'); + createSetting('runnewvoidspoison', 'New Voids Poison', 'Only run new voids in poison zones.', 'boolean', false, null, 'Maps'); + createSetting('onlystackedvoids', 'Stacked Voids Only', 'Only run stacked voids. ', 'boolean', false, null, 'Maps'); + + //Line 4 createSetting('TrimpleZ', 'Trimple Z', 'I don\'t really think doing this automatically is a good idea. You might want to farm for a bit before this, but I\'m not sure if it\'s meaningful at all to make a \'farm X minutes before trimple\' parameter to go along with it. Set it to the zone you want and it will run Trimple of Doom for Ancient Treasure AFTER farming and getting map stacks. If it is a negative number, this will be disabled after a successful run so you can set it differently next time.', 'valueNegative', 0, null, 'Maps'); - createSetting('AdvMapSpecialModifier', 'Map Special Modifier', 'EXPERIMENTAL. Attempt to select the BEST map special attacks mod. With this on, this will replace the normal behavior. If bugs, please report as this will become more default soon.', 'boolean', false, null, 'Maps'); + createSetting('AdvMapSpecialModifier', 'Map Special Modifier', 'BELOW 300 ONLY
Attempt to select the BEST map special modifier. When starting a map for Prestige it will use Prestigious. When starting a map for Farming (for equipment) it will use your best metal cache. In any other case (such as farming for map stacks) it will use Fast Attacks. In all cases it uses the best modifier that can be afforded.', 'boolean', true, null, 'Maps'); + createSetting('scryvoidmaps', 'VM Scryer', 'Only use if you have Scryhard II, for er, obvious reasons. Works without the scryer options. ', 'boolean', false, null, 'Maps'); + createSetting('buywepsvoid', 'VM Buy Weps', 'Buys gear in Void maps regardless of your H:D ratio. Useful if you want to overkill as much as possible. ', 'boolean', false, null, 'Maps'); + createSetting('farmWonders', 'Farm Wonders', 'Farms wonders until the selected amount and does BW at given zone to finish the challenge', 'boolean', false, null, 'Maps') + createSetting('wondersAmount', 'Wonders Amount', 'Select the amount of Wonders you want to farm in each given run, 0 to disable ', 'value', '0', null, "Maps"); + createSetting('maxExpZone', "Max XP Zone", 'Acquire Wonders from this zone down. This must have a value or other Experience settings will not work. If >z600, will complete Experience by running BW on this zone as well. For example, targeting three Wonders with a Max XP Zone of 600 will obtain the Wonders at: 600, 595, 590.', 'value', '600', null, 'Maps'); + createSetting('finishExpOnBw', 'Finish XP on BW', 'Finish Experience challenge by completing this level of BW. This level of BW should already be in your inventory. Use BW Raiding module if you want to raid to a specific level of BW before 601, or else you may accidentally complete the challenge at a lower or higher BW than intended using this setting. If this is an invalid BW value, it will run the next lowest valid BW zone (e.g. 606 will run 605).', 'value', '605', null, 'Maps'); + + //Shrine - U1 + document.getElementById('finishExpOnBw').parentNode.insertAdjacentHTML('afterend', '
'); + createSetting('Hshrine', 'AutoShrine', 'Turn this on if you want to use Shrines automatically. ', 'boolean', false, null, 'Maps'); + createSetting('Hshrinemaz', 'AutoShrine Settings', 'Click to open AutoShrine settings.
Zone: What zone to use Bone Shrine charges.
Cell: What cell to use Bone Shrine charges at, if you use it after cell 80 you will get the benefit of all the books. to use.
Amount: How many Bone Shrine charges you wish to use.
Example: If you put Zone: 40\, Cell: 10\, Amount: 3\, you will use 3 Bone Shrine Charges at zone 40 at cell 10. ', 'infoclick', false, null, 'Maps'); + createSetting('Hshrinezone', 'AutoShrine: Zone', 'zone', 'multiValue', [-1], null, 'Maps'); + createSetting('Hshrinecell', 'AutoShrine: Cell', 'cell', 'multiValue', [-1], null, 'Maps'); + createSetting('Hshrineamount', 'AutoShrine: Amount', 'amount', 'multiValue', [-1], null, 'Maps'); + createSetting('Hshrinecharge', 'AutoShrine: Charge', 'charge count you will never see this setting hehehehe', 'value', 0, null, 'Maps'); + + //RMaps + + //Line 1 + createSetting('RAutoMaps', ["Auto Maps Off", "Auto Maps On", "Auto Maps No Unique"], 'Automaps. The no unique setting will not run unique maps such as dimensions of rage. Recommended ON. ', 'multitoggle', 1, null, "Maps"); + createSetting('Rautomapsportal', 'AM Portal', 'Makes sure Auto Maps is on portal. ', 'boolean', false, null, 'Maps'); + createSetting('Rautomapsalways', 'AM Always', 'Makes sure Auto Maps is on always. ', 'boolean', false, null, 'Maps'); + createSetting('Rmapselection', 'Map Selection', 'Select which you prefer to use. Recommend Plentiful (Gardens) if you have unlocked it. ', 'dropdown', 'Mountain', ["Random", "Mountain", "Forest", "Sea", "Depths", "Plentiful", "Farmlands"], 'Maps'); + createSetting('RMaxMapBonusAfterZone', 'Max MapBonus After', 'Always gets Max Map Bonus from this zone on. (inclusive and after).
NOTE: Set -1 to disable entirely (default). Set 0 to use it always. ', 'value', '-1', null, 'Maps'); + createSetting('RMaxMapBonuslimit', 'Max MapBonus Limit', 'Limit the amount of Map Bonuses you get. Default is 10. ', 'value', '10', null, 'Maps'); + createSetting('RMaxMapBonushealth', 'Max MapBonus Health', 'Limit the amount of map bonuses you get when AutoMaps requires more health. Default is 10. ', 'value', '10', null, 'Maps'); + createSetting('Rhitssurvived', 'Hits Survived', 'Set this value to tell the script how many enemy attacks you wish to survive for. The default is 10. The lower this is the less health the script will get. If you set this too high it will farm too much so please be careful. ', 'value', '10', null, 'Maps'); + createSetting('Rmapcuntoff', 'Map Cut Off', 'Decides when to get max map bonus. 1 is default. This means it will take 1 hit to kill an enemy. ', 'value', '1', null, 'Maps'); + createSetting('RDisableFarm', 'Farming H:D', 'If H:D goes above this value, it will farm for Damage & Health. The lower this setting, the more it will want to farm. Default is 16. -1 to disable farming!', 'value', -1, null, 'Maps'); + + //Line 2 + createSetting('RVoidMaps', 'Void Maps', '0 to disable The zone at which you want all your void maps to be cleared inclusive of the zone you type. Runs them at Cell 70. Use odd zones on Lead.
', 'value', '0', null, "Maps"); + createSetting('Rvoidscell', 'Voids Cell', 'Run Voids at this Cell. -1 to run them at the default value, which is 70. ', 'value', '-1', null, 'Maps'); + createSetting('RRunNewVoidsUntilNew', 'New Voids Mod', '0 to disable. Positive numbers are added to your Void Map zone. -1 for no cap. This allows you to run new Void Maps obtained after your Void Map zone by adding this number to your Void Map zone.
Example Void map zone=187 and This setting=10. New Voids run until 197).
This means that any new void maps gained until Z197. CAUTION: May severely slow you down by trying to do too-high level void maps. Default 0 (OFF).', 'value', '0', null, 'Maps'); + createSetting('Rprispalace', 'Prismatic Palace', 'Run Prismatic Palace when its unlocked. ', 'boolean', true, null, 'Maps'); + createSetting('Rmeltpoint', 'Melting Point', '-1 to disable. When to run the map Melting Point. Use it like this: 50,91. The first number is what zone Melting Point should be run at, the second number is what Cell to run it at. In this example AutoMaps would run Melting Point at z50 cell 91. Must define both values. Works in the challenges Melt and Trappapalooza. ', 'multiValue', [-1], null, 'Maps'); + createSetting('Rfrozencastle', 'Frozen Castle', '-1 to disable. When to run the map Frozen Castle. Use it like this: 200,91. The first number is what zone Frozen Castle should be run at, the second number is what Cell to run it at. In this example AutoMaps would run Frozen Castle at z200 cell 91. Must define both values. Works in any challenge so be careful. ', 'multiValue', [-1], null, 'Maps'); + + //Timefarm + document.getElementById('Rfrozencastle').parentNode.insertAdjacentHTML('afterend', '
'); + createSetting('Rtimefarm', 'Time Farm', 'Turn this on if you want to use Time Farming. ', 'boolean', false, null, 'Maps'); + createSetting('Rtimefarmmaz', 'Time Farm Settings', 'Click to open the Time Farm settings. It will also put all your workers into what you are gathering.
Zone: What zone to start time farming.
Cell: What cell to start time farming at.
Time: How much time in Minutes to farm.
Level: How many map levels above your zone to use.
Map: What kind of map you want to use.
Special: What type of special you want to use.
Gather: What resource you would like to gather.
Example: If you put Zone: 60\, Cell: 10\, Time: 3\, Level: 5\, Map: Gardens\, Special: Large Metal Cache\, Gather: Metal\, you will farm at zone 60 at cell 10 for 3 minutes in a +5 Gardens map that has a Large Metal Cache while gathering metal. ', 'infoclick', false, null, 'Maps'); + createSetting('Rtimefarmzone', 'TF: Zone', 'zone', 'multiValue', [-1], null, 'Maps'); + createSetting('Rtimefarmcell', 'TF: Cell', 'cell', 'multiValue', [-1], null, 'Maps'); + createSetting('Rtimefarmtime', 'TF: Time', 'time', 'multiValue', [-1], null, 'Maps'); + createSetting('Rtimefarmlevel', 'TF: Map Level', 'level', 'multiValue', [0], null, 'Maps'); + createSetting('Rtimefarmmap', 'TF: Map Selection', 'map', 'textValue', 'undefined', null, 'Maps'); + createSetting('Rtimefarmspecial', 'TF: Special Selection', 'special', 'textValue', 'undefined', null, 'Maps'); + createSetting('Rtimefarmgather', 'TF: Gather Selection', 'gather', 'textValue', 'undefined', null, 'Maps'); + + //Smithyfarm + document.getElementById('Rtimefarmgather').parentNode.insertAdjacentHTML('afterend', '
'); + createSetting('Rsmithyfarm', 'Smithy Farm', 'Turn this on if you want to use Smithy Farming. ', 'boolean', false, null, 'Maps'); + createSetting('Rsmithyfarmmaz', 'Smithy Farm Settings', 'Click to open the Smithy Farm settings.
Zone: What zone to start smithy farming.
Cell: What cell to start smithy farming at.
Smithys: How many smithys you want to have at that zone.
Example: If you put Zone: 60\, Cell: 10\, Smithys: 2\, you will farm at zone 60 at cell 10 for 2 total smithies in an autogenerated map that will fill your resource needs\, gather and job appropriately', 'infoclick', false, null, 'Maps'); + createSetting('Rsmithyfarmzone', 'SF: Zone', 'zone', 'multiValue', [-1], null, 'Maps'); + createSetting('Rsmithyfarmcell', 'SF: Cell', 'cell', 'multiValue', [-1], null, 'Maps'); + createSetting('Rsmithyfarmamount', 'SF: Smithys', 'smithys', 'multiValue', [-1], null, 'Maps'); + + //Tributefarm + document.getElementById('Rsmithyfarmamount').parentNode.insertAdjacentHTML('afterend', '
'); + createSetting('Rtributefarm', 'Tribute Farm', 'Turn this on if you want to use Tribute Farming. ', 'boolean', false, null, 'Maps'); + createSetting('Rtributefarmmaz', 'Tribute Farm Settings', 'Click to open the Tribute Farm settings.
Zone: What zone to start tribute farming. It will also put all your workers into farming.
Cell: What cell to start tribute farming at.
Tributes: How many tributes to farm.
Level: How many map levels above your zone to use.
Map: What kind of map you want to use.
Special: What type of special you want to use.
Gather: What resource you would like to gather.
Example: If you put Zone: 40\, Cell: 10\, Tributes: 1000\, Level: 5\, Map: Gardens\, Special: Large Savory Cache\, Gather: Food\, you will farm at zone 40 at cell 10 for 1000 tributes in a +5 Gardens map that has a Large Savory Cache while gathering food. ', 'infoclick', false, null, 'Maps'); + createSetting('Rtributefarmzone', 'TrF: Zone', 'zone', 'multiValue', [-1], null, 'Maps'); + createSetting('Rtributefarmcell', 'TrF: Cell', 'cell', 'multiValue', [-1], null, 'Maps'); + createSetting('Rtributefarmamount', 'TrF: Tributes', 'tributes', 'multiValue', [-1], null, 'Maps'); + createSetting('Rtributefarmlevel', 'TrF: Map Level', 'level', 'multiValue', [0], null, 'Maps'); + createSetting('Rtributemapselection', 'TrF: Map Selection', 'map', 'textValue', 'undefined', null, 'Maps'); + createSetting('Rtributespecialselection', 'TrF: Special Selection', 'special', 'textValue', 'undefined', null, 'Maps'); + createSetting('Rtributegatherselection', 'TrF: Gather Selection', 'gather', 'textValue', 'undefined', null, 'Maps'); + + //Shrine - U2 + document.getElementById('Rtributegatherselection').parentNode.insertAdjacentHTML('afterend', '
'); + createSetting('Rshrine', 'AutoShrine', 'Turn this on if you want to use Shrines automatically. ', 'boolean', false, null, 'Maps'); + createSetting('Rshrinemaz', 'AutoShrine Settings', 'Click to open AutoShrine settings.
Zone: What zone to use Bone Shrine charges.
Cell: What cell to use Bone Shrine charges at, if you use it after cell 80 you will get the benefit of all the books. to use.
Amount: How many Bone Shrine charges you wish to use.
Example: If you put Zone: 40\, Cell: 10\, Amount: 3\, you will use 3 Bone Shrine Charges at zone 40 at cell 10. ', 'infoclick', false, null, 'Maps'); + createSetting('Rshrinezone', 'AutoShrine: Zone', 'zone', 'multiValue', [-1], null, 'Maps'); + createSetting('Rshrinecell', 'AutoShrine: Cell', 'cell', 'multiValue', [-1], null, 'Maps'); + createSetting('Rshrineamount', 'AutoShrine: Amount', 'amount', 'multiValue', [-1], null, 'Maps'); + createSetting('Rshrinecharge', 'AutoShrine: Charge', 'charge count you will never see this setting hehehehe', 'value', 0, null, 'Maps'); + + + //Spire + + //Line 1 + createSetting('MaxStacksForSpire', 'Max Map Bonus for Spire', 'Get max map bonus before running the Spire.', 'boolean', false, null, 'Spire'); + createSetting('MinutestoFarmBeforeSpire', 'Farm Before Spire', 'Farm level 200/199(or BW) maps for X minutes before continuing onto attempting Spire.
NOTE: Set 0 to disable entirely (default).
Setting to -1/Infinite does not work here, set a very high number instead. **PLEASE DO NOT USE THIS IT MAY NOT WORK AND I CANNOT FIX IT**', 'value', '0', null, 'Spire'); + createSetting('IgnoreSpiresUntil', 'Ignore Spires Until', 'Spire specific settings like end-at-cell are ignored until at least this zone is reached (0 to disable).
Does not work with Run Bionic Before Spire.', 'value', '200', null, 'Spire'); + createSetting('ExitSpireCell', 'Exit Spire After Cell', 'Optional/Rare. Exits the Spire early, after completing cell X. example: 40 for Row 4. (use 0 or -1 to disable)', 'value', '-1', null, 'Spire'); + createSetting('SpireBreedTimer', 'Spire Breed Timer', 'ONLY USE IF YOU USE VANILLA GASet a time for your GA in spire. Recommend not touching GA during this time. ', 'value', -1, null, 'Spire'); + createSetting('PreSpireNurseries', 'Nurseries pre-Spire', 'Set the maximum number of Nurseries to build for Spires. Overrides No Nurseries Until z and Max Nurseries so you can keep them seperate! Will build nurseries before z200 for Spire 1, but only on the zone of Spires 2+ to avoid unnecessary burning. Disable with -1.', 'value', -1, null, 'Spire'); + createSetting('spireshitbuy', 'Buy Gear in Spire', 'Will buy Weapons and Armor in Spire regardless of your H:D ratio. Respects your max gear level and ignore spires setting. ', 'boolean', false, null, 'Spire'); + createSetting('SkipSpires', 'Skip Spires', 'Will disregard your H:D ratio after Farm Before Spire is done (if set). Useful to die in spires if farming takes too long', 'boolean', false, null, 'Spire'); + + + //Raiding + + //Line 1 + createSetting('Praidingzone', 'P Raiding Z', 'Raids Maps for prestiges at zone specified. Example: 495, will raid Maps at 501-505 sequentially. Once all gear is obtained from the maps, it will revert back to regular farming. Use P Raiding HD to determine how many extra maps you wish you raid. Extremely helpful for spire. Best used in poison zones. You can use multiple values like this 495,506,525! ', 'multiValue', [-1], null, 'Raiding'); + createSetting('Praidingcell', 'P Raiding Cell', 'What Cell to start P Raiding at. Recommend below your BW Raiding cell if used together. -1 to Raid at cell 1. ', 'value', -1, null, 'Raiding'); + createSetting('PraidingHD', 'P Raiding HD', 'Checks if you can raid the map. If your HD value (calculated using the maps you will raid) is below this value it will not buy the map and you will stop raiding. The higher this value the higher zones it will raid. Can raid up to +10 depending on the zone. -1 or 0 to remove this check.', 'value', -1, null, 'Raiding'); + createSetting('PraidingP', 'P Raiding Poison', 'Maximum level of map to P Raid at in Poison. If this value is 10 it will be able to go to +10 maps in Poison. You should use this instead of the HD function if you feel the calculations are off, but you can use both if needed. -1 or 0 to have no max. ', 'value', -1, null, 'Raiding'); + createSetting('PraidingI', 'P Raiding Ice', 'Maximum level of map to P Raid at in Ice. If this value is 10 it will be able to go to +10 maps in Ice. You should use this instead of the HD function if you feel the calculations are off, but you can use both if needed. -1 or 0 to have no max. ', 'value', -1, null, 'Raiding'); + createSetting('PraidHarder', 'Hardcore P Raiding', '(EXPERIMENTAL) P Raid Harder: When enabled, always buys the highest prestige map we can afford when P raiding, with option to farm fragments for highest available prestige level.', 'boolean', false, null, 'Raiding'); + createSetting('MaxPraidZone', 'Max P Raid Zones', 'List of maximum zones to Praid corresponding to the list specified in Praiding zones. e.g. if P raiding zones setting is 491,495 and this setting is 495,505, AT will P raid up to 495 from 491, and 505 from 495. Set to -1 to always buy highest available prestige map. If no corrsponding value, or value is invalid, defaults to max available (up to +10)', 'multiValue', [-1], null, 'Raiding'); + createSetting('PraidFarmFragsZ', 'Farm Fragments Z', 'P Raiding harder: List of zones where we should farm fragments until we can afford the highest or target prestige map for P raiding. Set to -1 to never farm fragments. ', 'multiValue', [-1], null, 'Raiding'); + createSetting('PraidBeforeFarmZ', 'Raid before farm Z', 'P Raiding harder: List of zones where we should P Raid as far as we can afford before trying to farm fragments to Praid the highest or target prestige map. Only occasionally useful, e.g. if it picks up a Speedexplorer or farming fragments is slow due to low damage. Set to -1 to never raid prestiges before farming fragents.', 'multiValue', [-1], null, 'Raiding'); + createSetting('BWraid', 'BW Raiding', 'Raids BW at zone specified in BW Raiding Z/max. Turn off Climb BW. ', 'boolean', false, null, 'Raiding'); + createSetting('bwraidcell', 'BW Raiding Cell', 'What Cell to start BW Raiding at. Recommend above your P Raiding cell if used together. -1 to Raid at cell 1. ', 'value', -1, null, 'Raiding'); + createSetting('BWraidingz', 'Z to BW Raid', 'Raids BWs at zone specified. Example: 495, will raid all BWs for all gear starting from 495. Will skip lower BWs if you have enough damage. Once all gear is obtained, will return to regular farming. Accepts comma separated lists, and raids up to the value in the corrsponding position in the Max BW to raid setting. So if this is set to 480,495 and Max BW to Raid is set to 500,515 AT will BW raid up to 500 from 480, and 515 from 495. Make sure these lists are the same length or BW raiding may fail.', 'multiValue', [-1], null, 'Raiding'); + createSetting('BWraidingmax', 'Max BW to raid', 'Raids BWs until zone specified. Example: 515, will raid all BWs for all gear until 515. Will skip lower BWs if you have enough damage. Once all gear is obtained, will return to regular farming. Now accepts comma separated lists - see description of Z to BW raid setting for details.', 'multiValue', [-1], null, 'Raiding'); + + + //RRaiding + + //Line 1 + createSetting('RAMPraid', 'Praiding', 'MASTER BUTTON
Toggle Prestige Raiding. Use PR: Zone, PR: Raid and PR: Cell to Raid Prestiges in higher Maps.
I.e: World is 95, PR: Zone is [95,105], PR: Raid is [105,115], PR: Cell is 1. Will go into map creation at cell 1, create maps 101, 102, 103, 104, 105 with Prestige option. If you can\'t afford P maps, it will try without. If still unable to afford will buy the highest maps first without buying 101 and 102 for example. Raiding will take longer if you can\'t afford it. Once all maps are created it will run the lowest created then move onto the next till all created maps are finished. If you have enabled PR: Recycle it will then recycle those maps. There may be more options in the future depending on content added. ', 'boolean', false, null, 'Raiding'); + createSetting('RAMPraidmaz', 'Praiding Settings', 'Click to open the Praiding settings. ', 'infoclick', false, null, 'Raiding'); + createSetting('RAMPraidzone', 'PR: Zone', 'zone', 'multiValue', [-1], null, 'Raiding'); + createSetting('RAMPraidraid', 'PR: Raid', 'raid', 'multiValue', [-1], null, 'Raiding'); + createSetting('RAMPraidcell', 'PR: Cell', 'cell', 'multiValue', [-1], null, 'Raiding'); + createSetting('RAMPraidfrag', ['PR: Frag', 'PR: Frag Min', 'PR: Frag Max'], 'Farm for fragments to afford the maps you want to create. PR: Frag Min is used for absolute minimum frag costs (which includes no Prestige special, perfect sliders, random map and the difficulty and size options, however it will try to afford those options first!) and prioritises buying the most maps for a smoother sequential raid. PR: Frag Max is used for the ultimate Raiding experience. This option will probably take the most time to farm but may save you time in the actual raid. I would recommend using Min Mode if you don\'t have frag drop or explorer effic on your heirloom and Max if you are confident in your Fragment gains. ', 'multitoggle', 0, null, 'Raiding'); + createSetting('RAMPraidrecycle', 'PR: Recycle', 'Recycle maps created in Prestige Raiding. ', 'boolean', false, null, 'Raiding'); + + + + //Windstacking + + //Line 1 + createSetting('windstackingfiller', 'Use Daily Tab for Dailies!', 'These settings are for fillers ONLY. ', 'boolean', 'false', null, 'Windstacking'); + createSetting('turnwson', 'Turn WS On!', 'Turn on Windstacking Stance in Combat to see the settings! ', 'boolean', 'false', null, 'Windstacking'); + createSetting('WindStackingMin', 'Windstack Min Zone', 'For use with Windstacking Stance, enables windstacking in zones above and inclusive of the zone set. (Get specified windstacks then change to D, kill bad guy, then repeat). This is designed to force S use until you have specified stacks in wind zones, overriding scryer settings. All windstack settings apart from WS MAX work off this setting. ', 'value', '-1', null, 'Windstacking'); + createSetting('WindStackingMinHD', 'Windstack H:D', 'For use with Windstacking Stance, if your H:D is below this number it will use W inside windlight and S outside of it. If it is above it will start manually windstacking using heirloom swapping and stancing. If you just want to use W stance just set this to something impossibly high like 1e30. ', 'value', '-1', null, 'Windstacking'); + createSetting('WindStackingMax', 'Windstack Stacks', 'For use with Windstacking Stance. Amount of windstacks to obtain before switching to D stance. Default is 200, but I recommend anywhere between 175-190. In Wind Enlightenment it will add 100 stacks to your total automatically. So if this setting is 200 It will assume you want 300 stacks instead during enlightenment. ', 'value', '200', null, 'Windstacking'); + createSetting('windcutoff', 'Wind Damage Cutoff', 'Set this value to optimise your windstacking. Can work without AS3, but not recommended. AT normally uses 4 as its cutoff. I.e if the cutoff is above 4 it will buy max equipment. If you set this to 160, it will not get more damage till you are above x160. Essentially, the higher the value, the less damage AT wants to get, this will enable you to windstack to incredibly high amounts. -1 to disable/go back to default. Must set your windstacking min zone to use. ', 'value', '-1', null, 'Windstacking'); + createSetting('windcutoffmap', 'Wind Map Cutoff', 'Set this value to optimise your windstacking. Can work without AS3, but not recommended. AT normally uses 4 as its cutoff. I.e if the cutoff is above 4 it will get map bonus. If you set this to 160, it will not get more map bonus till you are above x160. Essentially, the higher the value, the less damage AT wants to get, this will enable you to windstack to incredibly high amounts. -1 to disable/go back to default. Must set your windstacking min zone to use. ', 'value', '-1', null, 'Windstacking'); + createSetting('wsmax', 'WS MAX', 'For maximising Windstacking an entire run. Withholds damage to try and get your max windstacks every wind zone. Not recommended for normal usage. Good for BPs. ', 'value', '-1', null, 'Windstacking'); + createSetting('wsmaxhd', 'WSM H:D', 'Fiddle with this to maximise your WSM settings. Default is 0.00025. Same logic applies from the normal H:D setting. ', 'value', '-1', null, 'Windstacking'); + + + + //ATGA + + //Line 1 + createSetting('ATGA2', 'ATGA', 'ATGA MASTER BUTTON
AT Geneticassist. Do not use vanilla GA, as it will conflict otherwise. May get fucky with super high values. ', 'boolean', 'false', null, 'ATGA'); + createSetting('ATGA2gen', 'ATGA: Gen %', 'ATGA: Geneassist %
ATGA will only hire geneticists if they cost less than this value. E.g if this setting is 1 it will only buy geneticists if they cost less than 1% of your food. Default is 1%. ', 'value', '1', null, 'ATGA'); + createSetting('ATGA2timer', 'ATGA: Timer', 'ATGA Timer
This is the default time your ATGA will use. ', 'value', '-1', null, 'ATGA'); + + //Zone Timers + document.getElementById('ATGA2timer').parentNode.insertAdjacentHTML('afterend', '
'); + createSetting('zATGA2timer', 'ATGA: T: Before Z', 'ATGA Timer: Before Z
ATGA will use the value you define in ATGA: T: BZT before the zone you have defined in this setting, overwriting your default timer. Useful for Liq or whatever. ', 'value', '-1', null, 'ATGA'); + createSetting('ztATGA2timer', 'ATGA: T: BZT', 'ATGA Timer: Before Z Timer
ATGA will use this value before the zone you have defined in ATGA: T: Before Z, overwriting your default timer. Useful for Liq or whatever. Does not work on challenges. ', 'value', '-1', null, 'ATGA'); + createSetting('ATGA2timerz', 'ATGA: T: After Z', 'ATGA Timer: After Z
ATGA will use the value you define in ATGA: T: AZT after the zone you have defined in this setting, overwriting your default timer. Useful for super push runs or whatever. Does not work on challenges. ', 'value', '-1', null, 'ATGA'); + createSetting('ATGA2timerzt', 'ATGA: T: AZT', 'ATGA Timer: After Z Timer
ATGA will use this value after the zone that has been defined in ATGA: T: After Z, overwriting your default timer. Useful for super push runs or whatever. ', 'value', '-1', null, 'ATGA'); + + //Spire Timers + document.getElementById('ATGA2timerzt').parentNode.insertAdjacentHTML('afterend', '
'); + createSetting('sATGA2timer', 'ATGA: T: Spire', 'ATGA Timer: Spire
ATGA will use this value in Spires. Respects your ignore Spires setting. Do not use this if you use the setting in the Spire tab! (As that uses vanilla GA) Nothing overwrites this except Daily Spire. ', 'value', '-1', null, 'ATGA'); + createSetting('dsATGA2timer', 'ATGA: T: Daily Spire', 'ATGA Timer: Daily Spire
ATGA will use this value in Daily Spires. Respects your ignore Spires setting. Do not use this if you use the setting in the Spire tab! (As that uses vanilla GA) Nothing overwrites this. ', 'value', '-1', null, 'ATGA'); + + //Daily Timers + document.getElementById('dsATGA2timer').parentNode.insertAdjacentHTML('afterend', '
'); + createSetting('dATGA2Auto', ['ATGA: Manual', 'ATGA: Auto No Spire', 'ATGA: Auto Dailies'], 'EXPERIMENTAL
ATGA Timer: Auto Dailies
ATGA will use automatically set breed timers in plague and bogged, overwriting your default timer.
Set No Spire to not override in spire, respecting ignore spire settings.', 'multitoggle', 2, null, 'ATGA'); + createSetting('dATGA2timer', 'ATGA: T: Dailies', 'ATGA Timer: Normal Dailies
ATGA will use this value for normal Dailies such as ones without plague etc, overwriting your default timer. Useful for pushing your dailies that extra bit at the end. Overwrites Default, Before Z and After Z. ', 'value', '-1', null, 'ATGA'); + createSetting('dhATGA2timer', 'ATGA: T: D: Hard', 'ATGA Timer: Hard Dailies
ATGA will use this value in Dailies that are considered Hard. Such Dailies include plaged, bloodthirst and Dailies with a lot of negative mods. Overwrites Default, Before Z and After Z and normal Daily ATGA Timer. ', 'value', '-1', null, 'ATGA'); + + //C2 Timers + document.getElementById('dhATGA2timer').parentNode.insertAdjacentHTML('afterend', '
'); + createSetting('cATGA2timer', 'ATGA: T: C2', 'ATGA Timer: C2s
ATGA will use this value in C2s. Overwrites Default, Before Z and After Z. ', 'value', '-1', null, 'ATGA'); + createSetting('chATGA2timer', 'ATGA: T: C: Hard', 'ATGA Timer: Hard C2s
ATGA will use this value in C2s that are considered Hard. Electricity, Nom, Toxicity. Overwrites Default, Before Z and After Z and C2 ATGA', 'value', '-1', null, 'ATGA'); + + + + //Challenges + + //Hide + createSetting('Rchallengehide', 'Hide Stuff', 'Enable seeing the hide challenges buttons. Feel free to turn this off once you are done. ', 'boolean', false, null, 'Challenges'); + createSetting('Rchallengehidequag', 'Quag', 'Set this on if you wish to hide the Quagmire challenge settings. ', 'boolean', false, null, 'Challenges'); + createSetting('Rchallengehidearch', 'Arch', 'Set this on if you wish to hide the Archaeology challenge settings. ', 'boolean', false, null, 'Challenges'); + createSetting('Rchallengehidemayhem', 'Mayhem', 'Set this on if you wish to hide the Mayhem challenge settings. ', 'boolean', false, null, 'Challenges'); + createSetting('Rchallengehidestorm', 'Storm', 'Set this on if you wish to hide the Storm challenge settings. ', 'boolean', false, null, 'Challenges'); + createSetting('Rchallengehideinsanity', 'Insanity', 'Set this on if you wish to hide the Insanity challenge settings. ', 'boolean', false, null, 'Challenges'); + createSetting('Rchallengehideexterminate', 'Exterminate', 'Set this on if you wish to hide the Exterminate challenge settings. ', 'boolean', false, null, 'Challenges'); + createSetting('Rchallengehidenurture', 'Nurture', 'Set this on if you wish to hide the Nurture challenge settings. ', 'boolean', false, null, 'Challenges'); + createSetting('Rchallengehidepanda', 'Pandemonium', 'Set this on if you wish to hide the Pandemonium challenge settings. ', 'boolean', false, null, 'Challenges'); + createSetting('Rchallengehidealchemy', 'Alchemy', 'Set this on if you wish to hide the Alchemy challenge settings. ', 'boolean', false, null, 'Challenges'); + createSetting('Rchallengehidehypothermia', 'Hypothermia', 'Set this on if you wish to hide the Hypothermia challenge settings. ', 'boolean', false, null, 'Challenges'); + createSetting('Rchallengehidedeso', 'Desolation', 'Set this on if you wish to hide the Desolation challenge settings. ', 'boolean', false, null, 'Challenges'); + + //Quagmire + document.getElementById('Rchallengehidedeso').parentNode.insertAdjacentHTML('afterend', '
'); + createSetting('Rblackbog', 'Quagmire', 'Enable Bog Running for Quagmire. ', 'boolean', false, null, 'Challenges'); + createSetting('Rblackbogmaz', 'Quagmire Settings', 'Click to open the Quagmire settings.
Zone: What zone to start bogging.
Black Bogs: How many Black Bogs to at specified zones.
Example: If you put Zone: 40\, Black Bogs: 10\, you will run 10 black bogs at zone 40. ', 'infoclick', false, null, 'Challenges'); + createSetting('Rblackbogzone', 'Zone', 'zone', 'multiValue', [-1], null, 'Challenges'); + createSetting('Rblackbogamount', 'Amount', 'black bogs', 'multiValue', [-1], null, 'Challenges'); + + //Nurture + createSetting('Rnurtureon', 'Nurture', 'Enables the Lab setting in Buildings and building labs through it. ', 'boolean', 'false', null, 'Challenges'); + + //Arch + createSetting('Rarchon', 'Archaeology', 'Turn on Archaeology settings. ', 'boolean', 'false', null, 'Challenges'); + createSetting('Rarchstring1', 'First String', 'First string to use in Archaeology. Put the zone you want to stop using this string and start using the second string (Make sure the second string has a value) at the start. I.e: 70,10a,10e ', 'textValue', 'undefined', null, 'Challenges'); + createSetting('Rarchstring2', 'Second String', 'Second string to use in Archaeology. Put the zone you want to stop using this string and start using the third string (Make sure the third string has a value) at the start. I.e: 94,10a,10e ', 'textValue', 'undefined', null, 'Challenges'); + createSetting('Rarchstring3', 'Third String', 'Third string to use in Archaeology. Make sure this is just your Archaeology string and nothing else. I.e: 10a,10e ', 'textValue', 'undefined', null, 'Challenges'); + + //Mayhem + createSetting('Rmayhemon', 'Mayhem', 'Turn on Mayhem settings. ', 'boolean', 'false', null, 'Challenges'); + createSetting('Rmayhemattack', 'M: Attack', 'Turn this on to ignore your farm settings so It will do maps if you cannot survive the hits you have defined in Maps. ', 'boolean', 'false', null, 'Challenges'); + createSetting('Rmayhemhealth', 'M: Health', 'Turn this on to ignore your farm settings so It will do maps if your HD is above the target you have defined in Maps. ', 'boolean', 'false', null, 'Challenges'); + createSetting('Rmayhemabcut', 'M: Attack Boss', 'What cut-off to use when farming for the boss using M: Attack. If this setting is 100, the script will farm till you can kill the boss in 100 average hits. ', 'value', '-1', null, 'Challenges'); + createSetting('Rmayhemamcut', 'M: Attack Map', 'What cut-off to use when farming maps using M: Attack and M: Smart Map. If this setting is 10, the script will do maps you can kill cells in 10 average hits. ', 'value', '-1', null, 'Challenges'); + createSetting('Rmayhemhcut', 'M: Health Cut-off', 'What cut-off to use when using M: Health. ', 'value', '-1', null, 'Challenges'); + createSetting('Rmayhemmap', ['M: Maps Off', 'M: Highest Map', 'M: Smart Map'], 'Control what maps you do to farm M: Attack and/or M: Health. M: Highest map always selects the highest map you have whether it be from Praiding, Time Farming or any you have manually created. M: Smart Map attempts to create a map best suited to the situation. Will calculate if you can survive and kill the map, and will try to buy all the necessary map attributes such as FA. ', 'multitoggle', 0, null, 'Challenges'); + + //Storm + createSetting('Rstormon', 'Storm', 'Turn on Storm settings. This also controls the entireity of Storm settings. If you turn this off it will not do anything in Storm. ', 'boolean', 'false', null, 'Challenges'); + createSetting('Rstormzone', 'S: Zone', 'What zone to start S: H:D and S: Multiplier. ', 'value', '-1', null, 'Challenges'); + createSetting('RstormHD', 'S: H:D', 'What H:D to use inside Storm. ', 'value', '-1', null, 'Challenges'); + createSetting('Rstormmult', 'S: Multiplier', 'Starting from the zone above S: Zone, this setting will multiply the H:D you have set in S: H:D. So if S: Zone was 100, S: H:D was 10, S: Multiplier was 1.2, at z101 your H:D target will be 12, then at z102 it will be 14.4 and so on. This way you can account for the zones getting stronger and you will not waste time farming for a really low H:D. ', 'value', '-1', null, 'Challenges'); + + //Insanity + createSetting('Rinsanityon', 'Insanity', 'Turn on Insanity settings. This also controls the entireity of IF. If you turn this off it will not Insanity Farm. ', 'boolean', 'false', null, 'Challenges'); + createSetting('Rinsanitymaz', 'Insanity Settings', 'Click to open the Insanity settings.
Zone: What zone to farm insanity stacks in.
Cell: What cell to start farming insanity stacks on.
Stacks: Number of stacks you want.
Level: How many map levels you want above zone.
Example: If you put Zone: 60\, Cell: 50\, Stacks: 500\, Level: 5\, you will farm at zone 60\, on cell 50 until you have 500 insanity stacks\, in a +5 map. ', 'infoclick', false, null, 'Challenges'); + createSetting('Rinsanityfarmzone', 'Insanity Farming', 'zone', 'multiValue', [-1], null, 'Challenges'); + createSetting('Rinsanityfarmcell', 'IF: Cell', 'cell', 'multiValue', '-1', null, 'Challenges'); + createSetting('Rinsanityfarmstack', 'IF: Stacks', 'stacks', 'multiValue', [-1], null, 'Challenges'); + createSetting('Rinsanityfarmlevel', 'IF: Map Level', 'level', 'multiValue', [0], null, 'Challenges'); + createSetting('Rinsanityfarmfrag', 'IF: Frags', 'Turn this on to farm fragments if you cannot afford the map you have selected for IF. ', 'boolean', 'false', null, 'Challenges'); + + //Exterminate + createSetting('Rexterminateon', 'Exterminate', 'Turn on Exterminate settings. This also controls the entireity of Exterminate. If you turn this off it will not calculate Exterminate. ', 'boolean', 'false', null, 'Challenges'); + createSetting('Rexterminatecalc', 'E: Calc', 'Calculate Exterminate enemies instead of the usual ones. May improve your challenge experience. ', 'boolean', 'false', null, 'Challenges'); + createSetting('Rexterminateeq', 'E: Equality', 'Will manage your equality \'better\' inside the challenge. When you have the experienced buff it will turn it off, when you dont it will turn it on and let it build up. ', 'boolean', 'false', null, 'Challenges'); + + //Panda + createSetting('Rpandaon', 'Pandemonium', 'Turn on Pandemonium settings. ', 'boolean', 'false', null, 'Challenges'); + createSetting('Rpandamaps', 'P: Mapping', 'Turn this on to automate mapping Pandemonium starting at the zone defined in P: Zone. Use the P: Attacks to define the maximum amount of hits an enemy in a map should take to kill. ', 'boolean', 'false', null, 'Challenges'); + createSetting('Rpandazone', 'P: Zone', 'What zone to start Pandemonium mapping at. Will ignore Pandemonium stacks below this zone. ', 'value', '-1', null, 'Challenges'); + createSetting('Rpandahits', 'P: Hits', 'How many hits an enemy in a plus map should take to kill. Will select up to +6 levels. If you cannot kill an enemy in the maximum number of hits in any plus map, will try to run a +1 map anyway. ', 'value', '-1', null, 'Challenges'); + + //Alch + createSetting('Ralchon', 'Alchemy', 'Turn on Alchemy settings. This also controls the entireity of AF. If you turn this off it will not Alchemy Farm. ', 'boolean', 'false', null, 'Challenges'); + createSetting('Ralchfarmmaz', 'Alchemy Settings', 'Click to open the Alchemy settings. Do not use vanilla autobrew AF will buy potions for you.
Zone: What zone to farm herbs and potions in.
Cell: What cell to start farming herbs and potions on.
Potion: You must pair a potion with a level here. Example: h15\,g20\,s15. This will farm Herby potion up to level 15 on the first AF zone\, Gaseous potion to level 20 and so on.
Level: How many map levels you want above zone.
Example: If you put Zone: 81\, Cell: 50\, Potion: h15\, Level: 5\, Map: Farmlands\, you will farm at zone 81\, on cell 50 until you can afford 15 total herby potions\, in a +5 map\, using a farmlands map. ', 'infoclick', false, null, 'Challenges'); + createSetting('Ralchfarmzone', 'Alchemy Farming', 'zone', 'multiValue', [-1], null, 'Challenges'); + createSetting('Ralchfarmcell', 'AF: Cell', 'cell', 'multiValue', '[-1]', null, 'Challenges'); + createSetting('Ralchfarmstack', 'AF: Potion', 'potion', 'textValue', 'undefined', null, 'Challenges'); + createSetting('Ralchfarmlevel', 'AF: Map Level', 'level', 'multiValue', [0], null, 'Challenges'); + createSetting('Ralchfarmselection', 'AF: Map Selection', 'map', 'textValue', 'l', null, 'Challenges'); + createSetting('Ralchfarmfrag', 'AF: Frags', 'Turn this on to farm fragments if you cannot afford the map you have selected for AF. ', 'boolean', 'false', null, 'Challenges'); + + //Hypo + createSetting('Rhypoon', 'Hypothermia', 'Turn on Hypothermia settings. This also controls the entireity of HF. If you turn this off it will not Hypothermia Farm. ', 'boolean', 'false', null, 'Challenges'); + createSetting('Rhypofarmmaz', 'Hypothermia Settings', 'Click to open the Hypothermia settings. HF will not spend wood on zones you are farming bonfires or until you have achieved your bonfire goal.
Zone: What zone to farm bonfires in.
Cell: What cell to start farming bonfires on.
Bonfire: The number of total bonfires in the run you want at that zone.
Level: How many map levels you want above zone.
Example: If you put Zone: 17\, Cell: 50\, Bonfire: 5\, Level: 5\, you will farm at zone 17\, on cell 50 until you can afford 5 total bonfires\, in a +5 map. ', 'infoclick', false, null, 'Challenges'); + createSetting('Rhypofarmzone', 'Hypothermia Farming', 'zone', 'multiValue', [-1], null, 'Challenges'); + createSetting('Rhypofarmcell', 'HF: Cell', 'cell', 'multiValue', [-1], null, 'Challenges'); + createSetting('Rhypofarmstack', 'HF: Bonfire', 'bonfire', 'multiValue', 'undefined', null, 'Challenges'); + createSetting('Rhypofarmlevel', 'HF: Map Level', 'level', 'multiValue', [0], null, 'Challenges'); + createSetting('Rhypofarmfrag', 'HF: Frags', 'Turn this on to farm fragments if you cannot afford the map you have selected for HF. ', 'boolean', 'false', null, 'Challenges'); + createSetting('Rhypocastle', 'Frozen Castle', 'What zone you wish you run frozen castle on to complete the challenge. Will run castle after voids so make sure thats set up right. ', 'value', '-1', null, 'Challenges'); + createSetting('Rhypovoids', 'After Voids', 'Only run Frozen castle after all voids have been completed. ', 'boolean', true, null, 'Challenges'); + createSetting('Rhypostorage', 'Storage', 'Turn this on to disable buying sheds unless you need more wood for your HF: Bonfire target price (AT AutoBuildings). Essentially this means you wont get accidently bonfires but you may lose out on smithies and shield prestiges. If you use vanilla autobuildings this setting is pointless. Disables AutoStorage until the first Bonfire farm zone that you reach during the challenge.', 'boolean', 'false', null, 'Challenges'); + + //Desolation + createSetting('Rdesoon', 'Desolation', 'Turn on Desolation settings. This also controls the entireity of Desolation settings. If you turn this off it will not do anything in Desolation. ', 'boolean', 'false', null, 'Challenges'); + createSetting('Rdesozone', 'D: Zone', 'What zone to start D: H:D and D: Multiplier. ', 'value', '-1', null, 'Challenges'); + createSetting('RdesoHD', 'D: H:D', 'What H:D to use inside Desolation. ', 'value', '-1', null, 'Challenges'); + createSetting('Rdesomult', 'D: Multiplier', 'Starting from the zone above D: Zone, this setting will multiply the H:D you have set in D: H:D. So if D: Zone was 100, D: H:D was 10, D: Multiplier was 1.2, at z101 your H:D target will be 12, then at z102 it will be 14.4 and so on. This way you can account for the zones getting stronger and you will not waste time farming for a really low H:D. ', 'value', '-1', null, 'Challenges'); + //Combat -//Combat - //Subsection1Line1 - createSetting('BetterAutoFight', ['Better AutoFight OFF', 'Better Auto Fight 1', 'Better Auto Fight 2'], '3-Way Button, Recommended. Will automatically handle fighting. The decision between BetterAutoFight 1 or 2 is up to your own discretion. The new BAF#2 does: A)Click fight anyway if we are dead and stuck in a loop due to Dimensional Generator and we can get away with adding time to it.(RemainingTime + ArmyAdd.Time < GeneTimer) and B) Clicks fight anyway if we are dead and have >=31 NextGroupTimer and deal with the consequences by firing genetecists afterwards. WARNING: If you autoportal with BetterAutoFight disabled, the game sits there doing nothing until you click FIGHT. (not good for afk) ', 'multitoggle', 1, null, "Combat"); - createSetting('AutoStance', ['Auto Stance OFF', 'Auto Stance 1', 'Auto Stance 2'], 'Automatically swap stances to avoid death. The decision between AutoStance 1 or 2 is up to your own discretion and they should be similar. ', 'multitoggle', 1, null, "Combat"); + //Line 1 + createSetting('BetterAutoFight', ['Better AutoFight OFF', 'Better Auto Fight', 'Vanilla'], '3-Way Button, Recommended. Will automatically handle fighting.
BAF = Old Algo (Fights if dead, new squad ready, new squad breed timer target exceeded, and if breeding takes under 0.5 seconds
BAF3 = Uses vanilla autofight and makes sure you fight on portal.
WARNING: If you autoportal with BetterAutoFight disabled, the game may sit there doing nothing until you click FIGHT. (not good for afk) ', 'multitoggle', 1, null, "Combat"); + createSetting('AutoStance', ['Auto Stance OFF', 'Auto Stance', 'D Stance', 'Windstacking'], 'Autostance: Automatically swap stances to avoid death.
D Stance: Keeps you in D stance regardless of Health.
Windstacking: For use after nature (z230), and will keep you in D stance unless you are windstacking (Only useful if transfer is maxed out and wind empowerment is high). Manages your Heirloom swapping and stance to obtain wind stacks efficiently. You must set your High Dmg and Low Dmg Heirlooms, Windstack H:D or WSMAX H:D where relevant for this to work. ', 'multitoggle', 1, null, "Combat"); createSetting('IgnoreCrits', ['Safety First', 'Ignore Void Strength', 'Ignore All Crits'], 'No longer switches to B against corrupted precision and/or void strength. Basically we now treat \'crit things\' as regular in both autoStance and autoStance2. In fact it no longer takes precision / strength into account and will manage like a normal enemy, thus retaining X / D depending on your needs. If you\'re certain your block is high enough regardless if you\'re fighting a crit guy in a crit daily, use this! Alternatively, manage the stances yourself.', 'multitoggle', 0, null, 'Combat'); - createSetting('PowerSaving', ['Don\'t care', 'Power Saving', 'Only Rush Voids'], 'Avoid killing your army impatiently. Don\'t force abandon trimps when prestiging. Will still Die To Use Z and aggressively autostance to aid progression and anything else. Made for Empower daily, you might find it helpful if you\'re doing Workplace Safety feat. Then again with that I strongly recommend doing it fully manually. Anyway, don\'t blame me whatever happens. Only Rush Voids will allow considering abandoning, not force one. Note: AT will no longer be able to fix when your scryer gets stuck!', 'multitoggle', 0, null, 'Combat'); - createSetting('ForceAbandon', 'Auto Force-Abandon', '(Trimpicide). If a new fight group is available and anticipation stacks arent maxed, force abandon and grab a new group. Located in the geneticist management script.', 'boolean', true, null, 'Combat'); + createSetting('PowerSaving', ['AutoAbandon', 'Don\'t Abandon', 'Only Rush Voids'], 'Autoabandon: Considers abandoning trimps for void maps/prestiges.
Don\'t Abandon: Will not abandon troops, but will still agressively autostance even if it will kill you (WILL NOT ABANDON TRIMPS TO DO VOIDS).
Only Rush Voids: Considers abandoning trimps for void maps, but not prestiges, still autostances aggressively.
Made for Empower daily, and you might find this helpful if you\'re doing Workplace Safety feat. Then again with that I strongly recommend doing it fully manually. Anyway, don\'t blame me whatever happens.
Note: AT will no longer be able to fix when your scryer gets stuck!', 'multitoggle', 0, null, 'Combat'); + createSetting('ForceAbandon', 'Trimpicide', 'If a new fight group is available and anticipation stacks aren\'t maxed, Trimpicide and grab a new group. Will not abandon in spire. Recommended ON. ', 'boolean', true, null, 'Combat'); createSetting('DynamicGyms', 'Dynamic Gyms', 'Designed to limit your block to slightly more than however much the enemy attack is. If MaxGyms is capped or GymWall is set, those will still work, and this will NOT override those (works concurrently), but it will further limit them. In the future it may override, but the calculation is not easy to get right so I dont want it undo-ing other things yet. ', 'boolean', false, null, 'Combat'); createSetting('AutoRoboTrimp', 'AutoRoboTrimp', 'Use RoboTrimps ability starting at this level, and every 5 levels thereafter. (set to 0 to disable. default 60.) 60 is a good choice for mostly everybody.', 'value', '60', null, 'Combat'); - - - -//Scryer - createSetting('UseScryerStance', 'Use Scryer Stance', 'MASTER BUTTON Stay in Scryer stance in z181 and above (Overrides Autostance). Falls back to regular Autostance when not in use (so leave that on). Get 2x resources or Dark Essence. All other buttons have no effect if this one is off.', 'boolean', true, null, 'Scryer'); - createSetting('ScryerUseWhenOverkill', 'Use When Overkill', 'Use when we can Overkill in S stance, for double loot with no speed penalty. Recommend this be on. NOTE: This being on, and being able to overkill in S will override ALL other settings (Except never use in spire). This is a boolean logic shortcut that disregards all the other settings including Min and Max Zone. If you ONLY want to use S during Overkill, as a workaround: turn this on and Min zone: to 9999 and everything else off(red). ', 'boolean', true, null, 'Scryer'); - createSetting('ScryerMinZone', 'Min Zone', 'Minimum zone to start using scryer in.(inclusive) Recommend:(60 or 181). This needs to be On & Valid for options other than Overkill to work. Tip: Use 9999 to disable all other Non-Overkill scryer usage.', 'value', '181', null, 'Scryer'); - createSetting('ScryerMaxZone', 'Max Zone', 'Zone to STOP using scryer at.(not inclusive) Recommend: Leave off (0 or -1 to disable: doesnt prevent options other than Overkill from working.) Positive numbers DO disable it past that zone. ', 'value', '230', null, 'Scryer'); - createSetting('ScryerUseinMaps2', ['Maybe Use in Maps', 'Force Use in Maps'], 'Maybe/Force Use in Maps. Overkill overrides this setting. Does not have to be on for Overkill Button to use S in maps. (Obeys zone settings)', 'multitoggle', 0, null, 'Scryer'); - createSetting('ScryerUseinVoidMaps2', ['Maybe Use in VoidMaps', 'Force Use in VoidMaps', 'Never Use in VoidMaps'], 'Maybe/Force/Never Use in Void Maps. Never WILL override the Overkill setting, and never use S in Void Maps. Maybe means default - treat Void Maps like any other cell (something else has to be ON to trigger Scryer). Force = Always use S.', 'multitoggle', 0, null, 'Scryer'); - createSetting('ScryerUseinSpire2', ['Maybe Use in Spire', 'Force Use in Spire', 'Never Use in Spire'], 'Maybe/Force/Never Use in Spire. Never WILL override the Overkill setting, and never use S in Spire. Maybe means default - treat Spire like any other cell (something else has to be ON to trigger Scryer). Force = Always use S.', 'multitoggle', 0, null, 'Scryer'); - //Line2 - createSetting('ScryerSkipBoss2', ['Default on Cell 100', 'Never Use on Cell 100 above VoidLevel', 'Never Use on Cell 100 (ALL Levels)'], 'On cell 100: Default/Never Use(above VoidLevel)/Never Use(ALL Levels). Overkill overrides this setting. Doesnt use Scrying stance for world Improbabilities/Bosses (cell 100) if you are past the level you have your VoidMaps set to run at. (or all levels, if set.) Default treats cell 100 like any other cell.', 'multitoggle', 0, null, 'Scryer'); - createSetting('ScryerSkipCorrupteds2', ['Maybe Use S on Corrupteds', 'Dont Use S on Corrupteds'], 'Overkill overrides this setting, even on Dont Use. Turning this Green doesnt use S stance for corrupted cells UNLESS you can overkill them. Red/Maybe just means default (corrupteds are treated like normal cells), so something else has to be ON to trigger Scryer to be used. Magma maps and Corrupted Voidmaps are classified under this box as corrupted and Green-DontUse here will override the ForceMaps/ForceVoidmaps (for now)', 'multitoggle', 0, null, 'Scryer'); - createSetting('ScryerDieToUseS', 'Die To Use S', 'Turning this on will switch you back to S even when doing so would kill you. Happens in scenarios where you used Skip Corrupteds that took you into regular Autostance X/H stance, killed the corrupted and reached a non-corrupted enemy that you wish to use S on, but you havent bred yet and you are too low on health to just switch back to S. So youd rather die, wait to breed, then use S for the full non-corrupted enemy, to maximize DE. This feature was added for 1 person, use at your own risk.', 'boolean', false, null, 'Scryer'); - createSetting('ScryerDieZ', 'Scryer Suicide Z', 'You know, Die To Use S is helpful and all, but sometimes it doesn\'t matter in early zones. Don\'t you think so? That was a rhetorical question, don\'t answer it. Like Void Maps config, you can put a decimal value for cell, like 230.60 for after zone 230 for >= 60th cell.', 'value', 230.60, null, 'Scryer'); - //createSetting('ScryUseinPoison', ' Scry in Poison', ['Maybe Use in Poison', 'Force Use in Poison', 'Never Use in Poison'] - - - - -// Dimensional Generator settings: - createSetting('UseAutoGen', ['Auto Generator OFF', 'Auto Generator ON'], 'MASTER BUTTON Dynamically switch generator modes. Required for the following mode management configurations to work. The Dimensional Generator is a building unlocked in The Magma, from z230.', 'multitoggle', 0, null, 'Magma'); - createSetting('AutoGen2', ['Default', 'Microtick', 'Max Cap', 'Overclock'], 'Before Z is reached, Microtick and Max Cap will switch between [Hybrid / Gain Fuel] to get EXACTLY one / FULL stacks of Capacity (not Storage) before using [Gain Mi]. Default will respect whatever you set it to and won\'t fiddle with it unless challenge overriding is on. Overclock will Gain Fuel until Z.', 'multitoggle', 2, null, 'Magma'); - createSetting('AutoGen2End', 'End Early Mode Z', 'On and after Z, be done with the mode we start with and switch to the final mode. -1 to disable.', 'value', 300, null, 'Magma'); - createSetting('AutoGen2SupplyEnd', 'End at Supply', 'On and after the zone for gathering the most magma by Supply, end Early Mode. Works alongside AutoGen2End and will end when either condition is met.', 'boolean', false, null, 'Magma'); - createSetting('AutoGen3', ['Gain Mi', 'Gain Fuel', 'Hybrid'], 'Mode to use after Z / SupplyEnd.', 'multitoggle', 1, null, 'Magma'); - createSetting('AutoGenDC', ['Daily: Normal', 'Daily: Fuel', 'Daily: Hybrid'], 'Use a special mode in dailies to make the most out of it. Overrides AutoGen3 unless Strong Override is on.', 'multitoggle', 1, null, 'Magma'); - createSetting('AutoGenC2', ['c2: Normal', 'c2: Fuel', 'c2: Hybrid'], 'Use a special mode when running challenge2s to make the most out of it. Overrides AutoGen3 unless Strong Override is on.', 'multitoggle', 1, null, 'Magma'); - createSetting('AutoGen2Override', ['Override Final Only', 'Strong Override'], 'Overrides apply to the final mode (always use early mode), or also to early mode (will stop microtick etc). Normal will not change anything.', 'multitoggle', 1, null, 'Magma'); - createSetting('AutoMagmiteSpender2', ['Spend Magmite OFF', 'Spend Magmite (Portal)', 'Spend Magmite Always'], 'Auto Spends any unspent Magmite immediately before portaling. (Or Always, if toggled). Part 1 buys any permanent one-and-done upgrades in order from most expensive to least. Part 2 then analyzes Efficiency vs Capacity for cost/benefit, and buys Efficiency if its BETTER than Capacity. If not, if the PRICE of Capacity is less than the price of Supply, it buys Capacity. If not, it buys Supply. And then it repeats itself until you run out of Magmite and cant buy anymore. For Magma z230+ purposes.', 'multitoggle', 1, null, 'Magma'); - createSetting('SupplyWall', 'Throttle Supply (or Capacity)', 'Positive number NOT 1 e.g. 2.5: Consider Supply when its cost * 2.5 is < Capacity, instead of immediately when < Cap. Effectively throttles supply for when you don\'t need too many.

Negative number (-1 is ok) e.g. -2.5: Consider Supply if it costs < Capacity * 2.5, buy more supplys! Effectively throttling capacity instead.

Set to 1: DISABLE SUPPLY only spend magmite on Efficiency, Capacity and Overclocker. (For some end game players, supply is worth probably figuratively nothing.)
Set to 0: IGNORE SETTING and use old behaviour (will still try to buy overclocker)
', 'valueNegative', 2, null, 'Magma'); - createSetting('OneTimeOnly', 'One Time / Overclock Only', 'Makes the magmite spending sequence only buy one time upgrades and overclock, ignoring Efficiency, Capacity and Supply. Intended for manual use. Does not disable itself.', 'boolean', false, null, 'Magma'); - createSetting('BuyOvclock', 'Buy Overclock', 'Turn this off to not buy anymore overclocks. Will still buy the first level if you don\'t already own it.', 'boolean', true, null, 'Magma'); + //Line 2 + createSetting('fightforever', 'Fight Always', 'U1: -1 to disable. Sends trimps to fight if they\'re not fighting, regardless of BAF. Has 2 uses. Set to 0 to always send out trimps. Or set a number higher than 0 to enable the H:D function. If the H:D ratio is below this number it will send them out. I.e, this is set to 1, it will send out trimps regardless with the H:D ratio is below 1. ', 'value', '-1', null, 'Combat'); + createSetting('addpoison', 'Poison Calc', 'Experimental.
Adds poison to the battlecalc. May improve your poison zone speed. ', 'boolean', 'false', null, 'Combat'); + createSetting('fullice', 'Ice Calc', 'Experimental.
Always calculates your ice to be a consistent level instead of going by the enemy debuff. Stops H:D spazzing out. ', 'boolean', 'false', null, 'Combat'); + createSetting('45stacks', 'Antistack Calc', 'Experimental.
Always calcs your damage as having full antistacks. Useful for windstacking. ', 'boolean', 'false', null, 'Combat'); + + + //RCombat + createSetting('Rfightforever', 'Fight Always', 'U2: -1 to disable. Sends trimps to fight if they\'re not fighting, regardless of BAF. Has 2 uses. Set to 0 to always send out trimps. Or set a number higher than 0 to enable the H:D function. If the H:D ratio is below this number it will send them out. I.e, this is set to 1, it will send out trimps regardless with the H:D ratio is below 1. ', 'value', '-1', null, 'Combat'); + createSetting('Rcalcmaxequality', ['Equality Calc Off', 'EC: On', 'EC: Health'], 'Experimental.
Adds Equality Scaling levels to the battlecalc. Will always calculate equality based on actual scaling levels when its turned off by other settings. Assumes you use Equality Scaling. Turning this on allows in-game Equality Scaling to adjust your Health accordingly. EC: Health only decreases enemies attack in the calculation which may improve speed. ', 'multitoggle', 0, null, 'Combat'); + createSetting('Rmanageequality', 'Manage Equality', 'Manages Equality for you. Sets Equality to 0 on Slow enemies, and Autoscaling on for Fast enemies. ', 'boolean', 'false', null, 'Combat'); + createSetting('Rcalcfrenzy', 'Frenzy Calc', 'Experimental.
Adds frenzy to the calc. Be warned\, it will not farm as much with this on as it expects 100% frenzy uptime. ', 'boolean', 'false', null, 'Combat'); + createSetting('Rmutecalc', 'Mute Calc', 'What zone to start calculating Mutations at. 0 to disable.', 'value', '-1', null, 'Combat'); + + + //Scryer + + //Line 1 + createSetting('UseScryerStance', 'Enable Scryer Stance', 'MASTER BUTTON Activates all other scrying settings, and overrides AutoStance when scryer conditions are met. Leave regular Autostance on while this is active. Scryer gives 2x Resources (Non-Helium/Nullifium) and a chance for Dark Essence. Once this is on, priority for Scryer decisions goes as such:
NEVER USE, FORCE USE, OVERKILL, MIN/MAX ZONE

NO OTHER BUTTONS WILL DO ANYTHING IF THIS IS OFF.', 'boolean', true, null, 'Scryer'); + createSetting('ScryerUseWhenOverkill', 'Use When Overkill', 'Overrides everything! Toggles stance when we can Overkill in S, giving us double loot with no speed penalty (minimum one overkill, if you have more than 1, it will lose speed) NOTE: This being on, and being able to overkill in S will override ALL other settings (Except never use in spire). This is a boolean logic shortcut that disregards all the other settings including Min and Max Zone. If you ONLY want to use S during Overkill, as a workaround: turn this on and Min zone: to 9999 and everything else off(red). ', 'boolean', true, null, 'Scryer'); + createSetting('ScryerMinZone', 'Min Zone', 'Minimum zone to start using scryer in.(inclusive) Recommend:(60 or 181). Overkill ignores this. This needs to be On & Valid for the MAYBE option on all other Scryer settings to do anything if Overkill is off. Tip: Use 9999 to disable all Non-Overkill, Non-Force, scryer usage.', 'value', '181', null, 'Scryer'); + createSetting('ScryerMaxZone', 'Max Zone', '0 or -1 to disable (Recommended)
Overkill ignores this. Zone to STOP using scryer at (not inclusive). Turning this ON with a positive number stops MAYBE use of all other Scryer settings.', 'value', '230', null, 'Scryer'); + createSetting('onlyminmaxworld', 'World Min & Max Only', 'Forces Scryer to only work in world regardless of other settings. ', 'boolean', false, null, 'Scryer'); + createSetting('ScryerUseinMaps2', ['Maps: NEVER', 'Maps: FORCE', 'Maps: MAYBE'], 'NEVER Means what it says!!!
FORCE means Scryer will ALWAYS activate in Maps
MAYBE means that Overkill and Min/Max use are allowed.
This setting requires use on Corrupteds to be on after corruption/magma.

Recommend MAYBE.', 'multitoggle', 2, null, 'Scryer'); + createSetting('ScryerUseinVoidMaps2', ['VoidMaps: NEVER', 'VoidMaps: FORCE', 'VoidMaps: MAYBE'], 'NEVER Means what it says!!!
FORCE means Scryer will ALWAYS activate in Void Maps
MAYBE means that Overkill and Min/Max use are allowed. ', 'multitoggle', 0, null, 'Scryer'); + + //Line 2 + createSetting('ScryerUseinPMaps', ['P Maps: NEVER', 'P Maps: FORCE', 'P Maps: MAYBE'], 'NEVER Means what it says!!!
FORCE means Scryer will ALWAYS activate in maps higher than your zone
MAYBE means that Overkill and Min/Max use are allowed.
Recommend NEVER.', 'multitoggle', 0, null, 'Scryer'); + createSetting('ScryerUseinBW', ['BW: NEVER', 'BW: FORCE', 'BW: MAYBE'], 'NEVER Means what it says!!!
FORCE means Scryer will ALWAYS activate in BW Maps
MAYBE means that Overkill and Min/Max use are allowed.
This setting requires use in Maps to be on.

Recommend NEVER.', 'multitoggle', 0, null, 'Scryer'); + createSetting('ScryerUseinSpire2', ['Spire: NEVER', 'Spire: FORCE', 'Spire: MAYBE'], 'NEVER Means what it says!!!
FORCE means Scryer will ALWAYS activate in the Spire
MAYBE means that Overkill and Min/Max use are allowed.
This setting requires use on Corrupteds to be on for corrupted enemies.

Recommend NEVER.', 'multitoggle', 0, null, 'Scryer'); + createSetting('ScryerSkipBoss2', ['Boss: NEVER (All Levels)', 'Boss: NEVER (Above VoidLevel)', 'Boss: MAYBE'], 'NEVER (All Levels) will NEVER use S in cell 100 of the world!!!
NEVER (Above VoidLevel) will NEVER use S in cell 100 of the world ABOVE the zone that your void maps are set to run at (Maps).
MAYBE treats the cell no differently to any other, Overkill and Min/Max Scryer is allowed.

Recommend NEVER (There is little benefit to double NON-HELIUM resources and a small chance of DE).', 'multitoggle', 0, null, 'Scryer'); + createSetting('ScryerSkipCorrupteds2', ['Corrupted: NEVER', 'Corrupted: FORCE', 'Corrupted: MAYBE'], 'NEVER Means what it says!!!
FORCE means Scryer will ALWAYS activate against Corrupted enemies
MAYBE means that Overkill and Min/Max use are allowed.
Magma maps and Corrupted Voidmaps are currently classified as corrupted and NEVER here will override Maps and Voidmaps use of Scryer

Recommend MAYBE.', 'multitoggle', 2, null, 'Scryer'); + createSetting('ScryerSkipHealthy', ['Healthy: NEVER', 'Healthy: FORCE', 'Healthy: MAYBE'], 'NEVER Means what it says!!!
FORCE means Scryer will ALWAYS activate against Healthy enemies
MAYBE means that Overkill and Min/Max use are allowed.
Corrupted Voidmaps are currently classified as Healthy (same as corrupted) and NEVER here will override Maps and Voidmaps use of Scryer

Recommend MAYBE.', 'multitoggle', 2, null, 'Scryer'); + createSetting('ScryUseinPoison', 'Scry in Poison', 'Decides what you do in Poison.
-1 = Maybe
0 = Never
Above 0 = Max Zone you want it scrying ', 'value', -1, null, 'Scryer'); + + //Line 3 + createSetting('ScryUseinWind', 'Scry in Wind', 'Decides what you do in Wind.
-1 = Maybe
0 = Never
Above 0 = Max Zone you want it scrying', 'value', -1, null, 'Scryer'); + createSetting('ScryUseinIce', 'Scry in Ice', 'Decides what you do in Ice.
-1 = Maybe
0 = Never
Above 0 = Max Zone you want it scrying', 'value', -1, null, 'Scryer'); + createSetting('ScryerDieZ', 'Die To Use S', '-1 to disable.
Turning this on will switch you back to S even when doing so would kill you. Happens in scenarios where you used Skip Corrupteds that took you into regular Autostance X/H stance, killed the corrupted and reached a non-corrupted enemy that you wish to use S on, but you havent bred yet and you are too low on health to just switch back to S. So you\'d rather die, wait to breed, then use S for the full non-corrupted enemy, to maximize DE. NOTE: Use at your own risk.
Use this input to set the minimum zone that scryer activates in (You can use decimal values to specify what cell this setting starts from)', 'value', 230.60, null, 'Scryer'); + createSetting('screwessence', 'Remaining Essence Only', 'Why scry when theres no essence? Turns off scrying when the remaining enemies with essence drops to 0. ', 'boolean', false, null, 'Scryer'); + + + //Magma + + createSetting('UseAutoGen', 'Auto Generator', 'Turn this on to use these settings. ', 'boolean', false, null, 'Magma'); + createSetting('beforegen', ['Gain Mi', 'Gain Fuel', 'Hybrid'], 'MODE BEFORE FUELING: Which mode to use before fueling. This is the mode which the generator will use if you fuel after z230. Using Hybrid mode before unlocking is very naughty and will be punished! ', 'multitoggle', 1, null, 'Magma'); + createSetting('fuellater', 'Start Fuel Z', 'Start fueling at this zone instead of 230. I would suggest you have a value lower than your max, for obvious reasons. Recommend starting at a value close-ish to your max supply. Use 230 to use your BEFORE FUEL setting. ', 'value', -1, null, 'Magma'); + createSetting('fuelend', 'End Fuel Z', 'End fueling at this zone. After this zone is reached, will follow your preference. -1 to fuel infinitely. ', 'value', -1, null, 'Magma'); + createSetting('defaultgen', ['Gain Mi', 'Gain Fuel', 'Hybrid'], 'MODE AFTER FUELING: Which mode to use after fueling. Using Hybrid mode before unlocking is very naughty and will be punished! ', 'multitoggle', 1, null, 'Magma'); + createSetting('AutoGenDC', ['Daily: Normal', 'Daily: Fuel', 'Daily: Hybrid'], 'Normal: Uses the AutoGen settings.
Fuel: Fuels the entire Daily.
Hybrid: Uses Hybrid for the entire Daily. Using Hybrid mode before unlocking is very naughty and will be punished! ', 'multitoggle', 1, null, 'Magma'); + createSetting('AutoGenC2', ['C2: Normal', 'C2: Fuel', 'C2: Hybrid'], 'Normal: Uses the AutoGen settings.
Fuel: Fuels the entire C2.
Hybrid: Uses Hybrid for the entire C2. Using Hybrid mode before unlocking is very naughty and will be punished! ', 'multitoggle', 1, null, 'Magma'); + + //Spend Mi + document.getElementById('AutoGenC2').parentNode.insertAdjacentHTML('afterend', '
'); + createSetting('spendmagmite', ['Spend Magmite OFF', 'Spend Magmite (Portal)', 'Spend Magmite Always'], 'Auto Spends any unspent Magmite immediately before portaling. (Or Always, if toggled). Part 1 buys any permanent one-and-done upgrades in order from most expensive to least. Part 2 then analyzes Efficiency vs Capacity for cost/benefit, and buys Efficiency if its BETTER than Capacity. If not, if the PRICE of Capacity is less than the price of Supply, it buys Capacity. If not, it buys Supply. And then it repeats itself until you run out of Magmite and cant buy anymore. ', 'multitoggle', 1, null, 'Magma'); + createSetting('ratiospend', 'Ratio Spending', 'Spends Magmite in a Ratio you define. ', 'boolean', false, null, 'Magma'); + createSetting('effratio', 'Efficiency', 'Use -1 or 0 to not spend on this. Any value above 0 will spend. ', 'value', -1, null, 'Magma'); + createSetting('capratio', 'Capacity', 'Use -1 or 0 to not spend on this. Any value above 0 will spend. ', 'value', -1, null, 'Magma'); + createSetting('supratio', 'Supply', 'Use -1 or 0 to not spend on this. Any value above 0 will spend. ', 'value', -1, null, 'Magma'); + createSetting('ocratio', 'Overclocker', 'Use -1 or 0 to not spend on this. Any value above 0 will spend. ', 'value', -1, null, 'Magma'); + createSetting('SupplyWall', 'Throttle Supply (or Capacity)', 'Positive number NOT 1 e.g. 2.5: Consider Supply when its cost * 2.5 is < Capacity, instead of immediately when < Cap. Effectively throttles supply for when you don\'t need too many.

Negative number (-1 is ok) e.g. -2.5: Consider Supply if it costs < Capacity * 2.5, buy more supplys! Effectively throttling capacity instead.

Set to 1: DISABLE SUPPLY only spend magmite on Efficiency, Capacity and Overclocker. Always try to get supply close to your HZE.
Set to 0: IGNORE SETTING and use old behaviour (will still try to buy overclocker)
', 'valueNegative', 0.4, null, 'Magma'); + createSetting('spendmagmitesetting', ['Normal', 'Normal & No OC', 'OneTime Only', 'OneTime & OC'], 'Normal: Spends Magmite Normally as Explained in Magmite spending behaviour.
Normal & No OC: Same as normal, except skips OC afterbuying 1 OC upgrade.
OneTime Only: Only Buys the One off upgrades except skips OC afterbuying 1 OC upgrade.
OneTime & OC: Buys all One off upgrades, then buys OC only. ', 'multitoggle', 0, null, 'Magma'); createSetting('MagmiteExplain', 'Magmite spending behaviour', '1. Buy one-and-done upgrades, expensive first, then consider 1st level of Overclocker;
2. Buy Overclocker IF AND ONLY IF we can afford it;
2.5. Exit if OneTimeOnly
3. Buy Efficiency if it is better than capacity;
4. Buy Capacity or Supply depending on which is cheaper, or based on SupplyWall', 'infoclick', 'MagmiteExplain', null, 'Magma'); - - - -//Heirloom Settings - createSetting('AutoHeirlooms', 'Auto Heirlooms', 'Automatically evaluate and carry the best heirlooms, and recommend upgrades for equipped items. AutoHeirlooms will only change carried items when the heirlooms window is not open. Carried items will be compared and swapped with the types that are already carried. If a carry spot is empty, it will be filled with the best shield (if available). Evaluation is based ONLY on the following mods (listed in order of priority, high to low): Void Map Drop Chance/Trimp Attack, Crit Chance/Crit Damage, Miner Efficiency/Metal Drop, Gem Drop/Dragimp Efficiency, Farmer/Lumberjack Efficiency. For the purposes of carrying, rarity trumps all of the stat evaluations. Empty mod slots are valued at the average value of the best missing mod.', 'boolean', false, null, "Heirlooms"); - createSetting('AutoHeirlooms2', 'Auto Heirlooms2', 'IMPORTANT SETTING. New algorithm for Heirlooms. While enabled, the old AutoHeirlooms algorithm will be disabled (the button will stay lit or you can turn that one off). CAUTION: Turning this on will immediately re-sort your heirlooms according to the new algorithm, and turning it off again DOES revert to the original algorithm even though it may NOT have a visible result on your heirlooms. (fyi: This lack of action highlights one of the problems with the old one.) ', 'boolean', false, null, 'Heirlooms'); - createSetting('AutoUpgradeHeirlooms', 'Auto Upgrade Heirlooms', 'Automatically buys the upgrades the script advises for the Equipped shield and staff, until we are out of nullifium.', 'boolean', false, null, 'Heirlooms'); - - - -//Golden Upgrade Strategies: - createSetting('AutoGoldenUpgrades', 'AutoGoldenUpgrades', 'IMPORTANT SETTING. Automatically Buy the specified Golden Upgrades as they become available. Faster than vanilla. NOTE: Void setting unlocks more settings: goldStrat, goldAlternating, goldZone and goldNoBattle. New: Void also has a \\"Max then Helium\\" setting so you can get the perfect 60% Voids then Helium. More buttons will become visible when you make selections.', 'dropdown', 'Void', ["Off", "Helium", "Battle", "Void"], 'Golden'); - createSetting('goldStrat', 'Strategy', 'VOID ONLY: After max Void golden upgrades, alternate between buying helium and battle upgrades. Or Choose a Zone to switch over completely at (zones lower than X will buy only battle, and zones higher than X only helium). Battle can be disabled completely with the goldNoBattle button. MAX THEN HELIUM setting so you can get the perfect 60% Voids then Helium', 'dropdown', 'Max then Helium', ["Off", "Alternating", "Zone", "Max then Helium"], 'Golden'); - createSetting('goldAlternating', 'GU VOID: Alternating', 'Buy a helium upgrade after X-1 battle upgrades have been purchased', 'value', '2', null, 'Golden'); - createSetting('goldZone', 'GU VOID: Zone', 'Buy a helium upgrade until zone X, then buy battle upgrades.', 'value', '200', null, 'Golden'); - createSetting('goldNoBattle', 'GU VOID: No Battle', 'Dont ever buy battle upgrades.', 'boolean', true, null, 'Golden'); - - - -// Nature settings: + //Heirloom + createSetting('highdmg', 'WS: High Damage', 'HIGH DAMAGE HEIRLOOM

Enter the name of your high damage heirloom. This is your heirloom that you will use normally. ', 'textValue', 'undefined', null, 'Heirlooms'); + createSetting('lowdmg', 'WS: Low Damage', 'LOW DAMAGE HEIRLOOM

Enter the name of your low damage heirloom. This is the heirloom that you will use for windstacking. ', 'textValue', 'undefined', null, 'Heirlooms'); + + //Heirloom Swapping + document.getElementById('lowdmg').parentNode.insertAdjacentHTML('afterend', '
'); + createSetting('Rhs', 'Heirloom Swapping', 'Heirloom swapping master button. Turn this on to allow heirloom swapping and its associated settings. ', 'boolean', false, null, 'Heirlooms'); + + //Shield Swapping + document.getElementById('Rhs').parentNode.insertAdjacentHTML('afterend', '
'); + createSetting('Rhsshield', 'Shields', 'Toggle to swap Shields', 'boolean', false, null, 'Heirlooms'); + createSetting('Rhsz', 'HS: Zone', 'Which zone to swap from your first heirloom you have defined to your second heirloom you have defined. I.e if this value is 75 it will switch to the second heirloom on z75', 'value', '-1', null, 'Heirlooms'); + createSetting('Rhs1', 'HS: First', 'First Heirloom to use

Enter the name of your first heirloom. This is the heirloom that you will use before swapping to the second heirloom at the zone you have defined in the HS: Zone. ', 'textValue', 'undefined', null, 'Heirlooms'); + createSetting('Rhs2', 'HS: Second', 'Second Heirloom to use

Enter the name of your second heirloom. This is the heirloom that you will use after swapping from the first heirloom at the zone you have defined in the HS: Zone. ', 'textValue', 'undefined', null, 'Heirlooms'); + + //Staff Swapping + document.getElementById('Rhs2').parentNode.insertAdjacentHTML('afterend', '
'); + createSetting('Rhsstaff', 'Staffs', 'Toggle to swap Staffs', 'boolean', false, null, 'Heirlooms'); + createSetting('Rhsworldstaff', 'World', 'World Staff

Enter the name of your world staff.', 'textValue', 'undefined', null, 'Heirlooms'); + createSetting('Rhsmapstaff', 'Map', 'Mapping staff

Enter the name of your mapping staff.', 'textValue', 'undefined', null, 'Heirlooms'); + createSetting('Rhstributestaff', 'Tribute', 'Tribute farming staff

Enter the name of the staff you would like to equip during tribute farming.', 'textValue', 'undefined', null, 'Heirlooms'); + + //Heirloom Line + document.getElementById('Rhstributestaff').parentNode.insertAdjacentHTML('afterend', '
'); + createSetting('autoheirlooms', 'Auto Heirlooms', 'Auto Heirlooms master button. Turn this on to enable all Auto Heirloom settings.

The Modifier points will be explained here. The more points an heirloom has, the better chance it has of being kept. If empty is selected, it will muliplty the score by 4.

E.g Mod 1 = CC (+5 if dropped, 1st modifier)
Mod 2 = CD (+5 if dropped, 2nd modifier)
Mod 3 = PB (+5 if dropped, 3rd modifier)
Mod 4 = Empty (x4 if dropped, +0 if not)
Mod 5 = Empty (x4 if dropped, +0 if not)

If an heirloom dropped with these exact modifiers, it would get a score of 192 (5+5+5*4*4=240). The highest point heirlooms will be kept.
You MUST select at least one modifier. It will fill up the slots first then recycle the lowest rarity. ', 'boolean', false, null, 'Heirlooms'); + createSetting('typetokeep', ['None', 'Shields', 'Staffs', 'Cores', 'All'], 'Shields: Keeps Shields and nothing else.
Staffs: Keeps Staffs and nothing else.
Cores: Keeps Cores and nothing else.
All: Keeps 4 Shields and 3 Staffs and 3 Cores. If you have protected heirlooms in your inventory it will overrite one slot. E.g if one heirloom is protected, you will keep 4 Shields and 3 Staffs and 2 Cores. ', 'multitoggle', 0, null, 'Heirlooms'); + createSetting('raretokeep', 'Rarity to Keep', 'Auto Heirlooms. Keeps the selected rarity of heirloom, recycles all others when your inventory is full. You may keep lower rarity heirlooms if you have empty slots. ', 'dropdown', 'Any', ["Any", "Common", "Uncommon", "Rare", "Epic", "Legendary", "Magnificent", "Ethereal", "Magmatic", "Plagued", "Radiating", "Hazardous", "Enigmatic"], 'Heirlooms'); + + //Shield Line + document.getElementById('raretokeep').parentNode.insertAdjacentHTML('afterend', '
'); + createSetting('keepshields', 'Shields', 'Auto Heirlooms. Enables in-depth shield settings. ', 'boolean', false, null, 'Heirlooms'); + createSetting('slot1modsh', 'Shield: Modifier 1', 'Auto Heirlooms. Keeps Shields with selected Mod. Modifier 1 is worth 5 points. ', 'dropdown', 'empty', ["empty", "playerEfficiency", "trainerEfficiency", "storageSize", "breedSpeed", "trimpHealth", "trimpAttack", "trimpBlock", "critDamage", "critChance", "voidMaps", "plaguebringer", "prismatic", "gammaBurst", "inequality"], 'Heirlooms'); + createSetting('slot2modsh', 'Shield: Modifier 2', 'Auto Heirlooms. Keeps Shields with selected Mod. Modifier 2 is worth 5 points. ', 'dropdown', 'empty', ["empty", "playerEfficiency", "trainerEfficiency", "storageSize", "breedSpeed", "trimpHealth", "trimpAttack", "trimpBlock", "critDamage", "critChance", "voidMaps", "plaguebringer", "prismatic", "gammaBurst", "inequality"], 'Heirlooms'); + createSetting('slot3modsh', 'Shield: Modifier 3', 'Auto Heirlooms. Keeps Shields with selected Mod. Modifier 3 is worth 5 points. ', 'dropdown', 'empty', ["empty", "playerEfficiency", "trainerEfficiency", "storageSize", "breedSpeed", "trimpHealth", "trimpAttack", "trimpBlock", "critDamage", "critChance", "voidMaps", "plaguebringer", "prismatic", "gammaBurst", "inequality"], 'Heirlooms'); + createSetting('slot4modsh', 'Shield: Modifier 4', 'Auto Heirlooms. Keeps Shields with selected Mod. Modifier 4 is worth 5 points. ', 'dropdown', 'empty', ["empty", "playerEfficiency", "trainerEfficiency", "storageSize", "breedSpeed", "trimpHealth", "trimpAttack", "trimpBlock", "critDamage", "critChance", "voidMaps", "plaguebringer", "prismatic", "gammaBurst", "inequality"], 'Heirlooms'); + createSetting('slot5modsh', 'Shield: Modifier 5', 'Auto Heirlooms. Keeps Shields with selected Mod. Modifier 5 is worth 5 points. ', 'dropdown', 'empty', ["empty", "playerEfficiency", "trainerEfficiency", "storageSize", "breedSpeed", "trimpHealth", "trimpAttack", "trimpBlock", "critDamage", "critChance", "voidMaps", "plaguebringer", "prismatic", "gammaBurst", "inequality"], 'Heirlooms'); + createSetting('slot6modsh', 'Shield: Modifier 6', 'Auto Heirlooms. Keeps Shields with selected Mod. Modifier 6 is worth 5 points. ', 'dropdown', 'empty', ["empty", "playerEfficiency", "trainerEfficiency", "storageSize", "breedSpeed", "trimpHealth", "trimpAttack", "trimpBlock", "critDamage", "critChance", "voidMaps", "plaguebringer", "prismatic", "gammaBurst", "inequality"], 'Heirlooms'); + createSetting('slot7modsh', 'Shield: Modifier 7', 'Auto Heirlooms. Keeps Shields with selected Mod. Modifier 7 is worth 5 points. ', 'dropdown', 'empty', ["empty", "playerEfficiency", "trainerEfficiency", "storageSize", "breedSpeed", "trimpHealth", "trimpAttack", "trimpBlock", "critDamage", "critChance", "voidMaps", "plaguebringer", "prismatic", "gammaBurst", "inequality"], 'Heirlooms'); + + //Staff Line + document.getElementById('slot7modsh').parentNode.insertAdjacentHTML('afterend', '
'); + createSetting('keepstaffs', 'Staffs', 'Auto Heirlooms. Enables in-depth staff settings. ', 'boolean', false, null, 'Heirlooms'); + createSetting('slot1modst', 'Staff: Modifier 1', 'Auto Heirlooms. Keeps Staffs with selected Mod. Modifier 1 is worth 5 points. ', 'dropdown', 'empty', ["empty", "metalDrop", "foodDrop", "woodDrop", "gemsDrop", "fragmentsDrop", "minerSpeed", "FarmerSpeed", "LumberjackSpeed", "DragimpSpeed", "ExplorerSpeed", "ScientistSpeed", "FluffyExp", "ParityPower"], 'Heirlooms'); + createSetting('slot2modst', 'Staff: Modifier 2', 'Auto Heirlooms. Keeps Staffs with selected Mod. Modifier 2 is worth 5 points. ', 'dropdown', 'empty', ["empty", "metalDrop", "foodDrop", "woodDrop", "gemsDrop", "fragmentsDrop", "minerSpeed", "FarmerSpeed", "LumberjackSpeed", "DragimpSpeed", "ExplorerSpeed", "ScientistSpeed", "FluffyExp", "ParityPower"], 'Heirlooms'); + createSetting('slot3modst', 'Staff: Modifier 3', 'Auto Heirlooms. Keeps Staffs with selected Mod. Modifier 3 is worth 5 points. ', 'dropdown', 'empty', ["empty", "metalDrop", "foodDrop", "woodDrop", "gemsDrop", "fragmentsDrop", "minerSpeed", "FarmerSpeed", "LumberjackSpeed", "DragimpSpeed", "ExplorerSpeed", "ScientistSpeed", "FluffyExp", "ParityPower"], 'Heirlooms'); + createSetting('slot4modst', 'Staff: Modifier 4', 'Auto Heirlooms. Keeps Staffs with selected Mod. Modifier 4 is worth 5 points. ', 'dropdown', 'empty', ["empty", "metalDrop", "foodDrop", "woodDrop", "gemsDrop", "fragmentsDrop", "minerSpeed", "FarmerSpeed", "LumberjackSpeed", "DragimpSpeed", "ExplorerSpeed", "ScientistSpeed", "FluffyExp", "ParityPower"], 'Heirlooms'); + createSetting('slot5modst', 'Staff: Modifier 5', 'Auto Heirlooms. Keeps Staffs with selected Mod. Modifier 5 is worth 5 points. ', 'dropdown', 'empty', ["empty", "metalDrop", "foodDrop", "woodDrop", "gemsDrop", "fragmentsDrop", "minerSpeed", "FarmerSpeed", "LumberjackSpeed", "DragimpSpeed", "ExplorerSpeed", "ScientistSpeed", "FluffyExp", "ParityPower"], 'Heirlooms'); + createSetting('slot6modst', 'Staff: Modifier 6', 'Auto Heirlooms. Keeps Staffs with selected Mod. Modifier 6 is worth 5 points. ', 'dropdown', 'empty', ["empty", "metalDrop", "foodDrop", "woodDrop", "gemsDrop", "fragmentsDrop", "minerSpeed", "FarmerSpeed", "LumberjackSpeed", "DragimpSpeed", "ExplorerSpeed", "ScientistSpeed", "FluffyExp", "ParityPower"], 'Heirlooms'); + createSetting('slot7modst', 'Staff: Modifier 7', 'Auto Heirlooms. Keeps Staffs with selected Mod. Modifier 7 is worth 5 points. ', 'dropdown', 'empty', ["empty", "metalDrop", "foodDrop", "woodDrop", "gemsDrop", "fragmentsDrop", "minerSpeed", "FarmerSpeed", "LumberjackSpeed", "DragimpSpeed", "ExplorerSpeed", "ScientistSpeed", "FluffyExp", "ParityPower"], 'Heirlooms'); + + //Core Line + document.getElementById('slot7modst').parentNode.insertAdjacentHTML('afterend', '
'); + createSetting('keepcores', 'Cores', 'Auto Heirlooms. Enables in-depth core settings. ', 'boolean', false, null, 'Heirlooms'); + createSetting('slot1modcr', 'Cores: Modifier 1', 'Auto Heirlooms. Keeps Cores with selected Mod. Modifier 1 is worth 5 points. ', 'dropdown', 'empty', ["empty", "fireTrap", "poisonTrap", "lightningTrap", "runestones", "strengthEffect", "condenserEffect"], 'Heirlooms'); + createSetting('slot2modcr', 'Cores: Modifier 2', 'Auto Heirlooms. Keeps Cores with selected Mod. Modifier 2 is worth 5 points. ', 'dropdown', 'empty', ["empty", "fireTrap", "poisonTrap", "lightningTrap", "runestones", "strengthEffect", "condenserEffect"], 'Heirlooms'); + createSetting('slot3modcr', 'Cores: Modifier 3', 'Auto Heirlooms. Keeps Cores with selected Mod. Modifier 3 is worth 5 points. ', 'dropdown', 'empty', ["empty", "fireTrap", "poisonTrap", "lightningTrap", "runestones", "strengthEffect", "condenserEffect"], 'Heirlooms'); + createSetting('slot4modcr', 'Cores: Modifier 4', 'Auto Heirlooms. Keeps Cores with selected Mod. Modifier 4 is worth 5 points. ', 'dropdown', 'empty', ["empty", "fireTrap", "poisonTrap", "lightningTrap", "runestones", "strengthEffect", "condenserEffect"], 'Heirlooms'); + + + + //Golden + + createSetting('AutoGoldenUpgrades', 'AutoGoldenUpgrades', 'Buys Golden Upgrades in Fillers. Helium buys all Helium golden upgrades. Battle buys all Battle golden upgrades. Void buys 8 Void golden upgrades (max number you can buy) then buys helium golden upgrades. Void + Battle buys 8 voids then battle. Will run way faster than Vanilla AutoGold so if you have this on expect it to win over vanilla settings. ', 'dropdown', 'Off', ["Off", "Helium", "Battle", "Void", "Void + Battle"], 'Golden'); + createSetting('dAutoGoldenUpgrades', 'Daily AutoGoldenUpgrades', 'Buys Golden Upgrades in Dailies. Helium buys all Helium golden upgrades. Battle buys all Battle golden upgrades. Void buys 8 Void golden upgrades (max number you can buy) then buys helium golden upgrades. Void + Battle buys 8 voids then battle. Will run way faster than Vanilla AutoGold so if you have this on expect it to win over vanilla settings. ', 'dropdown', 'Off', ["Off", "Helium", "Battle", "Void", "Void + Battle"], 'Golden'); + createSetting('cAutoGoldenUpgrades', 'C2 AutoGoldenUpgrades', 'Buys Golden Upgrades in C2s. Helium buys all Helium golden upgrades. Battle buys all Battle golden upgrades. Void buys 8 Void golden upgrades (max number you can buy) then buys helium golden upgrades. Void + Battle buys 8 voids then battle. Will run way faster than Vanilla AutoGold so if you have this on expect it to win over vanilla settings. ', 'dropdown', 'Off', ["Off", "Battle", "Void", "Void + Battle"], 'Golden'); + document.getElementById('cAutoGoldenUpgrades').parentNode.insertAdjacentHTML('afterend', '
'); + createSetting('voidheliumbattle', 'Void Battle', '-1 to disable.
Buys Battle goldens instead of Helium at this zone and onwards. This option only appears when selecting void. ', 'value', -1, null, 'Golden'); + createSetting('dvoidheliumbattle', 'Daily Void Battle', '-1 to disable.
Buys Battle goldens instead of Helium at this zone and onwards in Dailies. This option only appears when selecting void. ', 'value', -1, null, 'Golden'); + createSetting('radonbattle', 'Helium Battle', '-1 to disable.
Buys Battle goldens instead of helium after this many helium goldens have been purchased and onwards. This option only appears when selecting helium. ', 'value', -1, null, 'Golden'); + createSetting('dradonbattle', 'Daily Helium Battle', '-1 to disable.
Buys Battle goldens instead of helium after this many helium goldens have been purchased and onwards in Dailies. This option only appears when selecting helium. ', 'value', -1, null, 'Golden'); + createSetting('battleradon', 'Battle Helium', '-1 to disable.
Buys helium goldens instead of Battle after this many Battle goldens have been purchased and onwards. This option only appears when selecting battle. ', 'value', -1, null, 'Golden'); + createSetting('dbattleradon', 'Daily Battle Helium', '-1 to disable.
Buys helium goldens instead of Battle after this many battle goldens have been purchased and onwards in Dailies. This option only appears when selecting battle. ', 'value', -1, null, 'Golden'); + + + //RGolden + + createSetting('RAutoGoldenUpgrades', 'AutoGoldenUpgrades', 'Buys Golden Upgrades in Fillers. Radon buys all Radon golden upgrades. Battle buys all Battle golden upgrades. Void buys 8 Void golden upgrades (max number you can buy) then buys helium golden upgrades. Void + Battle buys 8 voids then battle. ', 'dropdown', 'Off', ["Off", "Radon", "Battle", "Void", "Void + Battle"], 'Golden'); + createSetting('RdAutoGoldenUpgrades', 'Daily AutoGoldenUpgrades', 'Buys Golden Upgrades in Dailies. Radon buys all Radon golden upgrades. Battle buys all Battle golden upgrades. Void buys 8 Void golden upgrades (max number you can buy) then buys helium golden upgrades. Void + Battle buys 8 voids then battle. ', 'dropdown', 'Off', ["Off", "Radon", "Battle", "Void", "Void + Battle"], 'Golden'); + createSetting('RcAutoGoldenUpgrades', 'C2 AutoGoldenUpgrades', 'Buys Golden Upgrades in C2s. Radon buys all Radon golden upgrades. Battle buys all Battle golden upgrades. Void buys 8 Void golden upgrades (max number you can buy) then buys helium golden upgrades. Void + Battle buys 8 voids then battle. ', 'dropdown', 'Off', ["Off", "Battle", "Void", "Void + Battle"], 'Golden'); + document.getElementById('RcAutoGoldenUpgrades').parentNode.insertAdjacentHTML('afterend', '
'); + createSetting('Rvoidheliumbattle', 'Void Battle', '-1 to disable.
Buys Battle goldens instead of Radon at this zone and onwards. This option only appears when selecting void. ', 'value', -1, null, 'Golden'); + createSetting('Rdvoidheliumbattle', 'Daily Void Battle', '-1 to disable.
Buys Battle goldens instead of Radon at this zone and onwards in Dailies. This option only appears when selecting void. ', 'value', -1, null, 'Golden'); + createSetting('Rradonbattle', 'Radon Battle', '-1 to disable.
Buys Battle goldens instead of Radon after this many Radon goldens have been purchased and onwards. This option only appears when selecting radon. ', 'value', -1, null, 'Golden'); + createSetting('Rdradonbattle', 'Daily Radon Battle', '-1 to disable.
Buys Battle goldens instead of Radon after this many Radon goldens have been purchased and onwards in Dailies. This option only appears when selecting radon. ', 'value', -1, null, 'Golden'); + createSetting('Rbattleradon', 'Battle Radon', '-1 to disable.
Buys Radon goldens instead of Battle after this many Battle goldens have been purchased and onwards. This option only appears when selecting battle. ', 'value', -1, null, 'Golden'); + createSetting('Rdbattleradon', 'Daily Battle Radon', '-1 to disable.
Buys Radon goldens instead of Battle after this many battle goldens have been purchased and onwards in Dailies. This option only appears when selecting battle. ', 'value', -1, null, 'Golden'); + + + + //AB + + createSetting('RAB', 'SA', 'Turn on SA settings and allow them to work. Do not open input settings when SA is on or you will crash. ', 'boolean', false, null, "SA"); + createSetting('RABpreset', 'Presets', 'Automatically switch presets depending on current enemy. You must make sure preset 1 is for Poison\, preset 2 Bleed and preset 3 Shock. If enemy has less than 2 resistances it will switch between the non-resisted presets till you kill the enemy. It will not purchase any equips or try different ones though so it may get stuck till you update your presets. ', 'boolean', false, null, "SA"); + createSetting('RABdustsimple', ['Simple Dust Off', 'SD: Equipped', 'SD: Non-hidden'], 'SD: Equipped automatically upgrades currently equipped items by lowest price. SD: Non-hidden automatically upgrades items that are not hidden and not equipped. ', 'multitoggle', 0, null, 'SA'); + createSetting('RABfarm', 'Save String', 'Saves your best Dust/s using SA level and your equipped items in a string. If this is on it will continously check your dust/s and generate a farm string if you beat your previous best. ', 'boolean', false, null, "SA"); + createSetting('RABfarmswitch', 'Switch', 'If this is on it will swtich directly to the SA level and equipped items. ', 'boolean', false, null, "SA"); + createSetting('RABfarmstring', 'String', 'This is your best farming string. Feel free to share it with other AT users. If you do use a shared string I advise you to change the second value (the dust part) to 0 so it calcs the actual dust you get instead of the shared strings. ', 'textValue', '-1', null, "SA"); + createSetting('RABsolve', 'Solver', 'Solves your current level including farming\, item levels\, and contracts. Currently does up to 10. ', 'boolean', false, null, "SA"); + + + + //Nature + + //Tokens createSetting('AutoNatureTokens', 'Spend Nature Tokens', 'MASTER BUTTON Automatically spend or convert nature tokens.', 'boolean', false, null, 'Nature'); + createSetting('tokenthresh', 'Token Threshold', 'If Tokens would go below this value it will not convert tokens. ', 'value', -1, null, 'Nature'); createSetting('AutoPoison', 'Poison', 'Spend/convert Poison tokens', 'dropdown', 'Off', ['Off', 'Empowerment', 'Transfer', 'Convert to Wind', 'Convert to Ice', 'Convert to Both'], 'Nature'); createSetting('AutoWind', 'Wind', 'Spend/convert Wind tokens', 'dropdown', 'Off', ['Off', 'Empowerment', 'Transfer', 'Convert to Poison', 'Convert to Ice', 'Convert to Both'], 'Nature'); createSetting('AutoIce', 'Ice', 'Spend/convert Ice tokens', 'dropdown', 'Off', ['Off', 'Empowerment', 'Transfer', 'Convert to Poison', 'Convert to Wind', 'Convert to Both'], 'Nature'); - - -//Display settings: - //Subsection1Line1 + //Enlights + document.getElementById('AutoIce').parentNode.insertAdjacentHTML('afterend', '
'); + createSetting('autoenlight', 'Enlight: Auto', 'Enables Automatic Enlightenment. Use the settings to define how it works. ', 'boolean', false, null, 'Nature'); + document.getElementById('autoenlight').parentNode.insertAdjacentHTML('afterend', '
'); + createSetting('pfillerenlightthresh', 'E: F: Poison', 'Activate Poison Enlight when Enlight cost is below this Thresh in Fillers. Consumes Tokens. -1 to disable. ', 'value', -1, null, 'Nature'); + createSetting('wfillerenlightthresh', 'E: F: Wind', 'Activate Wind Enlight when Enlight cost is below this Thresh in Fillers. Consumes Tokens. -1 to disable. ', 'value', -1, null, 'Nature'); + createSetting('ifillerenlightthresh', 'E: F: Ice', 'Activate Ice Enlight when Enlight cost is below this Thresh in Fillers. Consumes Tokens. -1 to disable. ', 'value', -1, null, 'Nature'); + document.getElementById('ifillerenlightthresh').parentNode.insertAdjacentHTML('afterend', '
'); + createSetting('pdailyenlightthresh', 'E: D: Poison', 'Activate Poison Enlight when Enlight cost is below this Thresh in Dailies. Consumes Tokens. -1 to disable. ', 'value', -1, null, 'Nature'); + createSetting('wdailyenlightthresh', 'E: D: Wind', 'Activate Wind Enlight when Enlight cost is below this Thresh in Dailies. Consumes Tokens. -1 to disable. ', 'value', -1, null, 'Nature'); + createSetting('idailyenlightthresh', 'E: D: Ice', 'Activate Ice Enlight when Enlight cost is below this Thresh in Dailies. Consumes Tokens. -1 to disable. ', 'value', -1, null, 'Nature'); + document.getElementById('idailyenlightthresh').parentNode.insertAdjacentHTML('afterend', '
'); + createSetting('pc2enlightthresh', 'E: C: Poison', 'Activate Poison Enlight when Enlight cost is below this Thresh in C2s. Consumes Tokens. -1 to disable. ', 'value', -1, null, 'Nature'); + createSetting('wc2enlightthresh', 'E: C: Wind', 'Activate Wind Enlight when Enlight cost is below this Thresh in C2s. Consumes Tokens. -1 to disable. ', 'value', -1, null, 'Nature'); + createSetting('ic2enlightthresh', 'E: C: Ice', 'Activate Ice Enlight when Enlight cost is below this Thresh in C2s. Consumes Tokens. -1 to disable. ', 'value', -1, null, 'Nature'); + + + //MAZ window Stuff + document.getElementById('Rtimefarmmaz').setAttribute('onclick', 'MAZLookalike("Time Farm", "Rtimefarm")'); + document.getElementById('Rdtimefarmmaz').setAttribute('onclick', 'MAZLookalike("dTime Farm", "Rdtimefarm")'); + document.getElementById('Rsmithyfarmmaz').setAttribute('onclick', 'MAZLookalike("Smithy Farm", "Rsmithyfarm")'); + document.getElementById('Rtributefarmmaz').setAttribute('onclick', 'MAZLookalike("Tribute Farm", "Rtributefarm")'); + document.getElementById('Hshrinemaz').setAttribute('onclick', 'MAZLookalike("Shrine - U1", "Hshrine")'); + document.getElementById('Hdshrinemaz').setAttribute('onclick', 'MAZLookalike("Shrine - U1 (Daily)", "Hdshrine")'); + document.getElementById('Rshrinemaz').setAttribute('onclick', 'MAZLookalike("Shrine - U2", "Rshrine")'); + document.getElementById('Rdshrinemaz').setAttribute('onclick', 'MAZLookalike("Shrine - U2 (Daily)", "Rdshrine")'); + document.getElementById('Rblackbogmaz').setAttribute('onclick', 'MAZLookalike("Quagmire", "Rblackbog")'); + document.getElementById('Rinsanitymaz').setAttribute('onclick', 'MAZLookalike("Insanity", "Rinsanityon")'); + document.getElementById('Ralchfarmmaz').setAttribute('onclick', 'MAZLookalike("Alch", "Ralchon")'); + document.getElementById('Rhypofarmmaz').setAttribute('onclick', 'MAZLookalike("Hypo", "Rhypoon")'); + document.getElementById('RAMPraidmaz').setAttribute('onclick', 'MAZLookalike("Praid", "RAMPraid")'); + document.getElementById('RdAMPraidmaz').setAttribute('onclick', 'MAZLookalike("dPraid", "RdAMPraid")'); + + //Display + + //Line 1 + createSetting('zonetracker', 'Zone', 'tracks zones you wil lnot see this huehue', 'value', 1, null, 'Display'); createSetting('EnhanceGrids', 'Enhance Grids', 'Apply slight visual enhancements to world and map grids that highlights with drop shadow all the exotic, powerful, skeletimps and other special imps.', 'boolean', false, null, 'Display'); + createSetting('showbreedtimer', 'Enable Breed Timer', 'Enables the display of the hidden breedtimer. Turn this off to reduce memory. ', 'boolean', true, null, 'Display'); + createSetting('showautomapstatus', 'Enable AutoMap Status', 'Enables the display of the map status. Turn this off to reduce memory. ', 'boolean', true, null, 'Display'); + createSetting('Rshowautomapstatus', 'Enable AutoMap Status', 'Enables the display of the map status. Turn this off to reduce memory. ', 'boolean', true, null, 'Display'); createSetting('EnableAFK', 'Go AFK Mode', '(Action Button). Go AFK uses a Black Screen, and suspends ALL the Trimps GUI visual update functions (updateLabels) to improve performance by not doing unnecessary stuff. This feature is primarily just a CPU and RAM saving mode. Everything will resume when you come back and press the Back button. Console debug output is also disabled. The blue color means this is not a settable setting, just a button. You can now also click the Zone # (World Info) area to go AFK now.', 'action', 'MODULES["performance"].EnableAFKMode()', null, 'Display'); - document.getElementById('battleSideTitle').setAttribute('onclick','MODULES["performance"].EnableAFKMode()'); + document.getElementById('battleSideTitle').setAttribute('onclick', 'MODULES["performance"].EnableAFKMode()'); document.getElementById('battleSideTitle').setAttribute('onmouseover', "getZoneStats(event);this.style.cursor='pointer'"); createSetting('ChangeLog', 'Show Changelog', '(Action Button). Shows the changelog popup message that AT loads on startup again, in case you missed it. The blue color means this is not a settable setting, just a button.', 'action', 'printChangelog()', null, 'Display'); - document.getElementById('Display').lastChild.insertAdjacentHTML('afterend','
'); + document.getElementById('Display').lastChild.insertAdjacentHTML('afterend', '
'); + + + + //SPAM + + //Line 1 -//SPAM settings: - //Subsection2Line1 createSetting('SpamGeneral', 'General Spam', 'General Spam = Notification Messages, Auto He/Hr', 'boolean', true, null, 'Display'); createSetting('SpamUpgrades', 'Upgrades Spam', 'Upgrades Spam', 'boolean', true, null, 'Display'); createSetting('SpamEquipment', 'Equipment Spam', 'Equipment Spam', 'boolean', true, null, 'Display'); @@ -464,48 +1173,64 @@ function initializeAllSettings() { createSetting('SpamOther', 'Other Spam', 'Other Spam = mostly Better Auto Fight (disable with: MODULES[\\"fight\\"].enableDebug=false ), Trimpicide & AutoBreed/Gene Timer changes, AnalyticsID, etc - a catch all. ', 'boolean', true, null, 'Display'); createSetting('SpamBuilding', 'Building Spam', 'Building Spam = all buildings, even storage', 'boolean', false, null, 'Display'); createSetting('SpamJobs', 'Job Spam', 'Job Spam = All jobs, in scientific notation', 'boolean', false, null, 'Display'); - //Line2 + + //Line 2 createSetting('SpamGraphs', 'Starting Zone Spam', 'Disables \'Starting new Zone ###\' , RoboTrimp MagnetoShreik, and any future Graph Spam that comes from graph logs.', 'boolean', true, null, 'Display'); createSetting('SpamMagmite', 'Magmite/Magma Spam', 'Everything in Magmite Module and Buy Magmamancers', 'boolean', true, null, 'Display'); createSetting('SpamPerks', 'AutoPerks Spam', 'Everything in related to AutoPerks', 'boolean', true, null, 'Display'); + createSetting('SpamNature', 'Nature Spam', 'Everything in related to Nature', 'boolean', true, null, 'Display'); - -// Export/Import/Default settings + + //Export/Import/Default createSetting('ImportAutoTrimps', 'Import AutoTrimps', 'Import your AutoTrimps Settings. Asks you to name it as a profile afterwards.', 'infoclick', 'ImportAutoTrimps', null, 'Import Export'); createSetting('ExportAutoTrimps', 'Export AutoTrimps', 'Export your AutoTrimps Settings as a output string text formatted in JSON.', 'infoclick', 'ExportAutoTrimps', null, 'Import Export'); createSetting('DefaultAutoTrimps', 'Reset to Default', 'Reset everything to the way it was when you first installed the script. ', 'infoclick', 'ResetDefaultSettingsProfiles', null, 'Import Export'); + createSetting('Export60', '-60 AT Settings', 'Gives you an AT settings String that you can use to import. Use if you are less than z60. May not work for you perfectly, should really only be used as an example!', 'infoclick', 'Export60', null, 'Import Export'); + createSetting('Export550', '550+ AT Settings', 'Gives you an AT settings String that you can use to import. Use if you are z550+. May not work for you perfectly, should really only be used as an example! ', 'infoclick', 'Export550', null, 'Import Export'); createSetting('CleanupAutoTrimps', 'Cleanup Saved Settings ', 'Deletes old values from previous versions of the script from your AutoTrimps Settings file.', 'infoclick', 'CleanupAutoTrimps', null, 'Import Export'); - createSetting('allowSettingsUpload', 'Allow Analytics Upload', 'Uploads your AUTOTRIMPS saved settings files (the same as Export AutoTrimps on this tab) anonymously - to https://autotrimps.site = the official Autotrimps development server. It will remain private for now, and aggregated for analytics to improve the script in the future and see which features are being used. Please Opt in. The upload will be approximately a small 5-10KB uncompressed text file every time the script is LOADED (for the time being until it is refined), and there is no concern for any personal data leak or privacy concern. This is all in good faith, and you are welcome to check the open source file modules/client-server.js. In the future, I will have to make a more fine-grained data-usage privacy-policy. Possible other data collected in the near-future may include certain game stats such as your highest zone, helium amount, bones, resource/magma/DE amounts, perk ratio selections. ', 'boolean', true, null, 'Import Export'); - settingsProfileMakeGUI(); //Settings Profile dropdown and Delete button. (this always shows up first - can be here last) - //createSetting('ExportModuleVars', 'Export Custom Variables', 'Export your custom MODULES variables.', 'infoclick', 'ExportModuleVars', null, 'Import Export'); - //createSetting('ImportModuleVars', 'Import Custom Variables', 'Import your custom MODULES variables (and save).', 'infoclick', 'ImportModuleVars', null, 'Import Export'); - //createSetting('ResetModuleVars', 'Reset Custom Variables', 'Reset(Delete) your custom MODULES variables, and return the script to normal. ', 'infoclick', 'ResetModuleVars', null, 'Import Export'); + + document.getElementById('Rchallengehidearch').setAttribute('onclick', 'settingChanged("Rchallengehidearch"), modifyParentNode("Rchallengehidearch", "Rarchstring3")'); + modifyParentNode("Rchallengehidearch", "Rarchstring3"); + + document.getElementById('Rchallengehidemayhem').setAttribute('onclick', 'settingChanged("Rchallengehidemayhem"), modifyParentNode("Rchallengehidemayhem", "Rmayhemmap")'); + modifyParentNode("Rchallengehidemayhem", "Rmayhemmap"); + + document.getElementById('Rchallengehidestorm').setAttribute('onclick', 'settingChanged("Rchallengehidestorm"), modifyParentNode("Rchallengehidestorm", "Rstormmult")'); + modifyParentNode("Rchallengehidestorm", "Rstormmult"); + + document.getElementById('Rchallengehideinsanity').setAttribute('onclick', 'settingChanged("Rchallengehideinsanity"), modifyParentNode("Rchallengehideinsanity", "Rinsanityfarmfrag")'); + modifyParentNode("Rchallengehideinsanity", "Rinsanityfarmfrag"); + + document.getElementById('Rchallengehideexterminate').setAttribute('onclick', 'settingChanged("Rchallengehideexterminate"), modifyParentNode("Rchallengehideexterminate", "Rexterminateeq")'); + modifyParentNode("Rchallengehideexterminate", "Rexterminateeq"); + + document.getElementById('Rchallengehidepanda').setAttribute('onclick', 'settingChanged("Rchallengehidepanda"), modifyParentNode("Rchallengehidepanda", "Rpandahits")'); + modifyParentNode("Rchallengehidepanda", "Rpandahits"); + + document.getElementById('Rchallengehidealchemy').setAttribute('onclick', 'settingChanged("Rchallengehidealchemy"), modifyParentNode("Rchallengehidealchemy", "Ralchfarmfrag")'); + modifyParentNode("Rchallengehidealchemy", "Ralchfarmfrag"); + + document.getElementById('Rchallengehidehypothermia').setAttribute('onclick', 'settingChanged("Rchallengehidehypothermia"), modifyParentNode("Rchallengehidehypothermia", "Rhypostorage")'); + modifyParentNode("Rchallengehidehypothermia", "Rhypostorage"); - //createSetting('PlayerLevel', 'PlayerLevel', 'PlayerLevel: Indicate around what level you are. noob, low, medium, high, spire, magma, expert, z450+, z500+, endgame and so on. Might be used to control which settings are visible in the future. ', 'dropdown', "Medium", ["Noob","Low","Medium","High","Spire","Magma","Expert","z450+","z500+","EndGame"], 'Display'); - /* - createSetting('ATModuleListDropdown', 'Modules', 'AT Module List Dropdown: Lists all the individual modules (.js files) that have been auto-loaded. It might be possible to unload these or something in the future.', 'dropdown', ATmoduleList[0], ATmoduleList, 'Import Export'); - document.getElementById('ATModuleListDropdown').multiple = true; //allow 4 multiple selections - document.getElementById('ATModuleListDropdown').size = 4; - document.getElementById('ATModuleListDropdown').height = '5vw'; - document.getElementById('ATModuleListDropdownLabel').style.verticalAlign = 'top'; - document.getElementById('ATModuleListDropdownLabel').parentNode.style.width = null; //make the next stuff fit on 1 line. - createSetting('ATModuleUnload', 'Unload Module', 'UnLoads a running module file this session', 'infoclick', 'ATModuleUnload', null, 'Import Export'); - createSetting('ATModuleLoad', 'ReLoad Module', 'Load/Reloads a module file (.js) and runs it.', 'infoclick', 'ATModuleLoad', null, 'Import Export'); - */ + document.getElementById('Rchallengehidedeso').setAttribute('onclick', 'settingChanged("Rchallengehidedeso"), modifyParentNode("Rchallengehidedeso", "Rdesomult")'); + modifyParentNode("Rchallengehidedeso", "Rdesomult"); + + settingsProfileMakeGUI(); + } -initializeAllSettings(); //EXECUTE -//Universal function that creates sets up the Settings database, structures and associated graphic elements +initializeAllSettings(); + function createSetting(id, name, description, type, defaultValue, list, container) { var btnParent = document.createElement("DIV"); - // btnParent.setAttribute('class', 'optionContainer'); btnParent.setAttribute('style', 'display: inline-block; vertical-align: top; margin-left: 1vw; margin-bottom: 1vw; width: 13.142vw;'); var btn = document.createElement("DIV"); btn.id = id; var loaded = autoTrimpSettings[id]; if (type == 'boolean') { - if (!(loaded && id == loaded.id)) + if (!(loaded && id == loaded.id && loaded.type === type)) autoTrimpSettings[id] = { id: id, name: name, @@ -523,7 +1248,43 @@ function createSetting(id, name, description, type, defaultValue, list, containe if (container) document.getElementById(container).appendChild(btnParent); else document.getElementById("autoSettings").appendChild(btnParent); } else if (type == 'value' || type == 'valueNegative') { - if (!(loaded && id == loaded.id)) + if (!(loaded && id == loaded.id && loaded.type === type)) + autoTrimpSettings[id] = { + id: id, + name: name, + description: description, + type: type, + value: loaded === undefined ? defaultValue : loaded + }; + btn.setAttribute("style", "font-size: 1.1vw;"); + btn.setAttribute('class', 'noselect settingsBtn btn-info'); + btn.setAttribute("onclick", `autoSetValueToolTip("${id}", "${name}", ${type == 'valueNegative'}, ${type == 'multiValue'})`); + btn.setAttribute("onmouseover", 'tooltip(\"' + name + '\", \"customText\", event, \"' + description + '\")'); + btn.setAttribute("onmouseout", 'tooltip("hide")'); + btn.textContent = name; + btnParent.appendChild(btn); + if (container) document.getElementById(container).appendChild(btnParent); + else document.getElementById("autoSettings").appendChild(btnParent); + } else if (type == 'multiValue' || type == 'valueNegative') { + if (!(loaded && id == loaded.id && loaded.type === type)) + autoTrimpSettings[id] = { + id: id, + name: name, + description: description, + type: type, + value: loaded === undefined ? defaultValue : loaded + }; + btn.setAttribute("style", "font-size: 1.1vw;"); + btn.setAttribute('class', 'noselect settingsBtn btn-info'); + btn.setAttribute("onclick", `autoSetValueToolTip("${id}", "${name}", ${type == 'valueNegative'}, ${type == 'multiValue'})`); + btn.setAttribute("onmouseover", 'tooltip(\"' + name + '\", \"customText\", event, \"' + description + '\")'); + btn.setAttribute("onmouseout", 'tooltip("hide")'); + btn.textContent = name; + btnParent.appendChild(btn); + if (container) document.getElementById(container).appendChild(btnParent); + else document.getElementById("autoSettings").appendChild(btnParent); + } else if (type == 'textValue') { + if (!(loaded && id == loaded.id && loaded.type === type)) autoTrimpSettings[id] = { id: id, name: name, @@ -533,7 +1294,7 @@ function createSetting(id, name, description, type, defaultValue, list, containe }; btn.setAttribute("style", "font-size: 1.1vw;"); btn.setAttribute('class', 'noselect settingsBtn btn-info'); - btn.setAttribute("onclick", 'autoSetValueToolTip("' + id + '", "' + name + '",'+`${(type == 'valueNegative')}`+')'); + btn.setAttribute("onclick", `autoSetTextToolTip("${id}", "${name}", ${type == 'textValue'})`); btn.setAttribute("onmouseover", 'tooltip(\"' + name + '\", \"customText\", event, \"' + description + '\")'); btn.setAttribute("onmouseout", 'tooltip("hide")'); btn.textContent = name; @@ -541,7 +1302,7 @@ function createSetting(id, name, description, type, defaultValue, list, containe if (container) document.getElementById(container).appendChild(btnParent); else document.getElementById("autoSettings").appendChild(btnParent); } else if (type == 'dropdown') { - if (!(loaded && id == loaded.id)) + if (!(loaded && id == loaded.id && loaded.type === type)) autoTrimpSettings[id] = { id: id, name: name, @@ -558,7 +1319,6 @@ function createSetting(id, name, description, type, defaultValue, list, containe btn.setAttribute("onmouseover", 'tooltip(\"' + name + '\", \"customText\", event, \"' + description + '\")'); btn.setAttribute("onmouseout", 'tooltip("hide")'); btn.setAttribute("onchange", 'settingChanged("' + id + '")'); - for (var item in list) { var option = document.createElement("option"); option.value = list[item]; @@ -566,7 +1326,6 @@ function createSetting(id, name, description, type, defaultValue, list, containe btn.appendChild(option); } btn.value = autoTrimpSettings[id].selected; - var dropdownLabel = document.createElement("Label"); dropdownLabel.id = id + "Label"; dropdownLabel.innerHTML = name + ":"; @@ -576,19 +1335,18 @@ function createSetting(id, name, description, type, defaultValue, list, containe if (container) document.getElementById(container).appendChild(btnParent); else document.getElementById("autoSettings").appendChild(btnParent); } else if (type == 'infoclick') { - btn.setAttribute('class', 'btn btn-info'); + btn.setAttribute('class', 'noselect settingsBtn settingBtn3'); btn.setAttribute("onclick", 'ImportExportTooltip(\'' + defaultValue + '\', \'update\')'); btn.setAttribute("onmouseover", 'tooltip(\"' + name + '\", \"customText\", event, \"' + description + '\")'); btn.setAttribute("onmouseout", 'tooltip("hide")'); - btn.setAttribute("style", "display: block; font-size: 0.8vw;"); + btn.setAttribute("style", "background-color: #d88839; color: black; font-size: 1.1vw;"); btn.textContent = name; - btnParent.style.width = ''; btnParent.appendChild(btn); if (container) document.getElementById(container).appendChild(btnParent); else document.getElementById("autoSettings").appendChild(btnParent); - return; //return means don't store it in autoTrimpSettings at the bottom + return; } else if (type == 'multitoggle') { - if (!(loaded && id == loaded.id)) + if (!(loaded && id == loaded.id && loaded.type === type)) autoTrimpSettings[id] = { id: id, name: name, @@ -605,12 +1363,9 @@ function createSetting(id, name, description, type, defaultValue, list, containe btnParent.appendChild(btn); if (container) document.getElementById(container).appendChild(btnParent); else document.getElementById("autoSettings").appendChild(btnParent); - } - else if(type === 'action') - { - //We're not storing the state on these. + } else if (type === 'action') { btn.setAttribute("style", "font-size: 1.1vw;"); - btn.setAttribute('class', 'noselect settingsBtn settingBtn3'); //color 3 is teal. + btn.setAttribute('class', 'noselect settingsBtn settingBtn3'); btn.setAttribute('onclick', defaultValue); btn.setAttribute("onmouseover", 'tooltip(\"' + name + '\", \"customText\", event, \"' + description + '\")'); btn.setAttribute("onmouseout", 'tooltip("hide")'); @@ -618,10 +1373,8 @@ function createSetting(id, name, description, type, defaultValue, list, containe btnParent.appendChild(btn); if (container) document.getElementById(container).appendChild(btnParent); else document.getElementById("autoSettings").appendChild(btnParent); - return; //return means don't store it in autoTrimpSettings at the bottom + return; } - - //make sure names/descriptions match what we have stored. if (autoTrimpSettings[id].name != name) autoTrimpSettings[id].name = name; if (autoTrimpSettings[id].description != description) @@ -629,7 +1382,6 @@ function createSetting(id, name, description, type, defaultValue, list, containe autoTrimpSettings["ATversion"] = ATversion; } -//makes labeled checkboxes. function createInput(id, name, description) { var $btnParent = document.createElement("DIV"); $btnParent.setAttribute('style', 'display: inline-block; vertical-align: top; margin-left: 0.5vw; margin-bottom: 0.5vw; width: 6.5vw;'); @@ -639,7 +1391,6 @@ function createInput(id, name, description) { $input.type = 'checkbox'; $input.setAttribute('id', id); $input.setAttribute('style', 'text-align: left; width: 0.8vw; '); - //$input.setAttribute('onkeypress', 'isValidKey2(this,event)'); $btnParent.appendChild($input); var $label = document.createElement("label"); $label.setAttribute('style', 'text-align: left; margin-left: 0.2vw; font-size: 0.6vw'); @@ -648,7 +1399,6 @@ function createInput(id, name, description) { document.getElementById("autoSettings").appendChild($btnParent); } -//Default Toggler handler for any setting of the 3 special types (boolean, multitoggle, dropdown, and handle PrestigeBackup) - not value type. function settingChanged(id) { var btn = autoTrimpSettings[id]; if (btn.type == 'boolean') { @@ -656,10 +1406,9 @@ function settingChanged(id) { document.getElementById(id).setAttribute('class', 'noselect settingsBtn settingBtn' + btn.enabled); } if (btn.type == 'multitoggle') { - //puts a 5 second pause in between cycling through from "on portal" to "always" so you can switch it to "off". if (id == 'AutoMagmiteSpender2' && btn.value == 1) { magmiteSpenderChanged = true; - setTimeout(function() { + setTimeout(function () { magmiteSpenderChanged = false; }, 5000); } @@ -671,29 +1420,29 @@ function settingChanged(id) { } if (btn.type == 'dropdown') { btn.selected = document.getElementById(id).value; - //part of the prestige dropdown's "backup" system to prevent internal tampering via the dynamic prestige algorithm. everytime we see a user initiated change, make a backup. - if (id == "Prestige") - autoTrimpSettings["PrestigeBackup"].selected = document.getElementById(id).value; + if (id == "Prestige") { + autoTrimpSettings["PrestigeBackup"] = { + selected: document.getElementById(id).value, + name: "PrestigeBackup", + id: "PrestigeBackup" + }; + } } - //console.log(id + " Setting Changed"); updateCustomButtons(); saveSettings(); checkPortalSettings(); - if ((autoTrimpSettings.AutoGen2.value == 3) && game.generatorUpgrades["Overclocker"].upgrades <= 0) - tooltip('confirm', null, 'update', 'WARNING: You are set to Overclock but do not have any Overclocker upgrades. AutoGen2 will default to \'Max Cap\' in this case. If this is not desired, please fix your AutoGen2 setting.', 'cancelTooltip()', 'Cannot Overclock'); } -//Popup Tooltip - ask them to enter some numerical input. (STANDARDIZED) -function autoSetValueToolTip(id, text,negative) { +function autoSetValueToolTip(id, text, negative, multi) { ranstring = text; var elem = document.getElementById("tooltipDiv"); var tooltipText = 'Type a number below. You can also use shorthand such as 2e5 or 200k.'; if (negative) - tooltipText += 'Accepts negative numbers as validated inputs.'; + tooltipText += ' Accepts negative numbers as validated inputs.'; else - tooltipText += 'Put -1 for Infinite.'; - tooltipText += '

'; - var costText = '

Apply
Cancel
'; + tooltipText += ' Put -1 for Infinite.'; + tooltipText += `

`; + var costText = '
Apply
Cancel
'; game.global.lockTooltip = true; elem.style.left = '32.5%'; elem.style.top = '25%'; @@ -709,41 +1458,72 @@ function autoSetValueToolTip(id, text,negative) { } box.focus(); } -//Keyboard handler - Enter Key accepts popup -function onKeyPressSetting(event, id,negative) { + +function autoSetTextToolTip(id, text) { + ranstring = text; + var elem = document.getElementById("tooltipDiv"); + var tooltipText = 'Type your input below'; + tooltipText += `

`; + var costText = '
Apply
Cancel
'; + game.global.lockTooltip = true; + elem.style.left = '32.5%'; + elem.style.top = '25%'; + document.getElementById('tipTitle').textContent = ranstring + ': Value Input'; + document.getElementById('tipText').innerHTML = tooltipText; + document.getElementById('tipCost').innerHTML = costText; + elem.style.display = 'block'; + var box = document.getElementById('customTextBox'); + box.focus(); +} + +function onKeyPressSetting(event, id, negative, multi) { if (event.which == 13 || event.keyCode == 13) { - autoSetValue(id,negative); + if (negative !== undefined && multi !== undefined) + autoSetValue(id, negative, multi); + else + autoSetText(id); + } +} + +function parseNum(num) { + if (num.split('e')[1]) { + num = num.split('e'); + num = Math.floor(parseFloat(num[0]) * (Math.pow(10, parseInt(num[1])))); + } else { + var letters = num.replace(/[^a-z]/gi, ''); + var base = 0; + if (letters.length) { + var suffices = ['K', 'M', 'B', 'T', 'Qa', 'Qi', 'Sx', 'Sp', 'Oc', 'No', 'Dc', 'Ud', 'Dd', 'Td', 'Qad', 'Qid', 'Sxd', 'Spd', 'Od', 'Nd', 'V', 'Uv', 'Dv', 'Tv', 'Qav', 'Qiv', 'Sxv', 'Spv', 'Ov', 'Nv', 'Tt']; + for (var x = 0; x < suffices.length; x++) { + if (suffices[x].toLowerCase() == letters) { + base = x + 1; + break; + } + } + if (base) num = Math.round(parseFloat(num.split(letters)[0]) * Math.pow(1000, base)); + } + if (!base) num = parseFloat(num); } + return num; } -//Custom Number Box - Suffix handler for numerical to string values in the prompted popup -function autoSetValue(id,negative) { + +function autoSetValue(id, negative, multi) { var num = 0; unlockTooltip(); tooltip('hide'); var numBox = document.getElementById('customNumberBox'); if (numBox) { num = numBox.value.toLowerCase(); - if (num.split('e')[1]) { - num = num.split('e'); - num = Math.floor(parseFloat(num[0]) * (Math.pow(10, parseInt(num[1])))); + if (multi) { + num = num.split(',').map(parseNum); } else { - var letters = num.replace(/[^a-z]/gi, ''); - var base = 0; - if (letters.length) { - var suffices = ['K', 'M', 'B', 'T', 'Qa', 'Qi', 'Sx', 'Sp', 'Oc', 'No', 'Dc', 'Ud', 'Dd', 'Td', 'Qad', 'Qid', 'Sxd', 'Spd', 'Od', 'Nd', 'V', 'Uv', 'Dv', 'Tv', 'Qav', 'Qiv', 'Sxv', 'Spv', 'Ov', 'Nv', 'Tt']; - for (var x = 0; x < suffices.length; x++) { - if (suffices[x].toLowerCase() == letters) { - base = x + 1; - break; - } - } - if (base) num = Math.round(parseFloat(num.split(letters)[0]) * Math.pow(1000, base)); - } - if (!base) num = parseFloat(num); + num = parseNum(num); } } else return; autoTrimpSettings[id].value = num; - if (num > -1 || negative) + if (Array.isArray(num)) { + document.getElementById(id).textContent = ranstring + ': ' + num[0] + '+'; + } else if (num > -1 || negative) document.getElementById(id).textContent = ranstring + ': ' + prettify(num); else document.getElementById(id).innerHTML = ranstring + ': ' + ""; @@ -751,7 +1531,22 @@ function autoSetValue(id,negative) { checkPortalSettings(); } -//toggles the display of the settings menu. 1 +function autoSetText(id) { + var textVal = 'empty'; + unlockTooltip(); + tooltip('hide'); + var textBox = document.getElementById('customTextBox'); + if (textBox) { + textVal = textBox.value + } else return; + autoTrimpSettings[id].value = textVal; + if (textVal != undefined) { + document.getElementById(id).textContent = ranstring + ': ' + textVal; + } + saveSettings(); + checkPortalSettings(); +} + function autoToggle(what) { if (what) { var $what = document.getElementById(what); @@ -766,8 +1561,11 @@ function autoToggle(what) { if (game.options.displayed) toggleSettingsMenu(); var $item = document.getElementById('graphParent'); - if ($item.style.display === 'block') + if ($item.style.display === 'block') { $item.style.display = 'none'; + trimpStatsDisplayed = false; + GRAPHSETTINGS.open = false; + } var $item = document.getElementById('autoTrimpsTabBarMenu'); if ($item.style.display === 'block') $item.style.display = 'none'; @@ -779,115 +1577,982 @@ function autoToggle(what) { } } -//toggles the display of the original settings menu button, -// when clicked, hiding the AT settings and graph. function autoPlusSettingsMenu() { var $item = document.getElementById('autoSettings'); if ($item.style.display === 'block') $item.style.display = 'none'; var $item = document.getElementById('graphParent'); - if ($item.style.display === 'block') + if ($item.style.display === 'block') { $item.style.display = 'none'; + trimpStatsDisplayed = false; + GRAPHSETTINGS.open = false; + } var $item = document.getElementById('autoTrimpsTabBarMenu'); if ($item.style.display === 'block') $item.style.display = 'none'; toggleSettingsMenu(); } -//Responsible for keeping the GUI in sync with the settings database and -// force-controlling the values of some and changing its visible or hidden status - function updateCustomButtons() { - //console.log("GUI: CustomButtons Updated"); - //Check for Theme Changed, and swap theme: - if (typeof MODULES["graphs"] !== 'undefined') - MODULES["graphs"].themeChanged(); + const isGraphModuleDefined = typeof MODULES.graphs !== 'undefined'; + const isLastThemeDefined = isGraphModuleDefined && typeof MODULES.graphs._lastTheme !== 'undefined'; + const hasThemeChanged = isLastThemeDefined && game.options.menu.darkTheme.enabled !== MODULES.graphs._lastTheme; + + if (isGraphModuleDefined && hasThemeChanged) { + MODULES.graphs.themeChanged(); + MODULES.graphs._lastTheme = game.options.menu.darkTheme.enabled; + debug("Theme change - AutoTrimps styles updated."); + } + function toggleElem(elem, showHide) { + var $item = document.getElementById(elem); + if ($item == null) return; var state = showHide ? '' : 'none'; var stateParent = showHide ? 'inline-block' : 'none'; - var item = document.getElementById(elem); - item.style.display = state; - item.parentNode.style.display = stateParent; + $item.style.display = state; + $item.parentNode.style.display = stateParent; } + function turnOff(elem) { toggleElem(elem, false); } + function turnOn(elem) { toggleElem(elem, true); } - //automaps button in GUI - document.getElementById("autoMapBtn").setAttribute("class", "noselect settingsBtn settingBtn" + autoTrimpSettings.AutoMaps.value); - //auto portal setting, hide until player has unlocked the balance challenge - (game.challenges.Balance.filter()) ? turnOn("AutoPortal") : turnOff("AutoPortal"); - //auto Daily settings, hide until player has unlocked the Daily challenges - var doDaily = game.challenges.Daily.filter(); - (doDaily) ? turnOn("AutoStartDaily") : turnOff("AutoStartDaily"); - (doDaily) ? turnOn("AutoFinishDaily") : turnOff("AutoFinishDaily"); - (doDaily && getPageSetting('AutoFinishDaily')) ? turnOn("AutoFinishDailyZone") : turnOff("AutoFinishDailyZone"); - //if custom auto portal is not selected, remove the custom value settingsbox - (autoTrimpSettings.AutoPortal.selected == "Custom") ? turnOn("CustomAutoPortal") : turnOff("CustomAutoPortal"); - //if HeHr is not selected, remove HeliumHourChallenge settingsbox + + //Hide settings + + //Radon + var radonon = getPageSetting('radonsettings') == 1; + //Bone Shrine + var boneShrinePurchased = game.permaBoneBonuses.boosts.owned > 0 ? true : false; + + //Tabs + if (document.getElementById("tabSpire") != null) { + document.getElementById("tabSpire").style.display = radonon ? "none" : ""; + } + if (document.getElementById("tabWindstacking") != null) { + document.getElementById("tabWindstacking").style.display = radonon ? "none" : ""; + } + if (document.getElementById("tabATGA") != null) { + document.getElementById("tabATGA").style.display = radonon ? "none" : ""; + } + if (document.getElementById("tabScryer") != null) { + document.getElementById("tabScryer").style.display = radonon ? "none" : ""; + } + if (document.getElementById("tabMagma") != null) { + document.getElementById("tabMagma").style.display = radonon ? "none" : ""; + } + if (document.getElementById("tabNature") != null) { + document.getElementById("tabNature").style.display = radonon ? "none" : ""; + } + if (document.getElementById("tabChallenges") != null) { + document.getElementById("tabChallenges").style.display = !radonon ? "none" : ""; + } + if (document.getElementById("tabSA") != null) { + document.getElementById("tabSA").style.display = !radonon ? "none" : ""; + } + + + + //Core + !radonon ? turnOn('ManualGather2') : turnOff("ManualGather2"); + !radonon ? turnOn('TrapTrimps') : turnOff("TrapTrimps"); + !radonon ? turnOn('BuyUpgradesNew') : turnOff("BuyUpgradesNew"); + (!radonon && getPageSetting('ManualGather2') == 2 && bwRewardUnlocked("Foremany")) ? turnOn("gathermetal") : turnOff("gathermetal"); + !radonon ? turnOn("amalcoord") : turnOff("amalcoord"); + !radonon && getPageSetting('amalcoord') == true ? turnOn("amalcoordt") : turnOff("amalcoordt"); + !radonon && getPageSetting('amalcoord') == true ? turnOn("amalcoordhd") : turnOff("amalcoordhd"); + !radonon && getPageSetting('amalcoord') == true ? turnOn("amalcoordz") : turnOff("amalcoordz"); + !radonon ? turnOn("AutoAllocatePerks") : turnOff("AutoAllocatePerks"); + !radonon && getPageSetting('AutoAllocatePerks') == 1 ? turnOn("fastallocate") : turnOff("fastallocate"); + boneShrinePurchased ? turnOn('AutoBoneChargeMax') : turnOff("AutoBoneChargeMax"); + boneShrinePurchased ? turnOn("AutoBoneChargeMaxStartZone") : turnOff("AutoBoneChargeMaxStartZone"); + + //Portal + !radonon ? turnOn("AutoPortal") : turnOff("AutoPortal"); + (!radonon && autoTrimpSettings.AutoPortal.selected == "Custom") ? turnOn("CustomAutoPortal") : turnOff("CustomAutoPortal"); var heHr = (autoTrimpSettings.AutoPortal.selected == "Helium Per Hour"); - (heHr || autoTrimpSettings.AutoPortal.selected == "Custom") ? turnOn("HeliumHourChallenge") : turnOff("HeliumHourChallenge"); - //if HeHr is not selected, remove HeHrDontPortalBefore settingsbox - (heHr) ? turnOn("HeHrDontPortalBefore") : turnOff("HeHrDontPortalBefore"); - //if HeHr is not selected, remove HeHr buffer settingsbox - (heHr) ? turnOn("HeliumHrBuffer") : turnOff("HeliumHrBuffer"); - //if ShieldBlock is for sure, remove ShieldBlock from settingsbox (achievement=12 means z100). - (game.achievements.zones.finished < 12) ? turnOn("BuyShieldblock") : function(){turnOff("BuyShieldblock");setPageSetting("BuyShieldblock",false);}(); - - //DROPDOWNS: updates dropdown selections. (ALL DROPDOWNS REQUIRE THIS BIT TO BE UPDATEY) - //todo check why this isnt possible to set automatically in the dropdown code. + !radonon && (heHr || autoTrimpSettings.AutoPortal.selected == "Custom") ? turnOn("HeliumHourChallenge") : turnOff("HeliumHourChallenge"); + !radonon && (heHr) ? turnOn("HeHrDontPortalBefore") : turnOff("HeHrDontPortalBefore"); + !radonon && (heHr) ? turnOn("HeliumHrBuffer") : turnOff("HeliumHrBuffer"); + + + //RCore + radonon ? turnOn('RManualGather2') : turnOff("RManualGather2"); + radonon ? turnOn('RTrapTrimps') : turnOff("RTrapTrimps"); + radonon ? turnOn('RBuyUpgradesNew') : turnOff("RBuyUpgradesNew"); + radonon ? turnOn("RAutoAllocatePerks") : turnOff("RAutoAllocatePerks"); + radonon && getPageSetting('RAutoAllocatePerks') == 2 ? turnOn("Rdumpgreed") : turnOff("Rdumpgreed"); + + //RPortal + radonon ? turnOn("RAutoPortal") : turnOff("RAutoPortal"); + (radonon && autoTrimpSettings.RAutoPortal.selected == "Custom") ? turnOn("RCustomAutoPortal") : turnOff("RCustomAutoPortal"); + var rnHr = (autoTrimpSettings.RAutoPortal.selected == "Radon Per Hour"); + radonon && (rnHr || autoTrimpSettings.RAutoPortal.selected == "Custom") ? turnOn("RadonHourChallenge") : turnOff("RadonHourChallenge"); + radonon && (rnHr) ? turnOn("RnHrDontPortalBefore") : turnOff("RnHrDontPortalBefore"); + radonon && (rnHr) ? turnOn("RadonHrBuffer") : turnOff("RadonHrBuffer"); + + + + //Daily + !radonon ? turnOn("buyheliumy") : turnOff("buyheliumy"); + !radonon ? turnOn("dscryvoidmaps") : turnOff("dscryvoidmaps"); + !radonon ? turnOn("dIgnoreSpiresUntil") : turnOff("dIgnoreSpiresUntil"); + !radonon ? turnOn("dExitSpireCell") : turnOff("dExitSpireCell"); + !radonon ? turnOn("dPreSpireNurseries") : turnOff("dPreSpireNurseries"); + !radonon ? turnOn("DailyVoidMod") : turnOff("DailyVoidMod"); + !radonon ? turnOn("dvoidscell") : turnOff("dvoidscell"); + !radonon ? turnOn("dRunNewVoidsUntilNew") : turnOff("dRunNewVoidsUntilNew"); + !radonon ? turnOn("drunnewvoidspoison") : turnOff("drunnewvoidspoison"); + !radonon ? turnOn("avoidempower") : turnOff("avoidempower"); + !radonon ? turnOn("dfightforever") : turnOff("dfightforever"); + !radonon ? turnOn("darmormagic") : turnOff("darmormagic"); + + //DRaid + !radonon ? turnOn("dPraidingzone") : turnOff("dPraidingzone"); + !radonon ? turnOn("dPraidingcell") : turnOff("dPraidingcell"); + !radonon ? turnOn("dPraidingHD") : turnOff("dPraidingHD"); + !radonon ? turnOn("dPraidingP") : turnOff("dPraidingP"); + !radonon ? turnOn("dPraidingI") : turnOff("dPraidingI"); + !radonon && getPageSetting('dPraidingzone') != -1 ? turnOn('dPraidHarder') : turnOff('dPraidHarder'); + !radonon && getPageSetting('dPraidHarder') ? turnOn('dPraidFarmFragsZ') : turnOff('dPraidFarmFragsZ'); + !radonon && getPageSetting('dPraidHarder') ? turnOn('dPraidBeforeFarmZ') : turnOff('dPraidBeforeFarmZ'); + !radonon && getPageSetting('dPraidHarder') ? turnOn('dMaxPraidZone') : turnOff('dMaxPraidZone'); + !radonon ? turnOn("Dailybwraid") : turnOff("Dailybwraid"); + !radonon && getPageSetting('Dailybwraid') == true ? turnOn("dbwraidcell") : turnOff("dbwraidcell"); + !radonon && getPageSetting('Dailybwraid') == true ? turnOn("dBWraidingz") : turnOff("dBWraidingz"); + !radonon && getPageSetting('Dailybwraid') == true ? turnOn("dBWraidingmax") : turnOff("dBWraidingmax"); + + //DWind + !radonon ? turnOn("use3daily") : turnOff("use3daily"); + !radonon ? turnOn("liqstack") : turnOff("liqstack"); + !radonon && getPageSetting('use3daily') == true ? turnOn("dwindhealthy") : turnOff("dwindhealthy"); + !radonon && getPageSetting('use3daily') == true ? turnOn("dusebstance") : turnOff("dusebstance"); + !radonon && getPageSetting('use3daily') == true ? turnOn("dWindStackingMin") : turnOff("dWindStackingMin"); + !radonon && getPageSetting('use3daily') == true ? turnOn("dWindStackingMinHD") : turnOff("dWindStackingMinHD"); + !radonon && getPageSetting('use3daily') == true ? turnOn("dWindStackingMax") : turnOff("dWindStackingMax"); + !radonon && getPageSetting('use3daily') == true ? turnOn("dwindcutoff") : turnOff("dwindcutoff"); + !radonon && getPageSetting('use3daily') == true ? turnOn("dwindcutoffmap") : turnOff("dwindcutoffmap"); + !radonon && getPageSetting('use3daily') == true ? turnOn("dwsmax") : turnOff("dwsmax"); + !radonon && getPageSetting('use3daily') == true ? turnOn("dwsmaxhd") : turnOff("dwsmaxhd"); + + //DLoom + !radonon && getPageSetting('dloomswap') > 0 ? turnOn('dloomswaphd') : turnOff('dloomswaphd'); + !radonon && getPageSetting('dloomswap') > 0 ? turnOn('dhighdmg') : turnOff('dhighdmg'); + !radonon && getPageSetting('dloomswap') > 0 ? turnOn('dlowdmg') : turnOff('dlowdmg'); + + //DPortal + !radonon ? turnOn("AutoStartDaily") : turnOff("AutoStartDaily"); + !radonon ? turnOn("u2daily") : turnOff("u2daily"); + !radonon ? turnOn("AutoPortalDaily") : turnOff("AutoPortalDaily"); + !radonon && getPageSetting('AutoPortalDaily') == 2 ? turnOn("dCustomAutoPortal") : turnOff("dCustomAutoPortal"); + !radonon && getPageSetting('AutoPortalDaily') == 1 ? turnOn("dHeHrDontPortalBefore") : turnOff("dHeHrDontPortalBefore"); + !radonon && getPageSetting('AutoPortalDaily') == 1 ? turnOn("dHeliumHrBuffer") : turnOff("dHeliumHrBuffer"); + !radonon && getPageSetting('AutoPortalDaily') > 0 ? turnOn("dHeliumHourChallenge") : turnOff("dHeliumHourChallenge"); + + //Shrine - U1 (Daily) + !radonon ? turnOn("Hdshrine") : turnOff("Hdshrine"); + (!radonon && getPageSetting('Hdshrine') == 1) ? turnOn("Hdshrinemaz") : turnOff("Hdshrinemaz"); + turnOff("Hdshrinezone"); + turnOff("Hdshrinecell"); + turnOff("Hdshrineamount"); + + + //RDaily + radonon ? turnOn("buyradony") : turnOff("buyradony"); + radonon ? turnOn("Rdscryvoidmaps") : turnOff("Rdscryvoidmaps"); + radonon ? turnOn("RdIgnoreSpiresUntil") : turnOff("RdIgnoreSpiresUntil"); + radonon ? turnOn("RDailyVoidMod") : turnOff("RDailyVoidMod"); + radonon ? turnOn("RdRunNewVoidsUntilNew") : turnOff("RdRunNewVoidsUntilNew"); + radonon ? turnOn("Ravoidempower") : turnOff("Ravoidempower"); + radonon ? turnOn("Rdfightforever") : turnOff("Rdfightforever"); + radonon ? turnOn("Rdarmormagic") : turnOff("Rdarmormagic"); + + //RDRaid + radonon ? turnOn("RdAMPraid") : turnOff("RdAMPraid"); + radonon && getPageSetting('RdAMPraid') == 1 ? turnOn("RdAMPraidmaz") : turnOff("RdAMPraidmaz"); + turnOff("RdAMPraidzone"); + turnOff("RdAMPraidraid"); + turnOff("RdAMPraidcell"); + radonon && getPageSetting('RdAMPraid') == 1 ? turnOn("RdAMPraidfrag") : turnOff("RdAMPraidfrag"); + radonon && getPageSetting('RdAMPraid') == 1 ? turnOn("RdAMPraidrecycle") : turnOff("RdAMPraidrecycle"); + + //RDTime Farm + radonon ? turnOn("Rdtimefarm") : turnOff("Rdtimefarm"); + (radonon && getPageSetting('Rdtimefarm') == 1) ? turnOn("Rdtimefarmmaz") : turnOff("Rdtimefarmmaz"); + turnOff("Rdtimefarmzone"); + turnOff("Rdtimefarmcell"); + turnOff("Rdtimefarmtime"); + turnOff("Rdtimefarmlevel"); + turnOff("Rdtimefarmmap"); + turnOff("Rdtimefarmspecial"); + turnOff("Rdtimefarmgather"); + + //RDHeirloom Swapping + radonon ? turnOn('Rdhs') : turnOff('Rdhs'); + var dhson = (getPageSetting('Rdhs') == 1); + + //RDShields + radonon && dhson ? turnOn('Rdhsshield') : turnOff('Rdhsshield'); + var dhsshieldon = (getPageSetting('Rdhsshield') == true); + radonon && dhson && dhsshieldon ? turnOn('Rdhsz') : turnOff('Rdhsz'); + radonon && dhson && dhsshieldon ? turnOn('Rdhs1') : turnOff('Rdhs1'); + radonon && dhson && dhsshieldon ? turnOn('Rdhs2') : turnOff('Rdhs2'); + + //RDStaffs + radonon && hson ? turnOn('Rdhsstaff') : turnOff('Rdhsstaff'); + var dhsstaffon = (getPageSetting('Rdhsstaff') == true); + radonon && dhson && dhsstaffon ? turnOn('Rdhsworldstaff') : turnOff('Rdhsworldstaff'); + radonon && dhson && dhsstaffon ? turnOn('Rdhsmapstaff') : turnOff('Rdhsmapstaff'); + radonon && dhson && dhsstaffon ? turnOn('Rdhstributestaff') : turnOff('Rdhstributestaff'); + + //Shrine - U2 (Daily) + radonon ? turnOn("Rdshrine") : turnOff("Rdshrine"); + (radonon && getPageSetting('Rdshrine') == 1) ? turnOn("Rdshrinemaz") : turnOff("Rdshrinemaz"); + turnOff("Rdshrinezone"); + turnOff("Rdshrinecell"); + turnOff("Rdshrineamount"); + + + //RDPortal + radonon ? turnOn("RAutoStartDaily") : turnOff("RAutoStartDaily"); + radonon ? turnOn("u1daily") : turnOff("u1daily"); + radonon ? turnOn("RAutoPortalDaily") : turnOff("RAutoPortalDaily"); + radonon && getPageSetting('RAutoPortalDaily') == 2 ? turnOn("RdCustomAutoPortal") : turnOff("RdCustomAutoPortal"); + radonon && getPageSetting('RAutoPortalDaily') == 1 ? turnOn("RdHeHrDontPortalBefore") : turnOff("RdHeHrDontPortalBefore"); + radonon && getPageSetting('RAutoPortalDaily') == 1 ? turnOn("RdHeliumHrBuffer") : turnOff("RdHeliumHrBuffer"); + radonon && getPageSetting('RAutoPortalDaily') > 0 ? turnOn("RdHeliumHourChallenge") : turnOff("RdHeliumHourChallenge"); + + + + //C2 + !radonon ? turnOn("FinishC2") : turnOff("FinishC2"); + !radonon ? turnOn("buynojobsc") : turnOff("buynojobsc"); + !radonon ? turnOn("cfightforever") : turnOff("cfightforever"); + !radonon ? turnOn("mapc2hd") : turnOff("mapc2hd"); + !radonon ? turnOn("novmsc2") : turnOff("novmsc2"); + !radonon ? turnOn("c2runnerstart") : turnOff("c2runnerstart"); + !radonon && getPageSetting('c2runnerstart') == true ? turnOn("c2runnerportal") : turnOff("c2runnerportal"); + !radonon && getPageSetting('c2runnerstart') == true ? turnOn("c2runnerpercent") : turnOff("c2runnerpercent"); + + + + //Buildings + !radonon ? turnOn("BuyBuildingsNew") : turnOff("BuyBuildingsNew"); + !radonon ? turnOn("MaxGym") : turnOff("MaxGym"); + !radonon ? turnOn("GymWall") : turnOff("GymWall"); + var fuckbuilding = (bwRewardUnlocked("AutoStructure") == true && bwRewardUnlocked("DecaBuild") && getPageSetting('hidebuildings') == true && getPageSetting('BuyBuildingsNew') == 0); + (!radonon && bwRewardUnlocked("AutoStructure") == true && bwRewardUnlocked("DecaBuild")) ? turnOn("hidebuildings") : turnOff("hidebuildings"); + (!radonon && !fuckbuilding) ? turnOn("MaxHut") : turnOff("MaxHut"); + (!radonon && !fuckbuilding) ? turnOn("MaxHouse") : turnOff("MaxHouse"); + (!radonon && !fuckbuilding) ? turnOn("MaxMansion") : turnOff("MaxMansion"); + (!radonon && !fuckbuilding) ? turnOn("MaxHotel") : turnOff("MaxHotel"); + (!radonon && !fuckbuilding) ? turnOn("MaxResort") : turnOff("MaxResort"); + (!radonon && !fuckbuilding) ? turnOn("MaxGateway") : turnOff("MaxGateway"); + (!radonon && !fuckbuilding) ? turnOn("MaxWormhole") : turnOff("MaxWormhole"); + (!radonon && !fuckbuilding) ? turnOn("MaxCollector") : turnOff("MaxCollector"); + (!radonon && !fuckbuilding) ? turnOn("MaxTribute") : turnOff("MaxTribute"); + (!radonon && !fuckbuilding) ? turnOn("MaxNursery") : turnOff("MaxNursery"); + (!radonon && !fuckbuilding) ? turnOn("NoNurseriesUntil") : turnOff("NoNurseriesUntil"); + (!radonon && !fuckbuilding) ? turnOn("NurseryWall") : turnOff("NurseryWall"); + (!radonon && !fuckbuilding) ? turnOn("WarpstationCap") : turnOff("WarpstationCap"); + (!radonon && !fuckbuilding) ? turnOn("WarpstationCoordBuy") : turnOff("WarpstationCoordBuy"); + (!radonon && !fuckbuilding) ? turnOn("FirstGigastation") : turnOff("FirstGigastation"); + (!radonon && !fuckbuilding) ? turnOn("DeltaGigastation") : turnOff("DeltaGigastation"); + (!radonon && !fuckbuilding) ? turnOn("AutoGigas") : turnOff("AutoGigas"); + (!radonon && !fuckbuilding && getPageSetting("AutoGigas") == true) ? turnOn("CustomTargetZone") : turnOff("CustomTargetZone"); + (!radonon && !fuckbuilding && getPageSetting("AutoGigas") == true) ? turnOn("CustomDeltaFactor") : turnOff("CustomDeltaFactor"); + (!radonon && !fuckbuilding) ? turnOn("WarpstationWall3") : turnOff("WarpstationWall3"); + + + //RBuildings + radonon ? turnOn("RBuyBuildingsNew") : turnOff("RBuyBuildingsNew"); + radonon ? turnOn("RMaxHut") : turnOff("RMaxHut"); + radonon ? turnOn("RMaxHouse") : turnOff("RMaxHouse"); + radonon ? turnOn("RMaxMansion") : turnOff("RMaxMansion"); + radonon ? turnOn("RMaxHotel") : turnOff("RMaxHotel"); + radonon ? turnOn("RMaxResort") : turnOff("RMaxResort"); + radonon ? turnOn("RMaxGateway") : turnOff("RMaxGateway"); + radonon ? turnOn("RMaxCollector") : turnOff("RMaxCollector"); + radonon ? turnOn("RMaxTribute") : turnOff("RMaxTribute"); + (radonon && getPageSetting('Rnurtureon') == true) ? turnOn("RMaxLabs") : turnOff("RMaxLabs"); + radonon ? turnOn("Rmeltsmithy") : turnOff("Rmeltsmithy"); + radonon ? turnOn("Rsmithylogic") : turnOff("Rsmithylogic"); + (radonon && getPageSetting('Rsmithylogic') == true) ? turnOn("Rsmithynumber") : turnOff("Rsmithynumber"); + (radonon && getPageSetting('Rsmithylogic') == true) ? turnOn("Rsmithypercent") : turnOff("Rsmithypercent"); + (radonon && getPageSetting('Rsmithylogic') == true) ? turnOn("Rsmithyseconds") : turnOff("Rsmithyseconds"); + + + + //Jobs + !radonon ? turnOn("BuyJobsNew") : turnOff("BuyJobsNew"); + !radonon ? turnOn("AutoMagmamancers") : turnOff("AutoMagmamancers"); + var fuckjobbies = (bwRewardUnlocked("AutoJobs") && getPageSetting('fuckjobs') == true && getPageSetting('BuyJobsNew') == 0); + (!radonon && bwRewardUnlocked("AutoJobs")) ? turnOn("fuckjobs") : turnOff("fuckjobs"); + (!radonon && !fuckjobbies) ? turnOn("FarmerRatio") : turnOff("FarmerRatio"); + (!radonon && !fuckjobbies) ? turnOn("LumberjackRatio") : turnOff("LumberjackRatio"); + (!radonon && !fuckjobbies) ? turnOn("MinerRatio") : turnOff("MinerRatio"); + (!radonon && !fuckjobbies) ? turnOn("MaxScientists") : turnOff("MaxScientists"); + (!radonon && !fuckjobbies) ? turnOn("MaxExplorers") : turnOff("MaxExplorers"); + (!radonon && !fuckjobbies) ? turnOn("MaxTrainers") : turnOff("MaxTrainers"); + + + //RJobs + radonon ? turnOn("RBuyJobsNew") : turnOff("RBuyJobsNew"); + radonon ? turnOn("RFarmerRatio") : turnOff("RFarmerRatio"); + radonon ? turnOn("RLumberjackRatio") : turnOff("RLumberjackRatio"); + radonon ? turnOn("RMinerRatio") : turnOff("RMinerRatio"); + radonon ? turnOn("RMaxExplorers") : turnOff("RMaxExplorers"); + radonon ? turnOn("Rshipfarmon") : turnOff("Rshipfarmon"); + (radonon && getPageSetting('Rshipfarmon') == true) ? turnOn("Rshipfarmzone") : turnOff("Rshipfarmzone"); + (radonon && getPageSetting('Rshipfarmon') == true) ? turnOn("Rshipfarmcell") : turnOff("Rshipfarmcell"); + (radonon && getPageSetting('Rshipfarmon') == true) ? turnOn("Rshipfarmamount") : turnOff("Rshipfarmamount"); + (radonon && getPageSetting('Rshipfarmon') == true) ? turnOn("Rshipfarmlevel") : turnOff("Rshipfarmlevel"); + (radonon && getPageSetting('Rshipfarmon') == true) ? turnOn("Rshipfarmfrag") : turnOff("Rshipfarmfrag"); + + + + //Gear + !radonon ? turnOn("BuyArmorNew") : turnOff("BuyArmorNew"); + !radonon ? turnOn("BuyWeaponsNew") : turnOff("BuyWeaponsNew"); + !radonon ? turnOn("CapEquip2") : turnOff("CapEquip2"); + !radonon ? turnOn("CapEquiparm") : turnOff("CapEquiparm"); + !radonon ? turnOn("dmgcuntoff") : turnOff("dmgcuntoff"); + !radonon ? turnOn("DynamicPrestige2") : turnOff("DynamicPrestige2"); + !radonon ? turnOn("Prestige") : turnOff("Prestige"); + !radonon ? turnOn("ForcePresZ") : turnOff("ForcePresZ"); + !radonon ? turnOn("PrestigeSkip1_2") : turnOff("PrestigeSkip1_2"); + !radonon ? turnOn("DelayArmorWhenNeeded") : turnOff("DelayArmorWhenNeeded"); + !radonon ? turnOn("BuyShieldblock") : turnOff("BuyShieldblock"); + !radonon ? turnOn("trimpsnotdie") : turnOff("trimpsnotdie"); + !radonon ? turnOn("gearamounttobuy") : turnOff("gearamounttobuy"); + !radonon ? turnOn("always2") : turnOff("always2"); + + + //RGear + + radonon ? turnOn("Requipon") : turnOff("Requipon"); + (radonon && getPageSetting('Requipon') == true) ? turnOn("Requipamount") : turnOff("Requipamount"); + (radonon && getPageSetting('Requipon') == true) ? turnOn("Requipcapattack") : turnOff("Requipcapattack"); + (radonon && getPageSetting('Requipon') == true) ? turnOn("Requipcaphealth") : turnOff("Requipcaphealth"); + (radonon && getPageSetting('Requipon') == true) ? turnOn("Requipzone") : turnOff("Requipzone"); + (radonon && getPageSetting('Requipon') == true) ? turnOn("Requippercent") : turnOff("Requippercent"); + (radonon && getPageSetting('Requipon') == true) ? turnOn("Requip2") : turnOff("Requip2"); + (radonon && getPageSetting('Requipon') == true) ? turnOn("Rdmgcuntoff") : turnOff("Rdmgcuntoff"); + + radonon ? turnOn("Requipfarmon") : turnOff("Requipfarmon"); + (radonon && getPageSetting('Requipfarmon') == true) ? turnOn("Requipfarmzone") : turnOff("Requipfarmzone"); + (radonon && getPageSetting('Requipfarmon') == true) ? turnOn("RequipfarmHD") : turnOff("RequipfarmHD"); + (radonon && getPageSetting('Requipfarmon') == true) ? turnOn("Requipfarmmult") : turnOff("Requipfarmmult"); + (radonon && getPageSetting('Requipfarmon') == true) ? turnOn("Requipfarmhits") : turnOff("Requipfarmhits"); + + + + //Maps + !radonon ? turnOn("AutoMaps") : turnOff("AutoMaps"); + (!radonon && getPageSetting('AutoMaps') == 2) ? turnOn("AMUblock") : turnOff("AMUblock"); + (!radonon && getPageSetting('AutoMaps') == 2) ? turnOn("AMUwall") : turnOff("AMUwall"); + (!radonon && getPageSetting('AutoMaps') == 2) ? turnOn("AMUanger") : turnOff("AMUanger"); + (!radonon && getPageSetting('AutoMaps') == 2) ? turnOn("AMUtrimple") : turnOff("AMUtrimple"); + (!radonon && getPageSetting('AutoMaps') == 2) ? turnOn("AMUprison") : turnOff("AMUprison"); + (!radonon && getPageSetting('AutoMaps') == 2) ? turnOn("AMUbw") : turnOff("AMUbw"); + (!radonon && getPageSetting('AutoMaps') == 2) ? turnOn("AMUstar") : turnOff("AMUstar"); + !radonon ? turnOn("automapsportal") : turnOff("automapsportal"); + !radonon ? turnOn("automapsalways") : turnOff("automapsalways"); + + + !radonon ? turnOn("mapselection") : turnOff("mapselection"); + !radonon ? turnOn("DynamicSiphonology") : turnOff("DynamicSiphonology"); + !radonon ? turnOn("PreferMetal") : turnOff("PreferMetal"); + !radonon ? turnOn("MaxMapBonusAfterZone") : turnOff("MaxMapBonusAfterZone"); + !radonon ? turnOn("MaxMapBonuslimit") : turnOff("MaxMapBonuslimit"); + !radonon ? turnOn("MaxMapBonushealth") : turnOff("MaxMapBonushealth"); + !radonon ? turnOn("mapcuntoff") : turnOff("mapcuntoff"); + !radonon ? turnOn("DisableFarm") : turnOff("DisableFarm"); + !radonon ? turnOn("LowerFarmingZone") : turnOff("LowerFarmingZone"); + !radonon ? turnOn("FarmWhenNomStacks7") : turnOff("FarmWhenNomStacks7"); + !radonon ? turnOn("VoidMaps") : turnOff("VoidMaps"); + !radonon ? turnOn("voidscell") : turnOff("voidscell"); + !radonon ? turnOn("RunNewVoidsUntilNew") : turnOff("RunNewVoidsUntilNew"); + !radonon ? turnOn("runnewvoidspoison") : turnOff("runnewvoidspoison"); + !radonon ? turnOn("onlystackedvoids") : turnOff("onlystackedvoids"); + !radonon ? turnOn("TrimpleZ") : turnOff("TrimpleZ"); + !radonon ? turnOn("AdvMapSpecialModifier") : turnOff("AdvMapSpecialModifier"); + !radonon ? turnOn("scryvoidmaps") : turnOff("scryvoidmaps"); + !radonon ? turnOn("buywepsvoid") : turnOff("buywepsvoid"); + !radonon ? turnOn("farmWonders") : turnOff("farmWonders"); + (!radonon && getPageSetting("farmWonders")) ? turnOn("wondersAmount") : turnOff("wondersAmount"); + (!radonon && getPageSetting("farmWonders")) ? turnOn("maxExpZone") : turnOff("maxExpZone"); + (!radonon && getPageSetting("farmWonders")) ? turnOn("finishExpOnBw") : turnOff("finishExpOnBw"); + + //Shrine - U1 + !radonon ? turnOn("Hshrine") : turnOff("Hshrine"); + (!radonon && getPageSetting('Hshrine') == true) ? turnOn("Hshrinemaz") : turnOff("Hshrinemaz"); + turnOff("Hshrinezone"); + turnOff("Hshrinecell"); + turnOff("Hshrineamount"); + turnOff("Hshrinecharge"); + + //RMaps + radonon ? turnOn("RAutoMaps") : turnOff("RAutoMaps"); + radonon ? turnOn("Rautomapsportal") : turnOff("Rautomapsportal"); + radonon ? turnOn("Rautomapsalways") : turnOff("Rautomapsalways"); + radonon ? turnOn("Rmapselection") : turnOff("Rmapselection"); + radonon ? turnOn("RMaxMapBonusAfterZone") : turnOff("RMaxMapBonusAfterZone"); + radonon ? turnOn("RMaxMapBonuslimit") : turnOff("RMaxMapBonuslimit"); + radonon ? turnOn("RMaxMapBonushealth") : turnOff("RMaxMapBonushealth"); + radonon ? turnOn("Rhitssurvived") : turnOff("Rhitssurvived"); + radonon ? turnOn("Rmapcuntoff") : turnOff("Rmapcuntoff"); + radonon ? turnOn("RDisableFarm") : turnOff("RDisableFarm"); + + radonon ? turnOn("Rtimefarm") : turnOff("Rtimefarm"); + (radonon && getPageSetting('Rtimefarm') == true) ? turnOn("Rtimefarmmaz") : turnOff("Rtimefarmmaz"); + turnOff("Rtimefarmzone"); + turnOff("Rtimefarmcell"); + turnOff("Rtimefarmtime"); + turnOff("Rtimefarmlevel"); + turnOff("Rtimefarmmap"); + turnOff("Rtimefarmspecial"); + turnOff("Rtimefarmgather"); + + radonon ? turnOn("Rsmithyfarm") : turnOff("Rsmithyfarm"); + (radonon && getPageSetting('Rsmithyfarm') == true) ? turnOn("Rsmithyfarmmaz") : turnOff("Rsmithyfarmmaz"); + turnOff("Rsmithyfarmzone"); + turnOff("Rsmithyfarmcell"); + turnOff("Rsmithyfarmamount"); + + radonon ? turnOn("Rtributefarm") : turnOff("Rtributefarm"); + (radonon && getPageSetting('Rtributefarm') == true) ? turnOn("Rtributefarmmaz") : turnOff("Rtributefarmmaz"); + turnOff("Rtributefarmzone"); + turnOff("Rtributefarmcell"); + turnOff("Rtributefarmamount"); + turnOff("Rtributefarmlevel"); + turnOff("Rtributemapselection"); + turnOff("Rtributespecialselection"); + turnOff("Rtributegatherselection"); + + // Shrine - U2 + radonon ? turnOn("Rshrine") : turnOff("Rshrine"); + (radonon && getPageSetting('Rshrine') == true) ? turnOn("Rshrinemaz") : turnOff("Rshrinemaz"); + turnOff("Rshrinezone"); + turnOff("Rshrinecell"); + turnOff("Rshrineamount"); + turnOff("Rshrinecharge"); + + radonon ? turnOn("RVoidMaps") : turnOff("RVoidMaps"); + radonon ? turnOn("Rvoidscell") : turnOff("Rvoidscell"); + radonon ? turnOn("RRunNewVoidsUntilNew") : turnOff("RRunNewVoidsUntilNew"); + radonon ? turnOn("Rprispalace") : turnOff("Rprispalace"); + radonon ? turnOn("Rmeltpoint") : turnOff("Rmeltpoint"); + radonon ? turnOn("Rfrozencastle") : turnOff("Rfrozencastle"); + + //Spire + !radonon ? turnOn("MaxStacksForSpire") : turnOff("MaxStacksForSpire"); + !radonon ? turnOn("MinutestoFarmBeforeSpire") : turnOff("MinutestoFarmBeforeSpire"); + !radonon ? turnOn("IgnoreSpiresUntil") : turnOff("IgnoreSpiresUntil"); + !radonon ? turnOn("ExitSpireCell") : turnOff("ExitSpireCell"); + !radonon ? turnOn("SpireBreedTimer") : turnOff("SpireBreedTimer"); + !radonon ? turnOn("PreSpireNurseries") : turnOff("PreSpireNurseries"); + !radonon ? turnOn("spireshitbuy") : turnOff("spireshitbuy"); + !radonon ? turnOn("SkipSpires") : turnOff("SkipSpires"); + + + + //Raiding + !radonon ? turnOn("Praidingzone") : turnOff("Praidingzone"); + !radonon ? turnOn("Praidingcell") : turnOff("Praidingcell"); + !radonon ? turnOn("PraidingHD") : turnOff("PraidingHD"); + !radonon ? turnOn("PraidingP") : turnOff("PraidingP"); + !radonon ? turnOn("PraidingI") : turnOff("PraidingI"); + !radonon && getPageSetting('Praidingzone') != -1 ? turnOn('PraidHarder') : turnOff('PraidHarder'); + !radonon && getPageSetting('PraidHarder') ? turnOn('PraidFarmFragsZ') : turnOff('PraidFarmFragsZ'); + !radonon && getPageSetting('PraidHarder') ? turnOn('PraidBeforeFarmZ') : turnOff('PraidBeforeFarmZ'); + !radonon && getPageSetting('PraidHarder') ? turnOn('MaxPraidZone') : turnOff('MaxPraidZone'); + !radonon ? turnOn("BWraid") : turnOff("BWraid"); + !radonon && getPageSetting('BWraid') == true ? turnOn("bwraidcell") : turnOff("bwraidcell"); + !radonon && getPageSetting('BWraid') == true ? turnOn("BWraidingz") : turnOff("BWraidingz"); + !radonon && getPageSetting('BWraid') == true ? turnOn("BWraidingmax") : turnOff("BWraidingmax"); + + //RPraiding + radonon ? turnOn("RAMPraid") : turnOff("RAMPraid"); + radonon && getPageSetting('RAMPraid') == true ? turnOn("RAMPraidmaz") : turnOff("RAMPraidmaz"); + turnOff("RAMPraidzone"); + turnOff("RAMPraidraid"); + turnOff("RAMPraidcell"); + radonon && getPageSetting('RAMPraid') == true ? turnOn("RAMPraidfrag") : turnOff("RAMPraidfrag"); + radonon && getPageSetting('RAMPraid') == true ? turnOn("RAMPraidrecycle") : turnOff("RAMPraidrecycle"); + + + + //Windstacking + var wson = (getPageSetting('AutoStance') == 3); + (!radonon && !wson) ? turnOn("turnwson") : turnOff("turnwson"); + (!radonon && wson) ? turnOn("windhealthy") : turnOff("windhealthy"); + (!radonon && wson) ? turnOn("usebstance") : turnOff("usebstance"); + (!radonon && wson) ? turnOn("WindStackingMin") : turnOff("WindStackingMin"); + (!radonon && wson) ? turnOn("WindStackingMinHD") : turnOff("WindStackingMinHD"); + (!radonon && wson) ? turnOn("WindStackingMax") : turnOff("WindStackingMax"); + (!radonon && wson) ? turnOn("windcutoff") : turnOff("windcutoff"); + (!radonon && wson) ? turnOn("windcutoffmap") : turnOff("windcutoffmap"); + (!radonon && wson) ? turnOn("wsmax") : turnOff("wsmax"); + (!radonon && wson) ? turnOn("wsmaxhd") : turnOff("wsmaxhd"); + + + //ATGA + !radonon ? turnOn("ATGA2") : turnOff("ATGA2"); + !radonon && getPageSetting('ATGA2') == true ? turnOn("ATGA2timer") : turnOff("ATGA2timer"); + !radonon && getPageSetting('ATGA2') == true ? turnOn("ATGA2gen") : turnOff("ATGA2gen"); + var ATGAon = (getPageSetting('ATGA2') == true && getPageSetting('ATGA2timer') > 0); + (!radonon && ATGAon) ? turnOn("zATGA2timer") : turnOff("zATGA2timer"); + (!radonon && ATGAon && getPageSetting('zATGA2timer') > 0) ? turnOn("ztATGA2timer") : turnOff("ztATGA2timer"); + (!radonon && ATGAon) ? turnOn("ATGA2timerz") : turnOff("ATGA2timerz"); + (!radonon && ATGAon && getPageSetting('ATGA2timerz') > 0) ? turnOn("ATGA2timerzt") : turnOff("ATGA2timerzt"); + (!radonon && ATGAon) ? turnOn("sATGA2timer") : turnOff("sATGA2timer"); + (!radonon && ATGAon) ? turnOn("dsATGA2timer") : turnOff("dsATGA2timer"); + (!radonon && ATGAon) ? turnOn("dATGA2timer") : turnOff("dATGA2timer"); + (!radonon && ATGAon) ? turnOn("dhATGA2timer") : turnOff("dhATGA2timer"); + (!radonon && ATGAon) ? turnOn("cATGA2timer") : turnOff("cATGA2timer"); + (!radonon && ATGAon) ? turnOn("chATGA2timer") : turnOff("chATGA2timer"); + (!radonon && ATGAon) ? turnOn("dATGA2Auto") : turnOff("dATGA2Auto"); + + + + //Combat + !radonon ? turnOn("AutoStance") : turnOff("AutoStance"); + !radonon ? turnOn("AutoStanceNew") : turnOff("AutoStanceNew"); + !radonon ? turnOn("DynamicGyms") : turnOff("DynamicGyms"); + !radonon ? turnOn("AutoRoboTrimp") : turnOff("AutoRoboTrimp"); + !radonon ? turnOn("fightforever") : turnOff("fightforever"); + !radonon ? turnOn("addpoison") : turnOff("addpoison"); + !radonon ? turnOn("fullice") : turnOff("fullice"); + !radonon ? turnOn("45stacks") : turnOff("45stacks"); + !radonon ? turnOn("ForceAbandon") : turnOff("ForceAbandon"); + !radonon && getPageSetting('AutoStance') != 3 ? turnOn("IgnoreCrits") : turnOff("IgnoreCrits"); + + + //RCombat + radonon ? turnOn("Rfightforever") : turnOff("Rfightforever"); + radonon ? turnOn("Rcalcmaxequality") : turnOff("Rcalcmaxequality"); + radonon ? turnOn("Rmanageequality") : turnOff("Rmanageequality"); + radonon ? turnOn("Rcalcfrenzy") : turnOff("Rcalcfrenzy"); + radonon ? turnOn("Rmutecalc") : turnOff("Rmutecalc"); + + + + //Challenges + + //Quagmire + radonon ? turnOn("Rblackbog") : turnOff("Rblackbog"); + (radonon && getPageSetting('Rblackbog') == true) ? turnOn("Rblackbogmaz") : turnOff("Rblackbogmaz"); + turnOff("Rblackbogzone"); + turnOff("Rblackbogamount"); + + //Arch + radonon ? turnOn("Rarchon") : turnOff("Rarchon"); + radonon && getPageSetting('Rarchon') == true ? turnOn("Rarchstring1") : turnOff("Rarchstring1"); + radonon && getPageSetting('Rarchon') == true ? turnOn("Rarchstring2") : turnOff("Rarchstring2"); + radonon && getPageSetting('Rarchon') == true ? turnOn("Rarchstring3") : turnOff("Rarchstring3"); + + //Mayhem + radonon ? turnOn("Rmayhemon") : turnOff("Rmayhemon"); + radonon && getPageSetting('Rmayhemon') == true ? turnOn("Rmayhemattack") : turnOff("Rmayhemattack"); + radonon && getPageSetting('Rmayhemon') == true ? turnOn("Rmayhemhealth") : turnOff("Rmayhemhealth"); + radonon && getPageSetting('Rmayhemon') == true ? turnOn("Rmayhemabcut") : turnOff("Rmayhemabcut"); + radonon && getPageSetting('Rmayhemon') == true ? turnOn("Rmayhemamcut") : turnOff("Rmayhemamcut"); + radonon && getPageSetting('Rmayhemon') == true ? turnOn("Rmayhemhcut") : turnOff("Rmayhemhcut"); + radonon && getPageSetting('Rmayhemon') == true ? turnOn("Rmayhemmap") : turnOff("Rmayhemmap"); + + //Storm + radonon ? turnOn("Rstormon") : turnOff("Rstormon"); + radonon && getPageSetting('Rstormon') == true ? turnOn("Rstormzone") : turnOff("Rstormzone"); + radonon && getPageSetting('Rstormon') == true ? turnOn("RstormHD") : turnOff("RstormHD"); + radonon && getPageSetting('Rstormon') == true ? turnOn("Rstormmult") : turnOff("Rstormmult"); + + //Insanity + radonon ? turnOn("Rinsanityon") : turnOff("Rinsanityon"); + radonon && getPageSetting('Rinsanityon') == true ? turnOn("Rinsanitymaz") : turnOff("Rinsanitymaz"); + turnOff("Rinsanityfarmzone"); + turnOff("Rinsanityfarmcell"); + turnOff("Rinsanityfarmstack"); + turnOff("Rinsanityfarmlevel"); + radonon && getPageSetting('Rinsanityon') == true ? turnOn("Rinsanityfarmfrag") : turnOff("Rinsanityfarmfrag"); + + //Exterminate + radonon ? turnOn("Rexterminateon") : turnOff("Rexterminateon"); + radonon && getPageSetting('Rexterminateon') == true ? turnOn("Rexterminatecalc") : turnOff("Rexterminatecalc"); + radonon && getPageSetting('Rexterminateon') == true ? turnOn("Rexterminateeq") : turnOff("Rexterminateeq"); + + //Nurture + radonon ? turnOn("Rnurtureon") : turnOff("Rnurtureon"); + + //Panda + radonon ? turnOn("Rpandaon") : turnOff("Rpandaon"); + radonon && getPageSetting('Rpandaon') == true ? turnOn("Rpandamaps") : turnOff("Rpandamaps"); + radonon && getPageSetting('Rpandaon') == true ? turnOn("Rpandazone") : turnOff("Rpandazone"); + radonon && getPageSetting('Rpandaon') == true ? turnOn("Rpandahits") : turnOff("Rpandahits"); + + //Alch + radonon ? turnOn("Ralchon") : turnOff("Ralchon"); + radonon && getPageSetting('Ralchon') == true ? turnOn("Ralchfarmmaz") : turnOff("Ralchfarmmaz"); + turnOff("Ralchfarmzone"); + turnOff("Ralchfarmcell"); + turnOff("Ralchfarmstack"); + turnOff("Ralchfarmlevel"); + turnOff("Ralchfarmselection"); + radonon && getPageSetting('Ralchon') == true ? turnOn("Ralchfarmfrag") : turnOff("Ralchfarmfrag"); + + //Hypo + radonon ? turnOn("Rhypoon") : turnOff("Rhypoon"); + radonon && getPageSetting('Rhypoon') == true ? turnOn("Rhypofarmmaz") : turnOff("Rhypofarmmaz"); + turnOff("Rhypofarmzone"); + turnOff("Rhypofarmcell"); + turnOff("Rhypofarmstack"); + turnOff("Rhypofarmlevel"); + radonon && getPageSetting('Rhypoon') == true ? turnOn("Rhypofarmfrag") : turnOff("Rhypofarmfrag"); + radonon && getPageSetting('Rhypoon') == true ? turnOn("Rhypocastle") : turnOff("Rhypocastle"); + radonon && getPageSetting('Rhypoon') == true ? turnOn("Rhypovoids") : turnOff("Rhypovoids"); + radonon && getPageSetting('Rhypoon') == true ? turnOn("Rhypostorage") : turnOff("Rhypostorage"); + + //Desolation + radonon ? turnOn("Rdesoon") : turnOff("Rdesoon"); + radonon && getPageSetting('Rdesoon') == true ? turnOn("Rdesozone") : turnOff("Rdesozone"); + radonon && getPageSetting('Rdesoon') == true ? turnOn("RdesoHD") : turnOff("RdesoHD"); + radonon && getPageSetting('Rdesoon') == true ? turnOn("Rdesomult") : turnOff("Rdesomult"); + + //Hide Challenges + radonon ? turnOn("Rchallengehide") : turnOff("Rchallengehide"); + radonon && getPageSetting('Rchallengehide') == true ? turnOn("Rchallengehidequag") : turnOff("Rchallengehidequag"); + radonon && getPageSetting('Rchallengehide') == true ? turnOn("Rchallengehidearch") : turnOff("Rchallengehidearch"); + radonon && getPageSetting('Rchallengehide') == true ? turnOn("Rchallengehidemayhem") : turnOff("Rchallengehidemayhem"); + radonon && getPageSetting('Rchallengehide') == true ? turnOn("Rchallengehidestorm") : turnOff("Rchallengehidestorm"); + radonon && getPageSetting('Rchallengehide') == true ? turnOn("Rchallengehideinsanity") : turnOff("Rchallengehideinsanity"); + radonon && getPageSetting('Rchallengehide') == true ? turnOn("Rchallengehideexterminate") : turnOff("Rchallengehideexterminate"); + radonon && getPageSetting('Rchallengehide') == true ? turnOn("Rchallengehidenurture") : turnOff("Rchallengehidenurture"); + radonon && getPageSetting('Rchallengehide') == true ? turnOn("Rchallengehidepanda") : turnOff("Rchallengehidepanda"); + radonon && getPageSetting('Rchallengehide') == true ? turnOn("Rchallengehidealchemy") : turnOff("Rchallengehidealchemy"); + radonon && getPageSetting('Rchallengehide') == true ? turnOn("Rchallengehidehypothermia") : turnOff("Rchallengehidehypothermia"); + radonon && getPageSetting('Rchallengehide') == true ? turnOn("Rchallengehidedeso") : turnOff("Rchallengehidedeso"); + + if (getPageSetting('Rchallengehidequag') == true) { + turnOff("Rblackbog"); + turnOff("Rblackbogmaz"); + turnOff("Rblackbogzone"); + turnOff("Rblackbogamount"); + } + if (getPageSetting('Rchallengehidearch') == true) { + turnOff("Rarchon"); + turnOff("Rarchstring1"); + turnOff("Rarchstring2"); + turnOff("Rarchstring3"); + } + if (getPageSetting('Rchallengehidemayhem') == true) { + turnOff("Rmayhemon"); + turnOff("Rmayhemattack"); + turnOff("Rmayhemhealth"); + turnOff("Rmayhemabcut"); + turnOff("Rmayhemamcut"); + turnOff("Rmayhemhcut"); + turnOff("Rmayhemmap"); + } + if (getPageSetting('Rchallengehidestorm') == true) { + turnOff("Rstormon"); + turnOff("Rstormzone"); + turnOff("RstormHD"); + turnOff("Rstormmult"); + } + if (getPageSetting('Rchallengehideinsanity') == true) { + turnOff("Rinsanityon"); + turnOff("Rinsanitymaz"); + turnOff("Rinsanityfarmzone"); + turnOff("Rinsanityfarmcell"); + turnOff("Rinsanityfarmstack"); + turnOff("Rinsanityfarmlevel"); + turnOff("Rinsanityfarmfrag"); + } + if (getPageSetting('Rchallengehideexterminate') == true) { + turnOff("Rexterminateon"); + turnOff("Rexterminatecalc"); + turnOff("Rexterminateeq"); + } + if (getPageSetting('Rchallengehidenurture') == true) { + turnOff("Rnurtureon"); + } + if (getPageSetting('Rchallengehidepanda') == true) { + turnOff("Rpandaon"); + turnOff("Rpandamaps"); + turnOff("Rpandazone"); + turnOff("Rpandahits"); + } + if (getPageSetting('Rchallengehidealchemy') == true) { + turnOff("Ralchon"); + turnOff("Ralchfarmmaz"); + turnOff("Ralchfarmzone"); + turnOff("Ralchfarmcell"); + turnOff("Ralchfarmstack"); + turnOff("Ralchfarmlevel"); + turnOff("Ralchfarmselection"); + turnOff("Ralchfarmfrag"); + } + if (getPageSetting('Rchallengehidehypothermia') == true) { + turnOff("Rhypoon"); + turnOff("Rhypofarmmaz"); + turnOff("Rhypofarmzone"); + turnOff("Rhypofarmcell"); + turnOff("Rhypofarmstack"); + turnOff("Rhypofarmlevel"); + turnOff("Rhypofarmfrag"); + turnOff("Rhypocastle"); + turnOff("Rhypovoids"); + turnOff("Rhypostorage"); + } + + if (getPageSetting('Rchallengehidedeso') == true) { + turnOff("Rdesoon"); + turnOff("Rdesozone"); + turnOff("RdesoHD"); + turnOff("Rdesomult"); + } + + + + //Scryer + !radonon ? turnOn("UseScryerStance") : turnOff("UseScryerStance"); + !radonon ? turnOn("ScryerUseWhenOverkill") : turnOff("ScryerUseWhenOverkill"); + !radonon ? turnOn("ScryerMinZone") : turnOff("ScryerMinZone"); + !radonon ? turnOn("ScryerMaxZone") : turnOff("ScryerMaxZone"); + !radonon ? turnOn("onlyminmaxworld") : turnOff("onlyminmaxworld"); + !radonon ? turnOn("ScryerUseinMaps2") : turnOff("ScryerUseinMaps2"); + !radonon ? turnOn("ScryerUseinVoidMaps2") : turnOff("ScryerUseinVoidMaps2"); + !radonon ? turnOn("ScryerUseinPMaps") : turnOff("ScryerUseinPMaps"); + !radonon ? turnOn("ScryerUseinBW") : turnOff("ScryerUseinBW"); + !radonon ? turnOn("ScryerUseinSpire2") : turnOff("ScryerUseinSpire2"); + !radonon ? turnOn("ScryerSkipBoss2") : turnOff("ScryerSkipBoss2"); + !radonon ? turnOn("ScryerSkipCorrupteds2") : turnOff("ScryerSkipCorrupteds2"); + !radonon ? turnOn("ScryerSkipHealthy") : turnOff("ScryerSkipHealthy"); + !radonon ? turnOn("ScryUseinPoison") : turnOff("ScryUseinPoison"); + !radonon ? turnOn("ScryUseinWind") : turnOff("ScryUseinWind"); + !radonon ? turnOn("ScryUseinIce") : turnOff("ScryUseinIce"); + !radonon ? turnOn("ScryerDieZ") : turnOff("ScryerDieZ"); + !radonon ? turnOn("screwessence") : turnOff("screwessence"); + + + //Magma + !radonon ? turnOn("UseAutoGen") : turnOff("UseAutoGen"); + !radonon ? turnOn("beforegen") : turnOff("beforegen"); + !radonon ? turnOn("fuellater") : turnOff("fuellater"); + !radonon ? turnOn("fuelend") : turnOff("fuelend"); + !radonon ? turnOn("defaultgen") : turnOff("defaultgen"); + !radonon ? turnOn("AutoGenDC") : turnOff("AutoGenDC"); + !radonon ? turnOn("AutoGenC2") : turnOff("AutoGenC2"); + !radonon ? turnOn("spendmagmite") : turnOff("spendmagmite"); + !radonon ? turnOn("ratiospend") : turnOff("ratiospend"); + var ratiospend = getPageSetting('ratiospend'); + (!radonon && !ratiospend) ? turnOn("SupplyWall") : turnOff("SupplyWall"); + (!radonon && !ratiospend) ? turnOn("spendmagmitesetting") : turnOff("spendmagmitesetting"); + (!radonon && !ratiospend) ? turnOn("MagmiteExplain") : turnOff("MagmiteExplain"); + (!radonon && ratiospend) ? turnOn("effratio") : turnOff("effratio"); + (!radonon && ratiospend) ? turnOn("capratio") : turnOff("capratio"); + (!radonon && ratiospend) ? turnOn("supratio") : turnOff("supratio"); + (!radonon && ratiospend) ? turnOn("ocratio") : turnOff("ocratio"); + + + //Golden + !radonon ? turnOn("AutoGoldenUpgrades") : turnOff("AutoGoldenUpgrades"); + !radonon ? turnOn("dAutoGoldenUpgrades") : turnOff("dAutoGoldenUpgrades"); + !radonon ? turnOn("cAutoGoldenUpgrades") : turnOff("cAutoGoldenUpgrades"); + !radonon && getPageSetting('AutoGoldenUpgrades') == "Void" ? turnOn('voidheliumbattle') : turnOff('voidheliumbattle'); + !radonon && getPageSetting('dAutoGoldenUpgrades') == "Void" ? turnOn('dvoidheliumbattle') : turnOff('dvoidheliumbattle'); + !radonon && getPageSetting('AutoGoldenUpgrades') == "Helium" ? turnOn('radonbattle') : turnOff('radonbattle'); + !radonon && getPageSetting('dAutoGoldenUpgrades') == "Helium" ? turnOn('dradonbattle') : turnOff('dradonbattle'); + !radonon && getPageSetting('AutoGoldenUpgrades') == "Battle" ? turnOn('battleradon') : turnOff('battleradon'); + !radonon && getPageSetting('dAutoGoldenUpgrades') == "Battle" ? turnOn('dbattleradon') : turnOff('dbattleradon'); + + //RGolden + radonon ? turnOn("RAutoGoldenUpgrades") : turnOff("RAutoGoldenUpgrades"); + radonon ? turnOn("RdAutoGoldenUpgrades") : turnOff("RdAutoGoldenUpgrades"); + radonon ? turnOn("RcAutoGoldenUpgrades") : turnOff("RcAutoGoldenUpgrades"); + radonon && getPageSetting('RAutoGoldenUpgrades') == "Void" ? turnOn('Rvoidheliumbattle') : turnOff('Rvoidheliumbattle'); + radonon && getPageSetting('RdAutoGoldenUpgrades') == "Void" ? turnOn('Rdvoidheliumbattle') : turnOff('Rdvoidheliumbattle'); + radonon && getPageSetting('RAutoGoldenUpgrades') == "Radon" ? turnOn('Rradonbattle') : turnOff('Rradonbattle'); + radonon && getPageSetting('RdAutoGoldenUpgrades') == "Radon" ? turnOn('Rdradonbattle') : turnOff('Rdradonbattle'); + radonon && getPageSetting('RAutoGoldenUpgrades') == "Battle" ? turnOn('Rbattleradon') : turnOff('Rbattleradon'); + radonon && getPageSetting('RdAutoGoldenUpgrades') == "Battle" ? turnOn('Rdbattleradon') : turnOff('Rdbattleradon'); + + + //AB + radonon ? turnOn("RAB") : turnOff("RAB"); + radonon && getPageSetting('RAB') == true ? turnOn("RABpreset") : turnOff("RABpreset"); + radonon && getPageSetting('RAB') == true ? turnOn("RABdustsimple") : turnOff("RABdustsimple"); + radonon && getPageSetting('RAB') == true ? turnOn("RABfarm") : turnOff("RABfarm"); + radonon && getPageSetting('RAB') == true ? turnOn("RABfarmswitch") : turnOff("RABfarmswitch"); + radonon && getPageSetting('RAB') == true ? turnOn("RABfarmstring") : turnOff("RABfarmstring"); + radonon && getPageSetting('RAB') == true ? turnOn("RABfarmsolve") : turnOff("RABfarmsolve"); + + + //Nature + !radonon ? turnOn("AutoNatureTokens") : turnOff("AutoNatureTokens"); + !radonon && getPageSetting('AutoNatureTokens') == true ? turnOn("tokenthresh") : turnOff("tokenthresh"); + !radonon && getPageSetting('AutoNatureTokens') == true ? turnOn("AutoPoison") : turnOff("AutoPoison"); + !radonon && getPageSetting('AutoNatureTokens') == true ? turnOn("AutoWind") : turnOff("AutoWind"); + !radonon && getPageSetting('AutoNatureTokens') == true ? turnOn("AutoIce") : turnOff("AutoIce"); + + + //Enlight + !radonon ? turnOn("autoenlight") : turnOff("autoenlight"); + !radonon && getPageSetting('autoenlight') == true ? turnOn("pfillerenlightthresh") : turnOff("pfillerenlightthresh"); + !radonon && getPageSetting('autoenlight') == true ? turnOn("wfillerenlightthresh") : turnOff("wfillerenlightthresh"); + !radonon && getPageSetting('autoenlight') == true ? turnOn("ifillerenlightthresh") : turnOff("ifillerenlightthresh"); + !radonon && getPageSetting('autoenlight') == true ? turnOn("pdailyenlightthresh") : turnOff("pdailyenlightthresh"); + !radonon && getPageSetting('autoenlight') == true ? turnOn("wdailyenlightthresh") : turnOff("wdailyenlightthresh"); + !radonon && getPageSetting('autoenlight') == true ? turnOn("idailyenlightthresh") : turnOff("idailyenlightthresh"); + !radonon && getPageSetting('autoenlight') == true ? turnOn("pc2enlightthresh") : turnOff("pc2enlightthresh"); + !radonon && getPageSetting('autoenlight') == true ? turnOn("wc2enlightthresh") : turnOff("wc2enlightthresh"); + !radonon && getPageSetting('autoenlight') == true ? turnOn("ic2enlightthresh") : turnOff("ic2enlightthresh"); + + + //Display + (game.worldUnlocks.easterEgg.locked == false) ? turnOn('AutoEggs') : turnOff('AutoEggs'); + turnOff("zonetracker"); + + + //Memory + if (getPageSetting('showbreedtimer') == false) turnOff("hiddenBreedTimer"); + if (getPageSetting('showautomapstatus') == false) turnOff("autoMapStatus"); + !radonon ? turnOn("showautomapstatus") : turnOff("showautomapstatus"); + radonon ? turnOn("Rshowautomapstatus") : turnOff("Rshowautomapstatus"); + + + //Heirloom Swapping + radonon ? turnOn('Rhs') : turnOff('Rhs'); + var hson = (getPageSetting('Rhs') == true); + + //Shields + radonon && hson ? turnOn('Rhsshield') : turnOff('Rhsshield'); + var hsshieldon = (getPageSetting('Rhsshield') == true); + radonon && hson && hsshieldon ? turnOn('Rhsz') : turnOff('Rhsz'); + radonon && hson && hsshieldon ? turnOn('Rhs1') : turnOff('Rhs1'); + radonon && hson && hsshieldon ? turnOn('Rhs2') : turnOff('Rhs2'); + + //Staffs + radonon && hson ? turnOn('Rhsstaff') : turnOff('Rhsstaff'); + var hsstaffon = (getPageSetting('Rhsstaff') == true); + radonon && hson && hsstaffon ? turnOn('Rhsworldstaff') : turnOff('Rhsworldstaff'); + radonon && hson && hsstaffon ? turnOn('Rhsmapstaff') : turnOff('Rhsmapstaff'); + radonon && hson && hsstaffon ? turnOn('Rhstributestaff') : turnOff('Rhstributestaff'); + + var autoheirloomenable = (getPageSetting('autoheirlooms') == true); + var keepshieldenable = (autoheirloomenable && getPageSetting('keepshields') == true); + var keepstaffenable = (autoheirloomenable && getPageSetting('keepstaffs') == true); + var keepcoreenable = (autoheirloomenable && getPageSetting('keepcores') == true); + + (autoheirloomenable) ? turnOn('typetokeep') : turnOff('typetokeep'); + (autoheirloomenable) ? turnOn('raretokeep') : turnOff('raretokeep'); + (autoheirloomenable) ? turnOn('keepshields') : turnOff('keepshields'); + (autoheirloomenable) ? turnOn('keepstaffs') : turnOff('keepstaffs'); + + (keepshieldenable) ? turnOn('slot1modsh') : turnOff('slot1modsh'); + (keepshieldenable) ? turnOn('slot2modsh') : turnOff('slot2modsh'); + (keepshieldenable) ? turnOn('slot3modsh') : turnOff('slot3modsh'); + (keepshieldenable) ? turnOn('slot4modsh') : turnOff('slot4modsh'); + (keepshieldenable) ? turnOn('slot5modsh') : turnOff('slot5modsh'); + (keepshieldenable) ? turnOn('slot6modsh') : turnOff('slot6modsh'); + (keepshieldenable) ? turnOn('slot7modsh') : turnOff('slot7modsh'); + + (keepstaffenable) ? turnOn('slot1modst') : turnOff('slot1modst'); + (keepstaffenable) ? turnOn('slot2modst') : turnOff('slot2modst'); + (keepstaffenable) ? turnOn('slot3modst') : turnOff('slot3modst'); + (keepstaffenable) ? turnOn('slot4modst') : turnOff('slot4modst'); + (keepstaffenable) ? turnOn('slot5modst') : turnOff('slot5modst'); + (keepstaffenable) ? turnOn('slot6modst') : turnOff('slot6modst'); + (keepstaffenable) ? turnOn('slot7modst') : turnOff('slot7modst'); + + (keepcoreenable) ? turnOn('slot1modcr') : turnOff('slot1modcr'); + (keepcoreenable) ? turnOn('slot2modcr') : turnOff('slot2modcr'); + (keepcoreenable) ? turnOn('slot3modcr') : turnOff('slot3modcr'); + (keepcoreenable) ? turnOn('slot4modcr') : turnOff('slot4modcr'); + + + //Dropdowns document.getElementById('AutoPortal').value = autoTrimpSettings.AutoPortal.selected; document.getElementById('HeliumHourChallenge').value = autoTrimpSettings.HeliumHourChallenge.selected; + document.getElementById('RAutoPortal').value = autoTrimpSettings.RAutoPortal.selected; + document.getElementById('RadonHourChallenge').value = autoTrimpSettings.RadonHourChallenge.selected; + document.getElementById('dHeliumHourChallenge').value = autoTrimpSettings.dHeliumHourChallenge.selected; + document.getElementById('RdHeliumHourChallenge').value = autoTrimpSettings.RdHeliumHourChallenge.selected; + document.getElementById('mapselection').value = autoTrimpSettings.mapselection.selected; + document.getElementById('Rmapselection').value = autoTrimpSettings.Rmapselection.selected; + document.getElementById('Prestige').value = autoTrimpSettings.Prestige.selected; document.getElementById('AutoGoldenUpgrades').value = autoTrimpSettings.AutoGoldenUpgrades.selected; + document.getElementById('dAutoGoldenUpgrades').value = autoTrimpSettings.dAutoGoldenUpgrades.selected; + document.getElementById('cAutoGoldenUpgrades').value = autoTrimpSettings.cAutoGoldenUpgrades.selected; + document.getElementById('RAutoGoldenUpgrades').value = autoTrimpSettings.RAutoGoldenUpgrades.selected; + document.getElementById('RdAutoGoldenUpgrades').value = autoTrimpSettings.RdAutoGoldenUpgrades.selected; + document.getElementById('RcAutoGoldenUpgrades').value = autoTrimpSettings.RcAutoGoldenUpgrades.selected; document.getElementById('AutoPoison').value = autoTrimpSettings.AutoPoison.selected; document.getElementById('AutoWind').value = autoTrimpSettings.AutoWind.selected; document.getElementById('AutoIce').value = autoTrimpSettings.AutoIce.selected; - //DerSkagg Mod: Golden Upgrade Settings. (Toggles relevant ones on/off) - if (autoTrimpSettings.AutoGoldenUpgrades.selected == "Void") { - turnOn("goldStrat"); - document.getElementById('goldStrat').value = autoTrimpSettings.goldStrat.selected; - if (autoTrimpSettings.goldStrat.selected == "Alternating") { - document.getElementById('goldAlternating').value = autoTrimpSettings.goldAlternating.selected; - turnOn("goldAlternating") - } else - turnOff("goldAlternating"); - (autoTrimpSettings.goldStrat.selected == "Zone") ? turnOn("goldZone") : turnOff("goldZone"); - (autoTrimpSettings.goldStrat.selected != "Off") ? turnOn("goldNoBattle") : turnOn("goldNoBattle"); - } else { - turnOff("goldStrat"); - turnOff("goldAlternating"); - turnOff("goldZone"); - turnOff("goldNoBattle"); - } - //document.getElementById('Prestige').value = autoTrimpSettings.Prestige.selected; //dont update this, dynamic prestige takes it over and is handled elsewhere. - //stop disable farming from needing a refresh - if (getPageSetting('DisableFarm')) + //Heirloom dropdowns + document.getElementById('raretokeep').value = autoTrimpSettings.raretokeep.selected; + document.getElementById('slot1modsh').value = autoTrimpSettings.slot1modsh.selected; + document.getElementById('slot2modsh').value = autoTrimpSettings.slot2modsh.selected; + document.getElementById('slot3modsh').value = autoTrimpSettings.slot3modsh.selected; + document.getElementById('slot4modsh').value = autoTrimpSettings.slot4modsh.selected; + document.getElementById('slot5modsh').value = autoTrimpSettings.slot5modsh.selected; + document.getElementById('slot6modsh').value = autoTrimpSettings.slot6modsh.selected; + document.getElementById('slot7modsh').value = autoTrimpSettings.slot7modsh.selected; + document.getElementById('slot1modst').value = autoTrimpSettings.slot1modst.selected; + document.getElementById('slot2modst').value = autoTrimpSettings.slot2modst.selected; + document.getElementById('slot3modst').value = autoTrimpSettings.slot3modst.selected; + document.getElementById('slot4modst').value = autoTrimpSettings.slot4modst.selected; + document.getElementById('slot5modst').value = autoTrimpSettings.slot5modst.selected; + document.getElementById('slot6modst').value = autoTrimpSettings.slot6modst.selected; + document.getElementById('slot7modst').value = autoTrimpSettings.slot7modst.selected; + document.getElementById('slot1modcr').value = autoTrimpSettings.slot1modcr.selected; + document.getElementById('slot2modcr').value = autoTrimpSettings.slot2modcr.selected; + document.getElementById('slot3modcr').value = autoTrimpSettings.slot3modcr.selected; + document.getElementById('slot4modcr').value = autoTrimpSettings.slot4modcr.selected; + + if (game.global.universe == 1) + document.getElementById('autoMapBtn').setAttribute('class', 'noselect settingsBtn settingBtn' + autoTrimpSettings.AutoMaps.value); + if (game.global.universe == 2) + document.getElementById('autoMapBtn').setAttribute('class', 'noselect settingsBtn settingBtn' + autoTrimpSettings.RAutoMaps.value); + + + if (game.global.universe == 1 && getPageSetting('DisableFarm') <= 0) shouldFarm = false; + if (game.global.universe == 2 && getPageSetting('RDisableFarm') <= 0) + RshouldFarm = false; - // handle metal preference MODULES["maps"] && (MODULES["maps"].preferGardens = !getPageSetting('PreferMetal')); - //if player has selected arbalest or gambeson but doesn't have them unlocked, just unselect it for them! It's magic! if (document.getElementById('Prestige').selectedIndex > 11 && game.global.slowDone == false) { document.getElementById('Prestige').selectedIndex = 11; autoTrimpSettings.Prestige.selected = "Bestplate"; } - //Bionic Before Spire - Auto turns on ability to run UniqueMaps - if (autoTrimpSettings.RunBionicBeforeSpire.enabled && getPageSetting('AutoMaps')==2) { - debug("RunBionicBeforeSpire incompatible with AutoMaps No Unique Maps, changing..."); - setPageSetting("AutoMaps",1); - } - //since this is a loop, make sure the Text contents of our buttons are set accurately. (after any setPageSetting) + for (var setting in autoTrimpSettings) { var item = autoTrimpSettings[setting]; - if (item.type == 'value' || item.type == 'valueNegative' || item.type == 'multitoggle') { + if (item.type == 'value' || item.type == 'valueNegative' || item.type == 'multitoggle' || item.type == 'multiValue' || item.type == 'textValue') { var elem = document.getElementById(item.id); + if (elem.parentNode.style.display === 'none') continue; if (elem != null) { if (item.type == 'multitoggle') elem.textContent = item.name[item.value]; - else if (item.value > -1 || item.type == 'valueNegative') + else if (item.type == 'multiValue') { + if (Array.isArray(item.value) && item.value.length == 1 && item.value[0] == -1) + elem.innerHTML = item.name + ': ' + ""; + else if (Array.isArray(item.value)) + elem.innerHTML = item.name + ': ' + item.value[0] + '+'; + else + elem.textContent = item.name + ': ' + item.value.toString(); + } else if (item.type == 'textValue' && item.value.substring !== undefined) { + if (item.value.length > 18) + elem.textContent = item.name + ': ' + item.value.substring(0, 21) + '...'; + else + elem.textContent = item.name + ': ' + item.value.substring(0, 21); + } else if (item.value > -1 || item.type == 'valueNegative') elem.textContent = item.name + ': ' + prettify(item.value); else elem.innerHTML = item.name + ': ' + ""; @@ -896,40 +2561,60 @@ function updateCustomButtons() { } } -//Checks portal related UI settings function checkPortalSettings() { var result = findOutCurrentPortalLevel(); var portalLevel = result.level; var leadCheck = result.lead; if (portalLevel == -1) return portalLevel; - var voidmaps = getPageSetting('VoidMaps'); + var voidmaps = 0; + if (game.global.challengeActive != "Daily") { + voidmaps = getPageSetting('VoidMaps'); + } + if (game.global.challengeActive == "Daily") { + voidmaps = getPageSetting('dVoidMaps'); + } if (voidmaps >= portalLevel) tooltip('confirm', null, 'update', 'WARNING: Your void maps are set to complete after your autoPortal, and therefore will not be done at all! Please Change Your Settings Now. This Box Will Not Go away Until You do. Remember you can choose \'Custom\' autoPortal along with challenges for complete control over when you portal.

Estimated autoPortal level: ' + portalLevel, 'cancelTooltip()', 'Void Maps Conflict'); - if ((leadCheck || game.global.challengeActive == 'Lead') && (voidmaps % 2 == 0 && portalLevel <= 181)) - tooltip('confirm', null, 'update', 'WARNING: Voidmaps run during Lead on an Even zone do not receive the 2x Helium Bonus for Odd zones, and are also tougher. You should probably fix this.', 'cancelTooltip()', 'Lead Challenge Void Maps'); return portalLevel; } -//Hider's He/Hr Info stats (in world sidebar) function getDailyHeHrStats() { - var words = ""; - if (game.global.challengeActive == "Daily") { - var getPercent = (game.stats.heliumHour.value() / (game.global.totalHeliumEarned - (game.global.heliumLeftover + game.resources.helium.owned))); - getPercent *= 100 + getDailyHeliumValue(countDailyWeight()); - words = "After Daily He/Hr: " + getPercent.toFixed(3) +'%'; + var a = ""; + if ("Daily" == game.global.challengeActive) { + var b = game.stats.heliumHour.value() / (game.global.totalHeliumEarned - (game.global.heliumLeftover + game.resources.helium.owned)); + b *= 100 + getDailyHeliumValue(countDailyWeight()), a = "After Daily He/Hr: " + b.toFixed(3) + "%" + } + return a +} + +function getDailyRnHrStats() { + var a = ""; + if ("Daily" == game.global.challengeActive) { + var b = game.stats.heliumHour.value() / (game.global.totalRadonEarned - (game.global.radonLeftover + game.resources.radon.owned)); + b *= 100 + getDailyHeliumValue(countDailyWeight()), a = "After Daily Rn/Hr: " + b.toFixed(3) + "%" } - return words; + return a } -//Part of import-export.js module. -function settingsProfileMakeGUI(){}; //blank on purpose, will be overwritten if necessary. - -//controls the button skips 2 of the tri-state automaps button -function toggleAutoMaps(){ - if (getPageSetting('AutoMaps')) - setPageSetting('AutoMaps',0); - else - setPageSetting('AutoMaps',1); - document.getElementById("autoMapBtn").setAttribute("class", "noselect settingsBtn settingBtn" + autoTrimpSettings.AutoMaps.value); -} \ No newline at end of file +function settingsProfileMakeGUI() { } + +function toggleAutoMaps() { + if (game.global.universe == 1) { + if (getPageSetting('AutoMaps')) { + setPageSetting('AutoMaps', 0); + } else { + setPageSetting('AutoMaps', 1); + } + document.getElementById('autoMapBtn').setAttribute('class', 'noselect settingsBtn settingBtn' + autoTrimpSettings.AutoMaps.value); + } + if (game.global.universe == 2) { + if (getPageSetting('RAutoMaps')) { + setPageSetting('RAutoMaps', 0); + } else { + setPageSetting('RAutoMaps', 1); + } + document.getElementById('autoMapBtn').setAttribute('class', 'noselect settingsBtn settingBtn' + autoTrimpSettings.RAutoMaps.value); + } + saveSettings(); +} diff --git a/dark-graph.css b/dark-graph.css index c8aecade9..bcacc0c90 100644 --- a/dark-graph.css +++ b/dark-graph.css @@ -1,8 +1,8 @@ -[id^='highcharts'] rect.highcharts-background, +[id^='highcharts'] .highcharts-background, [id^='highcharts'] .highcharts-tooltip > path:last-of-type { fill: rgba(0, 0, 0, 0.5) !important; } -[id^='highcharts'] rect.highcharts-selection-marker { +[id^='highcharts'] .highcharts-selection-marker { fill: rgba(255, 255, 255, 0.5); } [id^='highcharts'] .highcharts-xaxis > path, diff --git a/docs/AutoPerks EfficiencyQueue.txt b/docs/AutoPerks EfficiencyQueue.txt deleted file mode 100644 index 9a0337c6a..000000000 --- a/docs/AutoPerks EfficiencyQueue.txt +++ /dev/null @@ -1,29 +0,0 @@ -How AutoPerks Works: ----------------------- -Get list of Ratio'ed Perks. -Create an Efficiency queue of each of the 16 perks. - - Current Level - - Current Price @ that level - - Current Stat Increase @ that Level. - - Current Efficiency (price / stat increase). -Then the list of 16 perks is sorted by Efficiency, and the 1st one on the list is purchased. -Repeat ad nauseum 36 million iterations. - -for (var e in effQueue.array) { console.log("Effiency@ " + effQueue.array[e].efficiency + " Perk name: " + effQueue.array[e].name);} - -Effiency@ 30.00000000000003 Perk name: power -Effiency@ 4.0000000000000036 Perk name: toughness -Effiency@ 3.200000000000003e-9 Perk name: cunning -Effiency@ 1.3333333333333346 Perk name: pheromones -Effiency@ 1.0000000000000009 Perk name: motivation -Effiency@ 0.36 Perk name: carpentry -Effiency@ 0.13333333333333333 Perk name: artisanistry -Effiency@ 0.08 Perk name: resilience -Effiency@ 0.00030000000000000024 Perk name: power_II -Effiency@ 0.00014999999999999682 Perk name: looting_II -Effiency@ 0.00011333333333333333 Perk name: coordinated -Effiency@ 0.00004000000000000004 Perk name: toughness_II -Effiency@ 0.000008000000000000006 Perk name: motivation_II -Effiency@ 0.000002249999999999952 Perk name: carpentry_II -Effiency@ 0.000002 Perk name: resourceful -Effiency@ 0.000001 Perk name: overkill \ No newline at end of file diff --git a/docs/SettingsTooltipDocumentation.txt b/docs/SettingsTooltipDocumentation.txt deleted file mode 100644 index 289452cc1..000000000 --- a/docs/SettingsTooltipDocumentation.txt +++ /dev/null @@ -1,71 +0,0 @@ -Auto Gather/Build - Automatically gathers resources (and uses Turkimp on metal). Auto speed-builds your build queue and auto-researches science on demand. -Better Auto Fight - Will automatically handle fighting. It gives you autofight before you get the Battle upgrade in Zone 1.. .CAUTION: If you autoportal with BetterAutoFight disabled, the game sits there doing nothing until you click FIGHT. (not good for afk) -Auto Stance - Automatically swap stances to avoid death. -Trap Trimps - Automatically trap trimps when needed, including building traps. -Buy Storage - Will buy storage when resource is almost full. (like AutoStorage, even anticipates Jestimp) -Buy Jobs - Buys jobs based on ratios configured below. CAUTION: you cannot manually assign jobs with this. Toggle if you need to. -Buy Buildings - Will buy non storage buildings as soon as they are available -Buy Upgrades - Autobuy non equipment Upgrades -Buy Armor - Auto-Buy/Level-Up the most cost efficient armor available. -Buy Armor Upgrades - (Prestiges) & Gymystic. Will buy the most efficient armor upgrade available. -Buy Weapons - Auto-Buy/Level-Up the most cost efficient weapon available. -Buy Weapon Upgrades - (Prestiges) Will buy the most efficient weapon upgrade available. -Buy Shield Block - Will buy the shield block upgrade. CAUTION: If you are progressing past zone 60, you probably don't want this :) -Run Unique Maps - Relies on AutoMaps to choose to run Unique maps. Required for AutoPortal. Also needed for challenges: Electricity, Mapocalypse, Meditate, and Crushed (etc). Needed to auto-run The Wall and Dimension of Anger. -Auto Heirlooms - Automatically evaluate and carry the best heirlooms, and recommend upgrades for equipped items. AutoHeirlooms will only change carried items when the heirlooms window is not open. Carried items will be compared and swapped with the types that are already carried. If a carry spot is empty, it will be filled with the best shield (if available). Evaluation is based ONLY on the following mods (listed in order of priority, high to low): Void Map Drop Chance/Trimp Attack, Crit Chance/Crit Damage, Miner Efficiency/Metal Drop, Gem Drop/Dragimp Efficiency, Farmer/Lumberjack Efficiency. For the purposes of carrying, rarity trumps all of the stat evaluations. Empty mod slots are valued at the average value of the best missing mod. -Hire Scientists - Enable or disable hiring of scientists. Math: ScientistRatio=(FarmerRatio+LumberjackRatio+MinerRatio)/25 and stops hiring scientists after 250k Farmers. -Manage Breed Timer - Automatically manage the breed timer by purchasing Genetecists. Sets ideal anticpation stacks. If not using AutoStance, this will probably be undesirable... Picks appropriate times for various challenges (3.5s,11s,30s). Delays purchasing potency and nurseries if trying to raise the timer. EFFECTIVELY LOCKS THE BREED TIMER -Geneticist Timer - Breed time in seconds to shoot for using geneticists. Disable with -1 (and Disable ManageBreedTimer) to disable the Hiring/Firing of genetecists (and potency upgrades). CANNOT CHANGE WITH MANAGE BREED TIMER OPTION ON -Farmer Ratio - -Lumberjack Ratio - -Miner Ratio - -Max Explorers - Map the planet!! -Max Trainers - Fist bump me bro -Max Huts - -Max Houses - -Max Mansions - -Max Hotels - -Max Resorts - -Max Gateways - WARNING: Not recommended to raise above 25 -Max Wormholes - WARNING: Wormholes cost helium! Values below 0 do nothing. -Max Collectors - -First Gigastation - How many warpstations to buy before your first gigastation -Delta Gigastation - How many extra warpstations to buy for each gigastation. Supports fractional values. For example 2.5 will buy +2/+3/+2/+3... -Max Gyms - -Max Tributes - -Max Nurseries - -Void Maps - The zone at which you want all your void maps to be cleared (Cell 96). 0 is off -Prestige - Acquire prestiges through the selected item (inclusive) as soon as they are available in maps. Forces equip first mode. Automap must be enabled. THIS IS AN IMPORTANT SETTING related to speed climbing and should probably always be on something. If you find the script getting stuck somewhere, particularly where you should easily be able to kill stuff, setting this to an option lower down in the list will help ensure you are more powerful at all times, but will spend more time acquiring the prestiges in maps. -Auto Portal - Automatically portal. Will NOT auto-portal if you have a challenge active, the challenge setting dictates which challenge it will select for the next run. All challenge settings will portal right after the challenge ends, regardless. Helium Per Hour portals at cell 1 of the first level where your He/Hr went down even slightly compared to the current runs Best He/Hr. Take note, there is a Buffer option in the genBTC settings, which is like a grace percentage of how low it can dip without triggering. CAUTION: Selecting He/hr may immediately portal you if its lower. -Challenge for Helium per Hour and Custom - Automatically portal into this challenge when using helium per hour or custom autoportal. Custom portals after cell 100 of the zone specified. -Custom Portal - Automatically portal AFTER clearing this level.(ie: setting to 200 would portal when you first reach level 201) -Limit Equipment - Limit levels of equipment bought to:(level 11 - the prestige level). At or Above Prestige X (10), your equipment will remain at level 1. In other words, do not level equipment after ~level ~51, and only buy Prestiges. CAUTION: may reduce He/hr performance in many cases. -Breed Fire - Fire Lumberjacks and Miners to speed up breeding when needed. (Not genetecists). -Max Toxicity Stacks - Get maximum toxicity stacks before killing the improbability in each zone 60 and above. Generally only recommended for 1 run to maximize bone portal value. This setting will revert to disabled after a successful Max-Tox run + Toxicity Autoportal. -Run New Voids - Run new void maps acquired after the set void map zone. Runs them at Cell 95 by default, unless you set a decimal value indicating the cell, like: 187.75 CAUTION: May severely slow you down by trying to do too-high level voidmaps. Use the adjacent RunNewVoidsUntil setting to limit this. -Void Difficulty Check - How many hits to be able to take from a void map boss in dominance stance before we attempt the map. Higher values will get you stronger (by farming for health) before attempting. 2 should be fine. -Disable Farming - Disables the farming section of the automaps algorithm. This will cause it to always return to the zone upon reaching 10 map stacks. TROUBLESHOOTING: Save and Refresh when you toggle this, if necessary. INFO: The new Trimps 3.22 map-buttons greatly eliminate the usefulness of this. ALSO: NO LONGER DISABLES SIPHONOLOGY. -PauseAutoTrimps - PauseAutoTrimps(notincludingthegraphsmodule) -Warpstation Cap - Do not level Warpstations past Basewarp+DeltaGiga **. Without this, if a Giga wasnt available, it would level infinitely (wastes metal better spent on prestiges instead.) **The script bypasses this cap each time a new giga is bought, when it insta-buys as many as it can afford (since AT keeps available metal/gems to a low, overbuying beyond the cap to what is affordable at that first moment is not a bad thing). -Cap Equip to 10 - Do not level equipment past 10. Similar to LimitEquipment, Helps for early game when the script wants to level your tier2s to 40+, but unlike LimitEquipment, does not impact Zone 60+. -Skip Gear Level 58&59 - Dont Buy Gear during level 58 and 59, wait till level 60, when cost drops down to 10%. -Delay Armor - Delay buying armor prestige upgrades during Want More Damage or Farming automap-modes. -Dynamic Siphonology - Use the right level of siphonology based on your damage output. -Farm on >7 NomStacks - On Improbability(cell 100). Meant to be used with DisableFarming (otherwise farming would take care of this, but its slower). If Improbability already has 5 NomStacks, stack 30 Anticipation. If the Improbability has >7 NomStacks on it, get +200% dmg from MapBonus. If we still cant kill it, enter Farming mode at 30 stacks, Even with DisableFarming On! (exits when we get under 20x) -AutoRoboTrimp - Use RoboTrimps ability starting at this level, and every 5 levels thereafter. (set to 0 to disable) -He/Hr Portal Buffer % - When using the He/Hr Autoportal, it will portal if your He/Hr drops by this amount of % lower than your best for current run, default is 0% (ie: set to 5 to portal at 95% of your best) -Run New Voids Until - Put a cap on what zone new voids will run at, until this zone, inclusive. -Always Buy Lvl 2 Armor - Always Buy the 2nd point of Armor even if we dont need the HP. Its the most cost effective level, and the HP _need_ script isnt always adequate. -Dynamic Prestige - EXPERIMENTAL: Skip getting prestiges at first, and Gradually work up to the desired Prestige setting you have set. Runs with Dagger to save a significant amount of time until we need better gear, then starts increasing the prestige setting near the end of the run. ---NEW ALGORITHM 7/23/2016--- Examines which prestiges you have, how many missing ones youd need to achieve the desired target and starts running 5 maps or 2 maps every zone, Until the target prestige is reached. Example: For mace, starts getting the prerequisite prestiges 10 zones away from max, then more and more, finally reaching the desired prestige by the last final zone (also goes for 9 mapbonus on the last zone). IMPORTANT NOTE PLEASE READ: Final Zone Number is inherently tied to the AutoPortal setting. When using the Helium per Hour setting, it uses the zone we portaled at last run (game.global.lastPortal). If the AutoPortal is set to a challenge, it will use the last zone of the challenge. CAUTION: EXPERIMENTAL, please come to Discord chat if you have problems. -undefined - undefined -Run Bionic Before Spire - Run the Bionic Wonderlands I through VI and then repeatedly farms VI(level 200) before attempting Spire, for the purpose of farming. WARNING: The point at which it stops farming has yet to be fully decided upon or set in stone, so it currently runs Bionic VI until it runs out of new prestige item rewards, then runs Bionic VII until it runs out of prestige items from that one, and then attempts the spire. This amounts to somewhere around 144 minutes. DO NOT USE WITH HE/HR PORTAL. Not meant to be used every time, He/Hr suffers. -Cap Trainers to a % of Tributes - Only Buy a Trainer when its cost is LESS than X% of cost of a tribute. This setting can work in combination with the other one, or set the other one to -1 and this will take full control. Default: -1 (Disabled). 50% is close to the point where the cap does nothing. You can go as low as you want but recommended is 10% to 1%. (example: Trainer cost of 5001, Tribute cost of 100000, @ 5%, it would NOT buy the trainer.) -PrestigeBackup - Acquire prestiges through the selected item (inclusive) as soon as they are available in maps. Forces equip first mode. Automap must be enabled. THIS IS AN IMPORTANT SETTING related to speed climbing and should probably always be on something. If you find the script getting stuck somewhere, particularly where you should easily be able to kill stuff, setting this to an option lower down in the list will help ensure you are more powerful at all times, but will spend more time acquiring the prestiges in maps. -Auto Heirlooms2 - New algorithm for Heirlooms. While enabled, the old AutoHeirlooms algorithm will be disabled (the button will stay lit or you can turn that one off). CAUTION: Turning this on will immediately re-sort your heirlooms according to the new algorithm, and turning it off again DOES revert to the original algorithm even though it may NOT have a visible result on your heirlooms. (fyi: This lack of action highlights one of the problems with the old one.) -AutoGoldenUpgrades - Automatically Buy the specified Golden Upgrades as they become available. -Auto Upgrade Heirlooms - Automatically buy the upgrade the script advises for the Equipped shield and staff, until we are out of nullifium. -Minutes to Farm Before Spire - Farm level 200 maps for X minutes before continuing to beat spire (0 to disable) -Auto Maps - Automatically run maps to progress. Very Important. -Auto Worker Ratios - Automatically changes worker ratios based on current progress. WARNING: overrides worker ratio settings. Settings: 1/1/1 up to 300k trimps, 3/3/5 up to 3mil trimps, then 3/1/4 above 3 mil trimps, then 1/1/10 above 1000 tributes, then 1/2/22 above 1500 tributes. Uses 1/40/8 in Spire since we get plenty of metal from that. -Warpstation Wall - Do not level Warpstations if it costs over 1/4th of the current metal we own. (Experimental) -Exit Spire After Cell - Exits the Spire after completing cell X. example: 40 for Row 4. (0 to disable) \ No newline at end of file diff --git a/docs/TODO.md b/docs/TODO.md deleted file mode 100644 index 7bd8d4d26..000000000 --- a/docs/TODO.md +++ /dev/null @@ -1,136 +0,0 @@ -Document Code Structure: (for other developers): see main-doc.txt ----------------- -Main-Documentation (main-doc.txt) -TODO List (this file - TODO.md) -Update README.md/changelog(.json?)/version # (manually for now) -Code Comments (getting better) - -Near Future: ------------------------- -WebSite https://autotrimps.site - even just a link to github, or link to tutorials on how to install. --GRAPHS! -TODO 1: Add notes or labels to graph runs. (to indicate which settings we used) -TODO 1: HighCharts annotations module for "notes" comments to indicate which graph runs were what. -TODO: IMPLEMENTING A STANDARD FOR CLOUD GRAPH STATISTICS: - -now : Highest zone, helium, bones, Perk preset/ratios. - -next: ATSettings, MODULES, which graphs were clicked on. - - -new TODO LIST: 3/3/2018 and 3/4/2018 extended to 3/7 still working on it as of 3/20. -------------------------------------- -XXXX: AutoPerks - background thread / web worker -XXXX: AutoPerks - allocate speed improvement, shortcuts, (36 million iterations and 15 seconds @ 720Qa HE) - - maybe slow due to OO structure and repeated resolutions for pass2. -TODO: Perky - implement Altizar Perky new Perk manager interface -TODO: SPAM tab - more granular settings. maybe every module could have its own toggle? - working on it. -TODO: "Map Special Modifier": Special Modifiers, Perfect Sliders (way more fragments), Extra Zones (+0 to +10) - with a save config option - if you create a config with FA and +5 zones, and save it, next time you/the script creates a map, it will remember the setting - so if you want you can use the script to create 3 setups (there are 3 slots to save your config) - + maps should be only created at poison zones and when they will provide new equipment - prestigious when you need prestiges, lmc when you need more lvls in your eq - perfect sliders when you can afford it - make perfect sliders like if you're able to afford 3x the cost of it in frags, just buy it. otherwise no. and it will be rarer that way but still useful - another valid idea is burn out all your frags on perfect near the end i guess -TODO: (from old TODO LIST: 8/17/2016) BionicW toggle that can let AT do Bionic Wonderland maps if they haven't ever been done before? - (in the same vein, check for "Speed" achievements for unique maps and do them if they're not done yet and possible) -TODO: for alfa166: "Bionic OverBurner" :smiley: Make it Configurable to run BW 470 one time at z480 to unlock and run BW485, (with the +5 map kit) -TODO: Make a more configurable Auto Spend Nulli function for 2018 -TODO: Should invent a tool/script to plug in the version numbers, changelogs, docs. -TODO: Instead of hard-coded changelog, Break changelog out into a seperate file and HTTPRequest it, parse it and run it through a standardized display function. - Pull external .JSON Changelog and stuff from this site's API (obviously have to create a new server endpoint PHP script) -TODO: Modular Structured load of the modules/*.js files is less than robust now. Check status of each loaded, tally a count, double check success. - -FAR: In this way, the tracking and loading of modules can be timestamped and version controlled for itemization and aggregate cloud managed. -FAR TODO: Cloud management of Save Files (already uploading save files and naming them. just need to download) -FAR TODO: Cloud distributed graphs. Show similar users graphs? (STARTED) - -Could just upload all the graphs after every run (how to detect full run?) -FAR TODO: Theoretically the graphs database can be used as a pro-active future prediction model and conditions can be inferred from past runs. - Example: If Helium per/hour is ABOUT to go down based on previous cached runs (during the ambiguity period of about a few zones), portal earlier. - Think like Grace %% setting but automatic. -FAR TODO: Analysis of the Userbase and custom settings, even make queries to ask server for better decision making based on global multi-client probability state -TODO: Develop an internal utility for me to Scrape/Grep/Grok the .json analytics files already on the server. -FAR TODO: Import/Export/Append Graphs. is delete working on refresh? -FAR TODO: Graphs encoding vs. storage is wasteful of space. We need more. Compress data or RLE it -TODO: Structure of Graphs.js is very wonky and can be re-sorted, nested somehow. -TODO: GUI javascript warning message "Are you sure?" OK/cancel template. -TODO: Bundle a newbie profile into the profiles-defaults. -TODO: Keep generating content in this file very late at night, that nobody can see or care about - real smart use of my time. - - -Bugs To Fix: ----------------- -Last github pull request is from 2016 = needs to be cleared. Has useful code that could be imported into Settings file for version comparisons and settings migrations/in-place upgrades. -All Issues from January to February have been resolved. -Any Issues remaining from prior 2017 should be disregarded. -BUG 1: Bone Portal messes with graphs / Importing a savedgame in progress produces bad graphs -BUG 2: The graphs still can miss time and have gaps/skips and has zone innacuracies, additionally it can fail to track Trimps data entirely during background window Javascript AFK/idle/catchup mode. -BUG 2: Overkill and certain graphs can skip progress and get mis-aligned if the script was paused or was backgrounded. - - -Done Did: ----------- -Done: Visible Version Status Number in UI / Startup popup messages -Done: Essence graph -Done: Renamed Module names: Some stuff is named auto, some stuff isnt. Its AutoTrimps so isn't everything auto? Redundant? -Done: Renamed NewUI2.js as SettingsGUI - needs new name, some love. -Done: Add autotrimps.site data json upload capability (thanks to Swiffy) -Done: BUG 1: Liquification - the Auto-Skip-tons-of-zones-in-beginning - causes overkill graph to be off by a LOT. -Not actually a thing: "Max Magmamancers By Zone #" so we can buy them at the start, to gain 5% attack for the first 10 minutes, usually for cases when the void zone which is the same as the portal zone, and you want to stack that level up with all you've got. - -5% Attack is only given after 5 minutes. Misunderstanding. -Done: AutoTrimps Presets dropdown list to name, save, reload different profiles -Done: Partially: Split SettingsGUI.js up into front-end DOM+GUI, back-end functions for Settings/Modules/Profiles, and createSettings+descriptions. -Done: Fluffy XP Graph -Done: Pin the ATSettings Tab MenuBar + Minimize,Maximize,Close buttons. -Done: TODO: Graphs, make 2 arrows to cycle sequentially through the graphs without using the dropdown everytime. -Done: TODO: Put changelog show/hide popup Button into settings -Done: PrintChangelog: print changelog function should be refactored: another function should be made to create a DOM element for all the changelog lines, scrape the API data into it, and then print tooltip with header/footer. - -Other Improvements: ------------------- -AUTOMAPS: -Rewrite the automaps way of deciding/picking/buying/running maps. (convo below) ---------------------------------------------------------------------------------- --: Decide whether map stacks can help speed you up or not: -If you're more limited by you being dead and your lack of health, than damage output, its probably more likely to not be worth it. -also if you don't have the overkill perk increasing damage can get inefficient when damage output is wasted -so keeping a good "survivability to damage output" ratio is better than optimizing "damage output" -keep a count of how long you were dead and how long you were doing damage -if you're never dead, then the damage boost from map stacks is USUALLY worth it. (cant say for sure but im pretty sure) -I still think you'd have to run 1 full map to know for sure if its worth it. then extrapolate that out times 10 --: Summary: -never dead -> damage boost helps when not "early game when you're ripping through bad guys" -almost never alive, frequently dead -> if more damage output than damage taken (and enough hp to react to fast guys), go on, otherwise farm -occasionally dead and dies faster than breeding -> needs more damage -occasionally dead and dies slower than breeding -> advance -Also while doing this, determine more refined rules for entering the 3 modes: want dmg/want health/farming - --:230+ regular maps should really be treated differently from corruption -they don't have block pierce, and no special abilities --it doesnt go into the map bonus mode soon enough because of the fact that its gauging the zone on non-corrupted enemies - //we will get at least 85 toxstacks from the 1st voidmap UNLESS we have overkill, then we dont get enough. - //if a new fight group is available and anticipation stacks aren't 30, abandon and grab a new group - - -VOIDMAPS: -Void Map Farming - based on how much damage you do rather than your health/survival ---------------------------------------------------------------------------------- --:Voidmaps: - //TODO: Account for magmated voidmaps. (not /2) - //TODO: Account for daily. --:On Voids Diff: -if you have enough HP to survive poisonous without genetecists, i guess its easy -poison is really bad before you get geneticists for example -before you have geneticists poisonous is just awful -if you block everything, heinous is awful -if you almost block everything, destructive is awful -and then the double hit is somewhere in the middle -yeah i think they shift a lot depending on how strong you are -if you're strong enough that doing voids at 190 is a joke but can't do them later after you finish corrupted for example -for me right now I usually block close to 100% of the damage, which is why destruction and heinous are worst -poison is completely trivial when the maps are already easy -destruction = % damage, heinous = crit -if you're trying to do the void maps before you're actually strong though poison is a killer -yea thats a good point, people doing them at the challenge boundary vs at the end of their run -I also thing the difficulty check should consider block, if it doesn't already do that -i always found poison to be the most obnoxious of them early on because when you don't even have geneticists to fire to make breeding faster again it just takes sooo long -for a large part of the game I only did VMs when I could completely block everything, which made them trivial diff --git a/docs/dailymodifiers.txt b/docs/dailymodifiers.txt deleted file mode 100644 index 951395309..000000000 --- a/docs/dailymodifiers.txt +++ /dev/null @@ -1,94 +0,0 @@ -badHealth = enemy, health -badMapHealth = enemy, health -badMapStrength = enemy, attack -badStrength = enemy, attack -bloodthirst = enemy, stacks -bogged = self, health, drain -crits = enemy, crit -dedication = gathering -dysfunctional = breeding -evenTrimpBuff = self,+attack -explosive = enemy, attack, drainy -famine = gathering, loot -karma = loot, stacks -large = housing -maxDamage = self,attack -minDamage = self,attack -oddTrimpNerf = self,-attack -plague = -health, stacks -rampage = self, +attack, stacks -slippery= dodge -toxic = breeding, stacks -weakness= self, -attack, stacks - -Main.js @ line 5455 -var dailyModifiers = -{ - minDamage: { - description : "Trimp min damage reduced by X % (additive)." - }, - maxDamage: { - description : "Trimp max damage increased by X % (additive)." - }, - plague: { - //Half of electricity - description : "Enemies stack a debuff with each attack, damaging Trimps for X% of total health per turn per stack, resets on Trimp death." - }, - weakness: { - description : "Enemies stack a debuff with each attack, reducing Trimp attack by X% per stack. Stacks cap at 9 and reset on Trimp death." - }, - large: { - description : "All housing can store X% fewer Trimps" - }, - dedication: { - description : "Gain X% more resources from gathering" - }, - famine: { - description : "Gain X% less Metal, Food, Wood, and Gems from all sources" - }, - badStrength: { - description : "Enemy attack increased by X%." - }, - badHealth: { - description : "Enemy health increased by X%." - }, - badMapStrength: { - description : "Enemy attack in maps increased by X%." - }, - badMapHealth: { - description : "Enemy health in maps increased by X%." - }, - crits: { - description : "Enemies have a 25% chance to crit for X% of normal damage" - }, - bogged: { - description : "Your Trimps lose X% of their max health after each attack." - }, - dysfunctional: { - description : "Your Trimps breed X% slower" - }, - oddTrimpNerf: { - description : "Trimps have X% less attack on odd numbered zones" - }, - evenTrimpBuff: { - description : "Trimps have X% more attack on even numbered zones" - }, - karma: { - description : 'Gain a stack after killing an enemy, increasing all non Helium loot by X%. Stacks cap at Y, and reset after clearing a zone.' - }, - toxic: { - description : "Gain a stack after killing an enemy, reducing breed speed by X% (compounding). Stacks cap at Y, and reset after clearing a zone." - }, - bloodthirst: { - description : "Enemies gain a stack of Bloodthirst whenever Trimps die.Every X stacks, enemies will heal to full and gain an additive 50 % attack.Stacks cap at Y, and reset after killing an enemy." - }, - explosive: { - description : " Enemies instantly deal % of their attack damage when killed if (str > 15) UNLESS your block is as high as your maximum health " - }, - slippery: { - description : " Enemies have a % chance to dodge your attacks on odd ? / ?even zones." - }, - rampage: { - description : "Gain a stack after killing an enemy, increasing Trimp attack by % (additive). Stacks cap at ? , and reset when your Trimps die." - }, -} diff --git a/docs/main-doc.txt b/docs/main-doc.txt deleted file mode 100644 index 6a3cb24b1..000000000 --- a/docs/main-doc.txt +++ /dev/null @@ -1,283 +0,0 @@ -AutoTrimps - A Highly Extensive Idle Clicker Game Script - -Code Execution Structure,Behavior/Explanation: -============================================== -A script bootstrap file userscript "install.user.js" is ran by Tampermonkeyed/Greasemonkeyed and installed into permanence on the browser extension. This loads AutoTrimps2.js. First it loads utils.js for some tools, then it loads the Settings UI and then it Loads the Graphs, This loads all the 17 submodules *.js files in the modules/ dir, in a particular order as listed. From that point, a timeout/interval loop is set up to launch the Main Game and Re-run the "Main Loop" every 100ms (10x a second) in sync with the Game Loop. Also the Graphs has its own identical tick count and loop. Each module function is called during the "Main Loop" generally one by one, sequentially, in a particular order, each cycle. There is no future state, just current. The past state is limited to anything we explicitly choose to keep around like in the graphs db or other variables. -The main files are: AutoTrimps2.js, SettingsGUI.js, Graphs.js - Keep reading for details. The separate modules are documented below. - -MODULES (2018): -=============== -battlecalc.js -breedtimer.js -buildings.js -client-server.js -dimgen.js (not used anymore?) -dynprestige.js -equipment.js -fight.js -gather.js -heirlooms.js -import-export.js -jobs.js -magmite.js -maps.js -other.js -perks.js -portal.js -query.js -scryer.js -stance.js -upgrades.js -utils.js - -EXTERNAL FILES: -================ -FastPriorityQueue.js - AutoPerks - uses a 3rd party library for data queues -HighCharts.js - Graphs - uses a 3rd party library to draw the graphs... -tabs.css - User Interface - mandatory css styles for the settings tab or to rewrite or style the UI -dark-graph.css - Graphs - needed some tweaks to work for dark theme. - -GUI: -===== -Consists of SettingsGUI.js is the Settings section + styles of tabs.css - -SETTINGS: -========= -AlwaysArmorLvl2 -AutoFight -AutoGoldenUpgrades -AutoHeirlooms -AutoHeirlooms2 -AutoMaps -AutoPortal -AutoRoboTrimp -AutoStance -AutoUpgradeHeirlooms -BreedFire -BuyArmor -BuyArmorUpgrades -BuyBuildings -BuyJobs -BuyShieldblock -BuyStorage -BuyUpgrades -BuyWeapons -BuyWeaponUpgrades -CapEquip -CorruptionCalc -CustomAutoPortal -DefaultAutoTrimps -DelayArmorWhenNeeded -DeltaGigastation -DisableFarm -DynamicPrestige -DynamicSiphonology -ExitSpireCell -ExportAutoTrimps -FarmerRatio -FarmWhenNomStacks7 -FirstGigastation -GeneticistTimer -HeliumHourChallenge -HeliumHrBuffer -HireScientists -ImportAutoTrimps -LimitEquipment -LumberjackRatio -ManageBreedtimer -ManualGather -MaxCollector -MaxExplorers -MaxGateway -MaxGym -MaxHotel -MaxHouse -MaxHut -MaxMansion -MaxNursery -MaxResort -MaxTox -MaxTrainers -MaxTribute -MaxWormhole -MinerRatio -MinutestoFarmBeforeSpire -PauseScript -Prestige -RunBionicBeforeSpire -RunNewVoids -RunNewVoidsUntil -RunUniqueMaps -ScryerMaxZone -ScryerMinZone -ScryerSkipBoss2 -ScryerSkipCorrupteds2 -ScryerUseinMaps2 -ScryerUseinSpire2 -ScryerUseinVoidMaps2 -ScryerUseWhenOverkill -TrainerCaptoTributes -TrapTrimps -UseScryerStance -VoidCheck -VoidMaps -WaitTill60 -WarpstationCap -WarpstationWall -WorkerRatios - -GRAPHS - Graphs.js is the graphs section: + dark-graph.css (maybe need to darkify the css on the perks too window) -======= -HeliumPerHour -Helium -HeliumPerHour Instant -HeliumPerHour Delta -HeHr % / LifetimeHe -He % / LifetimeHe -Clear Time -Cumulative Clear Time -Run Time -Map Bonus -Void Maps -Void Map History -Loot Sources -Coords -Gigas -UnusedGigas -Lastwarp -Trimps -Nullifium Gained -DarkEssence -DarkEssencePerHour -OverkillCells -Magmite -Magmamancers - -AutoTrimps2.js Detailed Main Function Documentation (from 2016): -=================================================== -The main loop consists of the following subroutines, all of which are enable-able/disable-able by their buttons.: - workerRatios(); //"Auto Worker Ratios" - buyUpgrades(); //"Buy Upgrades" - autoGoldenUpgrades(); //"AutoGoldenUpgrades" (genBTC settings area) - buyStorage(); //"Buy Storage" - buyBuildings(); //"Buy Buildings" - buyJobs(); //"Buy Jobs" - manualLabor(); //"Auto Gather/Build" - autoMap(); //"Auto Maps" - manageGenes(); //"Genetecist Timer" / "Manage Breed Timer" - autoPortal(); //"Auto Portal" (hidden until level 60) - autoHeirlooms2(); or autoHeirlooms(); //"Auto Heirlooms 2" (genBTC settings area) or //"Auto Heirlooms" - toggleAutoTrap(); //"Trap Trimps" - autoRoboTrimp(); //"AutoRoboTrimp" (genBTC settings area) - autoNull(); //"Auto Upgrade Heirlooms" (genBTC settings area) - autoLevelEquipment(); //"Buy Armor", "Buy Armor Upgrades", "Buy Weapons","Buy Weapons Upgrades" - autoStance(); //"Auto Stance" - betterAutoFight(); //"Better Auto Fight" - prestigeChanging2(); //"Dynamic Prestige" (genBTC settings area) - userscripts(); //Runs any user provided scripts - by copying and pasting a function named userscripts() into the Chrome Dev console. (F12) - - -Version Numbered Files (files needing version string during minor upgrades): -====================== -.user.js -user.js -install.user.js -AutoTrimps2.js -Graphs.js -TODO: Should invent a tool/script to advance the version numbers, generate changelogs, auto-link docs. - -HOWTO = Become an AutoTrimps developer -====================================== -The script is setup to be able to be bootstrapped from Tampermonkey/Greasemonkey. -If you paste the AutoTrimps2.js into your Tampermonkey window directly, you can attempt to run a local developer copy and edit it in the tampermonkey edit window. This pulls from a repo and loads all the sub-modules .js files. -The point to understand is HTTPS and SSL is required. It has to be served over an actual HTTPS web-server so chrome can successfully load the secure content resources since https://trimps.github.io is technically the origin and any non-secure javascript resources will be flagged,denied and not-executed... -Simply, You can fork the project on github, find&replace my github URL with yours and upload all your changes to your own repo. And every time you make a change you will have to re-upload / defeat caching / reload to host the file. But this is non-ideal from a "agile" or "live" developer POV. -A better way is to set up a local HTTPS server, mirror my github repo to a local folder, and tell the webserver to run out of that folder, serving it up on https://localhost:4443 or some port number. -So instead of downloading Apache or a full complicated webserver or something, download python - or most computers these days have Python installed. You can use python to be a simple HTTP server with the following scripts, applicable to either Python2.x or Python3.x. -There are multiple ways to achieve the webserver, but this is the best way i've found (if it doesnt do HTTPS it wont work). -These scripts let you open a folder, double click the script, and start serving files out of that local dir instantly over HTTPS. -//(make sure you generate a self-signed .PEM cert to serve.) - this Cert is what provides the necessary SSL functionality - -# generate the cert with the following command (should be an openssl binary exe somewhere on the system) -# openssl req -new -x509 -keyout AutoTrimps.pem -out AutoTrimps.pem -days 365 -nodes -# run as follows: -# python https.py -# then in your browser, visit: -# https://localhost:4443 -# - -Choose the right version of https.py for your System: ----------------------------------------- -https.py = HTTPS Localhost Self serve - With Python 2: ----------------------------------------- -import BaseHTTPServer, SimpleHTTPServer -import ssl -httpd = BaseHTTPServer.HTTPServer(('localhost', 4443), SimpleHTTPServer.SimpleHTTPRequestHandler) -httpd.socket = ssl.wrap_socket (httpd.socket, certfile='./AutoTrimps.pem', server_side=True) -httpd.serve_forever() - ----------------------------------------- -https.py = HTTPS Localhost Self serve - With Python 3: ----------------------------------------- -import logging -import os -import sys -import http.server -import socketserver -import ssl -logging.info('Server running...') -httpd = socketserver.TCPServer(('localhost', 4443), http.server.SimpleHTTPRequestHandler) -httpd.socket = ssl.wrap_socket(httpd.socket, certfile='./AutoTrimps.pem', server_side=True) -httpd.serve_forever() - -//(make sure you generate a self-signed .PEM cert to serve.) - this Cert is what provides the necessary SSL functionality - -Make this batch script to double click to easily run the .py file from windows explorer without going to command line (mac/linux make a .sh file im sure you know how): --------------------- -SIMPLEHTTPSERVER.BAT --------------------- -@echo off -cd C:\Users\EOFL\Documents\GitHub\AutoTrimps -rem Infinite loop, counting from 1 to 10 with increment of 0. (just makes it restart on errors) -for /L %%n in (1,0,10) do ( - C:\Python36\python.exe https.py -) - - -HOWTO = Add A Button -===================== -All the buttons are created in SettingsGUI.js @ line 410 - with a function createSetting(): -This function takes 7 parameters and can make about 6 types of buttons: (boolean, value, valueNegative, dropdown, infoclick, multitoggle). The visual style will match similar. First determine the type of button, then copy a similar button. This explains the parameters: -function createSetting(id, name, description, type, defaultValue, list, container) -id = settings variable name -name = text on the button -description = tooltip when hovering inside the button. -type = boolean, value, valueNegative, dropdown, infoclick, multitoggle -defaultValue = pick the most common desirable setting -list = Only for dropdowns, the list of choices in ["one", "two", "three"] form -container = IMPORTANT: this will position the button in any of the tabbable sections "Main, Gear, Maps, Settings, Scryer" etc. - - These container tabs are what we will learn next: - -HOWTO = Add a New Tab (to the settings area.) -============================================= -All the tabs are created in SettingsGUI.js @ line 143 - the function is: initializeAllTabs(): -Inside there, follow the existing pattern and create a new line in the form of: - createTabs("Tab Name", "Tab Sub Heading"); - -Then you can use this new "Tab Name" as the container variable when you createSetting() and the button will go in there. - -HOWTO = Add a New Script Module -=============================== -AutoTrimps2.js is the module loader. Line 32: -var ATmodules = ['query', 'import-export', 'upgrades', 'heirlooms', 'buildings', 'jobs', 'equipment', 'gather', 'stance', 'battlecalc', 'maps', 'breedtimer', 'dynprestige', 'fight', 'scryer', 'magmite', 'portal', 'other', 'client-server', 'perks']; -They refer to .js files of the same name in the "modules" directory. -All you have to do is create a new file in modules/ named something.js and add ,'something' to the end of that list. -The script will then load it on startup, so it either has to run itself self-sufficiently, or you need to use ATs userscripts functionality to run it, something like this: -function userscripts() -{ - runModuleWhatever.FunctionFromThatModuleFile(); -} -Any function named userscripts will execute 10 times per second at the final portion of each game cycle. -This way means you can add your own code without contaminating AutoTrimps files directly. -Some Files contain/require game-code overwrites that need to be periodically checked and maintained. These are undocumented. Some are for the GUI and some are in utils.js maybe some for the heirlooms, and also graph loot... \ No newline at end of file diff --git a/docs/v2.1.5.1 b/docs/v2.1.5.1 deleted file mode 100644 index 1600aadd9..000000000 --- a/docs/v2.1.5.1 +++ /dev/null @@ -1,72 +0,0 @@ -v2.1.5.1 - 12/23/2016 -AutoTrimps2.js: -internals: fix module load order bug -move automaps re-enable after portal to mainCleanup -NEW: make AT use betterautofight on Zone 1 before Battle upgrade even when better autofight is disabled -internals: Change ATrunning variable - -docs/TODO.md: -Add a conversation about Void map difficulty so I dont forget - -Graphs.js -NEW: Add Magmite Graph -dont push updates if the game is paused. fix import on pause Clear Time problem -Change Loot Sources graph to 60 datapoints, every 15 seconds. -internals: refactor time graph functions -Change Dark Essence graph to be Total owned, not gained that run. -internals: refactor code for Dark Essence per Hour graph, adjust 0's zone alignment -internals: tried to change Loot Sources from having 0.5 tick lengths on the x-axis but failed. - -Autofight.js - Refactor; -betterAutoFight2 use lowLevelFight when scientist 1 is incomplete, not complete. -IMPORTANT: betterAutoFight2 dont use #3 when VoidMap is first ran (so it waits and loads your full Anticipation stacks) - -Automaps.js -add MODULE variable for SpireFarm199Maps -NEW: add a more efficient health check to make sure you can in fact kill the enemy on that specific cell you're on and you arent stuck on it due to it being fast and lack of health etc. -TODO: Account for magmated voidmaps. -TODO: Account for dailymods in voidmaps. -NEW: Change entire system of map sliders: - fixed bug where it was picking Metal maps at low level. - start all map sliders on 9/9/9 and decrement cost if needed based on priority that is assigned based on which situation. - -Autostance.js -Fix rare case when your enemyHealth == baseDamage -Fix some bugs in Autostance2 with Crit -Start fixing the scryer checkOnly thing but didnt finish. -NEW: (mentioned in automaps) autoStanceCheck now handles individual cell health checks that follow all the autostance rules (for automap) - -Battlecalc.js -Allow functions to be called with variables to disable stance correction and min/max damage range fluctuation. - -Buildings 1 & 2.js -Fix Green highlighting -NEW: Delay buying Gyms if we NEED gymystic - -Equipment.js -NEW: Skip buying shields (w/ shieldblock) if we NEED gymystic -Uncap Equipment levels during Metal Challenge - -Gather.js -Change Trapping Behavior, make it identical between gather1 and gather2. -Make sure watch challenge doesnt get stuck. - -Jobs.js -Only try to buy jobs (and therefore print message) if we can afford them. (reduce spam) -Add Auto Worker Ratios for Metal Challenge (acts somewhat weird but better than nothing) - -Other.js -TODO: coding the Auto Dimensional Generator (determined which functions to use) -TODO: start coding for Overclocker upgrade (need help/advice) - -Portal.js -NEW: AutoFinishDailyZone : Finish Daily by this # of zones earlier/later than your regular Custom AutoPortal zone or your Helium Dont Portal Before zone - -Utils.js -moved to mainLoop in AutoTrimps2.js - -SettingsGUI.js -Change wording to "Better" Auto Fight -AutoFinishDailyZone -TODO: Start coding the importModuleVars stuff for "Import your custom MODULES variables " -Create a way to make negative value boxes. \ No newline at end of file diff --git a/github/styles.css b/github/styles.css index 2e1768e14..a0739c56b 100644 --- a/github/styles.css +++ b/github/styles.css @@ -292,7 +292,7 @@ footer { padding:0; } - header ul, header p.view { + header ul, header .view { position:static; } diff --git a/highcharts.js b/highcharts.js new file mode 100644 index 000000000..42736c1f7 --- /dev/null +++ b/highcharts.js @@ -0,0 +1,581 @@ +/* + Highcharts JS v9.1.0 (2021-05-03) + + (c) 2009-2021 Torstein Honsi + + License: www.highcharts.com/license +*/ +(function(W,O){"object"===typeof module&&module.exports?(O["default"]=O,module.exports=W.document?O(W):O):"function"===typeof define&&define.amd?define("highcharts/highcharts",function(){return O(W)}):(W.Highcharts&&W.Highcharts.error(16,!0),W.Highcharts=O(W))})("undefined"!==typeof window?window:this,function(W){function O(D,b,e,z){D.hasOwnProperty(b)||(D[b]=z.apply(null,e))}var e={};O(e,"Core/Globals.js",[],function(){var D="undefined"!==typeof W?W:"undefined"!==typeof window?window:{},b;(function(b){b.SVG_NS= +"http://www.w3.org/2000/svg";b.product="Highcharts";b.version="9.1.0";b.win=D;b.doc=b.win.document;b.svg=b.doc&&b.doc.createElementNS&&!!b.doc.createElementNS(b.SVG_NS,"svg").createSVGRect;b.userAgent=b.win.navigator&&b.win.navigator.userAgent||"";b.isChrome=-1!==b.userAgent.indexOf("Chrome");b.isFirefox=-1!==b.userAgent.indexOf("Firefox");b.isMS=/(edge|msie|trident)/i.test(b.userAgent)&&!b.win.opera;b.isSafari=!b.isChrome&&-1!==b.userAgent.indexOf("Safari");b.isTouchDevice=/(Mobile|Android|Windows Phone)/.test(b.userAgent); +b.isWebKit=-1!==b.userAgent.indexOf("AppleWebKit");b.deg2rad=2*Math.PI/360;b.hasBidiBug=b.isFirefox&&4>parseInt(b.userAgent.split("Firefox/")[1],10);b.hasTouch=!!b.win.TouchEvent;b.marginNames=["plotTop","marginRight","marginBottom","plotLeft"];b.noop=function(){};b.supportsPassiveEvents=function(){var D=!1;if(!b.isMS){var e=Object.defineProperty({},"passive",{get:function(){D=!0}});b.win.addEventListener&&b.win.removeEventListener&&(b.win.addEventListener("testPassive",b.noop,e),b.win.removeEventListener("testPassive", +b.noop,e))}return D}();b.charts=[];b.dateFormats={};b.seriesTypes={};b.symbolSizes={}})(b||(b={}));return b});O(e,"Core/Utilities.js",[e["Core/Globals.js"]],function(D){function b(a,c,h,r){var y=c?"Highcharts error":"Highcharts warning";32===a&&(a=y+": Deprecated member");var d=w(a),M=d?y+" #"+a+": www.highcharts.com/errors/"+a+"/":a.toString();if("undefined"!==typeof r){var t="";d&&(M+="?");n(r,function(p,a){t+="\n - "+a+": "+p;d&&(M+=encodeURI(a)+"="+encodeURI(p))});M+=t}E(Highcharts,"displayError", +{chart:h,code:a,message:M,params:r},function(){if(c)throw Error(M);g.console&&-1===b.messages.indexOf(M)&&console.warn(M)});b.messages.push(M)}function e(a,c){var y={};n(a,function(g,h){if(C(a[h],!0)&&!a.nodeType&&c[h])g=e(a[h],c[h]),Object.keys(g).length&&(y[h]=g);else if(C(a[h])||a[h]!==c[h])y[h]=a[h]});return y}function z(a,c){return parseInt(a,c||10)}function H(a){return"string"===typeof a}function G(a){a=Object.prototype.toString.call(a);return"[object Array]"===a||"[object Array Iterator]"=== +a}function C(a,c){return!!a&&"object"===typeof a&&(!c||!G(a))}function B(a){return C(a)&&"number"===typeof a.nodeType}function x(a){var c=a&&a.constructor;return!(!C(a,!0)||B(a)||!c||!c.name||"Object"===c.name)}function w(a){return"number"===typeof a&&!isNaN(a)&&Infinity>a&&-Infinity=c-1&&(c=Math.floor(h)),Math.max(0,c-(y(a,"padding-left",!0)||0)-(y(a,"padding-right",!0)||0));if("height"===c)return Math.max(0,Math.min(a.offsetHeight,a.scrollHeight)-(y(a,"padding-top",!0)||0)-(y(a,"padding-bottom",!0)||0));g.getComputedStyle||b(27,!0);if(a=g.getComputedStyle(a,void 0)){var r=a.getPropertyValue(c);q(h,"opacity"!== +c)&&(r=z(r))}return r}function n(a,c,g){for(var h in a)Object.hasOwnProperty.call(a,h)&&c.call(g||a[h],a[h],h,a)}function J(a,c,g){function h(t,p){var c=a.removeEventListener||D.removeEventListenerPolyfill;c&&c.call(a,t,p,!1)}function y(t){var p;if(a.nodeName){if(c){var g={};g[c]=!0}else g=t;n(g,function(a,c){if(t[c])for(p=t[c].length;p--;)h(c,t[c][p].fn)})}}var r="function"===typeof a&&a.prototype||a;if(Object.hasOwnProperty.call(r,"hcEvents")){var M=r.hcEvents;c?(r=M[c]||[],g?(M[c]=r.filter(function(a){return g!== +a.fn}),h(c,g)):(y(M),M[c]=[])):(y(M),delete r.hcEvents)}}function E(a,g,h,r){h=h||{};if(c.createEvent&&(a.dispatchEvent||a.fireEvent&&a!==D)){var y=c.createEvent("Events");y.initEvent(g,!0,!0);h=d(y,h);a.dispatchEvent?a.dispatchEvent(h):a.fireEvent(g,h)}else if(a.hcEvents){h.target||d(h,{preventDefault:function(){h.defaultPrevented=!0},target:a,type:g});y=[];for(var m=a,M=!1;m.hcEvents;)Object.hasOwnProperty.call(m,"hcEvents")&&m.hcEvents[g]&&(y.length&&(M=!0),y.unshift.apply(y,m.hcEvents[g])),m= +Object.getPrototypeOf(m);M&&y.sort(function(a,p){return a.order-p.order});y.forEach(function(t){!1===t.fn.call(a,h)&&h.preventDefault()})}r&&!h.defaultPrevented&&r.call(a,h)}var m=D.charts,c=D.doc,g=D.win;"";(b||(b={})).messages=[];var a;Math.easeInOutSine=function(a){return-.5*(Math.cos(Math.PI*a)-1)};var h=Array.prototype.find?function(a,c){return a.find(c)}:function(a,c){var g,h=a.length;for(g=0;gg&&(g=a[c]);return g},arrayMin:function(a){for(var c=a.length,g=a[0];c--;)a[c]c?a=g&&(c=[1/g])));for(h=0;h=a||!r&&M<=(c[h]+(c[h+1]||c[h]))/2);h++);return d=N(d*g,-Math.round(Math.log(.001)/ +Math.LN10))},objectEach:n,offset:function(a){var h=c.documentElement;a=a.parentElement||a.parentNode?a.getBoundingClientRect():{top:0,left:0,width:0,height:0};return{top:a.top+(g.pageYOffset||h.scrollTop)-(h.clientTop||0),left:a.left+(g.pageXOffset||h.scrollLeft)-(h.clientLeft||0),width:a.width,height:a.height}},pad:function(a,c,g){return Array((c||2)+1-String(a).replace("-","").length).join(g||"0")+a},pick:q,pInt:z,relativeLength:function(a,c,g){return/%$/.test(a)?c*parseFloat(a)/100+(g||0):parseFloat(a)}, +removeEvent:J,splat:function(a){return G(a)?a:[a]},stableSort:function(a,c){var g=a.length,h,r;for(r=0;r>16,(e&65280)>>8,e&255,1]:4===w&&(B=[(e&3840)>>4|(e&3840)>>8,(e&240)>>4|e&240,(e&15)<<4|e&15,1])}if(!B)for(x=this.parsers.length;x--&&!B;){var v=this.parsers[x];(w=v.regex.exec(e))&&(B=v.parse(w))}}this.rgba=B||[]};b.prototype.get=function(b){var B=this.input,x=this.rgba;if("undefined"!==typeof this.stops){var w=z(B);w.stops=[].concat(w.stops);this.stops.forEach(function(v,f){w.stops[f]=[w.stops[f][0],v.get(b)]})}else w=x&&e(x[0])?"rgb"=== +b||!b&&1===x[3]?"rgb("+x[0]+","+x[1]+","+x[2]+")":"a"===b?x[3]:"rgba("+x.join(",")+")":B;return w};b.prototype.brighten=function(b){var B,x=this.rgba;if(this.stops)this.stops.forEach(function(w){w.brighten(b)});else if(e(b)&&0!==b)for(B=0;3>B;B++)x[B]+=H(255*b),0>x[B]&&(x[B]=0),255k?"AM":"PM",P:12>k?"am":"pm",S:w(n.getSeconds()),L:w(Math.floor(f%1E3),3)},e.dateFormats);x(n,function(a,c){for(;-1!==d.indexOf("%"+c);)d=d.replace("%"+c,"function"=== +typeof a?a.call(l,f):a)});return q?d.substr(0,1).toUpperCase()+d.substr(1):d};q.prototype.resolveDTLFormat=function(d){return C(d,!0)?d:(d=f(d),{main:d[0],from:d[1],to:d[2]})};q.prototype.getTimeTicks=function(f,l,q,u){var n=this,k=[],N={};var m=new n.Date(l);var c=f.unitRange,g=f.count||1,a;u=v(u,1);if(z(l)){n.set("Milliseconds",m,c>=d.second?0:g*Math.floor(n.get("Milliseconds",m)/g));c>=d.second&&n.set("Seconds",m,c>=d.minute?0:g*Math.floor(n.get("Seconds",m)/g));c>=d.minute&&n.set("Minutes",m, +c>=d.hour?0:g*Math.floor(n.get("Minutes",m)/g));c>=d.hour&&n.set("Hours",m,c>=d.day?0:g*Math.floor(n.get("Hours",m)/g));c>=d.day&&n.set("Date",m,c>=d.month?1:Math.max(1,g*Math.floor(n.get("Date",m)/g)));if(c>=d.month){n.set("Month",m,c>=d.year?0:g*Math.floor(n.get("Month",m)/g));var h=n.get("FullYear",m)}c>=d.year&&n.set("FullYear",m,h-h%g);c===d.week&&(h=n.get("Day",m),n.set("Date",m,n.get("Date",m)-h+u+(h4*d.month||n.getTimezoneOffset(l)!==n.getTimezoneOffset(q));l=m.getTime();for(m=1;lk.length&&k.forEach(function(a){0===a%18E5&&"000000000"===n.dateFormat("%H%M%S%L",a)&&(N[a]="day")})}k.info=G(f,{higherRanks:N,totalRange:c* +g});return k};return q}();e.Time=b;return e.Time});O(e,"Core/Options.js",[e["Core/Globals.js"],e["Core/Color/Color.js"],e["Core/Color/Palette.js"],e["Core/Time.js"],e["Core/Utilities.js"]],function(e,b,I,z,H){var D=e.isTouchDevice,C=e.svg;b=b.parse;var B=H.merge;"";var x={colors:I.colors,symbols:["circle","diamond","square","triangle","triangle-down"],lang:{loading:"Loading...",months:"January February March April May June July August September October November December".split(" "),shortMonths:"Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "), +weekdays:"Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" "),decimalPoint:".",numericSymbols:"kMGTPE".split(""),resetZoom:"Reset zoom",resetZoomTitle:"Reset zoom level 1:1",thousandsSep:" "},global:{},time:{Date:void 0,getTimezoneOffset:void 0,timezone:void 0,timezoneOffset:0,useUTC:!0},chart:{panning:{enabled:!1,type:"x"},styledMode:!1,borderRadius:0,colorCount:10,defaultSeriesType:"line",ignoreHiddenSeries:!0,spacing:[10,10,15,10],resetZoomButton:{theme:{zIndex:6},position:{align:"right", +x:-10,y:10}},zoomBySingleTouch:!1,width:null,height:null,borderColor:I.highlightColor80,backgroundColor:I.backgroundColor,plotBorderColor:I.neutralColor20},title:{text:"Chart title",align:"center",margin:15,widthAdjust:-44},subtitle:{text:"",align:"center",widthAdjust:-44},caption:{margin:15,text:"",align:"left",verticalAlign:"bottom"},plotOptions:{},labels:{style:{position:"absolute",color:I.neutralColor80}},legend:{enabled:!0,align:"center",alignColumns:!0,layout:"horizontal",labelFormatter:function(){return this.name}, +borderColor:I.neutralColor40,borderRadius:0,navigation:{activeColor:I.highlightColor100,inactiveColor:I.neutralColor20},itemStyle:{color:I.neutralColor80,cursor:"pointer",fontSize:"12px",fontWeight:"bold",textOverflow:"ellipsis"},itemHoverStyle:{color:I.neutralColor100},itemHiddenStyle:{color:I.neutralColor20},shadow:!1,itemCheckboxStyle:{position:"absolute",width:"13px",height:"13px"},squareSymbol:!0,symbolPadding:5,verticalAlign:"bottom",x:0,y:0,title:{style:{fontWeight:"bold"}}},loading:{labelStyle:{fontWeight:"bold", +position:"relative",top:"45%"},style:{position:"absolute",backgroundColor:I.backgroundColor,opacity:.5,textAlign:"center"}},tooltip:{enabled:!0,animation:C,borderRadius:3,dateTimeLabelFormats:{millisecond:"%A, %b %e, %H:%M:%S.%L",second:"%A, %b %e, %H:%M:%S",minute:"%A, %b %e, %H:%M",hour:"%A, %b %e, %H:%M",day:"%A, %b %e, %Y",week:"Week from %A, %b %e, %Y",month:"%B %Y",year:"%Y"},footerFormat:"",padding:8,snap:D?25:10,headerFormat:'{point.key}
',pointFormat:'\u25cf {series.name}: {point.y}
', +backgroundColor:b(I.neutralColor3).setOpacity(.85).get(),borderWidth:1,shadow:!0,style:{color:I.neutralColor80,cursor:"default",fontSize:"12px",whiteSpace:"nowrap"}},credits:{enabled:!0,href:"https://www.highcharts.com?credits",position:{align:"right",x:-10,verticalAlign:"bottom",y:-5},style:{cursor:"pointer",color:I.neutralColor40,fontSize:"9px"},text:"Highcharts.com"}};x.chart.styledMode=!1;"";var w=new z(B(x.global,x.time));return{defaultOptions:x,defaultTime:w,getOptions:function(){return x}, +setOptions:function(v){B(!0,x,v);if(v.time||v.global)e.time?e.time.update(B(x.global,x.time,v.global,v.time)):e.time=w;return x}}});O(e,"Core/Animation/Fx.js",[e["Core/Color/Color.js"],e["Core/Globals.js"],e["Core/Utilities.js"]],function(e,b,I){var D=e.parse,H=b.win,G=I.isNumber,C=I.objectEach;return function(){function b(b,w,v){this.pos=NaN;this.options=w;this.elem=b;this.prop=v}b.prototype.dSetter=function(){var b=this.paths,w=b&&b[0];b=b&&b[1];var v=this.now||0,f=[];if(1!==v&&w&&b)if(w.length=== +b.length&&1>v)for(var d=0;d=q+this.startTime){this.now=this.end;this.pos=1;this.update();var l=k[this.prop]=!0;C(k,function(d){!0!==d&&(l=!1)});l&&d&&d.call(f);b=!1}else this.pos=v.easing((w-this.startTime)/q),this.now=this.start+(this.end-this.start)*this.pos,this.update(),b=!0;return b};b.prototype.initPath=function(b,w,v){function f(d,m){for(;d.lengthl[1]){var u=v+ +l[1];0<=u?(l[0]=(+l[0]).toExponential(u).split("e")[0],v=u):(l[0]=l[0].split(".")[0]||0,b=20>v?(l[0]*Math.pow(10,l[1])).toFixed(v): +0,l[1]=0)}u=(Math.abs(l[1]?l[0]:b)+Math.pow(10,-Math.max(v,k)-1)).toFixed(v);k=String(x(u));var n=3b?"-":"")+(n?k.substr(0,n)+d:"");b=0>+l[1]&&!N?"0":b+k.substr(n).replace(/(\d{3})(?=\d)/g,"$1"+d);v&&(b+=f+u.slice(-v));l[1]&&0!==+b&&(b+="e"+l[1]);return b}var z=e.defaultOptions,H=e.defaultTime,G=b.getNestedProperty,C=b.isNumber,B=b.pick,x=b.pInt;return{dateFormat:function(b,v,f){return H.dateFormat(b,v,f)},format:function(b,v, +f){var d="{",q=!1,k=/f$/,l=/\.([0-9])/,N=z.lang,u=f&&f.time||H;f=f&&f.numberFormatter||D;for(var n=[];b;){var J=b.indexOf(d);if(-1===J)break;var E=b.slice(0,J);if(q){E=E.split(":");d=G(E.shift()||"",v);if(E.length&&"number"===typeof d)if(E=E.join(":"),k.test(E)){var m=parseInt((E.match(l)||["","-1"])[1],10);null!==d&&(d=f(d,m,N.decimalPoint,-1f.width)f={width:0, +height:0}}else f=this.htmlGetBBox();p.isSVG&&(c=f.width,p=f.height,K&&(f.height=p={"11px,17":14,"13px,20":16}[d&&d.fontSize+","+Math.round(p)]||p),t&&(d=t*w,f.width=Math.abs(p*Math.sin(d))+Math.abs(c*Math.cos(d)),f.height=Math.abs(p*Math.cos(d))+Math.abs(c*Math.sin(d))));if(b&&0]*>/g,"").replace(/</g,"<").replace(/>/g, +">")};e.prototype.toFront=function(){var a=this.element;a.parentNode.appendChild(a);return this};e.prototype.translate=function(a,c){return this.attr({translateX:a,translateY:c})};e.prototype.updateShadows=function(a,c,p){var t=this.shadows;if(t)for(var g=t.length;g--;)p.call(t[g],"height"===a?Math.max(c-(t[g].cutHeight||0),0):"d"===a?this.d:c,a,t[g])};e.prototype.updateTransform=function(){var a=this.scaleX,c=this.scaleY,p=this.inverted,g=this.rotation,d=this.matrix,h=this.element,F=this.translateX|| +0,r=this.translateY||0;p&&(F+=this.width,r+=this.height);F=["translate("+F+","+r+")"];J(d)&&F.push("matrix("+d.join(",")+")");p?F.push("rotate(90) scale(-1,1)"):g&&F.push("rotate("+g+" "+L(this.rotationOriginX,h.getAttribute("x"),0)+" "+L(this.rotationOriginY,h.getAttribute("y")||0)+")");(J(a)||J(c))&&F.push("scale("+L(a,1)+" "+L(c,1)+")");F.length&&h.setAttribute("transform",F.join(" "))};e.prototype.visibilitySetter=function(a,c,p){"inherit"===a?p.removeAttribute(c):this[c]!==a&&p.setAttribute(c, +a);this[c]=a};e.prototype.xGetter=function(a){"circle"===this.element.nodeName&&("x"===a?a="cx":"y"===a&&(a="cy"));return this._defaultGetter(a)};e.prototype.zIndexSetter=function(a,c){var p=this.renderer,g=this.parentGroup,t=(g||p).element||p.box,d=this.element;p=t===p.box;var h=!1;var r=this.added;var K;J(a)?(d.setAttribute("data-z-index",a),a=+a,this[c]===a&&(r=!1)):J(this[c])&&d.removeAttribute("data-z-index");this[c]=a;if(r){(a=this.zIndex)&&g&&(g.handleZ=!0);c=t.childNodes;for(K=c.length-1;0<= +K&&!h;K--){g=c[K];r=g.getAttribute("data-z-index");var m=!J(r);if(g!==d)if(0>a&&m&&!p&&!K)t.insertBefore(d,c[K]),h=!0;else if(P(r)<=a||m&&(!J(a)||0<=a))t.insertBefore(d,c[K+1]||null),h=!0}h||(t.insertBefore(d,c[p?3:0]||null),h=!0)}return h};return e}();e.prototype["stroke-widthSetter"]=e.prototype.strokeSetter;e.prototype.yGetter=e.prototype.xGetter;e.prototype.matrixSetter=e.prototype.rotationOriginXSetter=e.prototype.rotationOriginYSetter=e.prototype.rotationSetter=e.prototype.scaleXSetter=e.prototype.scaleYSetter= +e.prototype.translateXSetter=e.prototype.translateYSetter=e.prototype.verticalAlignSetter=function(a,c){this[c]=a;this.doTransform=!0};"";return e});O(e,"Core/Renderer/SVG/SVGLabel.js",[e["Core/Renderer/SVG/SVGElement.js"],e["Core/Utilities.js"]],function(e,b){function D(b,f){C(b)?b!==this[f]&&(this[f]=b,this.updateTextPadding()):this[f]=void 0}var z=this&&this.__extends||function(){var b=function(f,d){b=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(d,b){d.__proto__=b}||function(d, +b){for(var f in b)b.hasOwnProperty(f)&&(d[f]=b[f])};return b(f,d)};return function(f,d){function q(){this.constructor=f}b(f,d);f.prototype=null===d?Object.create(d):(q.prototype=d.prototype,new q)}}(),H=b.defined,G=b.extend,C=b.isNumber,B=b.merge,x=b.pick,w=b.removeEvent;return function(b){function f(d,q,k,l,e,u,n,v,E,m){var c=b.call(this)||this;c.paddingSetter=D;c.paddingLeftSetter=D;c.paddingRightSetter=D;c.init(d,"g");c.textStr=q;c.x=k;c.y=l;c.anchorX=u;c.anchorY=n;c.baseline=E;c.className=m;"button"!== +m&&c.addClass("highcharts-label");m&&c.addClass("highcharts-"+m);c.text=d.text("",0,0,v).attr({zIndex:1});if("string"===typeof e){var g=/^url\((.*?)\)$/.test(e);if(c.renderer.symbols[e]||g)c.symbolKey=e}c.bBox=f.emptyBBox;c.padding=3;c.baselineOffset=0;c.needsBox=d.styledMode||g;c.deferredAttr={};c.alignFactor=0;return c}z(f,b);f.prototype.alignSetter=function(d){d={left:0,center:.5,right:1}[d];d!==this.alignFactor&&(this.alignFactor=d,this.bBox&&C(this.xSetting)&&this.attr({x:this.xSetting}))};f.prototype.anchorXSetter= +function(d,b){this.anchorX=d;this.boxAttr(b,Math.round(d)-this.getCrispAdjust()-this.xSetting)};f.prototype.anchorYSetter=function(d,b){this.anchorY=d;this.boxAttr(b,d-this.ySetting)};f.prototype.boxAttr=function(d,b){this.box?this.box.attr(d,b):this.deferredAttr[d]=b};f.prototype.css=function(d){if(d){var b={},k=void 0;d=B(d);f.textProps.forEach(function(f){"undefined"!==typeof d[f]&&(b[f]=d[f],delete d[f])});this.text.css(b);k="width"in b;"fontSize"in b||"fontWeight"in b?this.updateTextPadding(): +k&&this.updateBoxSize()}return e.prototype.css.call(this,d)};f.prototype.destroy=function(){w(this.element,"mouseenter");w(this.element,"mouseleave");this.text&&this.text.destroy();this.box&&(this.box=this.box.destroy());e.prototype.destroy.call(this)};f.prototype.fillSetter=function(d,b){d&&(this.needsBox=!0);this.fill=d;this.boxAttr(b,d)};f.prototype.getBBox=function(){this.textStr&&0===this.bBox.width&&0===this.bBox.height&&this.updateBoxSize();var d=this.padding,b=x(this.paddingLeft,d);return{width:this.width, +height:this.height,x:this.bBox.x-b,y:this.bBox.y-d}};f.prototype.getCrispAdjust=function(){return this.renderer.styledMode&&this.box?this.box.strokeWidth()%2/2:(this["stroke-width"]?parseInt(this["stroke-width"],10):0)%2/2};f.prototype.heightSetter=function(d){this.heightSetting=d};f.prototype.on=function(d,b){var f=this,l=f.text,q=l&&"SPAN"===l.element.tagName?l:void 0;if(q){var u=function(l){("mouseenter"===d||"mouseleave"===d)&&l.relatedTarget instanceof Element&&(f.element.compareDocumentPosition(l.relatedTarget)& +Node.DOCUMENT_POSITION_CONTAINED_BY||q.element.compareDocumentPosition(l.relatedTarget)&Node.DOCUMENT_POSITION_CONTAINED_BY)||b.call(f.element,l)};q.on(d,u)}e.prototype.on.call(f,d,u||b);return f};f.prototype.onAdd=function(){var d=this.textStr;this.text.add(this);this.attr({text:H(d)?d:"",x:this.x,y:this.y});this.box&&H(this.anchorX)&&this.attr({anchorX:this.anchorX,anchorY:this.anchorY})};f.prototype.rSetter=function(d,b){this.boxAttr(b,d)};f.prototype.shadow=function(d){d&&!this.renderer.styledMode&& +(this.updateBoxSize(),this.box&&this.box.shadow(d));return this};f.prototype.strokeSetter=function(d,b){this.stroke=d;this.boxAttr(b,d)};f.prototype["stroke-widthSetter"]=function(d,b){d&&(this.needsBox=!0);this["stroke-width"]=d;this.boxAttr(b,d)};f.prototype["text-alignSetter"]=function(d){this.textAlign=d};f.prototype.textSetter=function(d){"undefined"!==typeof d&&this.text.attr({text:d});this.updateTextPadding()};f.prototype.updateBoxSize=function(){var d=this.text.element.style,b={},e=this.padding, +l=this.bBox=C(this.widthSetting)&&C(this.heightSetting)&&!this.textAlign||!H(this.text.textStr)?f.emptyBBox:this.text.getBBox();this.width=this.getPaddedWidth();this.height=(this.heightSetting||l.height||0)+2*e;this.baselineOffset=e+Math.min(this.renderer.fontMetrics(d&&d.fontSize,this.text).b,l.height||Infinity);this.needsBox&&(this.box||(d=this.box=this.symbolKey?this.renderer.symbol(this.symbolKey):this.renderer.rect(),d.addClass(("button"===this.className?"":"highcharts-label-box")+(this.className? +" highcharts-"+this.className+"-box":"")),d.add(this)),d=this.getCrispAdjust(),b.x=d,b.y=(this.baseline?-this.baselineOffset:0)+d,b.width=Math.round(this.width),b.height=Math.round(this.height),this.box.attr(G(b,this.deferredAttr)),this.deferredAttr={})};f.prototype.updateTextPadding=function(){var d=this.text;this.updateBoxSize();var b=this.baseline?0:this.baselineOffset,f=x(this.paddingLeft,this.padding);H(this.widthSetting)&&this.bBox&&("center"===this.textAlign||"right"===this.textAlign)&&(f+= +{center:.5,right:1}[this.textAlign]*(this.widthSetting-this.bBox.width));if(f!==d.x||b!==d.y)d.attr("x",f),d.hasBoxWidthChanged&&(this.bBox=d.getBBox(!0)),"undefined"!==typeof b&&d.attr("y",b);d.x=f;d.y=b};f.prototype.widthSetter=function(d){this.widthSetting=C(d)?d:void 0};f.prototype.getPaddedWidth=function(){var d=this.padding,b=x(this.paddingLeft,d);d=x(this.paddingRight,d);return(this.widthSetting||this.bBox.width||0)+b+d};f.prototype.xSetter=function(d){this.x=d;this.alignFactor&&(d-=this.alignFactor* +this.getPaddedWidth(),this["forceAnimate:x"]=!0);this.xSetting=Math.round(d);this.attr("translateX",this.xSetting)};f.prototype.ySetter=function(d){this.ySetting=this.y=Math.round(d);this.attr("translateY",this.ySetting)};f.emptyBBox={width:0,height:0,x:0,y:0};f.textProps="color direction fontFamily fontSize fontStyle fontWeight lineHeight textAlign textDecoration textOutline textOverflow width".split(" ");return f}(e)});O(e,"Core/Renderer/SVG/TextBuilder.js",[e["Core/Globals.js"],e["Core/Utilities.js"], +e["Core/Renderer/HTML/AST.js"]],function(e,b,I){var D=e.doc,H=e.SVG_NS,G=b.attr,C=b.isString,B=b.objectEach,x=b.pick;return function(){function b(b){var f=b.styles;this.renderer=b.renderer;this.svgElement=b;this.width=b.textWidth;this.textLineHeight=f&&f.lineHeight;this.textOutline=f&&f.textOutline;this.ellipsis=!(!f||"ellipsis"!==f.textOverflow);this.noWrap=!(!f||"nowrap"!==f.whiteSpace);this.fontSize=f&&f.fontSize}b.prototype.buildSVG=function(){var b=this.svgElement,f=b.element,d=b.renderer,e= +x(b.textStr,"").toString(),k=-1!==e.indexOf("<"),l=f.childNodes,N=l.length;d=this.width&&!b.added&&d.box;var u=//g;var n=[e,this.ellipsis,this.noWrap,this.textLineHeight,this.textOutline,this.fontSize,this.width].join();if(n!==b.textCache){b.textCache=n;for(delete b.actualWidth;N--;)f.removeChild(l[N]);k||this.ellipsis||this.width||-1!==e.indexOf(" ")&&(!this.noWrap||u.test(e))?""!==e&&(d&&d.appendChild(f),e=new I(e),this.modifyTree(e.nodes),e.addToDOM(b.element),this.modifyDOM(),this.ellipsis&& +-1!==(f.textContent||"").indexOf("\u2026")&&b.attr("title",this.unescapeEntities(b.textStr||"",["<",">"])),d&&d.removeChild(f)):f.appendChild(D.createTextNode(this.unescapeEntities(e)));C(this.textOutline)&&b.applyTextOutline&&b.applyTextOutline(this.textOutline)}};b.prototype.modifyDOM=function(){var b=this,f=this.svgElement,d=G(f.element,"x");[].forEach.call(f.element.querySelectorAll("tspan.highcharts-br"),function(f){f.nextSibling&&f.previousSibling&&G(f,{dy:b.getLineHeight(f.nextSibling), +x:d})});var e=this.width||0;if(e){var k=function(l,u){var n=l.textContent||"",k=n.replace(/([^\^])-/g,"$1- ").split(" "),q=!b.noWrap&&(1k){for(;E<=m;)c=Math.ceil((E+m)/2),d&&(g=l(d,c)),h=a(c,g&&g.length-1),E===m?E=m+1:h>k?m=c-1:E=c;0===m?b.textContent="":f&&m===f.length-1||(b.textContent=g||l(f||d,c))}d&&d.splice(0,c);q.actualWidth=h;q.rotation=n};b.prototype.unescapeEntities=function(b,f){B(this.renderer.escapes,function(d,e){f&&-1!==f.indexOf(d)||(b=b.toString().replace(new RegExp(d,"g"),e))});return b};return b}()});O(e,"Core/Renderer/SVG/SVGRenderer.js",[e["Core/Color/Color.js"],e["Core/Globals.js"],e["Core/Color/Palette.js"], +e["Core/Renderer/SVG/SVGElement.js"],e["Core/Renderer/SVG/SVGLabel.js"],e["Core/Renderer/HTML/AST.js"],e["Core/Renderer/SVG/TextBuilder.js"],e["Core/Utilities.js"]],function(e,b,I,z,H,G,C,B){var x=B.addEvent,w=B.attr,v=B.createElement,f=B.css,d=B.defined,q=B.destroyObjectProperties,k=B.extend,l=B.isArray,N=B.isNumber,u=B.isObject,n=B.isString,J=B.merge,E=B.pick,m=B.pInt,c=B.uniqueKey,g=b.charts,a=b.deg2rad,h=b.doc,r=b.isFirefox,A=b.isMS,y=b.isWebKit,L=b.noop,P=b.SVG_NS,R=b.symbolSizes,V=b.win,Q;B= +function(){function t(a,c,g,t,d,h,r){this.width=this.url=this.style=this.isSVG=this.imgCount=this.height=this.gradients=this.globalAnimation=this.defs=this.chartIndex=this.cacheKeys=this.cache=this.boxWrapper=this.box=this.alignedObjects=void 0;this.init(a,c,g,t,d,h,r)}t.prototype.init=function(a,c,g,t,d,b,K){var p=this.createElement("svg").attr({version:"1.1","class":"highcharts-root"});K||p.css(this.getStyle(t));t=p.element;a.appendChild(t);w(a,"dir","ltr");-1===a.innerHTML.indexOf("xmlns")&&w(t, +"xmlns",this.SVG_NS);this.isSVG=!0;this.box=t;this.boxWrapper=p;this.alignedObjects=[];this.url=this.getReferenceURL();this.createElement("desc").add().element.appendChild(h.createTextNode("Created with Highcharts 9.1.0"));this.defs=this.createElement("defs").add();this.allowHTML=b;this.forExport=d;this.styledMode=K;this.gradients={};this.cache={};this.cacheKeys=[];this.imgCount=0;this.setSize(c,g,!1);var F;r&&a.getBoundingClientRect&&(c=function(){f(a,{left:0,top:0});F=a.getBoundingClientRect(); +f(a,{left:Math.ceil(F.left)-F.left+"px",top:Math.ceil(F.top)-F.top+"px"})},c(),this.unSubPixelFix=x(V,"resize",c))};t.prototype.definition=function(a){return(new G([a])).addToDOM(this.defs.element)};t.prototype.getReferenceURL=function(){if((r||y)&&h.getElementsByTagName("base").length){if(!d(Q)){var a=c();a=(new G([{tagName:"svg",attributes:{width:8,height:8},children:[{tagName:"defs",children:[{tagName:"clipPath",attributes:{id:a},children:[{tagName:"rect",attributes:{width:4,height:4}}]}]},{tagName:"rect", +attributes:{id:"hitme",width:8,height:8,"clip-path":"url(#"+a+")",fill:"rgba(0,0,0,0.001)"}}]}])).addToDOM(h.body);f(a,{position:"fixed",top:0,left:0,zIndex:9E5});var g=h.elementFromPoint(6,6);Q="hitme"===(g&&g.id);h.body.removeChild(a)}if(Q)return V.location.href.split("#")[0].replace(/<[^>]*>/g,"").replace(/([\('\)])/g,"\\$1").replace(/ /g,"%20")}return""};t.prototype.getStyle=function(a){return this.style=k({fontFamily:'"Lucida Grande", "Lucida Sans Unicode", Arial, Helvetica, sans-serif',fontSize:"12px"}, +a)};t.prototype.setStyle=function(a){this.boxWrapper.css(this.getStyle(a))};t.prototype.isHidden=function(){return!this.boxWrapper.getBBox().width};t.prototype.destroy=function(){var a=this.defs;this.box=null;this.boxWrapper=this.boxWrapper.destroy();q(this.gradients||{});this.gradients=null;a&&(this.defs=a.destroy());this.unSubPixelFix&&this.unSubPixelFix();return this.alignedObjects=null};t.prototype.createElement=function(a){var c=new this.Element;c.init(this,a);return c};t.prototype.getRadialAttr= +function(a,c){return{cx:a[0]-a[2]/2+(c.cx||0)*a[2],cy:a[1]-a[2]/2+(c.cy||0)*a[2],r:(c.r||0)*a[2]}};t.prototype.buildText=function(a){(new C(a)).buildSVG()};t.prototype.getContrast=function(a){a=e.parse(a).rgba;a[0]*=1;a[1]*=1.2;a[2]*=.5;return 459a?a+3:Math.round(1.2*a);return{h:c,b:Math.round(.8*c),f:a}};t.prototype.rotCorr=function(c,g,t){var p=c;g&&t&&(p=Math.max(p*Math.cos(g*a),4));return{x:-c/3*Math.sin(g*a),y:p}};t.prototype.pathToSegments=function(a){for(var c=[],g=[],p={A:8,C:7,H:2,L:3,M:3,Q:5,S:5,T:3,V:2},t=0;t":">","'":"'",'"':"""};var M=function(a,c,g,d,h){h=h&&h.r||0;return[["M",a+h,c],["L",a+g-h,c],["C",a+g,c,a+g,c,a+g,c+h],["L",a+g,c+d-h],["C",a+g,c+d,a+g,c+d,a+ +g-h,c+d],["L",a+h,c+d],["C",a,c+d,a,c+d,a,c+d-h],["L",a,c+h],["C",a,c,a,c,a+h,c]]};L=function(a,c,g,d,h){return h&&h.r?M(a,c,g,d,h):[["M",a,c],["L",a+g,c],["L",a+g,c+d],["L",a,c+d],["Z"]]};B.prototype.symbols={circle:function(a,c,g,d){return this.arc(a+g/2,c+d/2,g/2,d/2,{start:.5*Math.PI,end:2.5*Math.PI,open:!1})},rect:L,square:L,triangle:function(a,c,g,d){return[["M",a+g/2,c],["L",a+g,c+d],["L",a,c+d],["Z"]]},"triangle-down":function(a,c,g,d){return[["M",a,c],["L",a+g,c],["L",a+g/2,c+d],["Z"]]}, +diamond:function(a,c,g,d){return[["M",a+g/2,c],["L",a+g,c+d/2],["L",a+g/2,c+d],["L",a,c+d/2],["Z"]]},arc:function(a,c,g,h,r){var t=[];if(r){var p=r.start||0,b=E(r.r,g);g=E(r.r,h||g);var m=(r.end||0)-.001;h=r.innerR;var f=E(r.open,.001>Math.abs((r.end||0)-p-2*Math.PI)),A=Math.cos(p),y=Math.sin(p),l=Math.cos(m),n=Math.sin(m);p=E(r.longArc,.001>m-p-Math.PI?0:1);t.push(["M",a+b*A,c+g*y],["A",b,g,0,p,E(r.clockwise,1),a+b*l,c+g*n]);d(h)&&t.push(f?["M",a+h*l,c+h*n]:["L",a+h*l,c+h*n],["A",h,h,0,p,d(r.clockwise)? +1-r.clockwise:0,a+h*A,c+h*y]);f||t.push(["Z"])}return t},callout:function(a,c,g,d,h){var p=Math.min(h&&h.r||0,g,d),t=p+6,r=h&&h.anchorX;h=h&&h.anchorY||0;var b=M(a,c,g,d,{r:p});if(!N(r))return b;a+r>=g?h>c+t&&h=a+r?h>c+t&&hd&&r>a+t&&rh&&r>a+t&&rthis.oldTextWidth)&&((a=this.textPxLength)||(B(b,{width:"",whiteSpace:E||"nowrap"}),a=b.offsetWidth),a=a>c);a&&(/[ \-]/.test(b.textContent||b.innerText)||"ellipsis"===b.style.textOverflow)?(B(b,{width:c+"px",display:"block",whiteSpace:E||"normal"}),this.oldTextWidth=c,this.hasBoxWidthChanged=!0):this.hasBoxWidthChanged=!1;g!==this.cTT&&(c=d.fontMetrics(b.style.fontSize,b).b,!x(m)||m===(this.oldRotation||0)&&n===this.oldAlign||this.setSpanRotation(m,J,c),this.getSpanCorrection(!x(m)&& +this.textPxLength||b.offsetWidth,c,J,m,n));B(b,{left:N+(this.xCorr||0)+"px",top:u+(this.yCorr||0)+"px"});this.cTT=g;this.oldRotation=m;this.oldAlign=n}}else this.alignOnAdd=!0},setSpanRotation:function(d,b,f){var l={},e=H&&!/Edge/.test(C.navigator.userAgent)?"-ms-transform":G?"-webkit-transform":D?"MozTransform":C.opera?"-o-transform":void 0;e&&(l[e]=l.transform="rotate("+d+"deg)",l[e+(D?"Origin":"-origin")]=l.transformOrigin=100*b+"% "+f+"px",B(this.element,l))},getSpanCorrection:function(d,b,f){this.xCorr= +-d*f;this.yCorr=-b}});return b});O(e,"Core/Renderer/HTML/HTMLRenderer.js",[e["Core/Renderer/HTML/AST.js"],e["Core/Renderer/SVG/SVGElement.js"],e["Core/Renderer/SVG/SVGRenderer.js"],e["Core/Utilities.js"]],function(e,b,I,z){var D=z.attr,G=z.createElement,C=z.extend,B=z.pick;C(I.prototype,{html:function(x,w,v){var f=this.createElement("span"),d=f.element,q=f.renderer,k=q.isSVG,l=function(d,f){["opacity","visibility"].forEach(function(l){d[l+"Setter"]=function(n,e,m){var c=d.div?d.div.style:f;b.prototype[l+ +"Setter"].call(this,n,e,m);c&&(c[e]=n)}});d.addedSetters=!0};f.textSetter=function(d){d!==this.textStr&&(delete this.bBox,delete this.oldTextWidth,e.setElementHTML(this.element,B(d,"")),this.textStr=d,f.doTransform=!0)};k&&l(f,f.element.style);f.xSetter=f.ySetter=f.alignSetter=f.rotationSetter=function(d,b){"align"===b?f.alignValue=f.textAlign=d:f[b]=d;f.doTransform=!0};f.afterSetters=function(){this.doTransform&&(this.htmlUpdateTransform(),this.doTransform=!1)};f.attr({text:x,x:Math.round(w),y:Math.round(v)}).css({position:"absolute"}); +q.styledMode||f.css({fontFamily:this.style.fontFamily,fontSize:this.style.fontSize});d.style.whiteSpace="nowrap";f.css=f.htmlCss;k&&(f.add=function(b){var e=q.box.parentNode,n=[];if(this.parentGroup=b){var k=b.div;if(!k){for(;b;)n.push(b),b=b.parentGroup;n.reverse().forEach(function(d){function b(c,g){d[g]=c;"translateX"===g?a.left=c+"px":a.top=c+"px";d.doTransform=!0}var c=D(d.element,"class"),g=d.styles||{};k=d.div=d.div||G("div",c?{className:c}:void 0,{position:"absolute",left:(d.translateX||0)+ +"px",top:(d.translateY||0)+"px",display:d.display,opacity:d.opacity,cursor:g.cursor,pointerEvents:g.pointerEvents},k||e);var a=k.style;C(d,{classSetter:function(a){return function(c){this.element.setAttribute("class",c);a.className=c}}(k),on:function(){n[0].div&&f.on.apply({element:n[0].div,onEvents:f.onEvents},arguments);return d},translateXSetter:b,translateYSetter:b});d.addedSetters||l(d)})}}else k=e;k.appendChild(d);f.added=!0;f.alignOnAdd&&f.htmlUpdateTransform();return f});return f}});return I}); +O(e,"Core/Axis/Tick.js",[e["Core/FormatUtilities.js"],e["Core/Globals.js"],e["Core/Utilities.js"]],function(e,b,I){var D=b.deg2rad,H=I.clamp,G=I.correctFloat,C=I.defined,B=I.destroyObjectProperties,x=I.extend,w=I.fireEvent,v=I.isNumber,f=I.merge,d=I.objectEach,q=I.pick;"";I=function(){function b(d,b,f,e,k){this.isNewLabel=this.isNew=!0;this.axis=d;this.pos=b;this.type=f||"";this.parameters=k||{};this.tickmarkOffset=this.parameters.tickmarkOffset;this.options=this.parameters.options;w(this,"init"); +f||e||this.addLabel()}b.prototype.addLabel=function(){var d=this,b=d.axis,f=b.options,n=b.chart,k=b.categories,E=b.logarithmic,m=b.names,c=d.pos,g=q(d.options&&d.options.labels,f.labels),a=b.tickPositions,h=c===a[0],r=c===a[a.length-1],A=d.label,y=(!g.step||1===g.step)&&1===b.tickInterval;a=a.info;var L,P;k=this.parameters.category||(k?q(k[c],m[c],c):c);E&&v(k)&&(k=G(E.lin2log(k)));if(b.dateTime&&a){var R=n.time.resolveDTLFormat(f.dateTimeLabelFormats[!f.grid&&a.higherRanks[c]||a.unitName]);var V= +R.main}d.isFirst=h;d.isLast=r;var Q={axis:b,chart:n,dateTimeLabelFormat:V,isFirst:h,isLast:r,pos:c,tick:d,tickPositionInfo:a,value:k};w(this,"labelFormat",Q);var M=function(a){return g.formatter?g.formatter.call(a,a):g.format?(a.text=b.defaultLabelFormatter.call(a),e.format(g.format,a,n)):b.defaultLabelFormatter.call(a,a)};f=M.call(Q,Q);if(P=R&&R.list)d.shortenLabel=function(){for(L=0;Lg&&e-a*hk&&(L=Math.round((l-e)/Math.cos(g*D)));else if(l=e+(1-a)*h,e-a*hk&&(A=k-d.x+A*a,y=-1),A=Math.min(r,A),AA||b.autoRotation&&(c.styles||{}).width)L=A;L&&(this.shortenLabel?this.shortenLabel():(P.width=Math.floor(L)+ +"px",(f.style||{}).textOverflow||(P.textOverflow="ellipsis"),c.css(P)))};b.prototype.moveLabel=function(b,f){var e=this,n=e.label,l=!1,k=e.axis,m=k.reversed;n&&n.textStr===b?(e.movedLabel=n,l=!0,delete e.label):d(k.ticks,function(c){l||c.isNew||c===e||!c.label||c.label.textStr!==b||(e.movedLabel=c.label,l=!0,c.labelPos=e.movedLabel.xy,delete c.label)});if(!l&&(e.labelPos||n)){var c=e.labelPos||n.xy;n=k.horiz?m?0:k.width+k.left:c.x;k=k.horiz?c.y:m?k.width+k.left:0;e.movedLabel=e.createLabel({x:n,y:k}, +b,f);e.movedLabel&&e.movedLabel.attr({opacity:0})}};b.prototype.render=function(d,b,f){var e=this.axis,l=e.horiz,k=this.pos,m=q(this.tickmarkOffset,e.tickmarkOffset);k=this.getPosition(l,k,m,b);m=k.x;var c=k.y;e=l&&m===e.pos+e.len||!l&&c===e.pos?-1:1;l=q(f,this.label&&this.label.newOpacity,1);f=q(f,1);this.isActive=!0;this.renderGridLine(b,f,e);this.renderMark(k,f,e);this.renderLabel(k,b,l,d);this.isNew=!1;w(this,"afterRender")};b.prototype.renderGridLine=function(d,b,f){var e=this.axis,l=e.options, +k=this.gridLine,m={},c=this.pos,g=this.type,a=q(this.tickmarkOffset,e.tickmarkOffset),h=e.chart.renderer,r=l.gridLineWidth,A=l.gridLineColor,y=l.gridLineDashStyle;"minor"===this.type&&(r=l.minorGridLineWidth,A=l.minorGridLineColor,y=l.minorGridLineDashStyle);k||(e.chart.styledMode||(m.stroke=A,m["stroke-width"]=r||0,m.dashstyle=y),g||(m.zIndex=1),d&&(b=0),this.gridLine=k=h.path().attr(m).addClass("highcharts-"+(g?g+"-":"")+"grid-line").add(e.gridGroup));if(k&&(f=e.getPlotLinePath({value:c+a,lineWidth:k.strokeWidth()* +f,force:"pass",old:d})))k[d||this.isNew?"attr":"animate"]({d:f,opacity:b})};b.prototype.renderMark=function(d,b,f){var e=this.axis,l=e.options,k=e.chart.renderer,m=this.type,c=e.tickSize(m?m+"Tick":"tick"),g=this.mark,a=!g,h=d.x;d=d.y;var r=q(l["minor"!==m?"tickWidth":"minorTickWidth"],!m&&e.isXAxis?1:0);l=l["minor"!==m?"tickColor":"minorTickColor"];c&&(e.opposite&&(c[0]=-c[0]),a&&(this.mark=g=k.path().addClass("highcharts-"+(m?m+"-":"")+"tick").add(e.axisGroup),e.chart.styledMode||g.attr({stroke:l, +"stroke-width":r})),g[a?"attr":"animate"]({d:this.getMarkPath(h,d,c[0],g.strokeWidth()*f,e.horiz,k),opacity:b}))};b.prototype.renderLabel=function(d,b,f,e){var l=this.axis,n=l.horiz,m=l.options,c=this.label,g=m.labels,a=g.step;l=q(this.tickmarkOffset,l.tickmarkOffset);var h=!0,r=d.x;d=d.y;c&&v(r)&&(c.xy=d=this.getLabelPosition(r,d,c,n,g,l,e,a),this.isFirst&&!this.isLast&&!m.showFirstLabel||this.isLast&&!this.isFirst&&!m.showLastLabel?h=!1:!n||g.step||g.rotation||b||0===f||this.handleOverflow(d),a&& +e%a&&(h=!1),h&&v(d.y)?(d.opacity=f,c[this.isNewLabel?"attr":"animate"](d),this.isNewLabel=!1):(c.attr("y",-9999),this.isNewLabel=!0))};b.prototype.replaceMovedLabel=function(){var d=this.label,b=this.axis,f=b.reversed;if(d&&!this.isNew){var e=b.horiz?f?b.left:b.width+b.left:d.xy.x;f=b.horiz?d.xy.y:f?b.width+b.top:b.top;d.animate({x:e,y:f,opacity:0},void 0,d.destroy);delete this.label}b.isDirty=!0;this.label=this.movedLabel;delete this.movedLabel};return b}();b.Tick=I;return b.Tick});O(e,"Core/Axis/Axis.js", +[e["Core/Animation/AnimationUtilities.js"],e["Core/Color/Color.js"],e["Core/Globals.js"],e["Core/Color/Palette.js"],e["Core/Options.js"],e["Core/Axis/Tick.js"],e["Core/Utilities.js"]],function(e,b,I,z,H,G,C){var B=e.animObject,x=H.defaultOptions,w=C.addEvent,v=C.arrayMax,f=C.arrayMin,d=C.clamp,q=C.correctFloat,k=C.defined,l=C.destroyObjectProperties,N=C.erase,u=C.error,n=C.extend,J=C.fireEvent,E=C.getMagnitude,m=C.isArray,c=C.isFunction,g=C.isNumber,a=C.isString,h=C.merge,r=C.normalizeTickInterval, +A=C.objectEach,y=C.pick,L=C.relativeLength,P=C.removeEvent,R=C.splat,V=C.syncTimeout;"";var Q=I.deg2rad;e=function(){function e(a,c){this.zoomEnabled=this.width=this.visible=this.userOptions=this.translationSlope=this.transB=this.transA=this.top=this.ticks=this.tickRotCorr=this.tickPositions=this.tickmarkOffset=this.tickInterval=this.tickAmount=this.side=this.series=this.right=this.positiveValuesOnly=this.pos=this.pointRangePadding=this.pointRange=this.plotLinesAndBandsGroups=this.plotLinesAndBands= +this.paddedTicks=this.overlap=this.options=this.offset=this.names=this.minPixelPadding=this.minorTicks=this.minorTickInterval=this.min=this.maxLabelLength=this.max=this.len=this.left=this.labelFormatter=this.labelEdge=this.isLinked=this.height=this.hasVisibleSeries=this.hasNames=this.coll=this.closestPointRange=this.chart=this.categories=this.bottom=this.alternateBands=void 0;this.init(a,c)}e.prototype.init=function(a,d){var b=d.isX,h=this;h.chart=a;h.horiz=a.inverted&&!h.isZAxis?!b:b;h.isXAxis=b; +h.coll=h.coll||(b?"xAxis":"yAxis");J(this,"init",{userOptions:d});h.opposite=y(d.opposite,h.opposite);h.side=y(d.side,h.side,h.horiz?h.opposite?0:2:h.opposite?1:3);h.setOptions(d);var p=this.options,t=p.labels,r=p.type;h.userOptions=d;h.minPixelPadding=0;h.reversed=y(p.reversed,h.reversed);h.visible=p.visible;h.zoomEnabled=p.zoomEnabled;h.hasNames="category"===r||!0===p.categories;h.categories=p.categories||h.hasNames;h.names||(h.names=[],h.names.keys={});h.plotLinesAndBandsGroups={};h.positiveValuesOnly= +!!h.logarithmic;h.isLinked=k(p.linkedTo);h.ticks={};h.labelEdge=[];h.minorTicks={};h.plotLinesAndBands=[];h.alternateBands={};h.len=0;h.minRange=h.userMinRange=p.minRange||p.maxZoom;h.range=p.range;h.offset=p.offset||0;h.max=null;h.min=null;d=y(p.crosshair,R(a.options.tooltip.crosshairs)[b?0:1]);h.crosshair=!0===d?{}:d;d=h.options.events;-1===a.axes.indexOf(h)&&(b?a.axes.splice(a.xAxis.length,0,h):a.axes.push(h),a[h.coll].push(h));h.series=h.series||[];a.inverted&&!h.isZAxis&&b&&"undefined"===typeof h.reversed&& +(h.reversed=!0);h.labelRotation=g(t.rotation)?t.rotation:void 0;A(d,function(a,d){c(a)&&w(h,d,a)});J(this,"afterInit")};e.prototype.setOptions=function(a){this.options=h(e.defaultOptions,"yAxis"===this.coll&&e.defaultYAxisOptions,[e.defaultTopAxisOptions,e.defaultRightAxisOptions,e.defaultBottomAxisOptions,e.defaultLeftAxisOptions][this.side],h(x[this.coll],a));J(this,"afterSetOptions",{userOptions:a})};e.prototype.defaultLabelFormatter=function(){var a=this.axis,c=g(this.value)?this.value:NaN,d= +a.chart.time,h=this.dateTimeLabelFormat,b=x.lang,r=b.numericSymbols;b=b.numericSymbolMagnitude||1E3;var e=r&&r.length,f=a.logarithmic?Math.abs(c):a.tickInterval,m=this.chart.numberFormatter;if(a.categories)var A=""+this.value;else if(h)A=d.dateFormat(h,c);else if(e&&1E3<=f)for(;e--&&"undefined"===typeof A;)a=Math.pow(b,e+1),f>=a&&0===10*c%a&&null!==r[e]&&0!==c&&(A=m(c/a,-1)+r[e]);"undefined"===typeof A&&(A=1E4<=Math.abs(c)?m(c,-1):m(c,-1,void 0,""));return A};e.prototype.getSeriesExtremes=function(){var a= +this,c=a.chart,d;J(this,"getSeriesExtremes",null,function(){a.hasVisibleSeries=!1;a.dataMin=a.dataMax=a.threshold=null;a.softThreshold=!a.isXAxis;a.stacking&&a.stacking.buildStacks();a.series.forEach(function(h){if(h.visible||!c.options.chart.ignoreHiddenSeries){var b=h.options,p=b.threshold;a.hasVisibleSeries=!0;a.positiveValuesOnly&&0>=p&&(p=null);if(a.isXAxis){if(b=h.xData,b.length){b=a.logarithmic?b.filter(a.validatePositiveValue):b;d=h.getXExtremes(b);var t=d.min;var r=d.max;g(t)||t instanceof +Date||(b=b.filter(g),d=h.getXExtremes(b),t=d.min,r=d.max);b.length&&(a.dataMin=Math.min(y(a.dataMin,t),t),a.dataMax=Math.max(y(a.dataMax,r),r))}}else if(h=h.applyExtremes(),g(h.dataMin)&&(t=h.dataMin,a.dataMin=Math.min(y(a.dataMin,t),t)),g(h.dataMax)&&(r=h.dataMax,a.dataMax=Math.max(y(a.dataMax,r),r)),k(p)&&(a.threshold=p),!b.softThreshold||a.positiveValuesOnly)a.softThreshold=!1}})});J(this,"afterGetSeriesExtremes")};e.prototype.translate=function(a,c,d,h,b,r){var p=this.linkedParent||this,t=1,e= +0,f=h&&p.old?p.old.transA:p.transA;h=h&&p.old?p.old.min:p.min;var F=p.minPixelPadding;b=(p.isOrdinal||p.brokenAxis&&p.brokenAxis.hasBreaks||p.logarithmic&&b)&&p.lin2val;f||(f=p.transA);d&&(t*=-1,e=p.len);p.reversed&&(t*=-1,e-=t*(p.sector||p.len));c?(a=(a*t+e-F)/f+h,b&&(a=p.lin2val(a))):(b&&(a=p.val2lin(a)),a=g(h)?t*(a-h)*f+e+t*F+(g(r)?f*r:0):void 0);return a};e.prototype.toPixels=function(a,c){return this.translate(a,!1,!this.horiz,null,!0)+(c?0:this.pos)};e.prototype.toValue=function(a,c){return this.translate(a- +(c?0:this.pos),!0,!this.horiz,null,!0)};e.prototype.getPlotLinePath=function(a){function c(a,c,g){if("pass"!==l&&ag)l?a=d(a,c,g):v=!0;return a}var h=this,b=h.chart,t=h.left,r=h.top,e=a.old,f=a.value,m=a.translatedValue,A=a.lineWidth,l=a.force,n,k,u,L,q=e&&b.oldChartHeight||b.chartHeight,P=e&&b.oldChartWidth||b.chartWidth,v,da=h.transB;a={value:f,lineWidth:A,old:e,force:l,acrossPanes:a.acrossPanes,translatedValue:m};J(this,"getPlotLinePath",a,function(a){m=y(m,h.translate(f,null,null,e));m=d(m, +-1E5,1E5);n=u=Math.round(m+da);k=L=Math.round(q-m-da);g(m)?h.horiz?(k=r,L=q-h.bottom,n=u=c(n,t,t+h.width)):(n=t,u=P-h.right,k=L=c(k,r,r+h.height)):(v=!0,l=!1);a.path=v&&!l?null:b.renderer.crispLine([["M",n,k],["L",u,L]],A||1)});return a.path};e.prototype.getLinearTickPositions=function(a,c,d){var g=q(Math.floor(c/a)*a);d=q(Math.ceil(d/a)*a);var h=[],b;q(g+a)===g&&(b=20);if(this.single)return[c];for(c=g;c<=d;){h.push(c);c=q(c+a,b);if(c===p)break;var p=c}return h};e.prototype.getMinorTickInterval=function(){var a= +this.options;return!0===a.minorTicks?y(a.minorTickInterval,"auto"):!1===a.minorTicks?null:a.minorTickInterval};e.prototype.getMinorTickPositions=function(){var a=this.options,c=this.tickPositions,d=this.minorTickInterval,g=[],h=this.pointRangePadding||0,b=this.min-h;h=this.max+h;var r=h-b;if(r&&r/d=this.minRange;var l=this.minRange;var n=(l-d+c)/2;n=[c-n,y(a.min,c-n)];A&&(n[2]=this.logarithmic?this.logarithmic.log2lin(this.dataMin):this.dataMin);c=v(n);d=[c+l,y(a.max,c+l)];A&&(d[2]=g?g.log2lin(this.dataMax):this.dataMax);d=f(d);d-c=L)R=L,m=0;else if(c.dataMax<=L){var Q=L;f=0}c.min=y(v,R,c.dataMin);c.max=y(w,Q,c.dataMax)}h&&(c.positiveValuesOnly&&!a&&0>=Math.min(c.min,y(c.dataMin,c.min))&&u(10,1,d),c.min= +q(h.log2lin(c.min),16),c.max=q(h.log2lin(c.max),16));c.range&&k(c.max)&&(c.userMin=c.min=v=Math.max(c.dataMin,c.minFromRange()),c.userMax=w=c.max,c.range=null);J(c,"foundExtremes");c.beforePadding&&c.beforePadding();c.adjustForMinRange();!(n||c.axisPointRange||c.stacking&&c.stacking.usePercentage||t)&&k(c.min)&&k(c.max)&&(d=c.max-c.min)&&(!k(v)&&m&&(c.min-=d*m),!k(w)&&f&&(c.max+=d*f));g(c.userMin)||(g(b.softMin)&&b.softMinc.max&&(c.max=w=b.softMax),g(b.ceiling)&&(c.max=Math.min(c.max,b.ceiling)));P&&k(c.dataMin)&&(L=L||0,!k(v)&&c.min=L?c.min=c.options.minRange?Math.min(L,c.max-c.minRange):L:!k(w)&&c.max>L&&c.dataMax<=L&&(c.max=c.options.minRange?Math.max(L,c.min+c.minRange):L));g(c.min)&&g(c.max)&&!this.chart.polar&&c.min>c.max&&(k(c.options.min)?c.max=c.min:k(c.options.max)&&(c.min=c.max));c.tickInterval=c.min===c.max||"undefined"===typeof c.min||"undefined"===typeof c.max?1: +t&&c.linkedParent&&!A&&l===c.linkedParent.options.tickPixelInterval?A=c.linkedParent.tickInterval:y(A,this.tickAmount?(c.max-c.min)/Math.max(this.tickAmount-1,1):void 0,n?1:(c.max-c.min)*l/Math.max(c.len,l));e&&!a&&c.series.forEach(function(a){a.processData(c.min!==(c.old&&c.old.min)||c.max!==(c.old&&c.old.max))});c.setAxisTranslation();J(this,"initialAxisTranslation");c.pointRange&&!A&&(c.tickInterval=Math.max(c.pointRange,c.tickInterval));a=y(b.minTickInterval,c.dateTime&&!c.series.some(function(a){return a.noSharedTooltip})? +c.closestPointRange:0);!A&&c.tickIntervalc.tickInterval||void 0!==this.tickAmount),!!this.tickAmount));this.tickAmount||(c.tickInterval=c.unsquish());this.setTickPositions()};e.prototype.setTickPositions=function(){var a=this.options,c=a.tickPositions;var d=this.getMinorTickInterval();var g=a.tickPositioner,h=this.hasVerticalPanning(),b="colorAxis"===this.coll,r=(b|| +!h)&&a.startOnTick;h=(b||!h)&&a.endOnTick;this.tickmarkOffset=this.categories&&"between"===a.tickmarkPlacement&&1===this.tickInterval?.5:0;this.minorTickInterval="auto"===d&&this.tickInterval?this.tickInterval/5:d;this.single=this.min===this.max&&k(this.min)&&!this.tickAmount&&(parseInt(this.min,10)===this.min||!1!==a.allowDecimals);this.tickPositions=d=c&&c.slice();!d&&(this.ordinal&&this.ordinal.positions||!((this.max-this.min)/this.tickInterval>Math.max(2*this.len,200))?d=this.dateTime?this.getTimeTicks(this.dateTime.normalizeTimeTickInterval(this.tickInterval, +a.units),this.min,this.max,a.startOfWeek,this.ordinal&&this.ordinal.positions,this.closestPointRange,!0):this.logarithmic?this.logarithmic.getLogTickPositions(this.tickInterval,this.min,this.max):this.getLinearTickPositions(this.tickInterval,this.min,this.max):(d=[this.min,this.max],u(19,!1,this.chart)),d.length>this.len&&(d=[d[0],d.pop()],d[0]===d[1]&&(d.length=1)),this.tickPositions=d,g&&(g=g.apply(this,[this.min,this.max])))&&(this.tickPositions=d=g);this.paddedTicks=d.slice(0);this.trimTicks(d, +r,h);this.isLinked||(this.single&&2>d.length&&!this.categories&&!this.series.some(function(a){return a.is("heatmap")&&"between"===a.options.pointPlacement})&&(this.min-=.5,this.max+=.5),c||g||this.adjustTickAmount());J(this,"afterSetTickPositions")};e.prototype.trimTicks=function(a,c,d){var g=a[0],h=a[a.length-1],b=!this.isOrdinal&&this.minPointOffset||0;J(this,"trimTicks");if(!this.isLinked){if(c&&-Infinity!==g)this.min=g;else for(;this.min-b>a[0];)a.shift();if(d)this.max=h;else for(;this.max+b< +a[a.length-1];)a.pop();0===a.length&&k(g)&&!this.options.tickPositions&&a.push((h+g)/2)}};e.prototype.alignToOthers=function(){var a={},c,d=this.options;!1!==this.chart.options.chart.alignTicks&&d.alignTicks&&!1!==d.startOnTick&&!1!==d.endOnTick&&!this.logarithmic&&this.chart[this.coll].forEach(function(d){var g=d.options;g=[d.horiz?g.left:g.top,g.width,g.height,g.pane].join();d.series.length&&(a[g]?c=!0:a[g]=1)});return c};e.prototype.getTickAmount=function(){var a=this.options,c=a.tickAmount,d= +a.tickPixelInterval;!k(a.tickInterval)&&!c&&this.lenc&&(this.finalTickAmt=c,c=5);this.tickAmount=c};e.prototype.adjustTickAmount=function(){var a=this.options,c=this.tickInterval,d=this.tickPositions,h=this.tickAmount,b=this.finalTickAmt,r=d&&d.length,e=y(this.threshold,this.softThreshold?0:null);if(this.hasData()&&g(this.min)&&g(this.max)){if(rh&&(this.tickInterval*=2,this.setTickPositions());if(k(b)){for(c=a=d.length;c--;)(3===b&&1===c%2||2>=b&&0e&&(c=e)),k(h)&&(be&&(b=e))),d.displayBtn="undefined"!==typeof c||"undefined"!==typeof b,d.setExtremes(c,b,!1,void 0,{trigger:"zoom"});a.zoomed=!0});return a.zoomed};e.prototype.setAxisSize=function(){var a=this.chart,c=this.options,d=c.offsets||[0,0,0,0],g=this.horiz,h=this.width=Math.round(L(y(c.width,a.plotWidth-d[3]+d[1]),a.plotWidth)),b=this.height=Math.round(L(y(c.height,a.plotHeight-d[0]+d[2]),a.plotHeight)),r=this.top=Math.round(L(y(c.top,a.plotTop+d[0]),a.plotHeight, +a.plotTop));c=this.left=Math.round(L(y(c.left,a.plotLeft+d[3]),a.plotWidth,a.plotLeft));this.bottom=a.chartHeight-b-r;this.right=a.chartWidth-h-c;this.len=Math.max(g?h:b,0);this.pos=g?c:r};e.prototype.getExtremes=function(){var a=this.logarithmic;return{min:a?q(a.lin2log(this.min)):this.min,max:a?q(a.lin2log(this.max)):this.max,dataMin:this.dataMin,dataMax:this.dataMax,userMin:this.userMin,userMax:this.userMax}};e.prototype.getThreshold=function(a){var c=this.logarithmic,d=c?c.lin2log(this.min):this.min; +c=c?c.lin2log(this.max):this.max;null===a||-Infinity===a?a=d:Infinity===a?a=c:d>a?a=d:cc?a.align="right":195c&&(a.align="left")});return a.align};e.prototype.tickSize=function(a){var c=this.options,d=c["tick"===a?"tickLength":"minorTickLength"],g=y(c["tick"===a?"tickWidth":"minorTickWidth"],"tick"===a&&this.isXAxis&& +!this.categories?1:0);if(g&&d){"inside"===c[a+"Position"]&&(d=-d);var h=[d,g]}a={tickSize:h};J(this,"afterTickSize",a);return a.tickSize};e.prototype.labelMetrics=function(){var a=this.tickPositions&&this.tickPositions[0]||0;return this.chart.renderer.fontMetrics(this.options.labels.style.fontSize,this.ticks[a]&&this.ticks[a].label)};e.prototype.unsquish=function(){var a=this.options.labels,c=this.horiz,d=this.tickInterval,h=d,b=this.len/(((this.categories?1:0)+this.max-this.min)/d),r,e=a.rotation, +f=this.labelMetrics(),m,A=Number.MAX_VALUE,l=Math.max(this.max-this.min,0),n=function(a){var c=a/(b||1);c=1l&&Infinity!==a&&Infinity!==b&&l&&(c=Math.ceil(l/d));return q(c*d)};if(c){if(!a.staggerLines&&!a.step)if(g(e))var k=[e];else b=a){m=n(Math.abs(f.h/Math.sin(Q*a)));var c=m+Math.abs(a/360);ch.step)return h.rotation?0:(this.staggerLines||1)*this.len/b;if(!d){a=h.style.width;if(void 0!==a)return parseInt(String(a),10);if(r)return r-c.spacing[3]}return.33*c.chartWidth};e.prototype.renderUnsquish=function(){var c=this.chart,d=c.renderer,g=this.tickPositions,h=this.ticks, +b=this.options.labels,r=b.style,e=this.horiz,f=this.getSlotWidth(),m=Math.max(1,Math.round(f-2*b.padding)),A={},y=this.labelMetrics(),l=r.textOverflow,n=0;a(b.rotation)||(A.rotation=b.rotation||0);g.forEach(function(a){a=h[a];a.movedLabel&&a.replaceMovedLabel();a&&a.label&&a.label.textPxLength>n&&(n=a.label.textPxLength)});this.maxLabelLength=n;if(this.autoRotation)n>m&&n>y.h?A.rotation=this.labelRotation:this.labelRotation=0;else if(f){var k=m;if(!l){var L="clip";for(m=g.length;!e&&m--;){var u=g[m]; +if(u=h[u].label)u.styles&&"ellipsis"===u.styles.textOverflow?u.css({textOverflow:"clip"}):u.textPxLength>f&&u.css({width:f+"px"}),u.getBBox().height>this.len/g.length-(y.h-y.f)&&(u.specificTextOverflow="ellipsis")}}}A.rotation&&(k=n>.5*c.chartHeight?.33*c.chartHeight:n,l||(L="ellipsis"));if(this.labelAlign=b.align||this.autoLabelAlign(this.labelRotation))A.align=this.labelAlign;g.forEach(function(a){var c=(a=h[a])&&a.label,d=r.width,g={};c&&(c.attr(A),a.shortenLabel?a.shortenLabel():k&&!d&&"nowrap"!== +r.whiteSpace&&(k=this.min&&a<=this.max||this.grid&&this.grid.isColumn)d[a]||(d[a]=new G(this,a)),g&&d[a].isNew&&d[a].render(c,!0,-1),d[a].render(c)};e.prototype.render=function(){var a=this,c=a.chart,d=a.logarithmic, +h=a.options,b=a.isLinked,r=a.tickPositions,e=a.axisTitle,f=a.ticks,m=a.minorTicks,y=a.alternateBands,l=h.stackLabels,n=h.alternateGridColor,k=a.tickmarkOffset,L=a.axisLine,u=a.showAxis,q=B(c.renderer.globalAnimation),P,v;a.labelEdge.length=0;a.overlap=!1;[f,m,y].forEach(function(a){A(a,function(a){a.isActive=!1})});if(a.hasData()||b)a.minorTickInterval&&!a.categories&&a.getMinorTickPositions().forEach(function(c){a.renderMinorTick(c)}),r.length&&(r.forEach(function(c,d){a.renderTick(c,d)}),k&&(0=== +a.min||a.single)&&(f[-1]||(f[-1]=new G(a,-1,null,!0)),f[-1].render(-1))),n&&r.forEach(function(g,h){v="undefined"!==typeof r[h+1]?r[h+1]+k:a.max-k;0===h%2&&ge&&(!f||k<=v)&&"undefined"!==typeof k&&l.push(k);k>v&&(n=!0);k=E}}}else e=this.lin2log(e),v=this.lin2log(v),b=f?d.getMinorTickInterval():k.tickInterval,b=G("auto"===b?null:b,this.minorAutoInterval,k.tickPixelInterval/(f?5:1)*(v-e)/((f?q/d.tickPositions.length:q)||1)),b=H(b,void 0,z(b)),l=d.getLinearTickPositions(b, +e,v).map(this.log2lin),f||(this.minorAutoInterval=b/5);f||(d.tickInterval=b);return l};b.prototype.lin2log=function(b){return Math.pow(10,b)};b.prototype.log2lin=function(b){return Math.log(b)/Math.LN10};return b}();b=function(){function b(){}b.compose=function(b){b.keepProps.push("logarithmic");D(b,"init",function(b){var e=this.logarithmic;"logarithmic"!==b.userOptions.type?this.logarithmic=void 0:e||(this.logarithmic=new C(this))});D(b,"afterInit",function(){var b=this.logarithmic;b&&(this.lin2val= +function(e){return b.lin2log(e)},this.val2lin=function(e){return b.log2lin(e)})})};return b}();b.compose(e);return b});O(e,"Core/Axis/PlotLineOrBand.js",[e["Core/Axis/Axis.js"],e["Core/Globals.js"],e["Core/Color/Palette.js"],e["Core/Utilities.js"]],function(e,b,I,z){var D=z.arrayMax,G=z.arrayMin,C=z.defined,B=z.destroyObjectProperties,x=z.erase,w=z.extend,v=z.fireEvent,f=z.isNumber,d=z.merge,q=z.objectEach,k=z.pick;z=function(){function b(d,b){this.axis=d;b&&(this.options=b,this.id=b.id)}b.prototype.render= +function(){v(this,"render");var b=this,e=b.axis,f=e.horiz,l=e.logarithmic,E=b.options,m=E.label,c=b.label,g=E.to,a=E.from,h=E.value,r=C(a)&&C(g),A=C(h),y=b.svgElem,L=!y,P=[],R=E.color,w=k(E.zIndex,0),Q=E.events;P={"class":"highcharts-plot-"+(r?"band ":"line ")+(E.className||"")};var M={},t=e.chart.renderer,p=r?"bands":"lines";l&&(a=l.log2lin(a),g=l.log2lin(g),h=l.log2lin(h));e.chart.styledMode||(A?(P.stroke=R||I.neutralColor40,P["stroke-width"]=k(E.width,1),E.dashStyle&&(P.dashstyle=E.dashStyle)): +r&&(P.fill=R||I.highlightColor10,E.borderWidth&&(P.stroke=E.borderColor,P["stroke-width"]=E.borderWidth)));M.zIndex=w;p+="-"+w;(l=e.plotLinesAndBandsGroups[p])||(e.plotLinesAndBandsGroups[p]=l=t.g("plot-"+p).attr(M).add());L&&(b.svgElem=y=t.path().attr(P).add(l));if(A)P=e.getPlotLinePath({value:h,lineWidth:y.strokeWidth(),acrossPanes:E.acrossPanes});else if(r)P=e.getPlotBandPath(a,g,E);else return;!b.eventsAdded&&Q&&(q(Q,function(a,c){y.on(c,function(a){Q[c].apply(b,[a])})}),b.eventsAdded=!0);(L|| +!y.d)&&P&&P.length?y.attr({d:P}):y&&(P?(y.show(!0),y.animate({d:P})):y.d&&(y.hide(),c&&(b.label=c=c.destroy())));m&&(C(m.text)||C(m.formatter))&&P&&P.length&&0this.max&&b>this.max;if(e&&l){if(d){var c=e.toString()===l.toString();m=0}for(d=0;dd){m=f;break}if(e[m]&&g.substr(e[m])!=="01-01 00:00:00.000".substr(e[m]))break; +"week"!==m&&(f=m)}if(m)var l=h.resolveDTLFormat(a[m]).main;return l};e.prototype.getLabel=function(){var d=this,c=this.chart.renderer,g=this.chart.styledMode,a=this.options,h="tooltip"+(x(a.className)?" "+a.className:""),e=a.style&&a.style.pointerEvents||(!this.followPointer&&a.stickOnContact?"auto":"none"),f,y=function(){d.inContact=!0},l=function(){var a=d.chart.hoverSeries;d.inContact=!1;if(a&&a.onMouseOut)a.onMouseOut()};if(!this.label){if(this.outside){var k=this.chart.options.chart.style;this.container= +f=b.doc.createElement("div");f.className="highcharts-tooltip-container";B(f,{position:"absolute",top:"1px",pointerEvents:e,zIndex:Math.max(this.options.style&&this.options.style.zIndex||0,(k&&k.zIndex||0)+3)});b.doc.body.appendChild(f);this.renderer=c=new b.Renderer(f,0,0,k,void 0,void 0,c.styledMode)}this.split?this.label=c.g(h):(this.label=c.label("",0,0,a.shape||"callout",null,null,a.useHTML,null,h).attr({padding:a.padding,r:a.borderRadius}),g||this.label.attr({fill:a.backgroundColor,"stroke-width":a.borderWidth}).css(a.style).css({pointerEvents:e}).shadow(a.shadow)); +g&&(this.applyFilter(),this.label.addClass("highcharts-tooltip-"+this.chart.index));if(d.outside&&!d.split){var n=this.label,q=n.xSetter,u=n.ySetter;n.xSetter=function(a){q.call(n,d.distance);f.style.left=a+"px"};n.ySetter=function(a){u.call(n,d.distance);f.style.top=a+"px"}}this.label.on("mouseenter",y).on("mouseleave",l).attr({zIndex:8}).add()}return this.label};e.prototype.getPosition=function(d,c,b){var a=this.chart,h=this.distance,g={},e=a.inverted&&b.h||0,f,m=this.outside,l=m?G.documentElement.clientWidth- +2*h:a.chartWidth,k=m?Math.max(G.body.scrollHeight,G.documentElement.scrollHeight,G.body.offsetHeight,G.documentElement.offsetHeight,G.documentElement.clientHeight):a.chartHeight,n=a.pointer.getChartPosition(),q=function(g){var e="x"===g;return[g,e?l:k,e?d:c].concat(m?[e?d*n.scaleX:c*n.scaleY,e?n.left-h+(b.plotX+a.plotLeft)*n.scaleX:n.top-h+(b.plotY+a.plotTop)*n.scaleY,0,e?l:k]:[e?d:c,e?b.plotX+a.plotLeft:b.plotY+a.plotTop,e?a.plotLeft:a.plotTop,e?a.plotLeft+a.plotWidth:a.plotTop+a.plotHeight])},u= +q("y"),t=q("x"),p=!this.followPointer&&N(b.ttBelow,!a.inverted===!!b.negative),v=function(a,c,d,b,r,f,A){var y=m?"y"===a?h*n.scaleY:h*n.scaleX:h,l=(d-b)/2,F=bK-e?K:K-e);else if(k)g[a]=Math.max(f,r+e+d>c?r:r+e);else return!1},w=function(a,c,d,b,e){var r;ec-h?r=!1:g[a]=ec-b/2?c-b-2:e-d/2;return r},E=function(a){var c=u;u=t;t=c;f=a},F=function(){!1!==v.apply(0,u)?!1!==w.apply(0,t)||f||(E(!0), +F()):f?g.x=g.y=0:(E(!0),F())};(a.inverted||1d})&&(d=d.map(function(a){var c=g(a.anchorX,a.anchorY,a.point.isHeader,a.boxWidth,!1);return v(a,{target:c.y,x:c.x})}));a.cleanSplit();b.distribute(d,ba);var H=U,ca=U;d.forEach(function(c){var d=c.x,b=c.boxWidth;c=c.isHeader;c||(a.outside&&U+dca&&(ca=U+d))});d.forEach(function(c){var d=c.x, +b=c.anchorX,h=c.pos,g=c.point.isHeader;h={visibility:"undefined"===typeof h?"hidden":"inherit",x:d,y:h+B,anchorX:b,anchorY:c.anchorY};if(a.outside&&db[0]?Math.max(Math.abs(b[0]),h.width-b[0]):Math.max(Math.abs(b[0]),h.width);a.height=0>b[1]?Math.max(Math.abs(b[1]),h.height-Math.abs(b[1])):Math.max(Math.abs(b[1]),h.height);this.tracker?this.tracker.attr(a):(this.tracker=c.renderer.rect(a).addClass("highcharts-tracker").add(c), +d.styledMode||this.tracker.attr({fill:"rgba(0,0,0,0)"}))}}};e.prototype.styledModeFormat=function(d){return d.replace('style="font-size: 10px"','class="highcharts-header"').replace(/style="color:{(point|series)\.color}"/g,'class="highcharts-color-{$1.colorIndex}"')};e.prototype.tooltipFooterHeaderFormatter=function(d,c){var b=c?"footer":"header",a=d.series,h=a.tooltipOptions,e=h.xDateFormat,m=a.xAxis,l=m&&"datetime"===m.options.type&&q(d.key),k=h[b+"Format"];c={isFooter:c,labelConfig:d};f(this,"headerFormatter", +c,function(c){l&&!e&&(e=this.getXDateFormat(d,h,m));l&&e&&(d.point&&d.point.tooltipDateKeys||["key"]).forEach(function(a){k=k.replace("{point."+a+"}","{point."+a+":"+e+"}")});a.chart.styledMode&&(k=this.styledModeFormat(k));c.text=D(k,{point:d,series:a},this.chart)});return c.text};e.prototype.update=function(d){this.destroy();l(!0,this.chart.options.tooltip.userOptions,d);this.init(this.chart,l(!0,this.options,d))};e.prototype.updatePosition=function(d){var c=this.chart,b=c.pointer,a=this.getLabel(), +h=d.plotX+c.plotLeft;c=d.plotY+c.plotTop;b=b.getChartPosition();d=(this.options.positioner||this.getPosition).call(this,a.width,a.height,d);if(this.outside){var e=(this.options.borderWidth||0)+2*this.distance;this.renderer.setSize(a.width+e,a.height+e,!1);if(1!==b.scaleX||1!==b.scaleY)B(this.container,{transform:"scale("+b.scaleX+", "+b.scaleY+")"}),h*=b.scaleX,c*=b.scaleY;h+=b.left-d.x;c+=b.top-d.y}this.move(Math.round(d.x),Math.round(d.y||0),h,c)};return e}();b.Tooltip=e;return b.Tooltip});O(e, +"Core/Pointer.js",[e["Core/Color/Color.js"],e["Core/Globals.js"],e["Core/Color/Palette.js"],e["Core/Tooltip.js"],e["Core/Utilities.js"]],function(e,b,I,z,H){var D=e.parse,C=b.charts,B=b.noop,x=H.addEvent,w=H.attr,v=H.css,f=H.defined,d=H.extend,q=H.find,k=H.fireEvent,l=H.isNumber,N=H.isObject,u=H.objectEach,n=H.offset,J=H.pick,E=H.splat;"";e=function(){function e(c,d){this.lastValidTouch={};this.pinchDown=[];this.runChartClick=!1;this.eventsToUnbind=[];this.chart=c;this.hasDragged=!1;this.options= +d;this.init(c,d)}e.prototype.applyInactiveState=function(c){var d=[],a;(c||[]).forEach(function(c){a=c.series;d.push(a);a.linkedParent&&d.push(a.linkedParent);a.linkedSeries&&(d=d.concat(a.linkedSeries));a.navigatorSeries&&d.push(a.navigatorSeries)});this.chart.series.forEach(function(a){-1===d.indexOf(a)?a.setState("inactive",!0):a.options.inactiveOtherPoints&&a.setAllPointsToState("inactive")})};e.prototype.destroy=function(){var c=this;this.eventsToUnbind.forEach(function(c){return c()});this.eventsToUnbind= +[];b.chartCount||(b.unbindDocumentMouseUp&&(b.unbindDocumentMouseUp=b.unbindDocumentMouseUp()),b.unbindDocumentTouchEnd&&(b.unbindDocumentTouchEnd=b.unbindDocumentTouchEnd()));clearInterval(c.tooltipTimeout);u(c,function(d,a){c[a]=void 0})};e.prototype.drag=function(c){var d=this.chart,a=d.options.chart,b=c.chartX,e=c.chartY,f=this.zoomHor,l=this.zoomVert,m=d.plotLeft,k=d.plotTop,n=d.plotWidth,q=d.plotHeight,u=this.selectionMarker,v=this.mouseDownX||0,t=this.mouseDownY||0,p=N(a.panning)?a.panning&& +a.panning.enabled:a.panning,w=a.panKey&&c[a.panKey+"Key"];if(!u||!u.touch)if(bm+n&&(b=m+n),ek+q&&(e=k+q),this.hasDragged=Math.sqrt(Math.pow(v-b,2)+Math.pow(t-e,2)),10c.options.findNearestPointBy.indexOf("y");c=c.searchPoint(a,b);if((b=N(c,!0)&&c.series)&&!(b=!N(e,!0))){b= +e.distX-c.distX;var h=e.dist-c.dist,g=(c.series.group&&c.series.group.zIndex)-(e.series.group&&e.series.group.zIndex);b=0<(0!==b&&d?b:0!==h?h:0!==g?g:e.series.index>c.series.index?-1:1)}b&&(e=c)});return e};e.prototype.getChartCoordinatesFromPoint=function(c,d){var a=c.series,b=a.xAxis;a=a.yAxis;var g=c.shapeArgs;if(b&&a){var e=J(c.clientX,c.plotX),f=c.plotY||0;c.isNode&&g&&l(g.x)&&l(g.y)&&(e=g.x,f=g.y);return d?{chartX:a.len+a.pos-f,chartY:b.len+b.pos-e}:{chartX:e+b.pos,chartY:f+a.pos}}if(g&&g.x&& +g.y)return{chartX:g.x,chartY:g.y}};e.prototype.getChartPosition=function(){if(this.chartPosition)return this.chartPosition;var c=this.chart.container,d=n(c);this.chartPosition={left:d.left,top:d.top,scaleX:1,scaleY:1};var a=c.offsetWidth;c=c.offsetHeight;2F.max&&(d=F.max-y,J=!0);J?(w-=.8*(w-l[g][0]),"number"===typeof x&&(x-=.8*(x-l[g][1])),a()):l[g]=[w,x];L||(f[g]=q-A,f[n]=y);f=L?1/u:u;e[n]=y;e[g]=d;b[L?c?"scaleY":"scaleX":"scale"+r]=u;b["translate"+r]=f*A+(w-f*K)};e.prototype.reset=function(c,d){var a=this.chart,b=a.hoverSeries,e=a.hoverPoint,g=a.hoverPoints,f=a.tooltip,l=f&&f.shared?g:e;c&&l&&E(l).forEach(function(a){a.series.isCartesian&&"undefined"=== +typeof a.plotX&&(c=!1)});if(c)f&&l&&E(l).length&&(f.refresh(l),f.shared&&g?g.forEach(function(a){a.setState(a.state,!0);a.series.isCartesian&&(a.series.xAxis.crosshair&&a.series.xAxis.drawCrosshair(null,a),a.series.yAxis.crosshair&&a.series.yAxis.drawCrosshair(null,a))}):e&&(e.setState(e.state,!0),a.axes.forEach(function(a){a.crosshair&&e.series[a.coll]===a&&a.drawCrosshair(null,e)})));else{if(e)e.onMouseOut();g&&g.forEach(function(a){a.setState()});if(b)b.onMouseOut();f&&f.hide(d);this.unDocMouseMove&& +(this.unDocMouseMove=this.unDocMouseMove());a.axes.forEach(function(a){a.hideCrosshair()});this.hoverX=a.hoverPoints=a.hoverPoint=null}};e.prototype.runPointActions=function(c,d){var a=this.chart,h=a.tooltip&&a.tooltip.options.enabled?a.tooltip:void 0,e=h?h.shared:!1,g=d||a.hoverPoint,f=g&&g.series||a.hoverSeries;f=this.getHoverData(g,f,a.series,(!c||"touchmove"!==c.type)&&(!!d||f&&f.directTouch&&this.isDirectTouch),e,c);g=f.hoverPoint;var l=f.hoverPoints;d=(f=f.hoverSeries)&&f.tooltipOptions.followPointer&& +!f.tooltipOptions.split;e=e&&f&&!f.noSharedTooltip;if(g&&(g!==a.hoverPoint||h&&h.isHidden)){(a.hoverPoints||[]).forEach(function(a){-1===l.indexOf(a)&&a.setState()});if(a.hoverSeries!==f)f.onMouseOver();this.applyInactiveState(l);(l||[]).forEach(function(a){a.setState("hover")});a.hoverPoint&&a.hoverPoint.firePointEvent("mouseOut");if(!g.series)return;a.hoverPoints=l;a.hoverPoint=g;g.firePointEvent("mouseOver");h&&h.refresh(e?l:g,c)}else d&&h&&!h.isHidden&&(g=h.getAnchor([{}],c),a.isInsidePlot(g[0], +g[1],{visiblePlotOnly:!0})&&h.updatePosition({plotX:g[0],plotY:g[1]}));this.unDocMouseMove||(this.unDocMouseMove=x(a.container.ownerDocument,"mousemove",function(a){var c=C[b.hoverChartIndex];if(c)c.pointer.onDocumentMouseMove(a)}),this.eventsToUnbind.push(this.unDocMouseMove));a.axes.forEach(function(d){var b=J((d.crosshair||{}).snap,!0),h;b&&((h=a.hoverPoint)&&h.series[d.coll]===d||(h=q(l,function(a){return a.series[d.coll]===d})));h||!b?d.drawCrosshair(c,h):d.hideCrosshair()})};e.prototype.scaleGroups= +function(c,d){var a=this.chart,b;a.series.forEach(function(h){b=c||h.getPlotBox();h.xAxis&&h.xAxis.zoomEnabled&&h.group&&(h.group.attr(b),h.markerGroup&&(h.markerGroup.attr(b),h.markerGroup.clip(d?a.clipRect:null)),h.dataLabelsGroup&&h.dataLabelsGroup.attr(b))});a.clipRect.attr(d||a.clipBox)};e.prototype.setDOMEvents=function(){var c=this,d=this.chart.container,a=d.ownerDocument;d.onmousedown=this.onContainerMouseDown.bind(this);d.onmousemove=this.onContainerMouseMove.bind(this);d.onclick=this.onContainerClick.bind(this); +this.eventsToUnbind.push(x(d,"mouseenter",this.onContainerMouseEnter.bind(this)));this.eventsToUnbind.push(x(d,"mouseleave",this.onContainerMouseLeave.bind(this)));b.unbindDocumentMouseUp||(b.unbindDocumentMouseUp=x(a,"mouseup",this.onDocumentMouseUp.bind(this)));for(var h=this.chart.renderTo.parentElement;h&&"BODY"!==h.tagName;)this.eventsToUnbind.push(x(h,"scroll",function(){delete c.chartPosition})),h=h.parentElement;b.hasTouch&&(this.eventsToUnbind.push(x(d,"touchstart",this.onContainerTouchStart.bind(this), +{passive:!1})),this.eventsToUnbind.push(x(d,"touchmove",this.onContainerTouchMove.bind(this),{passive:!1})),b.unbindDocumentTouchEnd||(b.unbindDocumentTouchEnd=x(a,"touchend",this.onDocumentTouchEnd.bind(this),{passive:!1})))};e.prototype.setHoverChartIndex=function(){var c=this.chart,d=b.charts[J(b.hoverChartIndex,-1)];if(d&&d!==c)d.pointer.onContainerMouseLeave({relatedTarget:!0});d&&d.mouseIsDown||(b.hoverChartIndex=c.index)};e.prototype.touch=function(c,d){var a=this.chart,b;this.setHoverChartIndex(); +if(1===c.touches.length)if(c=this.normalize(c),(b=a.isInsidePlot(c.chartX-a.plotLeft,c.chartY-a.plotTop,{visiblePlotOnly:!0}))&&!a.openMenu){d&&this.runPointActions(c);if("touchmove"===c.type){d=this.pinchDown;var e=d[0]?4<=Math.sqrt(Math.pow(d[0].chartX-c.chartX,2)+Math.pow(d[0].chartY-c.chartY,2)):!1}J(e,!0)&&this.pinch(c)}else d&&this.reset();else 2===c.touches.length&&this.pinch(c)};e.prototype.touchSelect=function(c){return!(!this.chart.options.chart.zoomBySingleTouch||!c.touches||1!==c.touches.length)}; +e.prototype.zoomOption=function(c){var d=this.chart,a=d.options.chart,b=a.zoomType||"";d=d.inverted;/touch/.test(c.type)&&(b=J(a.pinchType,b));this.zoomX=c=/x/.test(b);this.zoomY=b=/y/.test(b);this.zoomHor=c&&!d||b&&d;this.zoomVert=b&&!d||c&&d;this.hasZoom=c||b};return e}();return b.Pointer=e});O(e,"Core/MSPointer.js",[e["Core/Globals.js"],e["Core/Pointer.js"],e["Core/Utilities.js"]],function(e,b,I){function D(){var d=[];d.item=function(d){return this[d]};f(q,function(b){d.push({pageX:b.pageX,pageY:b.pageY, +target:b.target})});return d}function H(d,b,f,k){"touch"!==d.pointerType&&d.pointerType!==d.MSPOINTER_TYPE_TOUCH||!C[e.hoverChartIndex]||(k(d),k=C[e.hoverChartIndex].pointer,k[b]({type:f,target:d.currentTarget,preventDefault:x,touches:D()}))}var G=this&&this.__extends||function(){var d=function(b,e){d=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(d,b){d.__proto__=b}||function(d,b){for(var e in b)b.hasOwnProperty(e)&&(d[e]=b[e])};return d(b,e)};return function(b,e){function f(){this.constructor= +b}d(b,e);b.prototype=null===e?Object.create(e):(f.prototype=e.prototype,new f)}}(),C=e.charts,B=e.doc,x=e.noop,w=I.addEvent,v=I.css,f=I.objectEach,d=I.removeEvent,q={},k=!!e.win.PointerEvent;return function(b){function e(){return null!==b&&b.apply(this,arguments)||this}G(e,b);e.prototype.batchMSEvents=function(d){d(this.chart.container,k?"pointerdown":"MSPointerDown",this.onContainerPointerDown);d(this.chart.container,k?"pointermove":"MSPointerMove",this.onContainerPointerMove);d(B,k?"pointerup": +"MSPointerUp",this.onDocumentPointerUp)};e.prototype.destroy=function(){this.batchMSEvents(d);b.prototype.destroy.call(this)};e.prototype.init=function(d,e){b.prototype.init.call(this,d,e);this.hasZoom&&v(d.container,{"-ms-touch-action":"none","touch-action":"none"})};e.prototype.onContainerPointerDown=function(d){H(d,"onContainerTouchStart","touchstart",function(d){q[d.pointerId]={pageX:d.pageX,pageY:d.pageY,target:d.currentTarget}})};e.prototype.onContainerPointerMove=function(d){H(d,"onContainerTouchMove", +"touchmove",function(d){q[d.pointerId]={pageX:d.pageX,pageY:d.pageY};q[d.pointerId].target||(q[d.pointerId].target=d.currentTarget)})};e.prototype.onDocumentPointerUp=function(d){H(d,"onDocumentTouchEnd","touchend",function(d){delete q[d.pointerId]})};e.prototype.setDOMEvents=function(){b.prototype.setDOMEvents.call(this);(this.hasZoom||this.followTouchMove)&&this.batchMSEvents(w)};return e}(b)});O(e,"Core/Series/Point.js",[e["Core/Renderer/HTML/AST.js"],e["Core/Animation/AnimationUtilities.js"], +e["Core/FormatUtilities.js"],e["Core/Globals.js"],e["Core/Options.js"],e["Core/Utilities.js"]],function(e,b,I,z,H,G){var D=b.animObject,B=I.format,x=H.defaultOptions,w=G.addEvent,v=G.defined,f=G.erase,d=G.extend,q=G.fireEvent,k=G.getNestedProperty,l=G.isArray,N=G.isFunction,u=G.isNumber,n=G.isObject,J=G.merge,E=G.objectEach,m=G.pick,c=G.syncTimeout,g=G.removeEvent,a=G.uniqueKey;"";b=function(){function b(){this.colorIndex=this.category=void 0;this.formatPrefix="point";this.id=void 0;this.isNull=!1; +this.percentage=this.options=this.name=void 0;this.selected=!1;this.total=this.series=void 0;this.visible=!0;this.x=void 0}b.prototype.animateBeforeDestroy=function(){var a=this,c={x:a.startXPos,opacity:0},b,e=a.getGraphicalProps();e.singular.forEach(function(d){b="dataLabel"===d;a[d]=a[d].animate(b?{x:a[d].startXPos,y:a[d].startYPos,opacity:0}:c)});e.plural.forEach(function(c){a[c].forEach(function(c){c.element&&c.animate(d({x:a.startXPos},c.startYPos?{x:c.startXPos,y:c.startYPos}:{}))})})};b.prototype.applyOptions= +function(a,c){var e=this.series,h=e.options.pointValKey||e.pointValKey;a=b.prototype.optionsToObject.call(this,a);d(this,a);this.options=this.options?d(this.options,a):a;a.group&&delete this.group;a.dataLabels&&delete this.dataLabels;h&&(this.y=b.prototype.getNestedProperty.call(this,h));this.formatPrefix=(this.isNull=m(this.isValid&&!this.isValid(),null===this.x||!u(this.y)))?"null":"point";this.selected&&(this.state="select");"name"in this&&"undefined"===typeof c&&e.xAxis&&e.xAxis.hasNames&&(this.x= +e.xAxis.nameToX(this));"undefined"===typeof this.x&&e&&(this.x="undefined"===typeof c?e.autoIncrement(this):c);return this};b.prototype.destroy=function(){function a(){if(d.graphic||d.dataLabel||d.dataLabels)g(d),d.destroyElements();for(m in d)d[m]=null}var d=this,b=d.series,e=b.chart;b=b.options.dataSorting;var h=e.hoverPoints,l=D(d.series.chart.renderer.globalAnimation),m;d.legendItem&&e.legend.destroyItem(d);h&&(d.setState(),f(h,d),h.length||(e.hoverPoints=null));if(d===e.hoverPoint)d.onMouseOut(); +b&&b.enabled?(this.animateBeforeDestroy(),c(a,l.duration)):a();e.pointCount--};b.prototype.destroyElements=function(a){var c=this;a=c.getGraphicalProps(a);a.singular.forEach(function(a){c[a]=c[a].destroy()});a.plural.forEach(function(a){c[a].forEach(function(a){a.element&&a.destroy()});delete c[a]})};b.prototype.firePointEvent=function(a,c,d){var b=this,e=this.series.options;(e.point.events[a]||b.options&&b.options.events&&b.options.events[a])&&b.importEvents();"click"===a&&e.allowPointSelect&&(d= +function(a){b.select&&b.select(null,a.ctrlKey||a.metaKey||a.shiftKey)});q(b,a,c,d)};b.prototype.getClassName=function(){return"highcharts-point"+(this.selected?" highcharts-point-select":"")+(this.negative?" highcharts-negative":"")+(this.isNull?" highcharts-null-point":"")+("undefined"!==typeof this.colorIndex?" highcharts-color-"+this.colorIndex:"")+(this.options.className?" "+this.options.className:"")+(this.zone&&this.zone.className?" "+this.zone.className.replace("highcharts-negative",""):"")}; +b.prototype.getGraphicalProps=function(a){var c=this,d=[],b,e={singular:[],plural:[]};a=a||{graphic:1,dataLabel:1};a.graphic&&d.push("graphic","upperGraphic","shadowGroup");a.dataLabel&&d.push("dataLabel","dataLabelUpper","connector");for(b=d.length;b--;){var h=d[b];c[h]&&e.singular.push(h)}["dataLabel","connector"].forEach(function(d){var b=d+"s";a[d]&&c[b]&&e.plural.push(b)});return e};b.prototype.getLabelConfig=function(){return{x:this.category,y:this.y,color:this.color,colorIndex:this.colorIndex, +key:this.name||this.category,series:this.series,point:this,percentage:this.percentage,total:this.total||this.stackTotal}};b.prototype.getNestedProperty=function(a){if(a)return 0===a.indexOf("custom.")?k(a,this.options):this[a]};b.prototype.getZone=function(){var a=this.series,c=a.zones;a=a.zoneAxis||"y";var d=0,b;for(b=c[d];this[a]>=b.value;)b=c[++d];this.nonZonedColor||(this.nonZonedColor=this.color);this.color=b&&b.color&&!this.options.color?b.color:this.nonZonedColor;return b};b.prototype.hasNewShapeType= +function(){return(this.graphic&&(this.graphic.symbolName||this.graphic.element.nodeName))!==this.shapeType};b.prototype.init=function(c,d,b){this.series=c;this.applyOptions(d,b);this.id=v(this.id)?this.id:a();this.resolveColor();c.chart.pointCount++;q(this,"afterInit");return this};b.prototype.optionsToObject=function(a){var c={},d=this.series,e=d.options.keys,h=e||d.pointArrayMap||["y"],g=h.length,f=0,r=0;if(u(a)||null===a)c[h[0]]=a;else if(l(a))for(!e&&a.length>g&&(d=typeof a[0],"string"===d?c.name= +a[0]:"number"===d&&(c.x=a[0]),f++);rb-6&&gm?this.maxItemWidth: +a.itemWidth;b&&this.itemX-d+c>m&&(this.itemX=d,this.lastLineHeight&&(this.itemY+=f+this.lastLineHeight+g),this.lastLineHeight=0);this.lastItemY=f+this.itemY+g;this.lastLineHeight=Math.max(e,this.lastLineHeight);a._legendItemPos=[this.itemX,this.itemY];b?this.itemX+=c:(this.itemY+=f+e+g,this.lastLineHeight=e);this.offsetWidth=this.widthOption||Math.max((b?this.itemX-d-(a.checkbox?0:l):c)+d,this.offsetWidth)};c.prototype.getAllItems=function(){var a=[];this.chart.series.forEach(function(c){var b=c&& +c.options;c&&n(b.showInLegend,d(b.linkedTo)?!1:void 0,!0)&&(a=a.concat(c.legendItems||("point"===b.legendType?c.data:c)))});l(this,"afterGetAllItems",{allItems:a});return a};c.prototype.getAlignment=function(){var a=this.options;return this.proximate?a.align.charAt(0)+"tv":a.floating?"":a.align.charAt(0)+a.verticalAlign.charAt(0)+a.layout.charAt(0)};c.prototype.adjustMargins=function(a,c){var b=this.chart,e=this.options,h=this.getAlignment();h&&[/(lth|ct|rth)/,/(rtv|rm|rbv)/,/(rbh|cb|lbh)/,/(lbv|lm|ltv)/].forEach(function(g, +f){g.test(h)&&!d(a[f])&&(b[x[f]]=Math.max(b[x[f]],b.legend[(f+1)%2?"legendHeight":"legendWidth"]+[1,-1,-1,1][f]*e[f%2?"x":"y"]+n(e.margin,12)+c[f]+(b.titleOffset[f]||0)))})};c.prototype.proximatePositions=function(){var a=this.chart,c=[],d="left"===this.options.align;this.allItems.forEach(function(b){var e;var h=d;if(b.yAxis){b.xAxis.options.reversed&&(h=!h);b.points&&(e=k(h?b.points:b.points.slice(0).reverse(),function(a){return N(a.plotY)}));h=this.itemMarginTop+b.legendItem.getBBox().height+this.itemMarginBottom; +var g=b.yAxis.top-a.plotTop;b.visible?(e=e?e.plotY:b.yAxis.height,e+=g-.3*h):e=g+b.yAxis.height;c.push({target:e,size:h,item:b})}},this);I.distribute(c,a.plotHeight);c.forEach(function(c){c.item._legendItemPos[1]=a.plotTop-a.spacing[0]+c.pos})};c.prototype.render=function(){var a=this.chart,c=a.renderer,d=this.group,b=this.box,e=this.options,g=this.padding;this.itemX=g;this.itemY=this.initialItemY;this.lastItemY=this.offsetWidth=0;this.widthOption=J(e.width,a.spacingBox.width-g);var f=a.spacingBox.width- +2*g-e.x;-1<["rm","lm"].indexOf(this.getAlignment().substring(0,2))&&(f/=2);this.maxLegendWidth=this.widthOption||f;d||(this.group=d=c.g("legend").attr({zIndex:7}).add(),this.contentGroup=c.g().attr({zIndex:1}).add(d),this.scrollGroup=c.g().add(this.contentGroup));this.renderTitle();var m=this.getAllItems();E(m,function(a,c){return(a.options&&a.options.legendIndex||0)-(c.options&&c.options.legendIndex||0)});e.reversed&&m.reverse();this.allItems=m;this.display=f=!!m.length;this.itemHeight=this.totalItemWidth= +this.maxItemWidth=this.lastLineHeight=0;m.forEach(this.renderItem,this);m.forEach(this.layoutItem,this);m=(this.widthOption||this.offsetWidth)+g;var k=this.lastItemY+this.lastLineHeight+this.titleHeight;k=this.handleOverflow(k);k+=g;b||(this.box=b=c.rect().addClass("highcharts-legend-box").attr({r:e.borderRadius}).add(d),b.isNew=!0);a.styledMode||b.attr({stroke:e.borderColor,"stroke-width":e.borderWidth||0,fill:e.backgroundColor||"none"}).shadow(e.shadow);0g&&!1!==q.enabled?(this.clipHeight=k=Math.max(g-20-this.titleHeight-f,0),this.currentPage=n(this.currentPage, +1),this.fullHeight=a,F.forEach(function(a,c){var d=a._legendItemPos[1],b=Math.round(a.legendItem.getBBox().height),e=v.length;if(!e||d-v[e-1]>k&&(w||d)!==v[e-1])v.push(w||d),e++;a.pageIx=e-1;w&&(F[c-1].pageIx=e-1);c===F.length-1&&d+b-v[e-1]>k&&d!==w&&(v.push(d),a.pageIx=e);d!==w&&(w=d)}),l||(l=c.clipRect=b.clipRect(0,f,9999,0),c.contentGroup.clip(l)),S(k),u||(this.nav=u=b.g().attr({zIndex:1}).add(this.group),this.up=b.symbol("triangle",0,0,p,p).add(u),K("upTracker").on("click",function(){c.scroll(-1, +t)}),this.pager=b.text("",15,10).addClass("highcharts-legend-navigation"),d.styledMode||this.pager.css(q.style),this.pager.add(u),this.down=b.symbol("triangle-down",0,0,p,p).add(u),K("downTracker").on("click",function(){c.scroll(1,t)})),c.scroll(0),a=g):u&&(S(),this.nav=u.destroy(),this.scrollGroup.attr({translateY:1}),this.clipHeight=0);return a};c.prototype.scroll=function(a,c){var d=this,b=this.chart,e=this.pages,h=e.length,g=this.currentPage+a;a=this.clipHeight;var f=this.options.navigation,k= +this.pager,q=this.padding;g>h&&(g=h);0=Math.max(k+h,F.pos)&&f<=Math.min(k+h+e.width,F.pos+F.len)||(a.isInsidePlot=!1)}!d.ignoreY&&a.isInsidePlot&&(b=l&&(b?l.xAxis:l.yAxis)||{pos:g,len:Infinity},d=d.paneCoordinates? +b.pos+c:g+c,d>=Math.max(m+g,b.pos)&&d<=Math.min(m+g+e.height,b.pos+b.len)||(a.isInsidePlot=!1));M(this,"afterIsInsidePlot",a);return a.isInsidePlot};e.prototype.redraw=function(a){M(this,"beforeRedraw");var c=this.hasCartesianSeries?this.axes:this.colorAxis||[],d=this.series,b=this.pointer,e=this.legend,h=this.userOptions.legend,g=this.isDirtyLegend,f=this.isDirtyBox,m=this.renderer,k=m.isHidden(),F=[];this.setResponsive&&this.setResponsive(!1);l(this.hasRendered?a:!1,this);k&&this.temporaryDisplay(); +this.layOutTitles();for(a=d.length;a--;){var n=d[a];if(n.options.stacking||n.options.centerInCategory){var r=!0;if(n.isDirty){var K=!0;break}}}if(K)for(a=d.length;a--;)n=d[a],n.options.stacking&&(n.isDirty=!0);d.forEach(function(a){a.isDirty&&("point"===a.options.legendType?("function"===typeof a.updateTotals&&a.updateTotals(),g=!0):h&&(h.labelFormatter||h.labelFormat)&&(g=!0));a.isDirtyData&&M(a,"updatedData")});g&&e&&e.options.enabled&&(e.render(),this.isDirtyLegend=!1);r&&this.getStacks();c.forEach(function(a){a.updateNames(); +a.setScale()});this.getMargins();c.forEach(function(a){a.isDirty&&(f=!0)});c.forEach(function(a){var c=a.min+","+a.max;a.extKey!==c&&(a.extKey=c,F.push(function(){M(a,"afterSetExtremes",V(a.eventArgs,a.getExtremes()));delete a.eventArgs}));(f||r)&&a.redraw()});f&&this.drawChartBox();M(this,"predraw");d.forEach(function(a){(f||a.isDirty)&&a.visible&&a.redraw();a.isDirtyData=!1});b&&b.reset(!0);m.draw();M(this,"redraw");M(this,"render");k&&this.temporaryDisplay(!0);F.forEach(function(a){a.call()})}; +e.prototype.get=function(a){function c(c){return c.id===a||c.options&&c.options.id===a}var d=this.series,b;var e=Q(this.axes,c)||Q(this.series,c);for(b=0;!e&&b=f&&h<=m||k||!y(h))l=!0;b[k?"zoomX":"zoomY"]&&l&&(d=g.zoom(a.min,a.max),g.displayBtn&&(e=!0))});var g=c.resetZoomButton;e&&!g?c.showResetZoom():!e&&ea(g)&&(c.resetZoomButton=g.destroy());d&&c.redraw(T(c.options.chart.animation,a&&a.animation,100> +c.pointCount))};e.prototype.pan=function(a,c){var d=this,b=d.hoverPoints,e=d.options.chart,h=d.options.mapNavigation&&d.options.mapNavigation.enabled,g;c="object"===typeof c?c:{enabled:c,type:"x"};e&&e.panning&&(e.panning=c);var f=c.type;M(this,"pan",{originalEvent:a},function(){b&&b.forEach(function(a){a.setState()});var c=[1];"xy"===f?c=[1,0]:"y"===f&&(c=[0]);c.forEach(function(c){var b=d[c?"xAxis":"yAxis"][0],e=b.horiz,m=a[e?"chartX":"chartY"];e=e?"mouseDownX":"mouseDownY";var k=d[e],l=(b.pointRange|| +0)/2,F=b.reversed&&!d.inverted||!b.reversed&&d.inverted?-1:1,n=b.getExtremes(),r=b.toValue(k-m,!0)+l*F;F=b.toValue(k+b.len-m,!0)-l*F;var K=F=c&&r<=l&&(b.setExtremes(k,r,!1,!1,{trigger:"pan"}),d.resetZoomButton||h||k===c||r===l||!f.match("y")||(d.showResetZoom(),b.displayBtn=!1),g=!0),d[e]=m)});g&&d.redraw(!1); +A(d.container,{cursor:"move"})})};return e}();V(aa.prototype,{callbacks:[],collectionsWithInit:{xAxis:[aa.prototype.addAxis,[!0]],yAxis:[aa.prototype.addAxis,[!1]],series:[aa.prototype.addSeries]},collectionsWithUpdate:["xAxis","yAxis","zAxis","series"],propsRequireDirtyBox:"backgroundColor borderColor borderWidth borderRadius plotBackgroundColor plotBackgroundImage plotBorderColor plotBorderWidth plotShadow shadow".split(" "),propsRequireReflow:"margin marginTop marginRight marginBottom marginLeft spacing spacingTop spacingRight spacingBottom spacingLeft".split(" "), +propsRequireUpdateSeries:"chart.inverted chart.polar chart.ignoreHiddenSeries chart.type colors plotOptions time tooltip".split(" ")});z.chart=function(a,c,d){return new aa(a,c,d)};z.Chart=aa;"";return aa});O(e,"Mixins/LegendSymbol.js",[e["Core/Globals.js"],e["Core/Utilities.js"]],function(e,b){var D=b.merge,z=b.pick;return e.LegendSymbolMixin={drawRectangle:function(b,e){var D=b.symbolHeight,B=b.options.squareSymbol;e.legendSymbol=this.chart.renderer.rect(B?(b.symbolWidth-D)/2:0,b.baseline-D+1,B? +D:b.symbolWidth,D,z(b.options.symbolRadius,D/2)).addClass("highcharts-point").attr({zIndex:3}).add(e.legendGroup)},drawLineMarker:function(b){var e=this.options,C=e.marker,B=b.symbolWidth,x=b.symbolHeight,w=x/2,v=this.chart.renderer,f=this.legendGroup;b=b.baseline-Math.round(.3*b.fontMetrics.b);var d={};this.chart.styledMode||(d={"stroke-width":e.lineWidth||0},e.dashStyle&&(d.dashstyle=e.dashStyle));this.legendLine=v.path([["M",0,b],["L",B,b]]).addClass("highcharts-graph").attr(d).add(f);C&&!1!== +C.enabled&&B&&(e=Math.min(z(C.radius,w),w),0===this.symbol.indexOf("url")&&(C=D(C,{width:x,height:x}),e=0),this.legendSymbol=C=v.symbol(this.symbol,B/2-e,b-e,2*e,2*e,C).addClass("highcharts-point").add(f),C.isMarker=!0)}}});O(e,"Core/Series/Series.js",[e["Core/Animation/AnimationUtilities.js"],e["Core/Globals.js"],e["Mixins/LegendSymbol.js"],e["Core/Options.js"],e["Core/Color/Palette.js"],e["Core/Series/Point.js"],e["Core/Series/SeriesRegistry.js"],e["Core/Renderer/SVG/SVGElement.js"],e["Core/Utilities.js"]], +function(e,b,I,z,H,G,C,B,x){var w=e.animObject,v=e.setAnimation,f=b.hasTouch,d=b.svg,q=b.win,k=z.defaultOptions,l=C.seriesTypes,D=x.addEvent,u=x.arrayMax,n=x.arrayMin,J=x.clamp,E=x.cleanRecursively,m=x.correctFloat,c=x.defined,g=x.erase,a=x.error,h=x.extend,r=x.find,A=x.fireEvent,y=x.getNestedProperty,L=x.isArray,P=x.isFunction,R=x.isNumber,V=x.isString,Q=x.merge,M=x.objectEach,t=x.pick,p=x.removeEvent,O=x.splat,Z=x.syncTimeout;e=function(){function b(){this.zones=this.yAxis=this.xAxis=this.userOptions= +this.tooltipOptions=this.processedYData=this.processedXData=this.points=this.options=this.linkedSeries=this.index=this.eventsToUnbind=this.eventOptions=this.data=this.chart=this._i=void 0}b.prototype.init=function(a,c){A(this,"init",{options:c});var d=this,b=a.series,e;this.eventOptions=this.eventOptions||{};this.eventsToUnbind=[];d.chart=a;d.options=d.setOptions(c);var g=d.options;d.linkedSeries=[];d.bindAxes();h(d,{name:g.name,state:"",visible:!1!==g.visible,selected:!0===g.selected});c=g.events; +M(c,function(a,c){P(a)&&d.eventOptions[c]!==a&&(P(d.eventOptions[c])&&p(d,c,d.eventOptions[c]),d.eventOptions[c]=a,D(d,c,a))});if(c&&c.click||g.point&&g.point.events&&g.point.events.click||g.allowPointSelect)a.runTrackerClick=!0;d.getColor();d.getSymbol();d.parallelArrays.forEach(function(a){d[a+"Data"]||(d[a+"Data"]=[])});d.isCartesian&&(a.hasCartesianSeries=!0);b.length&&(e=b[b.length-1]);d._i=t(e&&e._i,-1)+1;d.opacity=d.options.opacity;a.orderSeries(this.insert(b));g.dataSorting&&g.dataSorting.enabled? +d.setDataSortingOptions():d.points||d.data||d.setData(g.data,!1);A(this,"afterInit")};b.prototype.is=function(a){return l[a]&&this instanceof l[a]};b.prototype.insert=function(a){var c=this.options.index,d;if(R(c)){for(d=a.length;d--;)if(c>=t(a[d].options.index,a[d]._i)){a.splice(d+1,0,this);break}-1===d&&a.unshift(this);d+=1}else a.push(this);return t(d,a.length-1)};b.prototype.bindAxes=function(){var c=this,d=c.options,b=c.chart,e;A(this,"bindAxes",null,function(){(c.axisTypes||[]).forEach(function(h){var g= +0;b[h].forEach(function(a){e=a.options;if(d[h]===g&&!e.isInternal||"undefined"!==typeof d[h]&&d[h]===e.id||"undefined"===typeof d[h]&&0===e.index)c.insert(a.series),c[h]=a,a.isDirty=!0;e.isInternal||g++});c[h]||c.optionalAxis===h||a(18,!0,b)})});A(this,"afterBindAxes")};b.prototype.updateParallelArrays=function(a,c){var d=a.series,b=arguments,e=R(c)?function(b){var e="y"===b&&d.toYData?d.toYData(a):a[b];d[b+"Data"][c]=e}:function(a){Array.prototype[c].apply(d[a+"Data"],Array.prototype.slice.call(b, +2))};d.parallelArrays.forEach(e)};b.prototype.hasData=function(){return this.visible&&"undefined"!==typeof this.dataMax&&"undefined"!==typeof this.dataMin||this.visible&&this.yData&&0=this.cropStart?k-this.cropStart:k);!h&&e[k]&&e[k].touched&&(k=void 0);return k};b.prototype.updateData=function(a,d){var b=this.options,e=b.dataSorting,h=this.points,g=[],f,k,m,l=this.requireSorting,n=a.length===h.length,r=!0;this.xIncrement=null;a.forEach(function(a,d){var k=c(a)&&this.pointClass.prototype.optionsToObject.call({series:this},a)||{}; +var r=k.x;if(k.id||R(r)){if(r=this.findPointIndex(k,m),-1===r||"undefined"===typeof r?g.push(a):h[r]&&a!==b.data[r]?(h[r].update(a,!1,null,!1),h[r].touched=!0,l&&(m=r+1)):h[r]&&(h[r].touched=!0),!n||d!==r||e&&e.enabled||this.hasDerivedData)f=!0}else g.push(a)},this);if(f)for(a=h.length;a--;)(k=h[a])&&!k.touched&&k.remove&&k.remove(!1,d);else!n||e&&e.enabled?r=!1:(a.forEach(function(a,c){h[c].update&&a!==h[c].y&&h[c].update(a,!1,null,!1)}),g.length=0);h.forEach(function(a){a&&(a.touched=!1)});if(!r)return!1; +g.forEach(function(a){this.addPoint(a,!1,null,null,!1)},this);null===this.xIncrement&&this.xData&&this.xData.length&&(this.xIncrement=u(this.xData),this.autoIncrement());return!0};b.prototype.setData=function(c,d,b,e){var h=this,g=h.points,f=g&&g.length||0,k,m=h.options,l=h.chart,r=m.dataSorting,n=null,q=h.xAxis;n=m.turboThreshold;var F=this.xData,p=this.yData,u=(k=h.pointArrayMap)&&k.length,v=m.keys,K=0,w=1,y;c=c||[];k=c.length;d=t(d,!0);r&&r.enabled&&(c=this.sortData(c));!1!==e&&k&&f&&!h.cropped&& +!h.hasGroupedData&&h.visible&&!h.isSeriesBoosting&&(y=this.updateData(c,b));if(!y){h.xIncrement=null;h.colorCounter=0;this.parallelArrays.forEach(function(a){h[a+"Data"].length=0});if(n&&k>n)if(n=h.getFirstValidPoint(c),R(n))for(b=0;ba?1:0}).forEach(function(a,c){a.x=c},this);d.linkedSeries&&d.linkedSeries.forEach(function(c){var d=c.options,b=d.data;d.dataSorting&&d.dataSorting.enabled||!b||(b.forEach(function(d,h){b[h]=e(c,d);a[h]&&(b[h].x=a[h].x,b[h].index=h)}),c.setData(b,!1))});return a};b.prototype.getProcessedData=function(c){var d=this.xData,b=this.yData,e=d.length;var h=0;var g=this.xAxis,f= +this.options;var k=f.cropThreshold;var m=c||this.getExtremesFromAll||f.getExtremesFromAll,l=this.isCartesian;c=g&&g.val2lin;f=!(!g||!g.logarithmic);var n=this.requireSorting;if(g){g=g.getExtremes();var r=g.min;var q=g.max}if(l&&this.sorted&&!m&&(!k||e>k||this.forceCrop))if(d[e-1]q)d=[],b=[];else if(this.yData&&(d[0]q)){h=this.cropData(this.xData,this.yData,r,q);d=h.xData;b=h.yData;h=h.start;var F=!0}for(k=d.length||1;--k;)if(e=f?c(d[k])-c(d[k-1]):d[k]-d[k-1],0e&&n&&(a(15,!1,this.chart),n=!1);return{xData:d,yData:b,cropped:F,cropStart:h,closestPointRange:p}};b.prototype.processData=function(a){var c=this.xAxis;if(this.isCartesian&&!this.isDirty&&!c.isDirty&&!this.yAxis.isDirty&&!a)return!1;a=this.getProcessedData();this.cropped=a.cropped;this.cropStart=a.cropStart;this.processedXData=a.xData;this.processedYData=a.yData;this.closestPointRange=this.basePointRange=a.closestPointRange};b.prototype.cropData=function(a,c,d,b,e){var h= +a.length,g=0,f=h,k;e=t(e,this.cropShoulder);for(k=0;k=d){g=Math.max(0,k-e);break}for(d=k;db){f=d+e;break}return{xData:a.slice(g,f),yData:c.slice(g,f),start:g,end:f}};b.prototype.generatePoints=function(){var a=this.options,c=a.data,d=this.data,b,e=this.processedXData,g=this.processedYData,f=this.pointClass,k=e.length,m=this.cropStart||0,l=this.hasGroupedData,n=a.keys,r=[],q;a=a.dataGrouping&&a.dataGrouping.groupAll?m:0;d||l||(d=[],d.length=c.length,d=this.data=d);n&& +l&&(this.options.keys=!1);for(q=0;q=f&&(e[r-m]||q)<=k;if(F&&q)if(F=p.length)for(;F--;)R(p[F])&&(h[g++]=p[F]);else h[g++]=p}a={dataMin:n(h),dataMax:u(h)};A(this,"afterGetExtremes",{dataExtremes:a});return a};b.prototype.applyExtremes=function(){var a=this.getExtremes();this.dataMin=a.dataMin;this.dataMax=a.dataMax;return a};b.prototype.getFirstValidPoint=function(a){for(var c=null,d=a.length,b=0;null===c&&b=B&&(B=null),E.total=E.stackTotal=N.total,E.percentage=N.total&&E.y/N.total*100,E.stackY=D,this.irregularWidths||N.setOffset(this.pointXOffset||0,this.barW||0));E.yBottom=c(B)?J(g.translate(B, +0,1,0,1),-1E5,1E5):null;l&&(D=this.modifyValue(D,E));E.plotY=void 0;R(D)&&(D=g.translate(D,!1,!0,!1,!0),"undefined"!==typeof D&&(E.plotY=J(D,-1E5,1E5)));E.isInside=this.isPointInside(E);E.clientX=q?m(b.translate(x,0,0,0,1,n)):v;E.negative=E[w]<(a[w+"Threshold"]||p||0);E.category=e&&"undefined"!==typeof e[E.x]?e[E.x]:E.x;if(!E.isNull&&!1!==E.visible){"undefined"!==typeof M&&(y=Math.min(y,Math.abs(v-M)));var M=v}E.zone=this.zones.length&&E.getZone();!E.graphic&&this.group&&h&&(E.isNew=!0)}this.closestPointRangePx= +y;A(this,"afterTranslate")};b.prototype.getValidPoints=function(a,c,d){var b=this.chart;return(a||this.points||[]).filter(function(a){return c&&!b.isInsidePlot(a.plotX,a.plotY,{inverted:b.inverted})?!1:!1!==a.visible&&(d||!a.isNull)})};b.prototype.getClipBox=function(a,c){var d=this.options,b=this.chart,e=b.inverted,h=this.xAxis,g=h&&this.yAxis,f=b.options.chart.scrollablePlotArea||{};a&&!1===d.clip&&g?a=e?{y:-b.chartWidth+g.len+g.pos,height:b.chartWidth,width:b.chartHeight,x:-b.chartHeight+h.len+ +h.pos}:{y:-g.pos,height:b.chartHeight,width:b.chartWidth,x:-h.pos}:(a=this.clipBox||b.clipBox,c&&(a.width=b.plotSizeX,a.x=(b.scrollablePixelsX||0)*(f.scrollPositionX||0)));return c?{width:a.width,x:a.x}:a};b.prototype.getSharedClipKey=function(a){if(this.sharedClipKey)return this.sharedClipKey;var c=[a&&a.duration,a&&a.easing,a&&a.defer,this.getClipBox(a).height,this.options.xAxis,this.options.yAxis].join();if(!1!==this.options.clip||a)this.sharedClipKey=c;return c};b.prototype.setClip=function(a){var c= +this.chart,d=this.options,b=c.renderer,e=c.inverted,h=this.clipBox,g=this.getClipBox(a),f=this.getSharedClipKey(a),k=c.sharedClips[f],m=c.sharedClips[f+"m"];a&&(g.width=0,e&&(g.x=c.plotHeight+(!1!==d.clip?0:c.plotTop)));k?c.hasLoaded||k.attr(g):(a&&(c.sharedClips[f+"m"]=m=b.clipRect(e?(c.plotSizeX||0)+99:-99,e?-c.plotLeft:-c.plotTop,99,e?c.chartWidth:c.chartHeight)),c.sharedClips[f]=k=b.clipRect(g),k.count={length:0});a&&!k.count[this.index]&&(k.count[this.index]=!0,k.count.length+=1);if(!1!==d.clip|| +a)this.group.clip(a||h?k:c.clipRect),this.markerGroup.clip(m);a||(k.count[this.index]&&(delete k.count[this.index],--k.count.length),0===k.count.length&&(h||(c.sharedClips[f]=k.destroy()),m&&(c.sharedClips[f+"m"]=m.destroy())))};b.prototype.animate=function(a){var c=this.chart,d=w(this.options.animation),b=this.sharedClipKey;if(a)this.setClip(d);else if(b){a=c.sharedClips[b];b=c.sharedClips[b+"m"];var e=this.getClipBox(d,!0);a&&a.animate(e,d);b&&b.animate({width:e.width+99,x:e.x-(c.inverted?0:99)}, +d)}};b.prototype.afterAnimate=function(){this.setClip();A(this,"afterAnimate");this.finishedAnimating=!0};b.prototype.drawPoints=function(){var a=this.points,c=this.chart,d,b,e=this.options.marker,h=this[this.specialGroup]||this.markerGroup,g=this.xAxis,f=t(e.enabled,!g||g.isRadial?!0:null,this.closestPointRangePx>=e.enabledThreshold*e.radius);if(!1!==e.enabled||this._hasPointMarkers)for(d=0;dx.max;a.resetZones&&0===h&&(h=void 0)});this.clips=g}else a.visible&&(k&&k.show(!0),m&&m.show(!0))};b.prototype.invertGroups=function(a){function c(){["group","markerGroup"].forEach(function(c){d[c]&&(b.renderer.isVML&&d[c].attr({width:d.yAxis.len,height:d.xAxis.len}),d[c].width=d.yAxis.len,d[c].height=d.xAxis.len,d[c].invert(d.isRadialSeries? +!1:a))})}var d=this,b=d.chart;d.xAxis&&(d.eventsToUnbind.push(D(b,"resize",c)),c(),d.invertGroups=c)};b.prototype.plotGroup=function(a,d,b,e,h){var g=this[a],f=!g;b={visibility:b,zIndex:e||.1};"undefined"===typeof this.opacity||this.chart.styledMode||"inactive"===this.state||(b.opacity=this.opacity);f&&(this[a]=g=this.chart.renderer.g().add(h));g.addClass("highcharts-"+d+" highcharts-series-"+this.index+" highcharts-"+this.type+"-series "+(c(this.colorIndex)?"highcharts-color-"+this.colorIndex+" ": +"")+(this.options.className||"")+(g.hasClass("highcharts-tracker")?" highcharts-tracker":""),!0);g.attr(b)[f?"attr":"animate"](this.getPlotBox());return g};b.prototype.getPlotBox=function(){var a=this.chart,c=this.xAxis,d=this.yAxis;a.inverted&&(c=d,d=this.xAxis);return{translateX:c?c.left:a.plotLeft,translateY:d?d.top:a.plotTop,scaleX:1,scaleY:1}};b.prototype.removeEvents=function(a){a||p(this);this.eventsToUnbind.length&&(this.eventsToUnbind.forEach(function(a){a()}),this.eventsToUnbind.length= +0)};b.prototype.render=function(){var a=this,c=a.chart,d=a.options,b=w(d.animation),e=!a.finishedAnimating&&c.renderer.isSVG&&b.duration,h=a.visible?"inherit":"hidden",g=d.zIndex,f=a.hasRendered,k=c.seriesGroup,m=c.inverted;A(this,"render");var l=a.plotGroup("group","series",h,g,k);a.markerGroup=a.plotGroup("markerGroup","markers",h,g,k);e&&a.animate&&a.animate(!0);l.inverted=t(a.invertible,a.isCartesian)?m:!1;a.drawGraph&&(a.drawGraph(),a.applyZones());a.visible&&a.drawPoints();a.drawDataLabels&& +a.drawDataLabels();a.redrawPoints&&a.redrawPoints();a.drawTracker&&!1!==a.options.enableMouseTracking&&a.drawTracker();a.invertGroups(m);!1===d.clip||a.sharedClipKey||f||l.clip(c.clipRect);e&&a.animate&&a.animate();f||(e&&b.defer&&(e+=b.defer),a.animationTimeout=Z(function(){a.afterAnimate()},e||0));a.isDirty=!1;a.hasRendered=!0;A(a,"afterRender")};b.prototype.redraw=function(){var a=this.chart,c=this.isDirty||this.isDirtyData,d=this.group,b=this.xAxis,e=this.yAxis;d&&(a.inverted&&d.attr({width:a.plotWidth, +height:a.plotHeight}),d.animate({translateX:t(b&&b.left,a.plotLeft),translateY:t(e&&e.top,a.plotTop)}));this.translate();this.render();c&&delete this.kdTree};b.prototype.searchPoint=function(a,c){var d=this.xAxis,b=this.yAxis,e=this.chart.inverted;return this.searchKDTree({clientX:e?d.len-a.chartY+d.pos:a.chartX-d.pos,plotY:e?b.len-a.chartX+b.pos:a.chartY-b.pos},c,a)};b.prototype.buildKDTree=function(a){function c(a,b,e){var h;if(h=a&&a.length){var g=d.kdAxisArray[b%e];a.sort(function(a,c){return a[g]- +c[g]});h=Math.floor(h/2);return{point:a[h],left:c(a.slice(0,h),b+1,e),right:c(a.slice(h+1),b+1,e)}}}this.buildingKdTree=!0;var d=this,b=-1r?"left":"right";q=0>r?"right":"left";d[p]&&(p=e(a,d[p],b+1,m),n=p[k]q;)p--;this.updateParallelArrays(n,"splice",p,0,0);this.updateParallelArrays(n,p);k&&n.name&&(k[q]=n.name);m.splice(p,0,a);r&&(this.data.splice(p,0,null),this.processData());"point"===h.legendType&&this.generatePoints();d&&(g[0]&&g[0].remove?g[0].remove(!1):(g.shift(),this.updateParallelArrays(n,"shift"),m.shift()));!1!==e&&A(this,"addPoint",{point:n});this.isDirtyData=this.isDirty=!0;c&&f.redraw(b)};b.prototype.removePoint=function(a, +c,d){var b=this,e=b.data,h=e[a],g=b.points,f=b.chart,k=function(){g&&g.length===e.length&&g.splice(a,1);e.splice(a,1);b.options.data.splice(a,1);b.updateParallelArrays(h||{series:b},"splice",a,1);h&&h.destroy();b.isDirty=!0;b.isDirtyData=!0;c&&f.redraw()};v(d,f);c=t(c,!0);h?h.firePointEvent("remove",null,k):k()};b.prototype.remove=function(a,c,d,b){function e(){h.destroy(b);g.isDirtyLegend=g.isDirtyBox=!0;g.linkSeries();t(a,!0)&&g.redraw(c)}var h=this,g=h.chart;!1!==d?A(h,"remove",null,e):e()};b.prototype.update= +function(c,d){c=E(c,this.userOptions);A(this,"update",{options:c});var b=this,e=b.chart,g=b.userOptions,f=b.initialType||b.type,k=e.options.plotOptions,m=c.type||g.type||e.options.chart.type,r=!(this.hasDerivedData||m&&m!==this.type||"undefined"!==typeof c.pointStart||"undefined"!==typeof c.pointInterval||b.hasOptionChanged("dataGrouping")||b.hasOptionChanged("pointStart")||b.hasOptionChanged("pointInterval")||b.hasOptionChanged("pointIntervalUnit")||b.hasOptionChanged("keys")),n=l[f].prototype,q, +p=["eventOptions","navigatorSeries","baseSeries"],u=b.finishedAnimating&&{animation:!1},v={};m=m||f;r&&(p.push("data","isDirtyData","points","processedXData","processedYData","xIncrement","cropped","_hasPointMarkers","_hasPointLabels","clips","nodes","layout","mapMap","mapData","minY","maxY","minX","maxX"),!1!==c.visible&&p.push("area","graph"),b.parallelArrays.forEach(function(a){p.push(a+"Data")}),c.data&&(c.dataSorting&&h(b.options.dataSorting,c.dataSorting),this.setData(c.data,!1)));c=Q(g,u,{index:"undefined"=== +typeof g.index?b.index:g.index,pointStart:t(k&&k.series&&k.series.pointStart,g.pointStart,b.xData[0])},!r&&{data:b.options.data},c);r&&c.data&&(c.data=b.options.data);p=["group","markerGroup","dataLabelsGroup","transformGroup"].concat(p);p.forEach(function(a){p[a]=b[a];delete b[a]});g=!1;if(l[m]){if(g=m!==b.type,b.remove(!1,!1,!1,!0),g)if(Object.setPrototypeOf)Object.setPrototypeOf(b,l[m].prototype);else{k=Object.hasOwnProperty.call(b,"hcEvents")&&b.hcEvents;for(q in n)b[q]=void 0;h(b,l[m].prototype); +k?b.hcEvents=k:delete b.hcEvents}}else a(17,!0,e,{missingModuleFor:m});p.forEach(function(a){b[a]=p[a]});b.init(e,c);if(r&&this.points){var w=b.options;!1===w.visible?(v.graphic=1,v.dataLabel=1):b._hasPointLabels||(c=w.marker,m=w.dataLabels,c&&(!1===c.enabled||"symbol"in c)&&(v.graphic=1),m&&!1===m.enabled&&(v.dataLabel=1));this.points.forEach(function(a){a&&a.series&&(a.resolveColor(),Object.keys(v).length&&a.destroyElements(v),!1===w.showInLegend&&a.legendItem&&e.legend.destroyItem(a))},this)}b.initialType= +f;e.linkSeries();g&&b.linkedSeries.length&&(b.isDirtyData=!0);A(this,"afterUpdate");t(d,!0)&&e.redraw(r?void 0:!1)};b.prototype.setName=function(a){this.name=this.options.name=this.userOptions.name=a;this.chart.isDirtyLegend=!0};b.prototype.hasOptionChanged=function(a){var c=this.options[a],d=this.chart.options.plotOptions,b=this.userOptions[a];return b?c!==b:c!==t(d&&d[this.type]&&d[this.type][a],d&&d.series&&d.series[a],c)};b.prototype.onMouseOver=function(){var a=this.chart,c=a.hoverSeries;a.pointer.setHoverChartIndex(); +if(c&&c!==this)c.onMouseOut();this.options.events.mouseOver&&A(this,"mouseOver");this.setState("hover");a.hoverSeries=this};b.prototype.onMouseOut=function(){var a=this.options,c=this.chart,d=c.tooltip,b=c.hoverPoint;c.hoverSeries=null;if(b)b.onMouseOut();this&&a.events.mouseOut&&A(this,"mouseOut");!d||this.stickyTracking||d.shared&&!this.noSharedTooltip||d.hide();c.series.forEach(function(a){a.setState("",!0)})};b.prototype.setState=function(a,c){var d=this,b=d.options,e=d.graph,h=b.inactiveOtherPoints, +g=b.states,f=b.lineWidth,k=b.opacity,m=t(g[a||"normal"]&&g[a||"normal"].animation,d.chart.options.chart.animation);b=0;a=a||"";if(d.state!==a&&([d.group,d.markerGroup,d.dataLabelsGroup].forEach(function(c){c&&(d.state&&c.removeClass("highcharts-series-"+d.state),a&&c.addClass("highcharts-series-"+a))}),d.state=a,!d.chart.styledMode)){if(g[a]&&!1===g[a].enabled)return;a&&(f=g[a].lineWidth||f+(g[a].lineWidthPlus||0),k=t(g[a].opacity,k));if(e&&!e.dashstyle)for(g={"stroke-width":f},e.animate(g,m);d["zone-graph-"+ +b];)d["zone-graph-"+b].animate(g,m),b+=1;h||[d.group,d.markerGroup,d.dataLabelsGroup,d.labelBySeries].forEach(function(a){a&&a.animate({opacity:k},m)})}c&&h&&d.points&&d.setAllPointsToState(a||void 0)};b.prototype.setAllPointsToState=function(a){this.points.forEach(function(c){c.setState&&c.setState(a)})};b.prototype.setVisible=function(a,c){var d=this,b=d.chart,e=d.legendItem,h=b.options.chart.ignoreHiddenSeries,g=d.visible;var f=(d.visible=a=d.options.visible=d.userOptions.visible="undefined"=== +typeof a?!g:a)?"show":"hide";["group","dataLabelsGroup","markerGroup","tracker","tt"].forEach(function(a){if(d[a])d[a][f]()});if(b.hoverSeries===d||(b.hoverPoint&&b.hoverPoint.series)===d)d.onMouseOut();e&&b.legend.colorizeItem(d,a);d.isDirty=!0;d.options.stacking&&b.series.forEach(function(a){a.options.stacking&&a.visible&&(a.isDirty=!0)});d.linkedSeries.forEach(function(c){c.setVisible(a,!1)});h&&(b.isDirtyBox=!0);A(d,f);!1!==c&&b.redraw()};b.prototype.show=function(){this.setVisible(!0)};b.prototype.hide= +function(){this.setVisible(!1)};b.prototype.select=function(a){this.selected=a=this.options.selected="undefined"===typeof a?!this.selected:a;this.checkbox&&(this.checkbox.checked=a);A(this,a?"select":"unselect")};b.prototype.shouldShowTooltip=function(a,c,d){void 0===d&&(d={});d.series=this;d.visiblePlotOnly=!0;return this.chart.isInsidePlot(a,c,d)};b.defaultOptions={lineWidth:2,allowPointSelect:!1,crisp:!0,showCheckbox:!1,animation:{duration:1E3},events:{},marker:{enabledThreshold:2,lineColor:H.backgroundColor, +lineWidth:0,radius:4,states:{normal:{animation:!0},hover:{animation:{duration:50},enabled:!0,radiusPlus:2,lineWidthPlus:1},select:{fillColor:H.neutralColor20,lineColor:H.neutralColor100,lineWidth:2}}},point:{events:{}},dataLabels:{animation:{},align:"center",defer:!0,formatter:function(){var a=this.series.chart.numberFormatter;return"number"!==typeof this.y?"":a(this.y,-1)},padding:5,style:{fontSize:"11px",fontWeight:"bold",color:"contrast",textOutline:"1px contrast"},verticalAlign:"bottom",x:0,y:0}, +cropThreshold:300,opacity:1,pointRange:0,softThreshold:!0,states:{normal:{animation:!0},hover:{animation:{duration:50},lineWidthPlus:1,marker:{},halo:{size:10,opacity:.25}},select:{animation:{duration:0}},inactive:{animation:{duration:50},opacity:.2}},stickyTracking:!0,turboThreshold:1E3,findNearestPointBy:"x"};return b}();h(e.prototype,{axisTypes:["xAxis","yAxis"],coll:"series",colorCounter:0,cropShoulder:1,directTouch:!1,drawLegendSymbol:I.drawLineMarker,isCartesian:!0,kdAxisArray:["clientX","plotY"], +parallelArrays:["x","y"],pointClass:G,requireSorting:!0,sorted:!0});C.series=e;"";"";return e});O(e,"Extensions/ScrollablePlotArea.js",[e["Core/Animation/AnimationUtilities.js"],e["Core/Axis/Axis.js"],e["Core/Chart/Chart.js"],e["Core/Series/Series.js"],e["Core/Globals.js"],e["Core/Utilities.js"]],function(e,b,I,z,H,G){var D=e.stop,B=G.addEvent,x=G.createElement,w=G.merge,v=G.pick;"";B(I,"afterSetChartSize",function(b){var d=this.options.chart.scrollablePlotArea,e=d&&d.minWidth;d=d&&d.minHeight;if(!this.renderer.forExport){if(e){if(this.scrollablePixelsX= +e=Math.max(0,e-this.chartWidth)){this.scrollablePlotBox=this.renderer.scrollablePlotBox=w(this.plotBox);this.plotBox.width=this.plotWidth+=e;this.inverted?this.clipBox.height+=e:this.clipBox.width+=e;var f={1:{name:"right",value:e}}}}else d&&(this.scrollablePixelsY=e=Math.max(0,d-this.chartHeight))&&(this.scrollablePlotBox=this.renderer.scrollablePlotBox=w(this.plotBox),this.plotBox.height=this.plotHeight+=e,this.inverted?this.clipBox.width+=e:this.clipBox.height+=e,f={2:{name:"bottom",value:e}}); +f&&!b.skipAxes&&this.axes.forEach(function(d){f[d.side]?d.getPlotLinePath=function(){var b=f[d.side].name,e=this[b];this[b]=e-f[d.side].value;var k=H.Axis.prototype.getPlotLinePath.apply(this,arguments);this[b]=e;return k}:(d.setAxisSize(),d.setAxisTranslation())})}});B(I,"render",function(){this.scrollablePixelsX||this.scrollablePixelsY?(this.setUpScrolling&&this.setUpScrolling(),this.applyFixed()):this.fixedDiv&&this.applyFixed()});I.prototype.setUpScrolling=function(){var b=this,d={WebkitOverflowScrolling:"touch", +overflowX:"hidden",overflowY:"hidden"};this.scrollablePixelsX&&(d.overflowX="auto");this.scrollablePixelsY&&(d.overflowY="auto");this.scrollingParent=x("div",{className:"highcharts-scrolling-parent"},{position:"relative"},this.renderTo);this.scrollingContainer=x("div",{className:"highcharts-scrolling"},d,this.scrollingParent);B(this.scrollingContainer,"scroll",function(){b.pointer&&delete b.pointer.chartPosition});this.innerContainer=x("div",{className:"highcharts-inner-container"},null,this.scrollingContainer); +this.innerContainer.appendChild(this.container);this.setUpScrolling=null};I.prototype.moveFixedElements=function(){var b=this.container,d=this.fixedRenderer,e=".highcharts-contextbutton .highcharts-credits .highcharts-legend .highcharts-legend-checkbox .highcharts-navigator-series .highcharts-navigator-xaxis .highcharts-navigator-yaxis .highcharts-navigator .highcharts-reset-zoom .highcharts-drillup-button .highcharts-scrollbar .highcharts-subtitle .highcharts-title".split(" "),k;this.scrollablePixelsX&& +!this.inverted?k=".highcharts-yaxis":this.scrollablePixelsX&&this.inverted?k=".highcharts-xaxis":this.scrollablePixelsY&&!this.inverted?k=".highcharts-xaxis":this.scrollablePixelsY&&this.inverted&&(k=".highcharts-yaxis");k&&e.push(k+":not(.highcharts-radial-axis)",k+"-labels:not(.highcharts-radial-axis-labels)");e.forEach(function(e){[].forEach.call(b.querySelectorAll(e),function(b){(b.namespaceURI===d.SVG_NS?d.box:d.box.parentNode).appendChild(b);b.style.pointerEvents="auto"})})};I.prototype.applyFixed= +function(){var b=!this.fixedDiv;var d=this.options.chart;var e=d.scrollablePlotArea;b?(this.fixedDiv=x("div",{className:"highcharts-fixed"},{position:"absolute",overflow:"hidden",pointerEvents:"none",zIndex:(d.style&&d.style.zIndex||0)+2,top:0},null,!0),this.scrollingContainer&&this.scrollingContainer.parentNode.insertBefore(this.fixedDiv,this.scrollingContainer),this.renderTo.style.overflow="visible",this.fixedRenderer=d=new H.Renderer(this.fixedDiv,this.chartWidth,this.chartHeight,this.options.chart.style), +this.scrollableMask=d.path().attr({fill:this.options.chart.backgroundColor||"#fff","fill-opacity":v(e.opacity,.85),zIndex:-1}).addClass("highcharts-scrollable-mask").add(),B(this,"afterShowResetZoom",this.moveFixedElements),B(this,"afterDrilldown",this.moveFixedElements),B(this,"afterLayOutTitles",this.moveFixedElements)):this.fixedRenderer.setSize(this.chartWidth,this.chartHeight);if(this.scrollableDirty||b)this.scrollableDirty=!1,this.moveFixedElements();d=this.chartWidth+(this.scrollablePixelsX|| +0);var k=this.chartHeight+(this.scrollablePixelsY||0);D(this.container);this.container.style.width=d+"px";this.container.style.height=k+"px";this.renderer.boxWrapper.attr({width:d,height:k,viewBox:[0,0,d,k].join(" ")});this.chartBackground.attr({width:d,height:k});this.scrollingContainer.style.height=this.chartHeight+"px";b&&(e.scrollPositionX&&(this.scrollingContainer.scrollLeft=this.scrollablePixelsX*e.scrollPositionX),e.scrollPositionY&&(this.scrollingContainer.scrollTop=this.scrollablePixelsY* +e.scrollPositionY));k=this.axisOffset;b=this.plotTop-k[0]-1;e=this.plotLeft-k[3]-1;d=this.plotTop+this.plotHeight+k[2]+1;k=this.plotLeft+this.plotWidth+k[1]+1;var l=this.plotLeft+this.plotWidth-(this.scrollablePixelsX||0),w=this.plotTop+this.plotHeight-(this.scrollablePixelsY||0);b=this.scrollablePixelsX?[["M",0,b],["L",this.plotLeft-1,b],["L",this.plotLeft-1,d],["L",0,d],["Z"],["M",l,b],["L",this.chartWidth,b],["L",this.chartWidth,d],["L",l,d],["Z"]]:this.scrollablePixelsY?[["M",e,0],["L",e,this.plotTop- +1],["L",k,this.plotTop-1],["L",k,0],["Z"],["M",e,w],["L",e,this.chartHeight],["L",k,this.chartHeight],["L",k,w],["Z"]]:[["M",0,0]];"adjustHeight"!==this.redrawTrigger&&this.scrollableMask.attr({d:b})};B(b,"afterInit",function(){this.chart.scrollableDirty=!0});B(z,"show",function(){this.chart.scrollableDirty=!0})});O(e,"Core/Axis/StackingAxis.js",[e["Core/Animation/AnimationUtilities.js"],e["Core/Utilities.js"]],function(e,b){var D=e.getDeferredAnimation,z=b.addEvent,H=b.destroyObjectProperties,G= +b.fireEvent,C=b.isNumber,B=b.objectEach,x=function(){function b(b){this.oldStacks={};this.stacks={};this.stacksTouched=0;this.axis=b}b.prototype.buildStacks=function(){var b=this.axis,e=b.series,d=b.options.reversedStacks,q=e.length,k;if(!b.isXAxis){this.usePercentage=!1;for(k=q;k--;){var l=e[d?k:q-k-1];l.setStackedPoints();l.setGroupedPoints()}for(k=0;kl&&v.shadow));q&&(q.startX=f.xMap,q.isArea=f.isArea)})};x.prototype.getGraphPath=function(b,e,f){var d=this,q=d.options,k=q.step,l,v=[],u=[],n;b=b||d.points;(l=b.reversed)&&b.reverse();(k={right:1, +center:2}[k]||k&&3)&&l&&(k=4-k);b=this.getValidPoints(b,!1,!(q.connectNulls&&!e&&!f));b.forEach(function(l,w){var m=l.plotX,c=l.plotY,g=b[w-1];(l.leftCliff||g&&g.rightCliff)&&!f&&(n=!0);l.isNull&&!G(e)&&0b&&u>d?(u=Math.max(b,d),n=2*d-u):uv&&n>d?(n=Math.max(v,d),u=2*d-n):n=Math.abs(c)&&.5a.closestPointRange*a.xAxis.transA;e=a.borderWidth=E(b.borderWidth,e?0:1);var g=a.xAxis,f=a.yAxis,m=b.threshold,l=a.translatedThreshold=f.getThreshold(m),q=E(b.minPointLength,5),v=a.getColumnMetrics(),u=v.width,t=a.barW=Math.max(u,1+2*e),p=a.pointXOffset=v.offset,w=a.dataMin,x=a.dataMax;c.inverted&&(l-=.5);b.pointPadding&&(t=Math.ceil(t));G.prototype.translate.apply(a);a.points.forEach(function(e){var h= +E(e.yBottom,l),r=999+Math.abs(h),y=u,A=e.plotX||0;r=d(e.plotY,-r,f.len+r);A+=p;var D=t,B=Math.min(r,h),z=Math.max(r,h)-B;if(q&&Math.abs(z)q?h-q:l-(C?q:0)}k(e.options.pointWidth)&&(y=D=Math.ceil(e.options.pointWidth),A-=Math.round((y-u)/2));b.centerInCategory&&(A=a.adjustForMissingColumns(A,y,e,v));e.barX=A;e.pointWidth=y;e.tooltipPos=c.inverted?[d(f.len+ +f.pos-c.plotLeft-r,f.pos-c.plotLeft,f.len+f.pos-c.plotLeft),g.len+g.pos-c.plotTop-A-D/2,z]:[g.left-c.plotLeft+A+D/2,d(r+f.pos-c.plotTop,f.pos-c.plotTop,f.len+f.pos-c.plotTop),z];e.shapeType=a.pointClass.prototype.shapeType||"rect";e.shapeArgs=a.crispCol.apply(a,e.isNull?[A,l,D,0]:[A,B,D,z])})};b.prototype.drawGraph=function(){this.group[this.dense?"addClass":"removeClass"]("highcharts-dense-data")};b.prototype.pointAttribs=function(a,c){var b=this.options,d=this.pointAttrToOptions||{};var e=d.stroke|| +"borderColor";var h=d["stroke-width"]||"borderWidth",g=a&&a.color||this.color,f=a&&a[e]||b[e]||g,k=a&&a[h]||b[h]||this[h]||0;d=a&&a.options.dashStyle||b.dashStyle;var m=E(a&&a.opacity,b.opacity,1);if(a&&this.zones.length){var l=a.getZone();g=a.options.color||l&&(l.color||a.nonZonedColor)||this.color;l&&(f=l.borderColor||f,d=l.dashStyle||d,k=l.borderWidth||k)}c&&a&&(a=J(b.states[c],a.options.states&&a.options.states[c]||{}),c=a.brightness,g=a.color||"undefined"!==typeof c&&v(g).brighten(a.brightness).get()|| +g,f=a[e]||f,k=a[h]||k,d=a.dashStyle||d,m=E(a.opacity,m));e={fill:g,stroke:f,"stroke-width":k,opacity:m};d&&(e.dashstyle=d);return e};b.prototype.drawPoints=function(){var a=this,c=this.chart,b=a.options,d=c.renderer,e=b.animationLimit||250,g;a.points.forEach(function(h){var f=h.graphic,k=!!f,m=f&&c.pointCount\u25cf {series.name}
',pointFormat:"x: {point.x}
y: {point.y}
"}});return w}(b);C(z.prototype,{drawTracker:e.prototype.drawTracker,sorted:!1,requireSorting:!1,noSharedTooltip:!0,trackerGroups:["group","markerGroup","dataLabelsGroup"],takeOrdinalPosition:!1});G(z,"afterTranslate",function(){this.applyJitter()});I.registerSeriesType("scatter", +z);"";return z});O(e,"Mixins/CenteredSeries.js",[e["Core/Globals.js"],e["Core/Series/Series.js"],e["Core/Utilities.js"]],function(e,b,I){var D=I.isNumber,H=I.pick,G=I.relativeLength,C=e.deg2rad;return e.CenteredSeriesMixin={getCenter:function(){var e=this.options,D=this.chart,w=2*(e.slicedOffset||0),v=D.plotWidth-2*w,f=D.plotHeight-2*w,d=e.center,q=Math.min(v,f),k=e.size,l=e.innerSize||0;"string"===typeof k&&(k=parseFloat(k));"string"===typeof l&&(l=parseFloat(l));e=[H(d[0],"50%"),H(d[1],"50%"),H(k&& +0>k?void 0:e.size,"100%"),H(l&&0>l?void 0:e.innerSize||0,"0%")];!D.angular||this instanceof b||(e[3]=0);for(d=0;4>d;++d)k=e[d],D=2>d||2===d&&/%$/.test(k),e[d]=G(k,[v,f,q,e[2]][d])+(D?w:0);e[3]>e[2]&&(e[3]=e[2]);return e},getStartAndEndRadians:function(b,e){b=D(b)?b:0;e=D(e)&&e>b&&360>e-b?e:b+360;return{start:C*(b+-90),end:C*(e+-90)}}}});O(e,"Series/Pie/PiePoint.js",[e["Core/Animation/AnimationUtilities.js"],e["Core/Series/Point.js"],e["Core/Utilities.js"]],function(e,b,I){var D=this&&this.__extends|| +function(){var b=function(e,d){b=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(b,d){b.__proto__=d}||function(b,d){for(var e in d)d.hasOwnProperty(e)&&(b[e]=d[e])};return b(e,d)};return function(e,d){function f(){this.constructor=e}b(e,d);e.prototype=null===d?Object.create(d):(f.prototype=d.prototype,new f)}}(),H=e.setAnimation,G=I.addEvent,C=I.defined;e=I.extend;var B=I.isNumber,x=I.pick,w=I.relativeLength;I=function(e){function f(){var b=null!==e&&e.apply(this,arguments)||this; +b.labelDistance=void 0;b.options=void 0;b.series=void 0;return b}D(f,e);f.prototype.getConnectorPath=function(){var b=this.labelPosition,e=this.series.options.dataLabels,f=e.connectorShape,l=this.connectorShapes;l[f]&&(f=l[f]);return f.call(this,{x:b.final.x,y:b.final.y,alignment:b.alignment},b.connectorPosition,e)};f.prototype.getTranslate=function(){return this.sliced?this.slicedTranslation:{translateX:0,translateY:0}};f.prototype.haloPath=function(b){var d=this.shapeArgs;return this.sliced||!this.visible? +[]:this.series.chart.renderer.symbols.arc(d.x,d.y,d.r+b,d.r+b,{innerR:d.r-1,start:d.start,end:d.end})};f.prototype.init=function(){b.prototype.init.apply(this,arguments);var d=this;d.name=x(d.name,"Slice");var e=function(b){d.slice("select"===b.type)};G(d,"select",e);G(d,"unselect",e);return d};f.prototype.isValid=function(){return B(this.y)&&0<=this.y};f.prototype.setVisible=function(b,e){var d=this,f=d.series,q=f.chart,v=f.options.ignoreHiddenPoint;e=x(e,v);b!==d.visible&&(d.visible=d.options.visible= +b="undefined"===typeof b?!d.visible:b,f.options.data[f.data.indexOf(d)]=d.options,["graphic","dataLabel","connector","shadowGroup"].forEach(function(e){if(d[e])d[e][b?"show":"hide"](b)}),d.legendItem&&q.legend.colorizeItem(d,b),b||"hover"!==d.state||d.setState(""),v&&(f.isDirty=!0),e&&q.redraw())};f.prototype.slice=function(b,e,f){var d=this.series;H(f,d.chart);x(e,!0);this.sliced=this.options.sliced=C(b)?b:!this.sliced;d.options.data[d.data.indexOf(this)]=this.options;this.graphic&&this.graphic.animate(this.getTranslate()); +this.shadowGroup&&this.shadowGroup.animate(this.getTranslate())};return f}(b);e(I.prototype,{connectorShapes:{fixedOffset:function(b,e,d){var f=e.breakAt;e=e.touchingSliceAt;return[["M",b.x,b.y],d.softConnector?["C",b.x+("left"===b.alignment?-5:5),b.y,2*f.x-e.x,2*f.y-e.y,f.x,f.y]:["L",f.x,f.y],["L",e.x,e.y]]},straight:function(b,e){e=e.touchingSliceAt;return[["M",b.x,b.y],["L",e.x,e.y]]},crookedLine:function(b,e,d){e=e.touchingSliceAt;var f=this.series,k=f.center[0],l=f.chart.plotWidth,v=f.chart.plotLeft; +f=b.alignment;var u=this.shapeArgs.r;d=w(d.crookDistance,1);l="left"===f?k+u+(l+v-k-u)*(1-d):v+(k-u)*d;d=["L",l,b.y];k=!0;if("left"===f?l>b.x||le.x)k=!1;b=[["M",b.x,b.y]];k&&b.push(d);b.push(["L",e.x,e.y]);return b}}});return I});O(e,"Series/Pie/PieSeries.js",[e["Mixins/CenteredSeries.js"],e["Series/Column/ColumnSeries.js"],e["Core/Globals.js"],e["Mixins/LegendSymbol.js"],e["Core/Color/Palette.js"],e["Series/Pie/PiePoint.js"],e["Core/Series/Series.js"],e["Core/Series/SeriesRegistry.js"], +e["Core/Renderer/SVG/SVGRenderer.js"],e["Core/Utilities.js"]],function(e,b,I,z,H,G,C,B,x,w){var v=this&&this.__extends||function(){var b=function(d,e){b=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(b,c){b.__proto__=c}||function(b,c){for(var d in c)c.hasOwnProperty(d)&&(b[d]=c[d])};return b(d,e)};return function(d,e){function f(){this.constructor=d}b(d,e);d.prototype=null===e?Object.create(e):(f.prototype=e.prototype,new f)}}(),f=e.getStartAndEndRadians;I=I.noop;var d=w.clamp,q= +w.extend,k=w.fireEvent,l=w.merge,D=w.pick,u=w.relativeLength;w=function(b){function e(){var d=null!==b&&b.apply(this,arguments)||this;d.center=void 0;d.data=void 0;d.maxLabelDistance=void 0;d.options=void 0;d.points=void 0;return d}v(e,b);e.prototype.animate=function(b){var d=this,c=d.points,e=d.startAngleRad;b||c.forEach(function(a){var c=a.graphic,b=a.shapeArgs;c&&b&&(c.attr({r:D(a.startR,d.center&&d.center[3]/2),start:e,end:e}),c.animate({r:b.r,start:b.start,end:b.end},d.options.animation))})}; +e.prototype.drawEmpty=function(){var b=this.startAngleRad,d=this.endAngleRad,c=this.options;if(0===this.total&&this.center){var e=this.center[0];var a=this.center[1];this.graph||(this.graph=this.chart.renderer.arc(e,a,this.center[1]/2,0,b,d).addClass("highcharts-empty-series").add(this.group));this.graph.attr({d:x.prototype.symbols.arc(e,a,this.center[2]/2,0,{start:b,end:d,innerR:this.center[3]/2})});this.chart.styledMode||this.graph.attr({"stroke-width":c.borderWidth,fill:c.fillColor||"none",stroke:c.color|| +H.neutralColor20})}else this.graph&&(this.graph=this.graph.destroy())};e.prototype.drawPoints=function(){var b=this.chart.renderer;this.points.forEach(function(d){d.graphic&&d.hasNewShapeType()&&(d.graphic=d.graphic.destroy());d.graphic||(d.graphic=b[d.shapeType](d.shapeArgs).add(d.series.group),d.delayedRendering=!0)})};e.prototype.generatePoints=function(){b.prototype.generatePoints.call(this);this.updateTotals()};e.prototype.getX=function(b,e,c){var g=this.center,a=this.radii?this.radii[c.index]|| +0:g[2]/2;b=Math.asin(d((b-g[1])/(a+c.labelDistance),-1,1));return g[0]+(e?-1:1)*Math.cos(b)*(a+c.labelDistance)+(01.5*Math.PI?z-=2*Math.PI:z<-Math.PI/2&&(z+=2*Math.PI);x.slicedTranslation={translateX:Math.round(Math.cos(z)* +e),translateY:Math.round(Math.sin(z)*e)};B=Math.cos(z)*b[2]/2;var t=Math.sin(z)*b[2]/2;x.tooltipPos=[b[0]+.7*B,b[1]+.7*t];x.half=z<-Math.PI/2||z>Math.PI/2?1:0;x.angle=z;E=Math.min(a,x.labelDistance/5);x.labelPosition={natural:{x:b[0]+B+Math.cos(z)*x.labelDistance,y:b[1]+t+Math.sin(z)*x.labelDistance},"final":{},alignment:0>x.labelDistance?"center":x.half?"right":"left",connectorPosition:{breakAt:{x:b[0]+B+Math.cos(z)*E,y:b[1]+t+Math.sin(z)*E},touchingSliceAt:{x:b[0]+B,y:b[1]+t}}}}k(this,"afterTranslate")}; +e.prototype.updateTotals=function(){var b,d=0,c=this.points,e=c.length,a=this.options.ignoreHiddenPoint;for(b=0;bm){E(b,function(a,c){return(c.rank||0)-(a.rank||0)});for(l=e=0;l<=m;)l+=b[e].size,e++;k=b.splice(e-1,b.length)}E(b,a);for(b=b.map(function(a){return{size:a.size,targets:[a.target], +align:u(a.align,.5)}});g;){for(e=b.length;e--;)g=b[e],l=(Math.min.apply(0,g.targets)+Math.max.apply(0,g.targets))/2,g.pos=v(l-g.size*g.align,0,c-g.size);e=b.length;for(g=!1;e--;)0b[e].pos&&(b[e-1].size+=b[e].size,b[e-1].targets=b[e-1].targets.concat(b[e].targets),b[e-1].align=.5,b[e-1].pos+b[e-1].size>c&&(b[e-1].pos=c-b[e-1].size),b.splice(e,1),g=!0)}f.push.apply(f,k);e=0;b.some(function(a){var b=0;if(a.targets.some(function(){f[e].pos=a.pos+b;if("undefined"!==typeof d&& +Math.abs(f[e].pos-f[e].target)>d)return f.slice(0,e+1).forEach(function(a){delete a.pos}),f.reducedLen=(f.reducedLen||c)-.1*c,f.reducedLen>.1*c&&I.distribute(f,c,d),!0;b+=f[e].size;e++}))return!0});E(f,a)};H.prototype.drawDataLabels=function(){function b(a,c){var b=c.filter;return b?(c=b.operator,a=a[b.property],b=b.value,">"===c&&a>b||"<"===c&&a="===c&&a>=b||"<="===c&&a<=b||"=="===c&&a==b||"==="===c&&a===b?!0:!1):!0}function c(a,c){var b=[],d;if(k(a)&&!k(c))b=a.map(function(a){return l(a,c)}); +else if(k(c)&&!k(a))b=c.map(function(c){return l(a,c)});else if(k(a)||k(c))for(d=Math.max(a.length,c.length);d--;)b[d]=l(a[d],c[d]);else b=l(a,c);return b}var d=this,a=d.chart,e=d.options,r=e.dataLabels,n=d.points,v,w=d.hasRendered||0,E=r.animation;E=r.defer?D(a,E,d):{defer:0,duration:0};var B=a.renderer;r=c(c(a.options.plotOptions&&a.options.plotOptions.series&&a.options.plotOptions.series.dataLabels,a.options.plotOptions&&a.options.plotOptions[d.type]&&a.options.plotOptions[d.type].dataLabels), +r);q(this,"drawDataLabels");if(k(r)||r.enabled||d._hasPointLabels){var C=d.plotGroup("dataLabelsGroup","data-labels",w?"inherit":"hidden",r.zIndex||6);C.attr({opacity:+w});!w&&(w=d.dataLabelsGroup)&&(d.visible&&C.show(!0),w[e.animation?"animate":"attr"]({opacity:1},E));n.forEach(function(g){v=J(c(r,g.dlOptions||g.options&&g.options.dataLabels));v.forEach(function(c,h){var k=c.enabled&&(!g.isNull||g.dataLabelOnNull)&&b(g,c),l=g.dataLabels?g.dataLabels[h]:g.dataLabel,m=g.connectors?g.connectors[h]: +g.connector,r=u(c.distance,g.labelDistance),n=!l;if(k){var q=g.getLabelConfig();var t=u(c[g.formatPrefix+"Format"],c.format);q=f(t)?x(t,q,a):(c[g.formatPrefix+"Formatter"]||c.formatter).call(q,c);t=c.style;var v=c.rotation;a.styledMode||(t.color=u(c.color,t.color,d.color,z.neutralColor100),"contrast"===t.color?(g.contrastColor=B.getContrast(g.color||d.color),t.color=!f(r)&&c.inside||0>r||e.stacking?g.contrastColor:z.neutralColor100):delete g.contrastColor,e.cursor&&(t.cursor=e.cursor));var w={r:c.borderRadius|| +0,rotation:v,padding:c.padding,zIndex:1};a.styledMode||(w.fill=c.backgroundColor,w.stroke=c.borderColor,w["stroke-width"]=c.borderWidth);N(w,function(a,c){"undefined"===typeof a&&delete w[c]})}!l||k&&f(q)?k&&f(q)&&(l?w.text=q:(g.dataLabels=g.dataLabels||[],l=g.dataLabels[h]=v?B.text(q,0,-9999,c.useHTML).addClass("highcharts-data-label"):B.label(q,0,-9999,c.shape,null,null,c.useHTML,null,"data-label"),h||(g.dataLabel=l),l.addClass(" highcharts-data-label-color-"+g.colorIndex+" "+(c.className||"")+ +(c.useHTML?" highcharts-tracker":""))),l.options=c,l.attr(w),a.styledMode||l.css(t).shadow(c.shadow),l.added||l.add(C),c.textPath&&!c.useHTML&&(l.setTextPath(g.getDataLabelPath&&g.getDataLabelPath(l)||g.graphic,c.textPath),g.dataLabelPath&&!c.textPath.enabled&&(g.dataLabelPath=g.dataLabelPath.destroy())),d.alignDataLabel(g,l,c,null,n)):(g.dataLabel=g.dataLabel&&g.dataLabel.destroy(),g.dataLabels&&(1===g.dataLabels.length?delete g.dataLabels:delete g.dataLabels[h]),h||delete g.dataLabel,m&&(g.connector= +g.connector.destroy(),g.connectors&&(1===g.connectors.length?delete g.connectors:delete g.connectors[h])))})})}q(this,"afterDrawDataLabels")};H.prototype.alignDataLabel=function(b,c,e,a,f){var g=this,h=this.chart,k=this.isCartesian&&h.inverted,l=this.enabledDataSorting,m=u(b.dlBox&&b.dlBox.centerX,b.plotX,-9999),n=u(b.plotY,-9999),q=c.getBBox(),v=e.rotation,w=e.align,t=h.isInsidePlot(m,Math.round(n),{inverted:k,paneCoordinates:!0,series:g}),p="justify"===u(e.overflow,l?"none":"justify"),D=this.visible&& +!1!==b.visible&&(b.series.forceDL||l&&!p||t||u(e.inside,!!this.options.stacking)&&a&&h.isInsidePlot(m,k?a.x+1:a.y+a.height-1,{inverted:k,paneCoordinates:!0,series:g}));var x=function(a){l&&g.xAxis&&!p&&g.setDataLabelStartPos(b,c,f,t,a)};if(D){var z=h.renderer.fontMetrics(h.styledMode?void 0:e.style.fontSize,c).b;a=d({x:k?this.yAxis.len-n:m,y:Math.round(k?this.xAxis.len-m:n),width:0,height:0},a);d(e,{width:q.width,height:q.height});v?(p=!1,m=h.renderer.rotCorr(z,v),m={x:a.x+(e.x||0)+a.width/2+m.x, +y:a.y+(e.y||0)+{top:0,middle:.5,bottom:1}[e.verticalAlign]*a.height},x(m),c[f?"attr":"animate"](m).attr({align:w}),x=(v+720)%360,x=180x,"left"===w?m.y-=x?q.height:0:"center"===w?(m.x-=q.width/2,m.y-=q.height/2):"right"===w&&(m.x-=q.width,m.y-=x?0:q.height),c.placed=!0,c.alignAttr=m):(x(a),c.align(e,void 0,a),m=c.alignAttr);p&&0<=a.height?this.justifyDataLabel(c,e,m,q,a,f):u(e.crop,!0)&&(D=h.isInsidePlot(m.x,m.y,{paneCoordinates:!0,series:g})&&h.isInsidePlot(m.x+q.width,m.y+q.height,{paneCoordinates:!0, +series:g}));if(e.shape&&!v)c[f?"attr":"animate"]({anchorX:k?h.plotWidth-b.plotY:b.plotX,anchorY:k?h.plotHeight-b.plotX:b.plotY})}f&&l&&(c.placed=!1);D||l&&!p||(c.hide(!0),c.placed=!1)};H.prototype.setDataLabelStartPos=function(b,c,d,a,e){var g=this.chart,f=g.inverted,h=this.xAxis,k=h.reversed,l=f?c.height/2:c.width/2;b=(b=b.pointWidth)?b/2:0;h=f?e.x:k?-l-b:h.width-l+b;e=f?k?this.yAxis.height-l+b:-l-b:e.y;c.startXPos=h;c.startYPos=e;a?"hidden"===c.visibility&&(c.show(),c.attr({opacity:0}).animate({opacity:1})): +c.attr({opacity:1}).animate({opacity:0},void 0,c.hide);g.hasRendered&&(d&&c.attr({x:c.startXPos,y:c.startYPos}),c.placed=!0)};H.prototype.justifyDataLabel=function(b,c,d,a,e,f){var g=this.chart,h=c.align,k=c.verticalAlign,l=b.box?0:b.padding||0,m=c.x;m=void 0===m?0:m;var n=c.y;var r=void 0===n?0:n;n=(d.x||0)+l;if(0>n){"right"===h&&0<=m?(c.align="left",c.inside=!0):m-=n;var q=!0}n=(d.x||0)+a.width-l;n>g.plotWidth&&("left"===h&&0>=m?(c.align="right",c.inside=!0):m+=g.plotWidth-n,q=!0);n=d.y+l;0>n&& +("bottom"===k&&0<=r?(c.verticalAlign="top",c.inside=!0):r-=n,q=!0);n=(d.y||0)+a.height-l;n>g.plotHeight&&("top"===k&&0>=r?(c.verticalAlign="bottom",c.inside=!0):r+=g.plotHeight-n,q=!0);q&&(c.x=m,c.y=r,b.placed=!f,b.align(c,void 0,e));return q};G.pie&&(G.pie.prototype.dataLabelPositioners={radialDistributionY:function(b){return b.top+b.distributeBox.pos},radialDistributionX:function(b,c,d,a){return b.getX(dc.bottom-2?a:d,c.half,c)},justify:function(b,c,d){return d[0]+(b.half?-1:1)*(c+b.labelDistance)}, +alignToPlotEdges:function(b,c,d,a){b=b.getBBox().width;return c?b+a:d-b-a},alignToConnectors:function(b,c,d,a){var e=0,g;b.forEach(function(a){g=a.dataLabel.getBBox().width;g>e&&(e=g)});return c?e+a:d-e-a}},G.pie.prototype.drawDataLabels=function(){var b=this,c=b.data,d,a=b.chart,e=b.options.dataLabels||{},k=e.connectorPadding,n,q=a.plotWidth,v=a.plotHeight,x=a.plotLeft,D=Math.round(a.chartWidth/3),E,B=b.center,C=B[2]/2,t=B[1],p,G,J,N,F=[[],[]],O,K,T,X,U=[0,0,0,0],W=b.dataLabelPositioners,Y;b.visible&& +(e.enabled||b._hasPointLabels)&&(c.forEach(function(a){a.dataLabel&&a.visible&&a.dataLabel.shortened&&(a.dataLabel.attr({width:"auto"}).css({width:"auto",textOverflow:"clip"}),a.dataLabel.shortened=!1)}),H.prototype.drawDataLabels.apply(b),c.forEach(function(a){a.dataLabel&&(a.visible?(F[a.half].push(a),a.dataLabel._pos=null,!f(e.style.width)&&!f(a.options.dataLabels&&a.options.dataLabels.style&&a.options.dataLabels.style.width)&&a.dataLabel.getBBox().width>D&&(a.dataLabel.css({width:Math.round(.7* +D)+"px"}),a.dataLabel.shortened=!0)):(a.dataLabel=a.dataLabel.destroy(),a.dataLabels&&1===a.dataLabels.length&&delete a.dataLabels))}),F.forEach(function(c,g){var h=c.length,l=[],m;if(h){b.sortByAngle(c,g-.5);if(0q-k&&0===g&&(n=Math.round(O+G-q+k),U[1]=Math.max(n,U[1])),0>K-N/2?U[0]=Math.max(Math.round(-K+N/2),U[0]):K+N/2>v&&(U[2]=Math.max(Math.round(K+ +N/2-v),U[2])),p.sideOverflow=n)}}}),0===w(U)||this.verifyDataLabelOverflow(U))&&(this.placeDataLabels(),this.points.forEach(function(c){Y=l(e,c.options.dataLabels);if(n=u(Y.connectorWidth,1)){var d;E=c.connector;if((p=c.dataLabel)&&p._pos&&c.visible&&0u(this.translatedThreshold,g.yAxis.len)),m=u(d.inside,!!this.options.stacking);h&&(a=l(h),0>a.y&&(a.height+=a.y,a.y=0),h=a.y+a.height-g.yAxis.len,0=n.x+n.width||x.x+x.width<= +n.x||x.y>=n.y+n.height||x.y+x.height<=n.y||((u.labelrank=B(d.minWidth,0)&&this.chartHeight>=B(d.minHeight,0)}).call(this)&&e.push(b._id)};e.prototype.currentOptions=function(b){function e(b,f,q,u){var k;C(b,function(b,l){if(!u&&-1 - Autotrimps by genbtc + Autotrimps by Zek @@ -18,13 +18,13 @@

Autotrimps

Automation for the idle incremental game 'Trimps'

-

View the Project on GitHub genbtc/AutoTrimps

+

View the Project on GitHub

@@ -54,11 +54,11 @@

Having trouble with Pages? Check out our documentation or contact support and we’ll help you sort it out.

-

This project is maintained by genbtc

+

This project is maintained by Zek

Hosted on GitHub Pages — Theme by orderedlist

- + diff --git a/install.user.js b/install.user.js deleted file mode 100644 index 8f864910a..000000000 --- a/install.user.js +++ /dev/null @@ -1,19 +0,0 @@ -// ==UserScript== -// @name AutoTrimps-genBTC -// @namespace https://github.com/genbtc/AutoTrimps -// @version 2.1.6.9-genbtc-3-23-2018 -// @updateURL https://github.com/genbtc/AutoTrimps/install.user.js -// @description Automate all the trimps! -// @author zininzinin, spindrjr, Ishkaru, genBTC -// @include *trimps.github.io* -// @include *kongregate.com/games/GreenSatellite/trimps -// @grant none -// ==/UserScript== - -var script = document.createElement('script'); -script.id = 'AutoTrimps-script'; -//This can be edited to be your own Github Repository URL. -script.src = 'https://genbtc.github.io/AutoTrimps/AutoTrimps2.js'; -//script.setAttribute('crossorigin',"use-credentials"); -script.setAttribute('crossorigin',"anonymous"); -document.head.appendChild(script); diff --git a/mods.js b/mods.js new file mode 100644 index 000000000..e4d724f9b --- /dev/null +++ b/mods.js @@ -0,0 +1,7 @@ +var script = document.createElement('script'); +script.id = 'AutoTrimps-Zek'; +script.src = 'https://Zorn192.github.io/AutoTrimps/AutoTrimps2.js'; +script.setAttribute('crossorigin',"anonymous"); +document.head.appendChild(script); + +var isSteam = true; diff --git a/modsGRAPH.js b/modsGRAPH.js new file mode 100644 index 000000000..38293664c --- /dev/null +++ b/modsGRAPH.js @@ -0,0 +1,5 @@ +var script = document.createElement('script'); +script.id = 'AutoTrimps-Graphs'; +script.src = 'https://Quiaaaa.github.io/AutoTrimps/GraphsOnly.js'; +script.setAttribute('crossorigin', "anonymous"); +document.head.appendChild(script); diff --git a/modules/MAZ.js b/modules/MAZ.js new file mode 100644 index 000000000..a7c1be549 --- /dev/null +++ b/modules/MAZ.js @@ -0,0 +1,630 @@ +function MAZLookalike(titleText, isItIn, event) { + + var zone; + var cell; + var setting; + var level; + var map; + var special; + var gather; + + zone = [0]; + cell = [0]; + + //Settings + + if (titleText == 'Time Farm') { + zone = 'Rtimefarmzone'; + cell = 'Rtimefarmcell'; + setting = 'Rtimefarmtime'; + level = 'Rtimefarmlevel'; + map = 'Rtimefarmmap'; + special = 'Rtimefarmspecial'; + gather = 'Rtimefarmgather'; + } else if (titleText == 'dTime Farm') { + zone = 'Rdtimefarmzone'; + cell = 'Rdtimefarmcell'; + setting = 'Rdtimefarmtime'; + level = 'Rdtimefarmlevel'; + map = 'Rdtimefarmmap'; + special = 'Rdtimefarmspecial'; + gather = 'Rdtimefarmgather'; + } else if (titleText.includes('Smithy Farm')) { + zone = 'Rsmithyfarmzone'; + cell = 'Rsmithyfarmcell'; + setting = 'Rsmithyfarmamount'; + } else if (titleText.includes('Tribute Farm')) { + zone = 'Rtributefarmzone'; + cell = 'Rtributefarmcell'; + setting = 'Rtributefarmamount'; + level = 'Rtributefarmlevel'; + map = 'Rtributemapselection'; + special = 'Rtributespecialselection'; + gather = 'Rtributegatherselection'; + } else if (titleText == 'Shrine - U1') { + zone = 'Hshrinezone'; + cell = 'Hshrinecell'; + setting = 'Hshrineamount'; + } else if (titleText == 'Shrine - U2') { + zone = 'Rshrinezone'; + cell = 'Rshrinecell'; + setting = 'Rshrineamount'; + } else if (titleText == 'Shrine - U1 (Daily)') { + zone = 'Hdshrinezone'; + cell = 'Hdshrinecell'; + setting = 'Hdshrineamount'; + } else if (titleText == 'Shrine - U2 (Daily)') { + zone = 'Rdshrinezone'; + cell = 'Rdshrinecell'; + setting = 'Rdshrineamount'; + } else if (titleText.includes('Quagmire')) { + zone = 'Rblackbogzone'; + setting = 'Rblackbogamount'; + } else if (titleText.includes('Insanity')) { + zone = 'Rinsanityfarmzone'; + cell = 'Rinsanityfarmcell'; + setting = 'Rinsanityfarmstack'; + level = 'Rinsanityfarmlevel'; + } else if (titleText.includes('Alch')) { + zone = 'Ralchfarmzone'; + cell = 'Ralchfarmcell'; + setting = 'Ralchfarmstack'; + level = 'Ralchfarmlevel'; + map = 'Ralchfarmselection'; + } else if (titleText.includes('Hypo')) { + zone = 'Rhypofarmzone'; + cell = 'Rhypofarmcell'; + setting = 'Rhypofarmstack'; + level = 'Rhypofarmlevel'; + } else if (titleText == 'Praid') { + zone = 'RAMPraidzone'; + cell = 'RAMPraidcell'; + setting = 'RAMPraidraid'; + } else if (titleText == 'dPraid') { + zone = 'RdAMPraidzone'; + cell = 'RdAMPraidcell'; + setting = 'RdAMPraidraid'; + } + + + cancelTooltip(); + titleText = !titleText ? 'undefined' : titleText; + if (titleText == 'undefined') return; + + var elem = document.getElementById("tooltipDiv"); + swapClass("tooltipExtra", "tooltipExtraNone", elem); + document.getElementById('tipText').className = ""; + + var tooltipText; + var costText = ""; + var titleText; + + var ondisplay = null; + var maxSettings = 120; + var windowHelp = "Welcome to AT\'s version of MaZ! Please read the tooltips of the settings button to get more detailed info on how to use this. However it should be easy enough to figure out!"; + + tooltipText = "\ +
\ +
\ +
\ +
Zone
" + if (!titleText.includes('Quagmire')) tooltipText += "
Cell
" + + //Windows + + if (titleText == 'Time Farm') { + tooltipText += "
Time
" + tooltipText += "
Map
" + tooltipText += "
Level
" + tooltipText += "
Special
" + tooltipText += "
Gather
" + } else if (titleText == 'dTime Farm') { + tooltipText += "
Time
" + tooltipText += "
Map
" + tooltipText += "
Level
" + tooltipText += "
Special
" + tooltipText += "
Gather
" + } else if (titleText.includes('Smithy Farm')) { + tooltipText += "
Smithys
" + } else if (titleText.includes('Tribute Farm')) { + tooltipText += "
Tributes
" + tooltipText += "
Map
" + tooltipText += "
Level
" + tooltipText += "
Special
" + tooltipText += "
Gather
" + } else if (titleText.includes('Shrine')) { + tooltipText += "
Amount
" + } else if (titleText.includes('Quagmire')) { + tooltipText += "
Black Bogs
" + } else if (titleText.includes('Insanity')) { + tooltipText += "
Stacks
" + tooltipText += "
Level
" + } else if (titleText.includes('Alch')) { + tooltipText += "
Potions
" + tooltipText += "
Map
" + tooltipText += "
Level
" + } else if (titleText.includes('Hypo')) { + tooltipText += "
Bonfires
" + tooltipText += "
Level
" + } else if (titleText == 'Praid') { + tooltipText += "
Raid
" + } else if (titleText == 'dPraid') { + tooltipText += "
Raid
" + } + + tooltipText += "
"; + + var current = autoTrimpSettings[zone].value; + + for (var x = 0; x < maxSettings; x++) { + var vals = { + check: true, + zone: -1, + cell: 81, + setting: 0, + map: 0, + level: -1, + special: 0, + gather: 0 + }; + var style = ""; + + if (current.length - 1 >= x) { + vals.zone = autoTrimpSettings[zone].value[x]; + if (!titleText.includes('Quagmire')) vals.cell = autoTrimpSettings[cell].value[x] ? autoTrimpSettings[cell].value[x] : 81; + + //Values + + if (titleText == 'Time Farm') { + vals.setting = autoTrimpSettings[setting].value[x] ? autoTrimpSettings[setting].value[x] : 0; + vals.map = autoTrimpSettings[map].value[x] ? autoTrimpSettings[map].value[x] : 0; + vals.level = autoTrimpSettings[level].value[x] ? autoTrimpSettings[level].value[x] : 0; + vals.special = autoTrimpSettings[special].value[x] ? autoTrimpSettings[special].value[x] : 0; + vals.gather = autoTrimpSettings[gather].value[x] ? autoTrimpSettings[gather].value[x] : 0; + } else if (titleText == 'dTime Farm') { + vals.setting = autoTrimpSettings[setting].value[x] ? autoTrimpSettings[setting].value[x] : 0; + vals.map = autoTrimpSettings[map].value[x] ? autoTrimpSettings[map].value[x] : 0; + vals.level = autoTrimpSettings[level].value[x] ? autoTrimpSettings[level].value[x] : 0; + vals.special = autoTrimpSettings[special].value[x] ? autoTrimpSettings[special].value[x] : 0; + vals.gather = autoTrimpSettings[gather].value[x] ? autoTrimpSettings[gather].value[x] : 0; + } else if (titleText.includes('Smithy Farm')) { + vals.setting = autoTrimpSettings[setting].value[x] ? autoTrimpSettings[setting].value[x] : 0; + } else if (titleText.includes('Tribute Farm')) { + vals.setting = autoTrimpSettings[setting].value[x] ? autoTrimpSettings[setting].value[x] : 0; + vals.map = autoTrimpSettings[map].value[x] ? autoTrimpSettings[map].value[x] : 0; + vals.level = autoTrimpSettings[level].value[x] ? autoTrimpSettings[level].value[x] : 0; + vals.special = autoTrimpSettings[special].value[x] ? autoTrimpSettings[special].value[x] : 0; + vals.gather = autoTrimpSettings[gather].value[x] ? autoTrimpSettings[gather].value[x] : 0; + } else if (titleText.includes('Shrine')) { + vals.setting = autoTrimpSettings[setting].value[x] ? autoTrimpSettings[setting].value[x] : 0; + } else if (titleText.includes('Quagmire')) { + vals.setting = autoTrimpSettings[setting].value[x] ? autoTrimpSettings[setting].value[x] : 0; + } else if (titleText.includes('Insanity')) { + vals.setting = autoTrimpSettings[setting].value[x] ? autoTrimpSettings[setting].value[x] : 0; + vals.level = autoTrimpSettings[level].value[x] ? autoTrimpSettings[level].value[x] : 0; + } else if (titleText.includes('Alch')) { + vals.setting = autoTrimpSettings[setting].value[x] ? autoTrimpSettings[setting].value[x] : 0; + vals.map = autoTrimpSettings[map].value[x] ? autoTrimpSettings[map].value[x] : 0; + vals.level = autoTrimpSettings[level].value[x] ? autoTrimpSettings[level].value[x] : 0; + } else if (titleText.includes('Hypo')) { + vals.setting = autoTrimpSettings[setting].value[x] ? autoTrimpSettings[setting].value[x] : 0; + vals.level = autoTrimpSettings[level].value[x] ? autoTrimpSettings[level].value[x] : 0; + } else if (titleText == 'Praid') { + vals.setting = autoTrimpSettings[setting].value[x] ? autoTrimpSettings[setting].value[x] : 0; + } else if (titleText == 'dPraid') { + vals.setting = autoTrimpSettings[setting].value[x] ? autoTrimpSettings[setting].value[x] : 0; + } + } else style = " style='display: none' "; + + var gatherDropdown = "\"\"\"" + var mapDropdown = "\"\"\"\"\"\"" + var specialsDropdown = "\\\\\\\\\\\\" + + var className = (vals.preset == 3) ? "windowBwMainOn" : "windowBwMainOff"; + tooltipText += "
"; + tooltipText += "
"; + tooltipText += "
"; + if (!titleText.includes('Quagmire')) tooltipText += "
"; + + //Tooltips + + if (titleText == 'Time Farm') { + tooltipText += "
"; + tooltipText += "
" + tooltipText += "
"; + tooltipText += "
" + tooltipText += "
" + } else if (titleText == 'dTime Farm') { + tooltipText += "
"; + tooltipText += "
" + tooltipText += "
"; + tooltipText += "
" + tooltipText += "
" + } else if (titleText.includes('Smithy Farm')) { + tooltipText += "
"; + } else if (titleText.includes('Tribute Farm')) { + tooltipText += "
"; + tooltipText += "
" + tooltipText += "
"; + tooltipText += "
" + tooltipText += "
" + } else if (titleText.includes('Shrine')) { + tooltipText += "
"; + } else if (titleText.includes('Quagmire')) { + tooltipText += "
"; + } else if (titleText.includes('Insanity')) { + tooltipText += "
"; + tooltipText += "
"; + } else if (titleText.includes('Alch')) { + tooltipText += "
"; + tooltipText += "
" + tooltipText += "
"; + } else if (titleText.includes('Hypo')) { + tooltipText += "
"; + tooltipText += "
"; + } else if (titleText == 'Praid') { + tooltipText += "
"; + } else if (titleText == 'dPraid') { + tooltipText += "
"; + } + + tooltipText += "
" + } + + tooltipText += "
+ Add Row
" + tooltipText += "
"; + costText = "
Save and CloseCancelSave
" + game.global.lockTooltip = true; + elem.style.display = 'block' + elem.style.top = "10%"; + elem.style.left = "10%"; + elem.style.height = 'auto'; + elem.style.maxHeight = window.innerHeight * .85 + 'px'; + elem.style.overflowY = 'scroll'; + swapClass('tooltipExtra', 'tooltipExtraLg', elem); + + titleText = (titleText) ? titleText : titleText; + lastTooltipTitle = titleText; + + document.getElementById("tipTitle").innerHTML = titleText; + document.getElementById("tipText").innerHTML = tooltipText; + document.getElementById("tipCost").innerHTML = costText; + elem.style.display = "block"; + if (ondisplay !== null) { + ondisplay(); + } + +} + +function settingsWindowSave(titleText, reopen) { + + var thisSetting = []; + var error = ""; + var maxSettings = 30; + + for (var x = 0; x < maxSettings; x++) { + + var zone; + var cell; + var setting; + var level; + var map; + var special; + var gather; + + world = [0]; + zone = [0]; + + //Settings + + if (titleText == 'Time Farm') { + zone = 'Rtimefarmzone'; + cell = 'Rtimefarmcell'; + setting = 'Rtimefarmtime'; + level = 'Rtimefarmlevel'; + map = 'Rtimefarmmap'; + special = 'Rtimefarmspecial'; + gather = 'Rtimefarmgather'; + } else if (titleText == 'dTime Farm') { + zone = 'Rdtimefarmzone'; + cell = 'Rdtimefarmcell'; + setting = 'Rdtimefarmtime'; + level = 'Rdtimefarmlevel'; + map = 'Rdtimefarmmap'; + special = 'Rdtimefarmspecial'; + gather = 'Rdtimefarmgather'; + } else if (titleText.includes('Smithy Farm')) { + zone = 'Rsmithyfarmzone'; + cell = 'Rsmithyfarmcell'; + setting = 'Rsmithyfarmamount'; + } else if (titleText.includes('Tribute Farm')) { + zone = 'Rtributefarmzone'; + cell = 'Rtributefarmcell'; + setting = 'Rtributefarmamount'; + level = 'Rtributefarmlevel'; + map = 'Rtributemapselection'; + special = 'Rtributespecialselection'; + gather = 'Rtributegatherselection'; + } else if (titleText == 'Shrine - U1') { + zone = 'Hshrinezone'; + cell = 'Hshrinecell'; + setting = 'Hshrineamount'; + } else if (titleText == 'Shrine - U2') { + zone = 'Rshrinezone'; + cell = 'Rshrinecell'; + setting = 'Rshrineamount'; + } else if (titleText == 'Shrine - U1 (Daily)') { + zone = 'Hdshrinezone'; + cell = 'Hdshrinecell'; + setting = 'Hdshrineamount'; + } else if (titleText == 'Shrine - U2 (Daily)') { + zone = 'Rdshrinezone'; + cell = 'Rdshrinecell'; + setting = 'Rdshrineamount'; + } else if (titleText.includes('Quagmire')) { + zone = 'Rblackbogzone'; + setting = 'Rblackbogamount'; + } else if (titleText.includes('Insanity')) { + zone = 'Rinsanityfarmzone'; + cell = 'Rinsanityfarmcell'; + setting = 'Rinsanityfarmstack'; + level = 'Rinsanityfarmlevel'; + } else if (titleText.includes('Alch')) { + zone = 'Ralchfarmzone'; + cell = 'Ralchfarmcell'; + setting = 'Ralchfarmstack'; + level = 'Ralchfarmlevel'; + map = 'Ralchfarmselection'; + } else if (titleText.includes('Hypo')) { + zone = 'Rhypofarmzone'; + cell = 'Rhypofarmcell'; + setting = 'Rhypofarmstack'; + level = 'Rhypofarmlevel'; + } else if (titleText == 'Praid') { + zone = 'RAMPraidzone'; + cell = 'RAMPraidcell'; + setting = 'RAMPraidraid'; + } else if (titleText == 'dPraid') { + zone = 'RdAMPraidzone'; + cell = 'RdAMPraidcell'; + setting = 'RdAMPraidraid'; + } + + var zone2 = document.getElementById('windowZone' + x); + if (!zone2 || zone2.value == "-1") { + continue; + }; + + zone = parseInt(document.getElementById('windowZone' + x).value, 10); + + var setting = 0; + var level = 0; + var map = 0; + var special = 0; + var gather = 0; + + if (!titleText.includes('Quagmire')) var cell = parseInt(document.getElementById('windowCell' + x).value, 10); + + if (titleText == 'Time Farm') { + setting = document.getElementById('windowSetting' + x).value; + level = parseInt(document.getElementById('windowLevel' + x).value, 10); + map = document.getElementById('windowMap' + x).value; + special = document.getElementById('windowSpecial' + x).value; + gather = document.getElementById('windowGather' + x).value; + } else if (titleText == 'dTime Farm') { + setting = document.getElementById('windowSetting' + x).value; + level = parseInt(document.getElementById('windowLevel' + x).value, 10); + map = document.getElementById('windowMap' + x).value; + special = document.getElementById('windowSpecial' + x).value; + gather = document.getElementById('windowGather' + x).value; + } else if (titleText.includes('Smithy Farm')) { + setting = document.getElementById('windowSetting' + x).value; + } else if (titleText.includes('Tribute Farm')) { + setting = document.getElementById('windowSetting' + x).value; + level = parseInt(document.getElementById('windowLevel' + x).value, 10); + map = document.getElementById('windowMap' + x).value; + special = document.getElementById('windowSpecial' + x).value; + gather = document.getElementById('windowGather' + x).value; + } else if (titleText.includes('Shrine')) { + setting = document.getElementById('windowSetting' + x).value; + } else if (titleText.includes('Quagmire')) { + setting = document.getElementById('windowSetting' + x).value; + } else if (titleText.includes('Insanity')) { + setting = document.getElementById('windowSetting' + x).value; + level = parseInt(document.getElementById('windowLevel' + x).value, 10); + } else if (titleText.includes('Alch')) { + setting = document.getElementById('windowSetting' + x).value; + level = parseInt(document.getElementById('windowLevel' + x).value, 10); + map = document.getElementById('windowMap' + x).value; + } else if (titleText.includes('Hypo')) { + setting = document.getElementById('windowSetting' + x).value; + level = parseInt(document.getElementById('windowLevel' + x).value, 10); + } else if (titleText == 'Praid') { + setting = document.getElementById('windowSetting' + x).value; + } else if (titleText == 'dPraid') { + setting = document.getElementById('windowSetting' + x).value; + } + + if (isNaN(zone) || zone < 6) { + error += " Preset " + (x + 1) + " needs a value for Start Zone that's greater than 5."; + continue; + } else if (zone > 1000) { + error += " Preset " + (x + 1) + " needs a value for Start Zone that's less than 1000."; + continue; + } + if (zone + level < 6) { + error += " Preset " + (x + 1) + " can\'t have a zone and map combination below zone 6."; + continue; + } + + if (level > 10) level = 10; + if (!titleText.includes('Quagmire')) { + if (cell < 1) cell = 1; + if (cell > 100) cell = 100; + } + + var thisThisSetting = { + zone: zone, + cell: cell, + level: level, + map: map, + setting: setting, + special: special, + gather: gather + }; + thisSetting.push(thisThisSetting); + } + + if (!titleText.includes('Quagmire')) thisSetting.sort(function(a, b) { + if (a.zone == b.zone) return (a.cell > b.cell) ? 1 : -1; + return (a.zone > b.zone) ? 1 : -1 + }); + + else thisSetting.sort(function(a, b) { + if (a.zone == b.zone) return (a.zone > b.zone) ? 1 : -1 + }); + + if (error) { + var elem = document.getElementById('windowError'); + if (elem) elem.innerHTML = error; + return; + } + + //Reset variables that are about to get used. + autoTrimpSettings[zone].value = []; + if (!titleText.includes('Quagmire')) autoTrimpSettings[cell].value = []; + + //Values + + if (titleText == 'Time Farm') { + autoTrimpSettings[level].value = []; + autoTrimpSettings[map].value = []; + autoTrimpSettings[setting].value = []; + autoTrimpSettings[special].value = []; + autoTrimpSettings[gather].value = []; + } else if (titleText == 'dTime Farm') { + autoTrimpSettings[level].value = []; + autoTrimpSettings[map].value = []; + autoTrimpSettings[setting].value = []; + autoTrimpSettings[special].value = []; + autoTrimpSettings[gather].value = []; + } else if (titleText.includes('Smithy Farm')) { + autoTrimpSettings[setting].value = []; + } else if (titleText.includes('Tribute Farm')) { + autoTrimpSettings[level].value = []; + autoTrimpSettings[map].value = []; + autoTrimpSettings[setting].value = []; + autoTrimpSettings[special].value = []; + autoTrimpSettings[gather].value = []; + } else if (titleText.includes('Shrine')) { + autoTrimpSettings[setting].value = []; + } else if (titleText.includes('Quagmire')) { + autoTrimpSettings[setting].value = []; + } else if (titleText.includes('Insanity')) { + autoTrimpSettings[level].value = []; + autoTrimpSettings[setting].value = []; + } else if (titleText.includes('Alch')) { + autoTrimpSettings[level].value = []; + autoTrimpSettings[map].value = []; + autoTrimpSettings[setting].value = []; + } else if (titleText.includes('Hypo')) { + autoTrimpSettings[level].value = []; + autoTrimpSettings[setting].value = []; + } else if (titleText == 'Praid') { + autoTrimpSettings[setting].value = []; + } else if (titleText == 'dPraid') { + autoTrimpSettings[setting].value = []; + } + + for (var x = 0; x < thisSetting.length; x++) { + autoTrimpSettings[zone].value[x] = thisSetting[x].zone + if (!titleText.includes('Quagmire')) autoTrimpSettings[cell].value[x] = thisSetting[x].cell + + //Saving + + if (titleText == 'Time Farm') { + autoTrimpSettings[level].value[x] = thisSetting[x].level + autoTrimpSettings[map].value[x] = thisSetting[x].map + autoTrimpSettings[setting].value[x] = thisSetting[x].setting + autoTrimpSettings[special].value[x] = thisSetting[x].special + autoTrimpSettings[gather].value[x] = thisSetting[x].gather + } else if (titleText == 'dTime Farm') { + autoTrimpSettings[level].value[x] = thisSetting[x].level + autoTrimpSettings[map].value[x] = thisSetting[x].map + autoTrimpSettings[setting].value[x] = thisSetting[x].setting + autoTrimpSettings[special].value[x] = thisSetting[x].special + autoTrimpSettings[gather].value[x] = thisSetting[x].gather + } else if (titleText.includes('Smithy Farm')) { + autoTrimpSettings[setting].value[x] = thisSetting[x].setting + } else if (titleText.includes('Tribute Farm')) { + autoTrimpSettings[level].value[x] = thisSetting[x].level + autoTrimpSettings[map].value[x] = thisSetting[x].map + autoTrimpSettings[setting].value[x] = thisSetting[x].setting + autoTrimpSettings[special].value[x] = thisSetting[x].special + autoTrimpSettings[gather].value[x] = thisSetting[x].gather + } else if (titleText.includes('Shrine')) { + autoTrimpSettings[setting].value[x] = thisSetting[x].setting + } else if (titleText.includes('Quagmire')) { + autoTrimpSettings[setting].value[x] = thisSetting[x].setting + } else if (titleText.includes('Insanity')) { + autoTrimpSettings[level].value[x] = thisSetting[x].level + autoTrimpSettings[setting].value[x] = thisSetting[x].setting + } else if (titleText.includes('Alch')) { + autoTrimpSettings[level].value[x] = thisSetting[x].level + autoTrimpSettings[map].value[x] = thisSetting[x].map + autoTrimpSettings[setting].value[x] = thisSetting[x].setting + } else if (titleText.includes('Hypo')) { + autoTrimpSettings[level].value[x] = thisSetting[x].level + autoTrimpSettings[setting].value[x] = thisSetting[x].setting + } else if (titleText == 'Praid') { + autoTrimpSettings[setting].value[x] = thisSetting[x].setting + } else if (titleText == 'dPraid') { + autoTrimpSettings[setting].value[x] = thisSetting[x].setting + } + + } + + cancelTooltip(true); + if (reopen) MAZLookalike(titleText); + + saveSettings(); + document.getElementById('tooltipDiv').style.overflowY = ''; +} + +function addRow() { + for (var x = 0; x < 30; x++) { + var elem = document.getElementById('windowZone' + x); + if (!elem) continue; + if (elem.value == -1) { + var parent = document.getElementById('windowRow' + x); + if (parent) { + parent.style.display = 'block'; + elem.value = game.global.world + 1 < 6 ? 6 : game.global.world + 1; + updateWindowPreset(x); + break; + } + } + } + var btnElem = document.getElementById('windowAddRowBtn'); + for (var y = 0; y < 30; y++) { + var elem = document.getElementById('windowZone' + y); + if (elem && elem.value == "-1") { + btnElem.style.display = 'inline-block'; + return; + } + } + btnElem.style.display = 'none'; +} + +function removeRow(index) { + var elem = document.getElementById('windowRow' + index); + if (!elem) return; + document.getElementById('windowZone' + index).value = -1; + elem.style.display = 'none'; + var btnElem = document.getElementById('windowAddRowBtn'); + btnElem.style.display = 'inline-block'; +} + +function updateWindowPreset(index) { + var special = document.getElementById('windowSpecial' + index); +} diff --git a/modules/ab.js b/modules/ab.js new file mode 100644 index 000000000..463b0b643 --- /dev/null +++ b/modules/ab.js @@ -0,0 +1,488 @@ +//AB + +function getCurrentAB(effect) { + + if (effect == false) { + return autoBattle.enemyLevel; + } + else { + var poison = autoBattle.enemy.poisonResist; + var bleed = autoBattle.enemy.bleedResist; + var shock = autoBattle.enemy.shockResist; + + var lowestResist = Math.min(poison,bleed,shock); + + var outEffect = ""; + if (poison == lowestResist) { + outEffect += "p"; + } + if (bleed == lowestResist) { + outEffect += "b"; + } + if (shock == lowestResist) { + outEffect += "s"; + } + + return outEffect; + } +}; + +function checkPreset(presetSlot) { + + for (var item in autoBattle.items) { + if (autoBattle.items[item].equipped && autoBattle.presets["p" + presetSlot].indexOf(item) == -1) { + return false; + } + } + return true; +} + +function ABcheck() { + + var winning = autoBattle.sessionEnemiesKilled >= autoBattle.sessionTrimpsKilled; + + if (winning) return 0; + + if (getCurrentAB(true) == "pbs" && (checkPreset(1) || checkPreset(2) || checkPreset(3))) { + if (checkPreset(1)) return 2; + else if (checkPreset(2)) return 3; + else if (checkPreset(3)) return 1; + } + else if (getCurrentAB(true) == "pb" && (checkPreset(1) || checkPreset(2))) { + if (checkPreset(1)) return 2; + else if (checkPreset(2)) return 1; + } + else if (getCurrentAB(true) == "ps" && (checkPreset(1) || checkPreset(3))) { + if (checkPreset(1)) return 3; + else if (checkPreset(3)) return 1; + } + else if (getCurrentAB(true) == "bs" && (checkPreset(2) || checkPreset(3))) { + if (checkPreset(2)) return 3; + else if (checkPreset(3)) return 2; + } + else if (getCurrentAB(true) == "p" && (checkPreset(2) || checkPreset(3))) { + return 1; + } + else if (getCurrentAB(true) == "b" && (checkPreset(1) || checkPreset(3))) { + return 2; + } + else if (getCurrentAB(true) == "s" && (checkPreset(1) || checkPreset(2))) { + return 3; + } +} + +function ABswitch() { + + if (ABcheck() > 0) { + if (ABcheck() == 1) autoBattle.loadPreset('p1'); + else if (ABcheck() == 2) autoBattle.loadPreset('p2'); + else if (ABcheck() == 3) autoBattle.loadPreset('p3'); + } +} + +function ABdustsimple() { + + var equips = []; + + for (var item in autoBattle.items) { + if (autoBattle.items[item].equipped) { + equips.push([item, autoBattle.upgradeCost(item)]); + } + } + + equips.sort(function(a, b) { + return a[1] - b[1]; + }); + + if (autoBattle.dust >= equips[0][1]) autoBattle.upgrade(equips[0][0]); +} + +function ABdustsimplenonhid() { + + var equips = []; + + for (var item in autoBattle.items) { + if (!autoBattle.items[item].equipped && !autoBattle.items[item].hidden) { + equips.push([item, autoBattle.upgradeCost(item)]); + } + } + + equips.sort(function(a, b) { + return a[1] - b[1]; + }); + + if (autoBattle.dust >= equips[0][1]) autoBattle.upgrade(equips[0][0]); +} + +function ABfarmsave() { + + var equips = []; + + for (var item in autoBattle.items) { + if (autoBattle.items[item].equipped) { + equips.push(item); + } + } + + var dustps = parseInt(autoBattle.getDustPs()); + + var bestdust = 0; + if (autoBattle.sessionEnemiesKilled > 2 && autoBattle.sessionEnemiesKilled > autoBattle.sessionTrimpsKilled) bestdust = dustps; + + var string = [autoBattle.enemyLevel, bestdust, equips]; + + if (getPageSetting('RABfarmstring') == "-1") { + setPageSetting('RABfarmstring', string); + } + else if (autoBattle.sessionEnemiesKilled > 8 && autoBattle.sessionEnemiesKilled > autoBattle.sessionTrimpsKilled && bestdust > 0 && autoTrimpSettings.RABfarmstring.value[1] < bestdust) { + setPageSetting('RABfarmstring', string); + } +} + +function ABfarmswitch() { + + if (autoBattle.enemyLevel != getPageSetting('RABfarmstring')[0]) { + autoBattle.enemyLevel = getPageSetting('RABfarmstring')[0]; + autoBattle.resetCombat(true) + } + + var match = false; + + for (var item in autoBattle.items) { + if (autoBattle.items[item].equipped && getPageSetting('RABfarmstring')[2].indexOf(item) == -1) { + match = true; + } + } + + if (match) { + var preset = getPageSetting('RABfarmstring')[2]; + var plength = preset.length; + if (plength > autoBattle.getMaxItems()) plength = autoBattle.getMaxItems(); + for (var item in autoBattle.items){ + autoBattle.items[item].equipped = false; + if (autoBattle.settings.loadHide.enabled) autoBattle.items[item].hidden = (autoBattle.items[item].owned) ? true : false; + } + for (var x = 0; x < plength; x++){ + if (!autoBattle.items[preset[x]] || !autoBattle.items[preset[x]].owned) continue; + autoBattle.items[preset[x]].equipped = true; + autoBattle.items[preset[x]].hidden = false; + } + autoBattle.resetCombat(true); + } +} + +function ABlevelswitch(level) { + if (autoBattle.enemyLevel != level) { + autoBattle.enemyLevel = level; + autoBattle.resetCombat(true); + } +} + +function ABsolver() { + + if (autoBattle.autoLevel) autoBattle.toggleAutoLevel(); + + var max = autoBattle.maxEnemyLevel; + var items = []; + var level = []; + var contract = ''; + + //Solver + + switch(max) { + + case 1: + + ABlevelswitch(1); + + items = ['Sword','Armor','Fists_of_Goo','Battery_Stick']; + level = [2,1,1,1]; + + break; + + case 2: + + ABlevelswitch(2); + + items = ['Sword','Armor','Fists_of_Goo','Battery_Stick']; + level = [3,2,1,2]; + + break; + + case 3: + + if (autoBattle.bonuses.Extra_Limbs.level < 1) { + items = ['Sword','Armor','Fists_of_Goo','Battery_Stick']; + level = [4,2,2,2]; + for (var equip in autoBattle.items) { + if (autoBattle.items[equip].level < level[items.indexOf(equip)]) { + ABlevelswitch(2); + } + if (autoBattle.items[equip].level >= level[items.indexOf(equip)]) { + if (autoBattle.bonuses.Extra_Limbs.level < 1) { + autoBattle.buyBonus('Extra_Limbs'); + } + } + } + } + + if (autoBattle.bonuses.Extra_Limbs.level >= 1) { + items = ['Sword','Armor','Fists_of_Goo','Battery_Stick','Pants']; + level = [4,3,2,2,4]; + var proceed = true; + for (var equip in autoBattle.items) { + if (autoBattle.items[equip].level < level[items.indexOf(equip)]) { + proceed = false; + } + } + + if (!proceed && autoBattle.enemyLevel != 2) { + autoBattle.enemyLevel = 2; + autoBattle.resetCombat(true); + } + + if (proceed && autoBattle.enemyLevel != 3) { + autoBattle.enemyLevel = 3; + autoBattle.resetCombat(true); + } + } + + break; + + case 4: + + if (!autoBattle.items.Raincoat.owned) { + contract = 'Raincoat'; + items = ['Sword','Armor','Fists_of_Goo','Battery_Stick','Pants']; + level = [4,3,2,2,4]; + ABlevelswitch(3); + } + + if (autoBattle.items.Raincoat.owned) { + items = ['Rusty_Dagger','Fists_of_Goo','Battery_Stick','Pants','Raincoat']; + level = [3,2,3,4,3]; + ABlevelswitch(4); + } + + break; + + case 5: + + ABlevelswitch(5); + + if (!autoBattle.items.Putrid_Pouch.owned) { + items = ['Rusty_Dagger','Fists_of_Goo','Battery_Stick','Pants','Raincoat']; + level = [3,3,3,4,3]; + var proceed = true; + for (var equip in autoBattle.items) { + if (autoBattle.items[equip].level < level[items.indexOf(equip)]) { + proceed = false; + } + } + if (proceed) { + if (!autoBattle.items.Putrid_Pouch.owned) { + contract = 'Putrid_Pouch'; + } + } + } + if (autoBattle.items.Putrid_Pouch.owned) { + items = ['Rusty_Dagger','Fists_of_Goo','Battery_Stick','Raincoat','Putrid_Pouch']; + level = [3,3,3,3,3]; + var proceed2 = true; + for (var equip in autoBattle.items) { + if (autoBattle.items[equip].level < level[items.indexOf(equip)]) { + proceed2 = false; + } + } + if (proceed2) { + if (!autoBattle.items.Chemistry_Set.owned) { + contract = 'Chemistry_Set'; + } + } + } + if (autoBattle.items.Chemistry_Set.owned) { + items = ['Menacing_Mask','Fists_of_Goo','Battery_Stick','Putrid_Pouch','Chemistry_Set']; + level = [4,3,3,3,2]; + } + + break; + + case 6: + + ABlevelswitch(6); + + if (!autoBattle.items.Labcoat.owned) { + items = ['Menacing_Mask','Fists_of_Goo','Battery_Stick','Putrid_Pouch','Chemistry_Set']; + level = [4,3,3,3,2]; + var proceed = true; + for (var equip in autoBattle.items) { + if (autoBattle.items[equip].level < level[items.indexOf(equip)]) { + proceed = false; + } + } + if (proceed) { + if (!autoBattle.items.Labcoat.owned) { + contract = 'Labcoat'; + } + } + } + if (autoBattle.items.Labcoat.owned) { + items = ['Fists_of_Goo','Battery_Stick','Putrid_Pouch','Chemistry_Set','Labcoat']; + level = [3,4,3,2,1]; + } + + break; + + case 7: + + items = ['Fists_of_Goo','Battery_Stick','Putrid_Pouch','Chemistry_Set','Labcoat']; + level = [3,4,3,4,2]; + ABlevelswitch(7); + + break; + + case 8: + + ABlevelswitch(8); + + if (!autoBattle.items.Comfy_Boots.owned) { + items = ['Fists_of_Goo','Battery_Stick','Putrid_Pouch','Chemistry_Set','Labcoat']; + level = [4,5,3,4,2]; + var proceed = true; + for (var equip in autoBattle.items) { + if (autoBattle.items[equip].level < level[items.indexOf(equip)]) { + proceed = false; + } + } + if (proceed) { + if (!autoBattle.items.Comfy_Boots.owned) { + contract = 'Comfy_Boots'; + } + } + } + if (autoBattle.items.Comfy_Boots.owned) { + items = ['Fists_of_Goo','Battery_Stick','Putrid_Pouch','Chemistry_Set','Labcoat']; + level = [4,5,3,4,2]; + if (autoBattle.items.Comfy_Boots.level < 3) { + autoBattle.upgrade('Comfy_Boots'); + } + } + + break; + + case 9: + + if (!autoBattle.items.Comfy_Boots.owned) { + contract = 'Comfy_Boots'; + } + + if (autoBattle.items.Comfy_Boots.level < 3) { + autoBattle.upgrade('Comfy_Boots'); + } + + if (autoBattle.items.Comfy_Boots.level >= 3 && autoBattle.bonuses.Extra_Limbs.level < 2) { + ABlevelswitch(8); + items = ['Fists_of_Goo','Battery_Stick','Putrid_Pouch','Chemistry_Set','Labcoat']; + level = [4,5,3,4,2]; + autoBattle.buyBonus('Extra_Limbs'); + } + + if (autoBattle.bonuses.Extra_Limbs.level >= 2 && autoBattle.items.Rusty_Dagger.level < 5) { + ABlevelswitch(8); + items = ['Rusty_Dagger','Fists_of_Goo','Battery_Stick','Putrid_Pouch','Chemistry_Set','Labcoat']; + level = [5,4,4,3,4,2]; + } + + if (autoBattle.items.Rusty_Dagger.level >= 5) { + ABlevelswitch(9); + items = ['Rusty_Dagger','Fists_of_Goo','Raincoat','Putrid_Pouch','Chemistry_Set','Labcoat']; + level = [5,4,4,3,4,2]; + } + + break; + + case 10: + + if (!autoBattle.items.Mood_Bracelet.owned) { + contract = 'Mood_Bracelet'; + items = ['Rusty_Dagger','Fists_of_Goo','Raincoat','Putrid_Pouch','Chemistry_Set','Labcoat']; + level = [5,4,4,4,4,2]; + ABlevelswitch(9); + } + if (autoBattle.items.Mood_Bracelet.owned && !autoBattle.items.Lifegiving_Gem.owned) { + contract = 'Lifegiving_Gem'; + items = ['Rusty_Dagger','Fists_of_Goo','Raincoat','Putrid_Pouch','Chemistry_Set','Labcoat']; + level = [5,4,4,4,4,2]; + ABlevelswitch(9); + } + if (autoBattle.items.Lifegiving_Gem.owned && !autoBattle.items.Hungering_Mold.owned) { + contract = 'Hungering_Mold'; + items = ['Rusty_Dagger','Fists_of_Goo','Raincoat','Putrid_Pouch','Chemistry_Set','Labcoat']; + level = [5,4,4,4,4,2]; + ABlevelswitch(10); + } + if (autoBattle.items.Hungering_Mold.owned && autoBattle.items.Hungering_Mold.level < 2) { + items = ['Rusty_Dagger','Fists_of_Goo','Raincoat','Putrid_Pouch','Chemistry_Set','Labcoat']; + level = [5,4,4,4,4,2]; + ABlevelswitch(10); + if (autoBattle.items.Putrid_Pouch.level < 4) { + autoBattle.upgrade('Putrid_Pouch'); + } + else if (autoBattle.items.Mood_Bracelet.level < 3) { + autoBattle.upgrade('Mood_Bracelet'); + } + else if (autoBattle.items.Hungering_Mold.level < 2) { + autoBattle.upgrade('Hungering_Mold'); + } + } + if (autoBattle.items.Hungering_Mold.level >= 2 && autoBattle.items.Mood_Bracelet.level >= 3 && autoBattle.items.Putrid_Pouch.level >= 4) { + contract = 'Bad_Medkit'; + items = ['Fists_of_Goo','Putrid_Pouch','Chemistry_Set','Labcoat','Mood_Bracelet','Hungering_Mold']; + level = [4,4,4,2,3,2]; + ABlevelswitch(10); + if (autoBattle.items.Bad_Medkit.level < 3) { + autoBattle.upgrade('Bad_Medkit'); + } + } + + break; + } + + //Equip items + + var needsEquipChange = false; + + for (var item of items) { + if (autoBattle.items[item].equipped == false) { needsEquipChange = true;} + } + + if (needsEquipChange) { + for (var item in autoBattle.items) { + autoBattle.items[item].equipped = false; + }; + + for (var item of items) { + if (autoBattle.items[item].owned) autoBattle.equip(item); + } + } + + //Level items + + for (var equip in autoBattle.items) { + if (autoBattle.items[equip].level < level[items.indexOf(equip)]) { + autoBattle.upgrade(equip); + } + } + + //Contract + + if (contract != '' && !autoBattle.items[contract].owned) { + autoBattle.acceptContract(contract); + if (autoBattle.activeContract == contract) { + if (game.global.world >= autoBattle.items[contract].zone) { + contractVoid = true; + } + } + } + +} diff --git a/modules/battlecalc.js b/modules/battlecalc.js deleted file mode 100644 index c365db94c..000000000 --- a/modules/battlecalc.js +++ /dev/null @@ -1,404 +0,0 @@ -//MODULES["battlecalc"] = {}; -//AutoTrimps: currently only used for health and block. attack is done by calcOurDmg below -// function ripped from Trimps "updates.js" line 1103 -// what is either "health" or "attack" or "block" -function getBattleStats(what,form,crit) { - var currentCalc = 0; -// var maxFluct = 0.2; -// var minFluct = 0.2; - if (what == "health" || what == "attack"){ - currentCalc += (what == "health") ? 50 : 6; -/* if (what == "attack"){ - //Discipline - if (game.global.challengeActive == "Discipline"){ - minFluct = 0.995; - maxFluct = 0.995; - } - else { - //Range - if (game.portal.Range.level > 0){ - minFluct -= (0.02 * game.portal.Range.level); - } - //MinDamageDaily - if (typeof game.global.dailyChallenge.minDamage !== 'undefined'){ - var addMin = dailyModifiers.minDamage.getMult(game.global.dailyChallenge.minDamage.strength); - minFluct += addMin; - if (minFluct > 1) minFluct = 1; - } - //MaxDamageDaily - if (typeof game.global.dailyChallenge.maxDamage !== 'undefined'){ - var addMax = dailyModifiers.maxDamage.getMult(game.global.dailyChallenge.maxDamage.strength); - maxFluct += addMax; - } - } - } */ - for (var equip in game.equipment){ - var temp = game.equipment[equip]; - if (typeof temp[what] === 'undefined' || temp.level <= 0 || temp.blockNow) continue; - var equipStrength = temp[what + "Calculated"] * temp.level; - currentCalc += equipStrength; - } - } - else if (what == "block"){ - //Add Gym - var gym = game.buildings.Gym; - if (gym.owned > 0){ - var gymStrength = gym.owned * gym.increase.by; - currentCalc += gymStrength; - } - var shield = game.equipment.Shield; - if (shield.blockNow && shield.level > 0){ - var shieldStrength = shield.level * shield.blockCalculated; - currentCalc += shieldStrength; - } - var trainer = game.jobs.Trainer; - if (trainer.owned > 0){ - var trainerStrength = trainer.owned * (trainer.modifier / 100); - trainerStrength = calcHeirloomBonus("Shield", "trainerEfficiency", trainerStrength); - currentCalc *= (trainerStrength + 1); - } - } - //Add coordination - currentCalc *= game.resources.trimps.maxSoldiers; - //Add achievements - if (what == "attack" && game.global.achievementBonus > 0){ - currentCalc *= 1 + (game.global.achievementBonus / 100); - } - //Add perk - var perk = ""; - if (what == "health") perk = "Toughness"; - if (what == "attack") perk = "Power"; - if (perk && game.portal[perk].level > 0){ - var PerkStrength = (game.portal[perk].level * game.portal[perk].modifier); - currentCalc *= (PerkStrength + 1); - } - perk = perk + "_II"; - if (game.portal[perk] && game.portal[perk].level > 0){ - var PerkStrength = (game.portal[perk].level * game.portal[perk].modifier); - currentCalc *= (PerkStrength + 1); - } - //Add resilience - if (what == "health" && game.portal.Resilience.level > 0){ - var resStrength = Math.pow(game.portal.Resilience.modifier + 1, game.portal.Resilience.level); - currentCalc *= resStrength; - } - //Add Geneticist - var geneticist = game.jobs.Geneticist; - if (geneticist.owned > 0 && what == "health"){ - var geneticistStrength = Math.pow(1.01, game.global.lastLowGen); - currentCalc *= geneticistStrength; - } - //Add Anticipation - var anticipation = game.portal.Anticipation; - if (anticipation.level > 0 && what == "attack"){ - var antiStrength = ((anticipation.level * anticipation.modifier * game.global.antiStacks) + 1); - currentCalc *= antiStrength; - } - //Add formations - if (form && game.global.formation > 0){ - var formStrength = 0.5; - if ((game.global.formation == 1 && what == "health") || (game.global.formation == 2 && what == "attack") || (game.global.formation == 3 && what == "block")) formStrength = 4; - currentCalc *= formStrength; - } - //Add Titimp - if (game.global.titimpLeft > 1 && game.global.mapsActive && what == "attack"){ - currentCalc *= 2; - } - //Add map bonus - if (!game.global.mapsActive && game.global.mapBonus > 0 && what == "attack"){ - var mapBonusMult = 0.2 * game.global.mapBonus; - currentCalc *= (1 + mapBonusMult); - mapBonusMult *= 100; - } - //Add RoboTrimp - if (what == "attack" && game.global.roboTrimpLevel > 0){ - var roboTrimpMod = 0.2 * game.global.roboTrimpLevel; - currentCalc *= (1 + roboTrimpMod); - roboTrimpMod *= 100; - } - //Add challenges: - if (what == "health" && game.global.challengeActive == "Life"){ - currentCalc *= game.challenges.Life.getHealthMult(); - } - if (what == "attack" && game.global.challengeActive == "Life"){ - currentCalc *= game.challenges.Life.getHealthMult(); - } - if (what == "health" && game.global.challengeActive == "Balance"){ - currentCalc *= game.challenges.Balance.getHealthMult(); - } - if (what == "attack" && game.global.challengeActive == "Lead" && ((game.global.world % 2) == 1)){ - currentCalc *= 1.5; - } - var heirloomBonus = calcHeirloomBonus("Shield", "trimp" + capitalizeFirstLetter(what), 0, true); - if (heirloomBonus > 0){ - currentCalc *= ((heirloomBonus / 100) + 1); - } - //Challenge: Decay - if (game.global.challengeActive == "Decay" && what == "attack"){ - currentCalc *= 5; - var stackStr = Math.pow(0.995, game.challenges.Decay.stacks); - currentCalc *= stackStr; - } - //Challenge: "Electricity" || "Mapocalypse" - if ((game.global.challengeActive == "Electricity" || game.global.challengeActive == "Mapocalypse") && what == "attack") { - var mult = (1 - (game.challenges.Electricity.stacks * 0.1)); - currentCalc *= mult; - } - //DEPRECATED?radiostacks increases from "Electricity" || "Mapocalypse" - if (game.global.radioStacks > 0) { - currentCalc *= (1 - (game.global.radioStacks * 0.1)); - } - //Daily: - if (game.global.challengeActive == "Daily"){ - var mult = 0; - if (typeof game.global.dailyChallenge.weakness !== 'undefined' && what == "attack"){ - mult = dailyModifiers.weakness.getMult(game.global.dailyChallenge.weakness.strength, game.global.dailyChallenge.weakness.stacks); - currentCalc *= mult; - } - if (typeof game.global.dailyChallenge.oddTrimpNerf !== 'undefined' && what == "attack" && (game.global.world % 2 == 1)){ - mult = dailyModifiers.oddTrimpNerf.getMult(game.global.dailyChallenge.oddTrimpNerf.strength); - currentCalc *= mult; - } - if (typeof game.global.dailyChallenge.evenTrimpBuff !== 'undefined' && what == "attack" && (game.global.world % 2 == 0)){ - mult = dailyModifiers.evenTrimpBuff.getMult(game.global.dailyChallenge.evenTrimpBuff.strength); - currentCalc *= mult; - } - if (typeof game.global.dailyChallenge.rampage !== 'undefined' && what == "attack"){ - mult = dailyModifiers.rampage.getMult(game.global.dailyChallenge.rampage.strength, game.global.dailyChallenge.rampage.stacks); - currentCalc *= mult; - } - if (typeof game.global.dailyChallenge.pressure !== 'undefined' && what == "health"){ - mult = dailyModifiers.pressure.getMult(game.global.dailyChallenge.pressure.strength, game.global.dailyChallenge.pressure.stacks); - currentCalc *= mult; - } - } - //Add golden battle - if (what != "block" && game.goldenUpgrades.Battle.currentBonus > 0){ - amt = game.goldenUpgrades.Battle.currentBonus; - currentCalc *= 1 + amt; - } - //VoidPower - if (what != "block" && game.talents.voidPower.purchased && game.global.voidBuff){ - amt = (game.talents.voidPower2.purchased) ? ((game.talents.voidPower3.purchased) ? 65 : 35) : 15; - currentCalc *= (1 + (amt / 100)); - } - //StillRowing2 - if (game.talents.stillRowing2.purchased && what == "attack" && game.global.spireRows >= 1){ - amt = game.global.spireRows * 0.06; - currentCalc *= (amt + 1); - } - //HealthStreanth - if (game.talents.healthStrength.purchased && what == "attack" && mutations.Healthy.active()){ - var cellCount = mutations.Healthy.cellCount(); - amt = (0.15 * cellCount); - currentCalc *= (amt + 1); - } - //Pumpkimp buff - if (game.global.sugarRush > 0 && what == "attack"){ - currentCalc *= sugarRush.getAttackStrength(); - textString += "Sugar Rush  x " + sugarRush.getAttackStrength() + "" + prettify(currentCalc) + "" + ((what == "attack") ? getFluctuation(currentCalc, minFluct, maxFluct) : "") + ""; - } - //Magma - if (mutations.Magma.active() && (what == "attack" || what == "health")){ - var mult = mutations.Magma.getTrimpDecay(); - var lvls = game.global.world - mutations.Magma.start() + 1; - currentCalc *= mult; - } - //Total C^2 Squared - if (game.global.totalSquaredReward > 0 && (what == "attack" || what == "health")){ - var amt = game.global.totalSquaredReward; - currentCalc *= (1 + (amt / 100)); - } - //Ice - if (what == "attack" && getEmpowerment() == "Ice"){ - var amt = 1 - game.empowerments.Ice.getCombatModifier(); - currentCalc *= (1 + amt); - } - //Fluffy - if (what == "attack" && Fluffy.isActive()){ - var amt = Fluffy.getDamageModifier(); - currentCalc *= amt; - } - if (crit) { - var critChance = getPlayerCritChance(); - if (what == "attack" && critChance){ - currentCalc *= getPlayerCritDamageMult(); - } - } - return currentCalc; -} - -function calcOurDmg(number,maxormin,disableStances,disableFlucts) { //number = base attack - var fluctuation = .2; //%fluctuation - var maxFluct = -1; - var minFluct = -1; - //Situational Trimp damage increases - if (game.global.radioStacks > 0) { - number *= (1 - (game.global.radioStacks * 0.1)); - } - if (game.global.antiStacks > 0) { - number *= ((game.global.antiStacks * game.portal.Anticipation.level * game.portal.Anticipation.modifier) + 1); - updateAntiStacks(); - } - // if (!game.global.mapsActive && game.global.mapBonus > 0){ - // number *= ((game.global.mapBonus * .2) + 1); - // } - // if (game.global.titimpLeft >= 1 && game.global.mapsActive){ - // number *= 2; - // } - if (game.global.achievementBonus > 0){ - number *= (1 + (game.global.achievementBonus / 100)); - } - if (game.global.challengeActive == "Discipline"){ - fluctuation = .995; - } - else if (game.portal.Range.level > 0){ - minFluct = fluctuation - (.02 * game.portal.Range.level); - } - if (game.global.challengeActive == "Decay"){ - number *= 5; - number *= Math.pow(0.995, game.challenges.Decay.stacks); - } - if (game.global.roboTrimpLevel > 0){ - number *= ((0.2 * game.global.roboTrimpLevel) + 1); - } - if (game.global.challengeActive == "Lead" && ((game.global.world % 2) == 1)){ - number *= 1.5; - } - if (game.goldenUpgrades.Battle.currentBonus > 0){ - number *= game.goldenUpgrades.Battle.currentBonus + 1; - } - if (game.talents.voidPower.purchased && game.global.voidBuff){ - var vpAmt = (game.talents.voidPower2.purchased) ? ((game.talents.voidPower3.purchased) ? 65 : 35) : 15; - number *= ((vpAmt / 100) + 1); - } - if (game.global.totalSquaredReward > 0){ - number *= ((game.global.totalSquaredReward / 100) + 1) - } - if (game.talents.magmamancer.purchased){ - number *= game.jobs.Magmamancer.getBonusPercent(); - } - if (game.talents.stillRowing2.purchased){ - number *= ((game.global.spireRows * 0.06) + 1); - } - if (game.talents.healthStrength.purchased && mutations.Healthy.active()){ - number *= ((0.15 * mutations.Healthy.cellCount()) + 1); - } - if (Fluffy.isActive()){ - number *= Fluffy.getDamageModifier(); - } - number *= (1 + (1 - game.empowerments.Ice.getCombatModifier())); - - if (game.global.challengeActive == "Daily"){ - if (typeof game.global.dailyChallenge.minDamage !== 'undefined'){ - if (minFluct == -1) minFluct = fluctuation; - minFluct += dailyModifiers.minDamage.getMult(game.global.dailyChallenge.minDamage.strength); - } - if (typeof game.global.dailyChallenge.maxDamage !== 'undefined'){ - if (maxFluct == -1) maxFluct = fluctuation; - maxFluct += dailyModifiers.maxDamage.getMult(game.global.dailyChallenge.maxDamage.strength); - } - if (typeof game.global.dailyChallenge.weakness !== 'undefined'){ - number *= dailyModifiers.weakness.getMult(game.global.dailyChallenge.weakness.strength, game.global.dailyChallenge.weakness.stacks); - } - if (typeof game.global.dailyChallenge.oddTrimpNerf !== 'undefined' && ((game.global.world % 2) == 1)){ - number *= dailyModifiers.oddTrimpNerf.getMult(game.global.dailyChallenge.oddTrimpNerf.strength); - } - if (typeof game.global.dailyChallenge.evenTrimpBuff !== 'undefined' && ((game.global.world % 2) == 0)){ - number *= dailyModifiers.evenTrimpBuff.getMult(game.global.dailyChallenge.evenTrimpBuff.strength); - } - if (typeof game.global.dailyChallenge.rampage !== 'undefined'){ - number *= dailyModifiers.rampage.getMult(game.global.dailyChallenge.rampage.strength, game.global.dailyChallenge.rampage.stacks); - } - } - if (!disableStances) { - //Formations - if (game.global.formation == 2) - number /= 4; - else if (game.global.formation != "0") - number *= 2; - } - if (!disableFlucts) { - if (minFluct > 1) minFluct = 1; - if (maxFluct == -1) maxFluct = fluctuation; - if (minFluct == -1) minFluct = fluctuation; - var min = Math.floor(number * (1 - minFluct)); - var max = Math.ceil(number + (number * maxFluct)); - - //number = Math.floor(Math.random() * ((max + 1) - min)) + min; - return maxormin ? max : min; - } - else - return number; -} - - -function calcBadGuyDmg(enemy,attack,daily,maxormin,disableFlucts) { - var number; - if (enemy) - number = enemy.attack; - else - number = attack; - - var fluctuation = .2; //%fluctuation - var maxFluct = -1; - var minFluct = -1; - - //Situational bad guy damage increases - if (game.global.challengeActive){ - //Challenge bonuses here - if (game.global.challengeActive == "Coordinate"){ - number *= getBadCoordLevel(); - } - else if (game.global.challengeActive == "Meditate"){ - number *= 1.5; - } - else if (enemy && game.global.challengeActive == "Nom" && typeof enemy.nomStacks !== 'undefined'){ - number *= Math.pow(1.25, enemy.nomStacks); - } - else if (game.global.challengeActive == "Watch") { - number *= 1.25; - } - else if (game.global.challengeActive == "Lead"){ - number *= (1 + (game.challenges.Lead.stacks * 0.04)); - } - else if (game.global.challengeActive == "Scientist" && getScientistLevel() == 5) { - number *= 10; - } - else if (game.global.challengeActive == "Corrupted"){ - number *= 3; - } - if (daily) - number = calcDailyAttackMod(number); - } - if (game.global.usingShriek) { - number *= game.mapUnlocks.roboTrimp.getShriekValue(); - } - - if (!disableFlucts) { - if (minFluct > 1) minFluct = 1; - if (maxFluct == -1) maxFluct = fluctuation; - if (minFluct == -1) minFluct = fluctuation; - var min = Math.floor(number * (1 - minFluct)); - var max = Math.ceil(number + (number * maxFluct)); - - //number = Math.floor(Math.random() * ((max + 1) - min)) + min; - return maxormin ? max : min; - } - else - return number; -} -function calcDailyAttackMod(number) { - if (game.global.challengeActive == "Daily"){ - if (typeof game.global.dailyChallenge.badStrength !== 'undefined'){ - number *= dailyModifiers.badStrength.getMult(game.global.dailyChallenge.badStrength.strength); - } - if (typeof game.global.dailyChallenge.badMapStrength !== 'undefined' && game.global.mapsActive){ - number *= dailyModifiers.badMapStrength.getMult(game.global.dailyChallenge.badMapStrength.strength); - } - if (typeof game.global.dailyChallenge.bloodthirst !== 'undefined'){ - number *= dailyModifiers.bloodthirst.getMult(game.global.dailyChallenge.bloodthirst.strength, game.global.dailyChallenge.bloodthirst.stacks) - } - } - return number; -} diff --git a/modules/breedtimer.js b/modules/breedtimer.js index 740500fdd..f0e34b364 100644 --- a/modules/breedtimer.js +++ b/modules/breedtimer.js @@ -1,27 +1,205 @@ MODULES["breedtimer"] = {}; -//These can be changed (in the console) if you know what you're doing: -MODULES["breedtimer"].buyGensIncrement = 5; //Buy this many geneticists at a time -MODULES["breedtimer"].fireGensIncrement = 10; //Fire this many geneticists at a time -MODULES["breedtimer"].fireGensFloor = 10; //Dont FIRE below this number (nothing to do with hiring up to it)(maybe is disregarded?) -MODULES["breedtimer"].breedFireOn = 6; //turn breedfire on at X seconds (if BreedFire) -MODULES["breedtimer"].breedFireOff = 2; //turn breedfire off at X seconds(if BreedFire) -MODULES["breedtimer"].killTitimpStacks = 5; //number of titimp stacks difference that must exist to Force Abandon -MODULES["breedtimer"].voidCheckPercent = 95; //Void Check health %, for force-Abandon during voidmap, if it dips below this during the Void (maybe this should be in automaps module) - -//Add breeding box (to GUI on startup): +MODULES["breedtimer"].voidCheckPercent = 95; + +function trimpsEffectivelyEmployed() { + //Init + var employedTrimps = game.resources.trimps.employed; + + //Multitasking + if (game.permaBoneBonuses.multitasking.owned) + employedTrimps *= (1 - game.permaBoneBonuses.multitasking.mult()); + + return employedTrimps; +} + +function breedingPS() { + //Init + var trimps = game.resources.trimps; + var breeding = new DecimalBreed(trimps.owned).minus(trimpsEffectivelyEmployed()); + + //Gets the modifier, then: 1.1x format -> 0.1 format -> 1.0 x breeding + return potencyMod().minus(1).mul(10).mul(breeding); +} + +function potencyMod() { + //Init + var trimps = game.resources.trimps; + var potencyMod = new DecimalBreed(trimps.potency); + + //Potency, Nurseries, Venimp, Broken Planet + if (game.upgrades.Potency.done > 0) potencyMod = potencyMod.mul(Math.pow(1.1, game.upgrades.Potency.done)); + if (game.buildings.Nursery.owned > 0) potencyMod = potencyMod.mul(Math.pow(1.01, game.buildings.Nursery.owned)); + if (game.unlocks.impCount.Venimp > 0) potencyMod = potencyMod.mul(Math.pow(1.003, game.unlocks.impCount.Venimp)); + if (game.global.brokenPlanet) potencyMod = potencyMod.div(10); + + //Pheromones + potencyMod = potencyMod.mul(1+ (game.portal.Pheromones.level * game.portal.Pheromones.modifier)); + + //Quick Trimps + if (game.singleRunBonuses.quickTrimps.owned) potencyMod = potencyMod.mul(2); + + //Dailies + if (game.global.challengeActive == "Daily"){ + //Dysfunctional + if (typeof game.global.dailyChallenge.dysfunctional !== 'undefined') + potencyMod = potencyMod.mul(dailyModifiers.dysfunctional.getMult(game.global.dailyChallenge.dysfunctional.strength)); + + //Toxic + if (typeof game.global.dailyChallenge.toxic !== 'undefined') + potencyMod = potencyMod.mul(dailyModifiers.toxic.getMult(game.global.dailyChallenge.toxic.strength, game.global.dailyChallenge.toxic.stacks)); + } + + //Toxicity + if (challengeActive("Toxicity") && game.challenges.Toxicity.stacks > 0) + potencyMod = potencyMod.mul(Math.pow(game.challenges.Toxicity.stackMult, game.challenges.Toxicity.stacks)); + + //Void Maps (Slow Breed) + if (game.global.voidBuff == "slowBreed") + potencyMod = potencyMod.mul(0.2); + + //Heirlooms + potencyMod = calcHeirloomBonusDecimal("Shield", "breedSpeed", potencyMod); + + //Geneticists + if (game.jobs.Geneticist.owned > 0) + potencyMod = potencyMod.mul(Math.pow(.98, game.jobs.Geneticist.owned)); + + return potencyMod.div(10).add(1); +} + +function breedTotalTime() { + //Init + var trimps = game.resources.trimps; + var trimpsMax = trimps.realMax(); + + //Calc + var maxBreedable = new DecimalBreed(trimpsMax).minus(trimpsEffectivelyEmployed()); + var breeding = maxBreedable.minus(trimps.getCurrentSend()); + + return DecimalBreed.log10(maxBreedable.div(breeding)).div(DecimalBreed.log10(potencyMod())).div(10); +} + +function breedTimeRemaining() { + //Init + var trimps = game.resources.trimps; + var trimpsMax = trimps.realMax(); + + //Calc + var maxBreedable = new DecimalBreed(trimpsMax).minus(trimpsEffectivelyEmployed()); + var breeding = new DecimalBreed(trimps.owned).minus(trimpsEffectivelyEmployed()); + return DecimalBreed.log10(maxBreedable.div(breeding)).div(DecimalBreed.log10(potencyMod())).div(10); +} + +var DecimalBreed = Decimal.clone({precision: 30, rounding: 4}); +var missingTrimps = new DecimalBreed(0); +function ATGA2() { + if (game.jobs.Geneticist.locked == false && getPageSetting('ATGA2') == true && getPageSetting('ATGA2timer') > 0 && game.global.challengeActive != "Trapper"){ + var trimps = game.resources.trimps; + var trimpsMax = trimps.realMax(); + var maxBreedable = new DecimalBreed(trimpsMax).minus(trimpsEffectivelyEmployed()); + var potencyMod = new DecimalBreed(trimps.potency); + if (game.upgrades.Potency.done > 0) potencyMod = potencyMod.mul(Math.pow(1.1, game.upgrades.Potency.done)); + if (game.buildings.Nursery.owned > 0) potencyMod = potencyMod.mul(Math.pow(1.01, game.buildings.Nursery.owned)); + if (game.unlocks.impCount.Venimp > 0) potencyMod = potencyMod.mul(Math.pow(1.003, game.unlocks.impCount.Venimp)); + if (game.global.brokenPlanet) potencyMod = potencyMod.div(10); + potencyMod = potencyMod.mul(1+ (game.portal.Pheromones.level * game.portal.Pheromones.modifier)); + if (game.singleRunBonuses.quickTrimps.owned) potencyMod = potencyMod.mul(2); + if (game.global.challengeActive == "Daily"){ + if (typeof game.global.dailyChallenge.dysfunctional !== 'undefined'){ + potencyMod = potencyMod.mul(dailyModifiers.dysfunctional.getMult(game.global.dailyChallenge.dysfunctional.strength)); + } + if (typeof game.global.dailyChallenge.toxic !== 'undefined'){ + potencyMod = potencyMod.mul(dailyModifiers.toxic.getMult(game.global.dailyChallenge.toxic.strength, game.global.dailyChallenge.toxic.stacks)); + } + } + if (challengeActive("Toxicity") && game.challenges.Toxicity.stacks > 0){ + potencyMod = potencyMod.mul(Math.pow(game.challenges.Toxicity.stackMult, game.challenges.Toxicity.stacks)); + } + if (game.global.voidBuff == "slowBreed"){ + potencyMod = potencyMod.mul(0.2); + } + potencyMod = calcHeirloomBonusDecimal("Shield", "breedSpeed", potencyMod); + if (game.jobs.Geneticist.owned > 0) potencyMod = potencyMod.mul(Math.pow(.98, game.jobs.Geneticist.owned)); + potencyMod = potencyMod.div(10).add(1); + var decimalOwned = missingTrimps.add(trimps.owned); + var timeRemaining = DecimalBreed.log10(maxBreedable.div(decimalOwned.minus(trimpsEffectivelyEmployed()))).div(DecimalBreed.log10(potencyMod)).div(10); + var currentSend = game.resources.trimps.getCurrentSend(); + var totalTime = DecimalBreed.log10(maxBreedable.div(maxBreedable.minus(currentSend))).div(DecimalBreed.log10(potencyMod)).div(10); + + var target; + if (getPageSetting('ATGA2timer') > 0) + target = new Decimal(getPageSetting('ATGA2timer')); + + if (getPageSetting('zATGA2timer') > 0 && getPageSetting('ztATGA2timer') > 0 && game.global.world < getPageSetting('zATGA2timer')) + target = new Decimal(getPageSetting('ztATGA2timer')); + if (getPageSetting('ATGA2timerz') > 0 && getPageSetting('ATGA2timerzt') > 0 && game.global.world >= getPageSetting('ATGA2timerz')) + target = new Decimal(getPageSetting('ATGA2timerzt')); + + if (game.global.runningChallengeSquared && getPageSetting('cATGA2timer') > 0 && challengeActive("Electricity") == false && challengeActive("Toxicity") == false && challengeActive("Nom") == false) + target = new Decimal(getPageSetting('cATGA2timer')); + if (game.global.runningChallengeSquared && getPageSetting('chATGA2timer') > 0 && (challengeActive("Electricity") || challengeActive("Toxicity") || challengeActive("Nom"))) + target = new Decimal(getPageSetting('chATGA2timer')); + + if (getPageSetting('dATGA2timer') > 0 && game.global.challengeActive == "Daily") + target = new Decimal(getPageSetting('dATGA2timer')); + if (getPageSetting('dhATGA2timer') > 0 && game.global.challengeActive == "Daily" && (typeof game.global.dailyChallenge.bogged !== 'undefined' || typeof game.global.dailyChallenge.plague !== 'undefined' || typeof game.global.dailyChallenge.pressure !== 'undefined')) + target = new Decimal(getPageSetting('dhATGA2timer')); + + if (game.global.challengeActive != "Daily" && getPageSetting('sATGA2timer') > 0 && isActiveSpireAT() == true) + target = new Decimal(getPageSetting('sATGA2timer')); + if (game.global.challengeActive == "Daily" && getPageSetting('dsATGA2timer') > 0 && disActiveSpireAT() == true) + target = new Decimal(getPageSetting('dsATGA2timer')); + + if ((getPageSetting('dATGA2Auto')==2||(getPageSetting('dATGA2Auto')==1 && disActiveSpireAT() && game.global.challengeActive == "Daily")) && game.global.challengeActive == "Daily" && (typeof game.global.dailyChallenge.bogged !== 'undefined' || typeof game.global.dailyChallenge.plague !== 'undefined')){ + plagueDamagePerStack = (game.global.dailyChallenge.plague !== undefined) ? dailyModifiers.plague.getMult(game.global.dailyChallenge.plague.strength, 1) : 0; + boggedDamage = (game.global.dailyChallenge.bogged !== undefined) ? dailyModifiers.bogged.getMult(game.global.dailyChallenge.bogged.strength) : 0; + atl = Math.ceil((Math.sqrt((plagueDamagePerStack/2+boggedDamage)**2 - 2 * plagueDamagePerStack * (boggedDamage-1)) - (plagueDamagePerStack/2+boggedDamage)) / plagueDamagePerStack); + target = new Decimal(Math.ceil(isNaN(atl) ? target : atl/1000*(((game.portal.Agility.level) ? 1000 * Math.pow(1 - game.portal.Agility.modifier, game.portal.Agility.level) : 1000) + ((game.talents.hyperspeed2.purchased && (game.global.world <= Math.floor((game.global.highestLevelCleared + 1) * 0.5))) || (game.global.mapExtraBonus == "fa")) * -100 + (game.talents.hyperspeed.purchased) * -100))); + } + + var now = new Date().getTime(); + var thresh = new DecimalBreed(totalTime.mul(0.02)); + var compareTime; + if (timeRemaining.cmp(1) > 0 && timeRemaining.cmp(target.add(1)) > 0) { + compareTime = new DecimalBreed(timeRemaining.add(-1));} + else { + compareTime = new DecimalBreed(totalTime);} + if (!thresh.isFinite()) thresh = new Decimal(0); + if (!compareTime.isFinite()) compareTime = new Decimal(999); + var genDif = new DecimalBreed(Decimal.log10(target.div(compareTime)).div(Decimal.log10(1.02))).ceil(); + + if (compareTime.cmp(target) < 0) { + if (game.resources.food.owned * (getPageSetting('ATGA2gen')/100) < getNextGeneticistCost()) {return;} + else if (timeRemaining.cmp(1) < 0 || target.minus((now - game.global.lastSoldierSentAt) / 1000).cmp(timeRemaining) > 0){ + if (genDif.cmp(0) > 0){ + if (genDif.cmp(10) > 0) genDif = new Decimal(10); + addGeneticist(genDif.toNumber()); + } + } + } + else if (compareTime.add(thresh.mul(-1)).cmp(target) > 0 || (potencyMod.cmp(1) == 0)){ + if (!genDif.isFinite()) genDif = new Decimal(-1); + if (genDif.cmp(0) < 0 && game.options.menu.gaFire.enabled != 2){ + if (genDif.cmp(-10) < 0) genDif = new Decimal(-10); + removeGeneticist(genDif.abs().toNumber()); + } + } + } +} + var addbreedTimerInsideText; function addBreedingBoxTimers() { var breedbarContainer = document.querySelector('#trimps > div.row'); var addbreedTimerContainer = document.createElement("DIV"); addbreedTimerContainer.setAttribute('class', "col-xs-11"); addbreedTimerContainer.setAttribute('style', 'padding-right: 0;'); - addbreedTimerContainer.setAttribute("onmouseover", 'tooltip(\"Hidden Next Group Breed Timer\", \"customText\", event, \"How long your next army has been breeding for, or how many anticipation stacks you will have if you send a new army now. This number is what BetterAutoFight #4 refers to when it says NextGroupBreedTimer.\")'); + addbreedTimerContainer.setAttribute("onmouseover", 'tooltip("Hidden Next Group Breed Timer", "customText", event, "How long your next army has been breeding for, or how many anticipation stacks you will have if you send a new army now.")'); addbreedTimerContainer.setAttribute("onmouseout", 'tooltip("hide")'); var addbreedTimerInside = document.createElement("DIV"); addbreedTimerInside.setAttribute('style', 'display: block;'); var addbreedTimerInsideIcon = document.createElement("SPAN"); addbreedTimerInsideIcon.setAttribute('class', "icomoon icon-clock"); - addbreedTimerInsideText = document.createElement("SPAN"); //updated in the top of mainLoop() each cycle + addbreedTimerInsideText = document.createElement("SPAN"); addbreedTimerInsideText.id = 'hiddenBreedTimer'; addbreedTimerInside.appendChild(addbreedTimerInsideIcon); addbreedTimerInside.appendChild(addbreedTimerInsideText); @@ -30,198 +208,50 @@ function addBreedingBoxTimers() { } addBreedingBoxTimers(); -//Add GUI popup for hovering over the army group size and translate that to breeding time -function addToolTipToArmyCount() { - var $armycount = document.getElementById('trimpsFighting'); - if ($armycount.className != "tooltipadded") { - $armycount.setAttribute("onmouseover", 'tooltip(\"Army Count\", \"customText\", event, \"To Fight now would add: \" + prettify(getArmyTime()) + \" seconds to the breed timer.\")'); - $armycount.setAttribute("onmouseout", 'tooltip("hide")'); - $armycount.setAttribute("class", 'tooltipadded'); - } -} -/* -function testBreedManager() { - var oldPotency = testPotencyMod(); - safeFireJob('Farmer', 1); - canAffordJob('Geneticist', false, 1); - safeBuyJob('Geneticist', 1); - var newPotency = testPotencyMod(); - var potencyGap = newPotency - oldPotency; - var targetBreed = getPageSetting('GeneticistTimer'); - var estimateBreedTime = getBreedTime(null,1); - var genDif = Math.ceil(Math.log10(targetBreed / compareTime) / Math.log10(1.02)); - var realTime = game.global.realBreedTime; -} -*/ -function controlGeneticistassist(targetTime) { - var hasGA = game.global.Geneticistassist; - if (hasGA) { - //The targetTime GA setting has to match one in the list. [use the last slot] - game.global.GeneticistassistSetting = targetTime; - game.global.GeneticistassistSteps = [-1,10,30,targetTime]; - toggleGeneticistassist(true); //true means updateOnly - } -} -//controlGeneticistassist(45); +function addToolTipToArmyCount(){var a=document.getElementById("trimpsFighting");"tooltipadded"!=a.className&&(a.setAttribute("onmouseover","tooltip(\"Army Count\", \"customText\", event, \"To Fight now would add: \" + prettify(getArmyTime()) + \" seconds to the breed timer.\")"),a.setAttribute("onmouseout","tooltip(\"hide\")"),a.setAttribute("class","tooltipadded"))} -//Controls "Auto Breed Timer" and "Geneticist Timer" - adjust geneticists to reach desired breed timer -function autoBreedTimer() { - var customVars = MODULES["breedtimer"]; - var fWorkers = Math.ceil(game.resources.trimps.realMax() / 2) - game.resources.trimps.employed; - var newSquadRdy = game.resources.trimps.realMax() <= game.resources.trimps.owned + 1; - var defaultBreedTimer = game.talents.patience.purchased && getPageSetting('UsePatience') ? 45 : 30; - var targetBreed = getPageSetting('GeneticistTimer'); - var newGeneTimerSetting=0; -//TIMER MANAGEMENT SECTION: - var manageBreedTimer = getPageSetting('ManageBreedtimer'); - if (manageBreedTimer) { - if(game.portal.Anticipation.level == 0) newGeneTimerSetting = 0; - else if(game.global.challengeActive == 'Electricity' || game.global.challengeActive == 'Mapocalypse') newGeneTimerSetting = 3.5; - else if(game.global.challengeActive == 'Nom' || game.global.challengeActive == 'Toxicity') { - if(getPageSetting('FarmWhenNomStacks7') && game.global.gridArray[99].nomStacks >= 5 && !game.global.mapsActive) - //if Improbability already has 5 nomstacks, do 30 antistacks. - newGeneTimerSetting = defaultBreedTimer; - else - newGeneTimerSetting = 10; - } - else if (getPageSetting('SpireBreedTimer') > -1 && isActiveSpireAT()) - newGeneTimerSetting = getPageSetting('SpireBreedTimer'); - else - newGeneTimerSetting = defaultBreedTimer; - if (newGeneTimerSetting != targetBreed) { - setPageSetting('GeneticistTimer',newGeneTimerSetting); - //controlGeneticistassist(newGeneTimerSetting); - debug("Changing the Geneticist Timer to a new value : " + newGeneTimerSetting, "other"); - } - } - var inDamageStance = game.upgrades.Dominance.done ? game.global.formation == 2 : game.global.formation == 0; - var inScryerStance = (game.global.world >= 60 && game.global.highestLevelCleared >= 180) && game.global.formation == 4; -//HIRING SECTION: - //Don't hire geneticists if total breed time remaining is greater than our target breed time - //Don't hire geneticists if we have already reached 30 anti stacks (put off further delay to next trimp group) //&& (game.global.lastBreedTime/1000 + getBreedTime(true) < targetBreed) - var time = getBreedTime(); - var timeLeft = getBreedTime(true); - var boughtGenRound1 = false; - if ((newSquadRdy || (game.global.lastBreedTime/1000 + timeLeft < targetBreed)) && targetBreed > time && !game.jobs.Geneticist.locked && targetBreed > timeLeft && game.resources.trimps.soldiers > 0 && !breedFire) { - //Buy geneticists in Increments of 1 for now: - var hiredNumGens = customVars.buyGensIncrement; - var doBuy = canAffordJob('Geneticist', false, hiredNumGens); - //insert 10% of total food limit here? or cost vs tribute? - if (doBuy) { - var firingForJobs = (game.options.menu.fireForJobs.enabled && game.jobs['Geneticist'].allowAutoFire); - //if there's no free worker spots, fire a farmer - if (!firingForJobs && fWorkers < hiredNumGens) - safeFireJob('Farmer', hiredNumGens); - safeBuyJob('Geneticist', hiredNumGens); - //debug("Bought this many Geneticists: " + hiredNumGens + ". Jobs Now: " + game.jobs.Geneticist.owned, "breed"); - boughtGenRound1 = true; - } - } -//FIRING SECTION: - var time = getBreedTime(); - var timeLeft = getBreedTime(true); - var fire1 = targetBreed*1.02 < time; - var fire2 = targetBreed*1.02 < timeLeft; - var fireobj = fire1 ? time : timeLeft; - //if we need to speed up our breeding - //if we have potency upgrades available, buy them. If geneticists are unlocked, or we aren't managing the breed timer, just buy them - if ((targetBreed < time || !game.jobs.Geneticist.locked || !getPageSetting('ManageBreedtimer') || game.global.challengeActive == 'Watch') && game.upgrades.Potency.allowed > game.upgrades.Potency.done && canAffordTwoLevel('Potency') && getPageSetting('BuyUpgrades')) { - buyUpgrade('Potency'); - } - //otherwise, if we have too many geneticists, (total time) - start firing them #1 - //otherwise, if we have too many geneticists, (remaining time) - start firing them #2 - else if (!boughtGenRound1 && (fire1 || fire2) && !game.jobs.Geneticist.locked && game.jobs.Geneticist.owned > customVars.fireGensFloor) { - //var timeGap = (time + timeLeft) > targetBreed ? targetBreed : targetBreed - (time + timeLeft); - var timeOK = fireobj > 0 ? fireobj : 0.1; - var numgens = Math.ceil(Math.log10(targetBreed / timeOK) / Math.log10(1.02)); - //debug("2a. Time: " + getBreedTime(true) + " / " + getBreedTime(),"breed"); - //debug("2b. " + numgens + " Genes.. / " + game.jobs.Geneticist.owned + " -> " + (game.jobs.Geneticist.owned+numgens),"breed"); - if (Number.isNaN(numgens)) numgens = 0; - safeBuyJob('Geneticist', numgens); - //debug("This many Geneticists were FIRED: " + numgens + ". Jobs Now: " + game.jobs.Geneticist.owned, "breed"); - //debug("2c. Time: " + getBreedTime(true) + " / " + getBreedTime(),"breed" ); - } - //if our time remaining to full trimps is still too high, fire some jobs to get-er-done - //needs option to toggle? advanced options? - else if ((targetBreed < timeLeft || (game.resources.trimps.soldiers == 0 && timeLeft > customVars.breedFireOn)) && breedFire == false && getPageSetting('BreedFire') && game.global.world > 10) { - breedFire = true; - } - - //reset breedFire once we have less than 2 seconds remaining - if(timeLeft < customVars.breedFireOff) breedFire = false; - - //Force Abandon Code (AutoTrimpicide): - targetBreed = parseInt(getPageSetting('GeneticistTimer')); - newSquadRdy = game.resources.trimps.realMax() <= game.resources.trimps.owned + 1; - var nextgrouptime = (game.global.lastBreedTime/1000); - if (targetBreed > defaultBreedTimer) targetBreed = defaultBreedTimer; //play nice with custom timers over default. - var newstacks = nextgrouptime >= targetBreed ? targetBreed : nextgrouptime; - //kill titimp if theres less than (5) seconds left on it or, we stand to gain more than (5) antistacks. - var killTitimp = (game.global.titimpLeft < customVars.killTitimpStacks || (game.global.titimpLeft >= customVars.killTitimpStacks && newstacks - game.global.antiStacks >= customVars.killTitimpStacks)) - if (game.portal.Anticipation.level && game.global.antiStacks < targetBreed && game.resources.trimps.soldiers > 0 && killTitimp) { - //if a new fight group is available and anticipation stacks aren't maxed, force abandon and grab a new group - if (newSquadRdy && nextgrouptime >= targetBreed) { - forceAbandonTrimps(); - } - //if we're sitting around breeding forever and over (5) anti stacks away from target. - else if (newSquadRdy && nextgrouptime >= 31 && newstacks - game.global.antiStacks >= customVars.killTitimpStacks) { - forceAbandonTrimps(); - } - } -} - -//Abandon trimps function that should handle all special cases. function abandonVoidMap() { var customVars = MODULES["breedtimer"]; - //do nothing if the button isnt set to on. if (!getPageSetting('ForceAbandon')) return; - //exit out of the voidmap if we go back into void-farm-for-health mode (less than 95%, account for some leeway during equipment buying.) if (game.global.mapsActive && getCurrentMapObject().location == "Void") { - var targetBreed = parseInt(getPageSetting('GeneticistTimer')); - if(voidCheckPercent < customVars.voidCheckPercent) { - //only exit if it happened for reasons other than random losses of anti-stacks. if (game.portal.Anticipation.level) { - if (targetBreed == 0 || targetBreed == -1) + var antistacklimitv = 45; + if (!game.talents.patience.purchased) + antistacklimitv = 30; + if (((game.jobs.Amalgamator.owned > 0) ? Math.floor((new Date().getTime() - game.global.lastSoldierSentAt) / 1000) : Math.floor(game.global.lastBreedTime / 1000)) >= antistacklimitv && game.global.antiStacks < antistacklimitv) { mapsClicked(true); - else if (game.global.antiStacks == targetBreed) + } + else if (game.global.antiStacks == antistacklimitv) mapsClicked(true); } else mapsClicked(true); } return; - } } -//Abandon trimps function that should handle all special cases. + function forceAbandonTrimps() { - //do nothing if the button isnt set to on. if (!getPageSetting('ForceAbandon')) return; - //dont if 0; +} + function safeBuyBuilding(building) { if (isBuildingInQueue(building)) return false; - //check if building is locked, or else it can buy 'phantom' buildings and is not exactly safe. if (game.buildings[building].locked) return false; var oldBuy = preBuy2(); - //build 2 at a time if we have the mastery for it. - //Note: Bypasses any "Max" caps by 1 if they are odd numbers and we can afford the 2nd one. - if (game.talents.doubleBuild.purchased) { + + if (bwRewardUnlocked("DecaBuild")) { + game.global.buyAmt = 10; + if (!canAffordBuilding(building)) { game.global.buyAmt = 2; - if (!canAffordBuilding(building)) { + if (!canAffordBuilding(building)) game.global.buyAmt = 1; - if (!canAffordBuilding(building)) { - postBuy2(oldBuy); - return false; - } - } - } else { + } + } + else if (bwRewardUnlocked("DoubleBuild")) { + game.global.buyAmt = 2; + if (!canAffordBuilding(building)) game.global.buyAmt = 1; - if (!canAffordBuilding(building)) { - postBuy2(oldBuy); - return false; - } - } + } + else game.global.buyAmt = 1; + + if (!canAffordBuilding(building)) { + postBuy2(oldBuy); + return false; + } + game.global.firing = false; + if (building == 'Gym' && getPageSetting('GymWall')) { game.global.buyAmt = 1; } - //buy max warpstations when we own <2 (ie: after a new giga) - //thereafter, buy only 1 warpstation - if (building == 'Warpstation') { + if (building == 'Warpstation' && !game.buildings[building].locked && canAffordBuilding(building)) { if (game.buildings.Warpstation.owned < 2) { game.global.buyAmt = 'Max'; game.global.maxSplit = 1; @@ -51,51 +54,54 @@ function safeBuyBuilding(building) { postBuy2(oldBuy); return; } - debug('Building ' + building, "buildings", '*hammer2'); - buyBuilding(building, true, true); + if (building != 'Trap') debug('Building ' + building, "buildings", '*hammer2'); + if (!game.buildings[building].locked && canAffordBuilding(building)) { + buyBuilding(building, true, true); + } postBuy2(oldBuy); return true; } -//Decision function to buy best "Food" Buildings function buyFoodEfficientHousing() { - var foodHousing = ["Hut", "House", "Mansion", "Hotel", "Resort"]; - var unlockedHousing = []; - for (var house in foodHousing) { - if (game.buildings[foodHousing[house]].locked === 0) { - unlockedHousing.push(foodHousing[house]); - } - } - var buildorder = []; - for (var house in unlockedHousing) { - var building = game.buildings[unlockedHousing[house]]; - var cost = getBuildingItemPrice(building, "food", false, 1); - var ratio = cost / building.increase.by; - buildorder.push({ - 'name': unlockedHousing[house], - 'ratio': ratio - }); - document.getElementById(unlockedHousing[house]).style.border = "1px solid #FFFFFF"; - } - buildorder.sort(function (a, b) { - return a.ratio - b.ratio; - }); - var bestfoodBuilding = null; - //if this building is first, its best. - var bb = buildorder[0]; - var max = getPageSetting('Max' + bb.name); - if (game.buildings[bb.name].owned < max || max == -1) { - bestfoodBuilding = bb.name; + //Init + var ignoresLimit = getPageSetting('FoodEfficiencyIgnoresMax') + var unlockedHousing = ["Hut", "House", "Mansion", "Hotel", "Resort"].filter(b => !game.buildings[b].locked); + + //Resets Border Color + unlockedHousing.forEach(b => document.getElementById(b).style.border = "1px solid #FFFFFF") + + //Checks for Limits + if (!ignoresLimit) { + unlockedHousing = unlockedHousing.filter(b => { + //Filter out buildings that are past the limits + if (game.buildings[b].owned < getPageSetting('Max' + b) || getPageSetting('Max' + b) < 1) + return true; + + //But paints their border before removing them + document.getElementById(b).style.border = "1px solid orange" + return false + }) } - //if we found something make it green and buy it - if (bestfoodBuilding) { - document.getElementById(bestfoodBuilding).style.border = "1px solid #00CC01"; - safeBuyBuilding(bestfoodBuilding); + + //Determines Food Efficiency for each housing + var buildOrder = unlockedHousing.map(b => ({ + 'name': b, + 'ratio': getBuildingItemPrice(game.buildings[b], "food", false, 1) / game.buildings[b].increase.by + })); + + //Grabs the most Food Efficient Housing + if (buildOrder.length == 0) return; + bestFoodBuilding = buildOrder.reduce((best, current) => current.ratio < best.ratio ? current : best) + + //If Food Efficiency Ignores Limit is enabled, then it only buy Huts and Houses here + if (!ignoresLimit || ["Hut", "House"].includes(bestFoodBuilding.name)) { + document.getElementById(bestFoodBuilding.name).style.border = "1px solid #00CC01"; + safeBuyBuilding(bestFoodBuilding.name); } } function buyGemEfficientHousing() { - var gemHousing = ["Hotel", "Resort", "Gateway", "Collector", "Warpstation"]; + var gemHousing = ["Mansion", "Hotel", "Resort", "Gateway", "Collector", "Warpstation"]; var unlockedHousing = []; for (var house in gemHousing) { if (game.buildings[gemHousing[house]].locked === 0) { @@ -107,109 +113,116 @@ function buyGemEfficientHousing() { var building = game.buildings[unlockedHousing[house]]; var cost = getBuildingItemPrice(building, "gems", false, 1); var ratio = cost / building.increase.by; - //don't consider Gateway if we can't afford it right now - hopefully to prevent game waiting for fragments to buy gateway when collector could be bought right now - if (unlockedHousing[house] == "Gateway" && !canAffordBuilding('Gateway')) - continue; obj[unlockedHousing[house]] = ratio; document.getElementById(unlockedHousing[house]).style.border = "1px solid #FFFFFF"; } var keysSorted = Object.keys(obj).sort(function (a, b) { return obj[a] - obj[b]; }); - bestBuilding = null; - //loop through the array and find the first one that isn't limited by max settings + var bestGemBuilding = null; for (var best in keysSorted) { var max = getPageSetting('Max' + keysSorted[best]); if (max === false) max = -1; - if (game.buildings[keysSorted[best]].owned < max || max == -1) { - bestBuilding = keysSorted[best]; - document.getElementById(bestBuilding).style.border = "1px solid #00CC00"; - //WarpStation Cap: + if (game.buildings[keysSorted[best]].owned < max || max == -1 || (getPageSetting('GemEfficiencyIgnoresMax') && keysSorted[best] != "Gateway")) { + bestGemBuilding = keysSorted[best]; + document.getElementById(bestGemBuilding).style.border = "1px solid #00CC00"; + + //Gateway Wall + if (bestGemBuilding == "Gateway" && getPageSetting('GatewayWall') > 1) { + if (getBuildingItemPrice(game.buildings.Gateway, "fragments", false, 1) > (game.resources.fragments.owned / getPageSetting('GatewayWall'))) { + document.getElementById(bestGemBuilding).style.border = "1px solid orange"; + bestGemBuilding = null; + continue; + } + } + var skipWarp = false; - if (getPageSetting('WarpstationCap') && bestBuilding == "Warpstation") { - //Warpstation Cap - if we are past the basewarp+deltagiga level, "cap" and just wait for next giga. - if (game.buildings.Warpstation.owned >= (Math.floor(game.upgrades.Gigastation.done * getPageSetting('DeltaGigastation')) + getPageSetting('FirstGigastation'))) - skipWarp = true; + if (getPageSetting('WarpstationCap') && bestGemBuilding == "Warpstation") { + var firstGigaOK = MODULES["upgrades"].autoGigas == false || game.upgrades.Gigastation.done > 0; + var gigaCapped = game.buildings.Warpstation.owned >= (Math.floor(game.upgrades.Gigastation.done * getPageSetting('DeltaGigastation')) + getPageSetting('FirstGigastation')) + if (firstGigaOK && gigaCapped) skipWarp = true; } - //WarpStation Wall: var warpwallpct = getPageSetting('WarpstationWall3'); - if (warpwallpct > 1 && bestBuilding == "Warpstation") { - //Warpstation Wall - allow only warps that cost 1/n'th less then current metal (try to save metal for next prestige) + if (warpwallpct > 1 && bestGemBuilding == "Warpstation") { if (getBuildingItemPrice(game.buildings.Warpstation, "metal", false, 1) * Math.pow(1 - game.portal.Resourceful.modifier, game.portal.Resourceful.level) > (game.resources.metal.owned / warpwallpct)) skipWarp = true; } if (skipWarp) - bestBuilding = null; - //'Buy Warp to Hit Coord': (override Cap/Wall) + bestGemBuilding = null; var getcoord = getPageSetting('WarpstationCoordBuy'); if (getcoord && skipWarp) { var toTip = game.buildings.Warpstation; -/* - //calc Cost - var warpMetalOK = getBuildingItemPrice(toTip, "metal", false, 1) * Math.pow(1 - game.portal.Resourceful.modifier, game.portal.Resourceful.level) / game.resources.metal.owned; - var warpGemsOK = getBuildingItemPrice(toTip, "gems", false, 1) * Math.pow(1 - game.portal.Resourceful.modifier, game.portal.Resourceful.level) / game.resources.gems.owned; - //var afford = Math.floor(Math.min(warpMetalOK,warpGemsOK)); - if (warpMetalOK <= 1 && warpGemsOK <= 1) { -*/ if (canAffordBuilding("Warpstation")) { var howMany = calculateMaxAfford(game.buildings["Warpstation"], true); - //calc trimps needed to next Coord var needCoord = game.upgrades.Coordination.allowed - game.upgrades.Coordination.done > 0; var coordReplace = (game.portal.Coordinated.level) ? (25 * Math.pow(game.portal.Coordinated.modifier, game.portal.Coordinated.level)).toFixed(3) : 25; - if (!canAffordCoordinationTrimps()){ + if (!canAffordCoordinationTrimps()) { var nextCount = (game.portal.Coordinated.level) ? game.portal.Coordinated.currentSend : game.resources.trimps.maxSoldiers; var amtToGo = ((nextCount * 3) - game.resources.trimps.realMax()); - //calc amount of trimps that warpstation increases by var increase = toTip.increase.by; if (game.portal.Carpentry.level && toTip.increase.what == "trimps.max") increase *= Math.pow(1.1, game.portal.Carpentry.level); if (game.portal.Carpentry_II.level && toTip.increase.what == "trimps.max") increase *= (1 + (game.portal.Carpentry_II.modifier * game.portal.Carpentry_II.level)); - //do it - if (amtToGo < increase*howMany) - bestBuilding = "Warpstation"; + if (amtToGo < increase * howMany) + bestGemBuilding = "Warpstation"; } } } break; } } - //if we found something make it green and buy it - if (bestBuilding) { - safeBuyBuilding(bestBuilding); + if (bestGemBuilding) { + bestBuilding = bestGemBuilding + safeBuyBuilding(bestGemBuilding); } } -//Main Decision Function that determines cost efficiency and Buys all housing (gems), or calls buyFoodEfficientHousing, and also non-storage buildings (Gym,Tribute,Nursery)s function buyBuildings() { - if ((game.jobs.Miner.locked && game.global.challengeActive != 'Metal') || (game.jobs.Scientist.locked && game.global.challengeActive != "Scientist")) - return; var customVars = MODULES["buildings"]; var oldBuy = preBuy2(); + var hidebuild = (getPageSetting('BuyBuildingsNew')===0 && getPageSetting('hidebuildings')==true); game.global.buyAmt = 1; - buyFoodEfficientHousing(); //["Hut", "House", "Mansion", "Hotel", "Resort"]; - buyGemEfficientHousing(); //["Hotel", "Resort", "Gateway", "Collector", "Warpstation"]; - //WormHoles: - if (getPageSetting('MaxWormhole') > 0 && game.buildings.Wormhole.owned < getPageSetting('MaxWormhole') && !game.buildings.Wormhole.locked) { + if (!hidebuild) { + buyFoodEfficientHousing(); + buyGemEfficientHousing(); + } + if (!hidebuild && getPageSetting('MaxWormhole') > 0 && game.buildings.Wormhole.owned < getPageSetting('MaxWormhole') && !game.buildings.Wormhole.locked) { safeBuyBuilding('Wormhole'); } - //Buy non-housing buildings: + //Gyms: if (!game.buildings.Gym.locked && (getPageSetting('MaxGym') > game.buildings.Gym.owned || getPageSetting('MaxGym') == -1)) { var skipGym = false; + + //Dynamic Gyms if (getPageSetting('DynamicGyms')) { - //getBattleStats calculation comes from battlecalc.js and shows the tooltip-table block amount. calcBadGuyDmg is in that file also - if (!game.global.preMapsActive && getBattleStats("block", true) > calcBadGuyDmg(getCurrentEnemy(), null, true,true)) - skipGym = true; - } - //still buy gyms if we are farming for voids - if (doVoids && voidCheckPercent > 0) - skipGym = false; - //(unless gymwall; thats why its after. debateable.) + //Target Zone + var targetZone = game.global.world; + + //Enemy stats + var block = calcOurBlock() / (game.global.brokenPlanet ? 2 : 1); + var pierce = game.global.brokenPlanet ? (getPierceAmt() * (game.global.formation == 3 ? 2 : 1)) : 0; + var nextGym = game.upgrades.Gymystic.modifier + Math.max(0, game.upgrades.Gymystic.done-1)/100; + var currentEnemyDamageOK = block > nextGym * calcSpecificEnemyAttack(); + var zoneEnemyDamageOK = block > calcBadGuyDmg(null, getEnemyMaxAttack(game.global.world, 90, 'Snimp', 1.0), true, true) * (1 - pierce); + + //Challenge stats + var moreBlockThanHealth = block >= nextGym * calcOurHealth(false); + var crushedOK = game.global.challengeActive != "Crushed"; + var explosiveOK = game.global.challengeActive != "Daily" || typeof game.global.dailyChallenge.explosive == "undefined"; + var challengeOK = moreBlockThanHealth || crushedOK && explosiveOK; + + //Stop buying Gyms if we already have enough block for our current enemy and also a C99 Snimp + if (currentEnemyDamageOK && zoneEnemyDamageOK && challengeOK) skipGym = true; + } + + //Gym Wall var gymwallpct = getPageSetting('GymWall'); if (gymwallpct > 1) { - //Gym Wall - allow only gyms that cost 1/n'th less then current wood (try to save wood for nurseries for new z230+ Magma nursery strategy) - if (getBuildingItemPrice(game.buildings.Gym, "wood", false, 1) * Math.pow(1 - game.portal.Resourceful.modifier, game.portal.Resourceful.level) > (game.resources.wood.owned / gymwallpct)) - skipGym = true; - } + if (getBuildingItemPrice(game.buildings.Gym, "wood", false, 1) * Math.pow(1 - game.portal.Resourceful.modifier, game.portal.Resourceful.level) + > (game.resources.wood.owned / gymwallpct)) + skipGym = true; + } + //ShieldBlock cost Effectiveness: if (game.equipment['Shield'].blockNow) { var gymEff = evaluateEquipmentEfficiency('Gym'); @@ -217,65 +230,50 @@ function buyBuildings() { if ((gymEff.Wall) || (gymEff.Factor <= shieldEff.Factor && !gymEff.Wall)) skipGym = true; } - //needGymystic is eval'ed by equipment.js line 204, Which is called AFTER buildings.js (spans two cycles) - if (needGymystic) skipGym = true; - if (!skipGym) - safeBuyBuilding('Gym'); - needGymystic = false; //needs reset after buyBuildings + + //Buy Gym + if (!((game.upgrades['Gymystic'].allowed - game.upgrades['Gymystic'].done) > 0) && !skipGym) safeBuyBuilding('Gym'); } + //Tributes: - if (!game.buildings.Tribute.locked && (getPageSetting('MaxTribute') > game.buildings.Tribute.owned || getPageSetting('MaxTribute') == -1)) { + if (!game.buildings.Tribute.locked && !hidebuild && (getPageSetting('MaxTribute') > game.buildings.Tribute.owned || getPageSetting('MaxTribute') == -1)) safeBuyBuilding('Tribute'); + + //Nurseries Init + var nurseryZoneOk = game.global.world >= getPageSetting('NoNurseriesUntil'); + var maxNurseryOk = getPageSetting('MaxNursery') < 0 || game.buildings.Nursery.owned < getPageSetting('MaxNursery'); + + var spireNurseryActive = game.global.challengeActive != "Daily" && (game.global.world > 200 && isActiveSpireAT() || game.global.world <= 200 && getPageSetting('IgnoreSpiresUntil') <= 200); + var nurseryPreSpire = spireNurseryActive && game.buildings.Nursery.owned < getPageSetting('PreSpireNurseries'); + + var dailySpireNurseryActive = game.global.challengeActive == "Daily" && (disActiveSpireAT() || game.global.world <= 200 && getPageSetting('dIgnoreSpiresUntil') <= 200); + var dailyNurseryPreSpire = dailySpireNurseryActive && game.buildings.Nursery.owned < getPageSetting('dPreSpireNurseries'); + + var skipNursery = false; + var nurserywall = getPageSetting('NurseryWall'); + if (nurserywall > 0) { + var nurserywood = (getBuildingItemPrice(game.buildings.Nursery, "wood", false, 1) * Math.pow(1 - game.portal.Resourceful.modifier, game.portal.Resourceful.level)); + var nurserygem = (getBuildingItemPrice(game.buildings.Nursery, "gems", false, 1) * Math.pow(1 - game.portal.Resourceful.modifier, game.portal.Resourceful.level)); + var nurserymetal = (getBuildingItemPrice(game.buildings.Nursery, "metal", false, 1) * Math.pow(1 - game.portal.Resourceful.modifier, game.portal.Resourceful.level)); + if (nurserywood > (game.resources.wood.owned * (nurserywall / 100))) { + skipNursery = true; + } + else if (nurserygem > (game.resources.gems.owned * (nurserywall / 100))) { + skipNursery = true; + } + else if (nurserymetal > (game.resources.metal.owned * (nurserywall / 100))) { + skipNursery = true; + } + } + + //Nurseries + if (game.buildings.Nursery.locked == 0 && !hidebuild && !skipNursery && (nurseryZoneOk && maxNurseryOk || nurseryPreSpire || dailyNurseryPreSpire)) { + safeBuyBuilding('Nursery'); } - var targetBreed = parseInt(getPageSetting('GeneticistTimer')); -//NURSERIES: - //NoNurseriesUntil', 'No Nurseries Until z', 'For Magma z230+ purposes. Nurseries get shut down, and wasting nurseries early on is probably a bad idea. Might want to set this to 230+ as well.' - var nursminlvl = getPageSetting('NoNurseriesUntil'); - //Activate dynamic Nurseries to buy nurseries from NoNurseriesUntilZone up to portal before zone. - function dynamicNurseries() { - var maxNursery = getPageSetting('MaxNursery'); - var finalZone = getPageSetting('HeHrDontPortalBefore') - var numZ = finalZone - nursminlvl; - var perZ = maxNursery / ((numZ / 10 + 1)); - return perZ; - } - var dynNursStop = 0; - if (getPageSetting('DynamicNurseries')) { - dynNursStop = dynamicNurseries(); - } - var preSpireOverride = getPageSetting('PreSpireNurseries'); - //override NoNurseriesUntil and MaxNursery if on a Spire >= IgnoreSpiresUntil, or on a world zone < 200 when IgnoreSpiresUntil is set to <= 200 - var overrideNurseries = preSpireOverride >= 0 && (isActiveSpireAT() || (game.global.world < 200 && getPageSetting('IgnoreSpiresUntil') <= 200)); - if (game.global.world < nursminlvl && !overrideNurseries) { - postBuy2(oldBuy); - return; - } - var maxNursery = overrideNurseries ? preSpireOverride : getPageSetting('MaxNursery'); - if (dynNursStop > 0) - maxNursery = dynNursStop; - //only buy nurseries if enabled, and we need to lower our breed time, or our target breed time is 0, or we aren't trying to manage our breed time before geneticists, and they aren't locked - //even if we are trying to manage breed timer pre-geneticists, start buying nurseries once geneticists are unlocked AS LONG AS we can afford a geneticist (to prevent nurseries from outpacing geneticists soon after they are unlocked) - if ((targetBreed < getBreedTime() || targetBreed <= 0 || - (targetBreed < getBreedTime(true) && game.global.challengeActive == 'Watch') || - (!game.jobs.Geneticist.locked && canAffordJob('Geneticist', false, 1))) && !game.buildings.Nursery.locked) { - var nwr = customVars.nursCostRatio; //nursery to warpstation/collector cost ratio. Also for extra gems. - var nursCost = getBuildingItemPrice(game.buildings.Nursery, "gems", false, 1); - var warpCost = getBuildingItemPrice(game.buildings.Warpstation, "gems", false, 1); - var collCost = getBuildingItemPrice(game.buildings.Collector, "gems", false, 1); - var resomod = Math.pow(1 - game.portal.Resourceful.modifier, game.portal.Resourceful.level); //need to apply the resourceful mod when comparing anything other than building vs building. - //buy nurseries irrelevant of warpstations (after we unlock them) - if we have enough extra gems that its not going to impact anything. note:(we will be limited by wood anyway - might use a lot of extra wood) - var buyWithExtraGems = (!game.buildings.Warpstation.locked && nursCost * resomod < nwr * game.resources.gems.owned); - if ((maxNursery > game.buildings.Nursery.owned || maxNursery == -1) && - (buyWithExtraGems || - ((nursCost < nwr * warpCost || game.buildings.Warpstation.locked) && - (nursCost < nwr * collCost || game.buildings.Collector.locked || !game.buildings.Warpstation.locked)))) { - safeBuyBuilding('Nursery'); - } - } + postBuy2(oldBuy); } -//Buys more storage if resource is over 85% full (or 50% if Zone 2-10) (or 70% if zone==1) function buyStorage() { var customVars = MODULES["buildings"]; var packMod = 1 + game.portal.Packrat.level * game.portal.Packrat.modifier; @@ -296,10 +294,337 @@ function buyStorage() { if ((game.global.world == 1 && owned > max * customVars.storageLowlvlCutoff1) || (game.global.world >= 2 && game.global.world < 10 && owned > max * customVars.storageLowlvlCutoff2) || (owned + jest > max * customVars.storageMainCutoff)) { - // debug('Buying ' + B + '(' + Bs[B] + ') at ' + Math.floor(game.resources[Bs[B]].owned / (game.resources[Bs[B]].max * packMod * 0.99) * 100) + '%'); if (canAffordBuilding(B) && game.triggers[B].done) { safeBuyBuilding(B); } } } } + +//Radon + +var RhousingList = ['Hut', 'House', 'Mansion', 'Hotel', 'Resort', 'Gateway', 'Collector']; + +function RsafeBuyBuilding(building) { + if (isBuildingInQueue(building)) + return false; + if (game.buildings[building].locked) + return false; + var oldBuy = preBuy2(); + + if (bwRewardUnlocked("DecaBuild")) { + game.global.buyAmt = 10; + if (!canAffordBuilding(building)) { + game.global.buyAmt = 2; + if (!canAffordBuilding(building)) + game.global.buyAmt = 1; + } + } + else if (bwRewardUnlocked("DoubleBuild")) { + game.global.buyAmt = 2; + if (!canAffordBuilding(building)) + game.global.buyAmt = 1; + } + else game.global.buyAmt = 1; + + if (!canAffordBuilding(building)) { + postBuy2(oldBuy); + return false; + } + + game.global.firing = false; + + debug('Building ' + building, "buildings", '*hammer2'); + if (!game.buildings[building].locked && canAffordBuilding(building)) { + buyBuilding(building, true, true); + } + postBuy2(oldBuy); + return true; +} + +function RbuyFoodEfficientHousing() { + var foodHousing = ["Hut", "House", "Mansion", "Hotel", "Resort"]; + var unlockedHousing = []; + for (var house in foodHousing) { + if (game.buildings[foodHousing[house]].locked === 0) { + unlockedHousing.push(foodHousing[house]); + } + } + var buildorder = []; + if (unlockedHousing.length > 0) { + for (var house in unlockedHousing) { + var building = game.buildings[unlockedHousing[house]]; + var cost = getBuildingItemPrice(building, "food", false, 1); + var ratio = cost / building.increase.by; + buildorder.push({ + 'name': unlockedHousing[house], + 'ratio': ratio + }); + document.getElementById(unlockedHousing[house]).style.border = "1px solid #FFFFFF"; + } + buildorder.sort(function (a, b) { + return a.ratio - b.ratio; + }); + var bestfoodBuilding = null; + var bb = buildorder[0]; + var max = getPageSetting('RMax' + bb.name); + if (game.buildings[bb.name].owned < max || max == -1) { + bestfoodBuilding = bb.name; + } + if (smithylogic(bestfoodBuilding, 'wood', false) && bestfoodBuilding) { + document.getElementById(bestfoodBuilding).style.border = "1px solid #00CC01"; + RsafeBuyBuilding(bestfoodBuilding); + } + } +} + +function RbuyGemEfficientHousing() { + var gemHousing = ["Mansion", "Hotel", "Resort", "Gateway", "Collector"]; + var unlockedHousing = []; + for (var house in gemHousing) { + if (game.buildings[gemHousing[house]].locked === 0) { + unlockedHousing.push(gemHousing[house]); + } + } + var obj = {}; + for (var house in unlockedHousing) { + var building = game.buildings[unlockedHousing[house]]; + var cost = getBuildingItemPrice(building, "gems", false, 1); + var ratio = cost / building.increase.by; + obj[unlockedHousing[house]] = ratio; + document.getElementById(unlockedHousing[house]).style.border = "1px solid #FFFFFF"; + } + var keysSorted = Object.keys(obj).sort(function (a, b) { + return obj[a] - obj[b]; + }); + bestBuilding = null; + for (var best in keysSorted) { + var max = getPageSetting('RMax' + keysSorted[best]); + if (max === false) max = -1; + if (game.buildings[keysSorted[best]].owned < max || max == -1) { + bestBuilding = keysSorted[best]; + document.getElementById(bestBuilding).style.border = "1px solid #00CC00"; + break; + } + } + if (smithylogic(bestBuilding, 'gems', false) && bestBuilding) { + RsafeBuyBuilding(bestBuilding); + } +} + +var smithybought = 0; + +function mostEfficientHousing() { + + //Housing + var HousingTypes = ['Hut', 'House', 'Mansion', 'Hotel', 'Resort', 'Gateway', 'Collector']; + + // Which houses we actually want to check + var housingTargets = []; + for (var house of HousingTypes) { + var maxHousing = (getPageSetting('RMax' + house) === -1 ? Infinity : getPageSetting('RMax' + house)); + if (!game.buildings[house].locked && game.buildings[house].owned < maxHousing) { + housingTargets.push(house); + } + } + + var mostEfficient = { + name: "", + time: Infinity + } + + for (var housing of housingTargets) { + + var worstTime = -Infinity; + var currentOwned = game.buildings[housing].owned; + for (var resource in game.buildings[housing].cost) { + + // Get production time for that resource + var baseCost = game.buildings[housing].cost[resource][0]; + var costScaling = game.buildings[housing].cost[resource][1]; + var avgProduction = getPsString(resource, true); + if (avgProduction <= 0) avgProduction = 1; + var housingBonus = game.buildings.Hut.increase.by; + if (!game.buildings.Hub.locked) { housingBonus += 500;} + + // Only keep the slowest producer, aka the one that would take the longest to generate resources for + worstTime = Math.max(baseCost * Math.pow(costScaling, currentOwned - 1) / (avgProduction * housingBonus), worstTime); + if (resource == 'wood' && !Rhyposhouldwood) worstTime = Infinity; + } + + if (mostEfficient.time > worstTime) { + mostEfficient.name = housing; + mostEfficient.time = worstTime; + } + } + if (mostEfficient.name == "") mostEfficient.name = null; + + return mostEfficient.name; +} + +function RbuyStorage(buyFood, buyWood, buyMetal) { + + // Simple map for resources to the names of their storage buildings. + var Resources = {}; + if (buyFood) {Resources.food = "Barn";} + if (buyWood) {Resources.wood = "Shed";} + if (buyMetal) {Resources.metal = "Forge";} + + // Check if we're currently running trimple/atlantrimp + var isOnTrimple = game.global.currentMapId; + for (var Map in game.global.mapsOwnedArray) { + if (Map.id == isOnTrimple) { + if (Map.name == "Atlantrimp" || Map.name == "Trimple Of Doom"){ + isOnTrimple = true;; + } + } + } + + // Calculate whatever would send us over the current max + var jestImps = {}; + for (var Res in Resources){ + + // Calculate maximum resources for given resource + var resMax = game.resources[Res].max; + if (game.global.universe == 1) { + resMax *= 1 + game.portal.Packrat.level * game.portal.Packrat.modifier; + } else { + resMax *= 1 + game.portal.Packrat.radLevel * game.portal.Packrat.modifier; + } + resMax = calcHeirloomBonus("Shield", "storageSize", resMax, false); + + // Check if we're in a map + var curRes = game.resources[Res].owned; + if (game.global.mapsActive) + { + if (isOnTrimple) { + jestImps[Res] = curRes * 2; + } else { + jestImps[Res] = curRes + scaleToCurrentMap(simpleSeconds(Res, 45)); + } + } else { + jestImps[Res] = curRes * 1.1; + } + + + if (resMax < jestImps[Res]){ + if (canAffordBuilding(Resources[Res]) && !(game.buildings[Resources[Res]].locked)){ + buyBuilding(Resources[Res], true, true, 1); + } + } + } + +} + +function RbuyBuildings() { + + // Storage + if (game.global.challengeActive == "Hypothermia" && getPageSetting('Rhypostorage')) { + + var hypofarmzone; + var hypofarmamount; + var bonfire = game.challenges.Hypothermia.totalBonfires; + var wood = game.resources.wood.max; + var woodmax = wood * (1 + game.portal.Packrat.radLevel * game.portal.Packrat.modifier); + woodmax = calcHeirloomBonus("Shield", "storageSize", woodmax, false); + + hypofarmzone = getPageSetting('Rhypofarmzone'); + hypofarmamount = getPageSetting('Rhypofarmstack'); + + var hypoamountfarmindex = hypofarmzone.indexOf(game.global.world); + var hypoamountzones = hypofarmamount[hypoamountfarmindex]; + + var currentprice = (1e10 * Math.pow(100, game.challenges.Hypothermia.totalBonfires)); + var targetprice = (currentprice * Math.pow(100, ((hypoamountzones - bonfire) - 1))) * 1.05; + targetprice += (targetprice / 1000); + + if (game.global.world > (getPageSetting('Rhypofarmzone')[getPageSetting('Rhypofarmzone').length - 1])) { + if (!game.global.autoStorage) { + toggleAutoStorage(false); + } + } + + else { + if (game.global.autoStorage) { + toggleAutoStorage(false); + } + + if (targetprice >= 1e10 && ((woodmax * Math.pow(2, game.buildings.Shed.purchased - game.buildings.Shed.owned)) < targetprice)) { + buyBuilding('Shed', true, true, 1); + } + + RbuyStorage(true, false, true); + } + } + else { + if (!game.global.autoStorage) { + toggleAutoStorage(false); + } + } + + + //Smithy + if (!game.buildings.Smithy.locked && canAffordBuilding("Smithy", false, false, false, false, 1) && Rhyposhouldwood) { + // On quest challenge + if (game.global.challengeActive == 'Quest') { + if (smithybought > game.global.world) {smithybought = 0;} + + if (smithybought < game.global.world && (questcheck() == 7 || (RcalcHDratio() * 10 >= getPageSetting('Rmapcuntoff')))) { + buyBuilding("Smithy", true, true, 1); + smithybought = game.global.world; + } + } else { + buyBuilding("Smithy", true, true, 1); + } + } + + //Microchip + if (!game.buildings.Microchip.locked && canAffordBuilding('Microchip')) { + buyBuilding('Microchip', true, true, 1); + } + + //Housing + var HousingTypes = ['Hut', 'House', 'Mansion', 'Hotel', 'Resort', 'Gateway', 'Collector']; + + // Which houses we actually want to check + var housingTargets = []; + for (var house in HousingTypes) { + var maxHousing = (getPageSetting('RMax' + house) === -1 ? Infinity : getPageSetting('RMax' + house)); + if (!game.buildings[HousingTypes[house]].locked && game.buildings[HousingTypes[house]].owned < maxHousing) { + housingTargets.push(house); + } + } + + var boughtHousing = false; + + do { + + boughtHousing = false; + var housing = mostEfficientHousing(); + + if (housing != null && canAffordBuilding(housing) && game.buildings[housing].purchased < (getPageSetting('RMax' + housing) === -1 ? Infinity : getPageSetting('RMax' + housing))) { + buyBuilding(housing, true, true, 1); + boughtHousing = true; + } + } while (boughtHousing) + + //Tributes + if (!game.buildings.Tribute.locked) { + var buyTributeCount = getMaxAffordable(Math.pow(1.05, game.buildings.Tribute.owned) * 10000, game.resources.food.owned,1.05,true); + + if (getPageSetting('RMaxTribute') > game.buildings.Tribute.owned) { + buyTributeCount = Math.min(buyTributeCount, getPageSetting('RMaxTribute') - game.buildings.Tribute.owned); + } + if (getPageSetting('RMaxTribute') < 0 || (getPageSetting('RMaxTribute') > game.buildings.Tribute.owned)) { + buyBuilding('Tribute', true, true, buyTributeCount); + } + } + + //Labs + if (!game.buildings.Laboratory.locked && getPageSetting('Rnurtureon') == true) { + if (!isBuildingInQueue('Laboratory') && (getPageSetting('RMaxLabs') < 0 || (getPageSetting('RMaxLabs') > game.buildings.Laboratory.owned))) { + buyBuilding('Laboratory', true, true, 1); + } + } + +} diff --git a/modules/calc.js b/modules/calc.js new file mode 100644 index 000000000..ccbfd378c --- /dev/null +++ b/modules/calc.js @@ -0,0 +1,1773 @@ +var critCC = 1; +var critDD = 1; +var trimpAA = 1; + +//Helium + +function addPoison(realDamage, zone) { + //Init + if (!zone) zone = game.global.world; + + //Poison is inactive + if (getEmpowerment(zone) != "Poison") return 0; + + //Real amount to be added in the next attack + if (realDamage) return game.empowerments.Poison.getDamage(); + + //Dynamically determines how much we are benefiting from poison based on Current Amount * Transfer Rate + if (getPageSetting("addpoison")) return game.empowerments["Poison"].getDamage() * getRetainModifier("Poison"); + + return 0; +} + +function calcCorruptionScale(zone, base) { + var startPoint = (game.global.challengeActive == "Corrupted" || game.global.challengeActive == "Eradicated") ? 1 : 150; + var scales = Math.floor((zone - startPoint) / 6); + var realValue = base * Math.pow(1.05, scales); + return parseFloat(prettify(realValue)); +} + +function getTrimpAttack() { + var dmg = 6; + var equipmentList = ["Dagger", "Mace", "Polearm", "Battleaxe", "Greatsword", "Arbalest"]; + for (var i = 0; i < equipmentList.length; i++) { + if (game.equipment[equipmentList[i]].locked !== 0) continue; + var attackBonus = game.equipment[equipmentList[i]].attackCalculated; + var level = game.equipment[equipmentList[i]].level; + dmg += attackBonus * level; + } + if (mutations.Magma.active()) { + dmg *= mutations.Magma.getTrimpDecay(); + } + dmg *= game.resources.trimps.maxSoldiers; + if (game.portal.Power.level > 0) { + dmg += (dmg * game.portal.Power.level * game.portal.Power.modifier); + } + if (game.portal.Power_II.level > 0) { + dmg *= (1 + (game.portal.Power_II.modifier * game.portal.Power_II.level)); + } + if (game.global.formation !== 0) { + dmg *= (game.global.formation == 2) ? 4 : 0.5; + } + return dmg; +} + +function calcOurHealth(stance) { + var health = 50; + + if (game.resources.trimps.maxSoldiers > 0) { + var equipmentList = ["Shield", "Boots", "Helmet", "Pants", "Shoulderguards", "Breastplate", "Gambeson"]; + for (var i = 0; i < equipmentList.length; i++) { + if (game.equipment[equipmentList[i]].locked !== 0) continue; + var healthBonus = game.equipment[equipmentList[i]].healthCalculated; + var level = game.equipment[equipmentList[i]].level; + health += healthBonus * level; + } + } + health *= game.resources.trimps.maxSoldiers; + if (game.goldenUpgrades.Battle.currentBonus > 0) { + health *= game.goldenUpgrades.Battle.currentBonus + 1; + } + if (game.portal.Toughness.level > 0) { + health *= ((game.portal.Toughness.level * game.portal.Toughness.modifier) + 1); + } + if (game.portal.Toughness_II.level > 0) { + health *= ((game.portal.Toughness_II.level * game.portal.Toughness_II.modifier) + 1); + } + if (game.portal.Resilience.level > 0) { + health *= (Math.pow(game.portal.Resilience.modifier + 1, game.portal.Resilience.level)); + } + + health *= game.challenges.Frigid.getTrimpMult(); + + health *= game.challenges.Mayhem.getTrimpMult(); + + health *= game.challenges.Pandemonium.getTrimpMult(); + + health *= game.challenges.Desolation.getTrimpMult(); + + var geneticist = game.jobs.Geneticist; + if (geneticist.owned > 0) { + health *= (Math.pow(1.01, game.global.lastLowGen)); + } + if (stance && game.global.formation > 0) { + var formStrength = 0.5; + if (game.global.formation == 1) formStrength = 4; + health *= formStrength; + } + if (game.global.challengeActive == "Life") { + health *= game.challenges.Life.getHealthMult(); + } else if (challengeActive("Balance")) { + health *= game.challenges.Balance.getHealthMult(); + } else if (typeof game.global.dailyChallenge.pressure !== 'undefined') { + health *= (dailyModifiers.pressure.getMult(game.global.dailyChallenge.pressure.strength, game.global.dailyChallenge.pressure.stacks)); + } + if (mutations.Magma.active()) { + var mult = mutations.Magma.getTrimpDecay(); + var lvls = game.global.world - mutations.Magma.start() + 1; + health *= mult; + } + var heirloomBonus = calcHeirloomBonus("Shield", "trimpHealth", 0, true); + if (heirloomBonus > 0) { + health *= ((heirloomBonus / 100) + 1); + } + if (game.global.radioStacks > 0) { + health *= (1 - (game.global.radioStacks * 0.1)); + } + if (game.global.totalSquaredReward > 0) { + health *= (1 + (game.global.totalSquaredReward / 100)); + } + if (game.jobs.Amalgamator.owned > 0) { + health *= game.jobs.Amalgamator.getHealthMult(); + } + if (game.talents.voidPower.purchased && game.global.voidBuff) { + var amt = (game.talents.voidPower2.purchased) ? ((game.talents.voidPower3.purchased) ? 65 : 35) : 15; + health *= (1 + (amt / 100)); + } + return health; +} + +function highDamageShield() { + if (game.global.challengeActive != "Daily" && game.global.ShieldEquipped.name == getPageSetting('highdmg')) { + critCC = getPlayerCritChance(); + critDD = getPlayerCritDamageMult(); + trimpAA = (calcHeirloomBonus("Shield", "trimpAttack", 1, true) / 100); + } + if (game.global.challengeActive == "Daily" && game.global.ShieldEquipped.name == getPageSetting('dhighdmg')) { + critCC = getPlayerCritChance(); + critDD = getPlayerCritDamageMult(); + trimpAA = (calcHeirloomBonus("Shield", "trimpAttack", 1, true) / 100); + } +} + +function getCritMulti(high) { + + var critChance = getPlayerCritChance(); + var CritD = getPlayerCritDamageMult(); + + if ( + high && + (getPageSetting('AutoStance') == 3 && getPageSetting('highdmg') != undefined && game.global.challengeActive != "Daily") || + (getPageSetting('use3daily') == true && getPageSetting('dhighdmg') != undefined && game.global.challengeActive == "Daily") + ) { + highDamageShield(); + critChance = critCC; + CritD = critDD; + } + + var lowTierMulti = getMegaCritDamageMult(Math.floor(critChance)); + var highTierMulti = getMegaCritDamageMult(Math.ceil(critChance)); + var highTierChance = critChance - Math.floor(critChance) + + return ((1 - highTierChance) * lowTierMulti + highTierChance * highTierMulti) * CritD +} + +function calcOurBlock(stance) { + var block = 0; + var gym = game.buildings.Gym; + if (gym.owned > 0) { + var gymStrength = gym.owned * gym.increase.by; + block += gymStrength; + } + var shield = game.equipment.Shield; + if (shield.blockNow && shield.level > 0) { + var shieldStrength = shield.level * shield.blockCalculated; + block += shieldStrength; + } + var trainer = game.jobs.Trainer; + if (trainer.owned > 0) { + var trainerStrength = trainer.owned * (trainer.modifier / 100); + trainerStrength = calcHeirloomBonus("Shield", "trainerEfficiency", trainerStrength); + block *= (trainerStrength + 1); + } + block *= game.resources.trimps.maxSoldiers; + if (stance && game.global.formation == 3) { + block *= 4; + } + var heirloomBonus = calcHeirloomBonus("Shield", "trimpBlock", 0, true); + if (heirloomBonus > 0) { + block *= ((heirloomBonus / 100) + 1); + } + if (game.global.radioStacks > 0) { + block *= (1 - (game.global.radioStacks * 0.1)); + } + return block; +} + +function calcOurDmg(minMaxAvg, incStance, incFlucts) { + var number = getTrimpAttack(); + var fluctuation = .2; + var maxFluct = -1; + var minFluct = -1; + if (game.jobs.Amalgamator.owned > 0) { + number *= game.jobs.Amalgamator.getDamageMult(); + } + if (game.challenges.Electricity.stacks > 0) { + number *= (1 - (game.challenges.Electricity.stacks * 0.1)); + } + if (getPageSetting('45stacks') == false && game.global.antiStacks > 0) { + number *= ((game.global.antiStacks * game.portal.Anticipation.level * game.portal.Anticipation.modifier) + 1); + } + if (getPageSetting('45stacks') == true && game.global.antiStacks > 0) { + number *= ((45 * game.portal.Anticipation.level * game.portal.Anticipation.modifier) + 1); + } + if (game.global.mapBonus > 0) { + var mapBonus = game.global.mapBonus; + if (game.talents.mapBattery.purchased && mapBonus == 10) mapBonus *= 2; + number *= ((mapBonus * .2) + 1); + } + if (game.global.achievementBonus > 0) { + number *= (1 + (game.global.achievementBonus / 100)); + } + if (challengeActive("Discipline")) { + fluctuation = .995; + } else if (game.portal.Range.level > 0) { + minFluct = fluctuation - (.02 * game.portal.Range.level); + } + if (game.global.challengeActive == "Decay") { + number *= 5; + number *= Math.pow(0.995, game.challenges.Decay.stacks); + } + if (game.global.roboTrimpLevel > 0) { + number *= ((0.2 * game.global.roboTrimpLevel) + 1); + } + if (challengeActive("Lead") && ((game.global.world % 2) == 1)) { + number *= 1.5; + } + if (game.goldenUpgrades.Battle.currentBonus > 0) { + number *= game.goldenUpgrades.Battle.currentBonus + 1; + } + if (game.talents.voidPower.purchased && game.global.voidBuff) { + var vpAmt = (game.talents.voidPower2.purchased) ? ((game.talents.voidPower3.purchased) ? 65 : 35) : 15; + number *= ((vpAmt / 100) + 1); + } + if (game.global.totalSquaredReward > 0) { + number *= ((game.global.totalSquaredReward / 100) + 1); + } + if (getPageSetting('fullice') == true && getEmpowerment() == "Ice") { + number *= (Fluffy.isRewardActive('naturesWrath') ? 3 : 2); + } + if (getPageSetting('fullice') == false && getEmpowerment() == "Ice") { + number *= (game.empowerments.Ice.getDamageModifier() + 1); + } + if (getEmpowerment() == "Poison" && getPageSetting('addpoison') == true) { + number *= (1 + game.empowerments.Poison.getModifier()); + number *= 4; + } + if (game.talents.magmamancer.purchased) { + number *= game.jobs.Magmamancer.getBonusPercent(); + } + if (game.talents.stillRowing2.purchased) { + number *= ((game.global.spireRows * 0.06) + 1); + } + if (game.global.voidBuff && game.talents.voidMastery.purchased) { + number *= 5; + } + if (game.talents.healthStrength.purchased && mutations.Healthy.active()) { + number *= ((0.15 * mutations.Healthy.cellCount()) + 1); + } + if (game.talents.herbalist.purchased) { + number *= game.talents.herbalist.getBonus(); + } + + number *= game.challenges.Frigid.getTrimpMult(); + + number *= game.challenges.Mayhem.getTrimpMult(); + + number *= game.challenges.Pandemonium.getTrimpMult(); + + number *= game.challenges.Desolation.getTrimpMult(); + + if (game.global.sugarRush > 0) { + number *= sugarRush.getAttackStrength(); + } + if (playerSpireTraps.Strength.owned) { + var strBonus = playerSpireTraps.Strength.getWorldBonus(); + number *= (1 + (strBonus / 100)); + } + if (Fluffy.isRewardActive('voidSiphon') && game.stats.totalVoidMaps.value) { + number *= (1 + (game.stats.totalVoidMaps.value * 0.05)); + } + if (game.global.challengeActive == "Life") { + number *= game.challenges.Life.getHealthMult(); + } + if (game.singleRunBonuses.sharpTrimps.owned) { + number *= 1.5; + } + if (game.global.uberNature == "Poison") { + number *= 3; + } + if (incStance && game.talents.scry.purchased && game.global.formation == 4 && (mutations.Healthy.active() || mutations.Corruption.active())) { + number *= 2; + } + if (game.global.challengeActive == "Daily" && game.talents.daily.purchased) { + number *= 1.5; + } + if (challengeActive("Lead") && game.global.world % 2 == 1 && game.global.world != 179) { + number /= 1.5; + } + if (game.global.challengeActive == "Daily") { + if (typeof game.global.dailyChallenge.minDamage !== 'undefined') { + if (minFluct == -1) minFluct = fluctuation; + minFluct += dailyModifiers.minDamage.getMult(game.global.dailyChallenge.minDamage.strength); + } + if (typeof game.global.dailyChallenge.maxDamage !== 'undefined') { + if (maxFluct == -1) maxFluct = fluctuation; + maxFluct += dailyModifiers.maxDamage.getMult(game.global.dailyChallenge.maxDamage.strength); + } + if (typeof game.global.dailyChallenge.oddTrimpNerf !== 'undefined' && ((game.global.world % 2) == 1)) { + number *= dailyModifiers.oddTrimpNerf.getMult(game.global.dailyChallenge.oddTrimpNerf.strength); + } + if (typeof game.global.dailyChallenge.evenTrimpBuff !== 'undefined' && ((game.global.world % 2) == 0)) { + number *= dailyModifiers.evenTrimpBuff.getMult(game.global.dailyChallenge.evenTrimpBuff.strength); + } + if (typeof game.global.dailyChallenge.rampage !== 'undefined') { + number *= dailyModifiers.rampage.getMult(game.global.dailyChallenge.rampage.strength, game.global.dailyChallenge.rampage.stacks); + } + } + number = calcHeirloomBonus("Shield", "trimpAttack", number) + if (Fluffy.isActive()) { + number *= Fluffy.getDamageModifier(); + } + // Gamma Burst + if (autoBattle.oneTimers.Burstier.owned == false) { + if (gammaBurstPct > 0 && (calcOurHealth() / (calcBadGuyDmg(null, getEnemyMaxAttack(game.global.world, 50, 'Snimp', 1.0))) >= 5)) { + number *= (gammaBurstPct + 1) / 5; + } + } + if (autoBattle.oneTimers.Burstier.owned == true) { + if (gammaBurstPct > 0 && (calcOurHealth() / (calcBadGuyDmg(null, getEnemyMaxAttack(game.global.world, 50, 'Snimp', 1.0))) >= 4)) { + number *= (gammaBurstPct + 1) / 4; + } + } + + + if (!incStance && game.global.formation != 0) { + number /= (game.global.formation == 2) ? 4 : 0.5; + } + + var min = number; + var max = number; + var avg = number; + + min *= (getCritMulti(false) * 0.8); + avg *= getCritMulti(false); + max *= (getCritMulti(false) * 1.2); + + if (incFlucts) { + if (minFluct > 1) minFluct = 1; + if (maxFluct == -1) maxFluct = fluctuation; + if (minFluct == -1) minFluct = fluctuation; + + min *= (1 - minFluct); + max *= (1 + maxFluct); + avg *= 1 + (maxFluct - minFluct) / 2; + } + + if (minMaxAvg == "min") return min; + else if (minMaxAvg == "max") return max; + else if (minMaxAvg == "avg") return avg; +} + +function calcDailyAttackMod(number) { + if (game.global.challengeActive == "Daily") { + if (typeof game.global.dailyChallenge.badStrength !== 'undefined') { + number *= dailyModifiers.badStrength.getMult(game.global.dailyChallenge.badStrength.strength); + } + if (typeof game.global.dailyChallenge.badMapStrength !== 'undefined' && game.global.mapsActive) { + number *= dailyModifiers.badMapStrength.getMult(game.global.dailyChallenge.badMapStrength.strength); + } + if (typeof game.global.dailyChallenge.bloodthirst !== 'undefined') { + number *= dailyModifiers.bloodthirst.getMult(game.global.dailyChallenge.bloodthirst.strength, game.global.dailyChallenge.bloodthirst.stacks); + } + } + return number; +} + +function badGuyChallengeMult() { + var number=1; + + //WARNING! Something is afoot! + //A few challenges + if (challengeActive("Meditate")) number *= 1.5; + else if (challengeActive("Watch")) number *= 1.25; + else if (game.global.challengeActive == "Corrupted") number *= 3; + else if (game.global.challengeActive == "Domination") number *= 2.5; + else if (game.global.challengeActive == "Coordinate") number *= getBadCoordLevel(); + else if (game.global.challengeActive == "Scientist" && getScientistLevel() == 5) number *= 10; + + //Obliterated and Eradicated + else if (game.global.challengeActive == "Obliterated" || game.global.challengeActive == "Eradicated"){ + var oblitMult = (game.global.challengeActive == "Eradicated") ? game.challenges.Eradicated.scaleModifier : 1e12; + var zoneModifier = Math.floor(game.global.world / game.challenges[game.global.challengeActive].zoneScaleFreq); + oblitMult *= Math.pow(game.challenges[game.global.challengeActive].zoneScaling, zoneModifier); + number *= oblitMult + } + + return number; +} + +function badGuyCritMult(enemy, critPower=2, block, health) { + //Pre-Init + if (getPageSetting('IgnoreCrits') == 2) return 1; + if (!enemy) enemy = getCurrentEnemy(); + if (!enemy || critPower <= 0) return 1; + if (!block) block = game.global.soldierCurrentBlock; + if (!health) health = game.global.soldierHealth; + + //Init + var regular=1, challenge=1; + + //Non-challenge crits + if (enemy.corrupted == 'corruptCrit') regular = 5; + else if (enemy.corrupted == 'healthyCrit') regular = 7; + else if (game.global.voidBuff == 'getCrit' && getPageSetting('IgnoreCrits') != 1) regular = 5; + + //Challenge crits + var crushed = game.global.challengeActive == "Crushed"; + var critDaily = game.global.challengeActive == "Daily" && typeof game.global.dailyChallenge.crits !== 'undefined'; + + //Challenge multiplier + if (critDaily) challenge = dailyModifiers.crits.getMult(game.global.dailyChallenge.crits.strength); + else if (crushed && health > block) challenge = 5; + + //Result -- Yep. Crits may crit! Yey! + if (critPower == 2) return regular * challenge; + else return Math.max(regular, challenge); +} + +function calcEnemyBaseAttack(type, zone, cell, name) { + //Pre-Init + if (!type) type = (!game.global.mapsActive) ? "world" : (getCurrentMapObject().location == "Void" ? "void" : "map"); + if (!zone) zone = (type == "world" || !game.global.mapsActive) ? game.global.world : getCurrentMapObject().level; + if (!cell) cell = (type == "world" || !game.global.mapsActive) ? getCurrentWorldCell().level : (getCurrentMapCell() ? getCurrentMapCell().level : 1); + if (!name) name = getCurrentEnemy() ? getCurrentEnemy().name : "Snimp"; + + //Init + var attack = 50 * Math.sqrt(zone) * Math.pow(3.27, zone/2) - 10; + + //Zone 1 + if (zone == 1) { + attack *= 0.35; + attack = (0.2 * attack) + (0.75 * attack * (cell / 100)); + } + + //Zone 2 + else if (zone == 2) { + attack *= 0.5; + attack = (0.32 * attack) + (0.68 * attack * (cell / 100)); + } + + //Before Breaking the Planet + else if (zone < 60) { + attack = (0.375 * attack) + (0.7 * attack * (cell / 100)); + attack *= 0.85; + } + + //After Breaking the Planet + else { + attack = (0.4 * attack) + (0.9 * attack * (cell / 100)); + attack *= Math.pow(1.15, zone - 59); + } + + //Maps + if (zone > 5 && type != "world") attack *= 1.1; + + //Specific Imp + if (name) attack *= game.badGuys[name].attack; + + return Math.floor(attack); +} + + +function calcEnemyAttackCore(type, zone, cell, name, minOrMax, customAttack) { + //Pre-Init + if (!type) type = (!game.global.mapsActive) ? "world" : (getCurrentMapObject().location == "Void" ? "void" : "map"); + if (!zone) zone = (type == "world" || !game.global.mapsActive) ? game.global.world : getCurrentMapObject().level; + if (!cell) cell = (type == "world" || !game.global.mapsActive) ? getCurrentWorldCell().level : (getCurrentMapCell() ? getCurrentMapCell().level : 1); + if (!name) name = getCurrentEnemy() ? getCurrentEnemy().name : "Snimp"; + + //Init + var attack = calcEnemyBaseAttack(type, zone, cell, name); + + //Spire - Overrides the base attack number + if (type == "world" && game.global.spireActive) attack = calcSpire(99, "Snimp", "attack"); + + //Map and Void Corruption + if (type != "world") { + //Corruption + var corruptionScale = calcCorruptionScale(game.global.world, 3); + if (mutations.Magma.active()) attack *= corruptionScale / (type == "void" ? 1 : 2); + else if (type == "void" && mutations.Corruption.active()) attack *= corruptionScale / 2; + } + + //Use custom values instead + if (customAttack) attack = customAttack; + + //WARNING! Check every challenge! + //A few challenges + if (challengeActive("Meditate")) attack *= 1.5; + else if (challengeActive("Watch")) attack *= 1.25; + else if (game.global.challengeActive == "Corrupted") attack *= 3; + else if (game.global.challengeActive == "Scientist" && getScientistLevel() == 5) attack *= 10; + + //Coordinate + if (game.global.challengeActive == "Coordinate") { + var amt = 1; + for (var i=1; i 0 && getPageSetting('ExitSpireCell') <= 100) + exitCell = (getPageSetting('ExitSpireCell') - 1); + if (game.global.challengeActive == "Daily" && disActiveSpireAT() && getPageSetting('dExitSpireCell') > 0 && getPageSetting('dExitSpireCell') <= 100) + exitCell = (getPageSetting('dExitSpireCell') - 1); + var enemy = cell == 99 ? (exitCell == 99 ? game.global.gridArray[99].name : "Snimp") : name; + var base = (what == "attack") ? game.global.getEnemyAttack(exitCell, enemy, false) : (calcEnemyBaseHealth(game.global.world, exitCell, enemy) * 2); + var mod = (what == "attack") ? 1.17 : 1.14; + var spireNum = Math.floor((game.global.world - 100) / 100); + if (spireNum > 1) { + var modRaiser = 0; + modRaiser += ((spireNum - 1) / 100); + if (what == "attack") modRaiser *= 8; + if (what == "health") modRaiser *= 2; + mod += modRaiser; + } + base *= Math.pow(mod, exitCell); + base *= game.badGuys[enemy][what]; + return base; +} + +function calcBadGuyDmg(enemy, attack, daily, maxormin, disableFlucts) { + var number; + if (enemy) + number = enemy.attack; + else + number = attack; + var fluctuation = .2; + var maxFluct = -1; + var minFluct = -1; + + if (!enemy && game.global.challengeActive) { + if (game.global.challengeActive == "Coordinate") { + number *= getBadCoordLevel(); + } else if (challengeActive("Meditate")) { + number *= 1.5; + } else if (enemy && challengeActive("Nom") && typeof enemy.nomStacks !== 'undefined') { + number *= Math.pow(1.25, enemy.nomStacks); + } else if (challengeActive("Watch")) { + number *= 1.25; + } else if (challengeActive("Lead")) { + number *= (1 + (game.challenges.Lead.stacks * 0.04)); + } else if (game.global.challengeActive == "Scientist" && getScientistLevel() == 5) { + number *= 10; + } else if (game.global.challengeActive == "Corrupted") { + number *= 3; + } else if (game.global.challengeActive == "Domination") { + if (game.global.lastClearedCell == 98) { + number *= 2.5; + } else number *= 0.1; + } else if (game.global.challengeActive == "Obliterated" || game.global.challengeActive == "Eradicated") { + var oblitMult = (game.global.challengeActive == "Eradicated") ? game.challenges.Eradicated.scaleModifier : 1e12; + var zoneModifier = Math.floor(game.global.world / game.challenges[game.global.challengeActive].zoneScaleFreq); + oblitMult *= Math.pow(game.challenges[game.global.challengeActive].zoneScaling, zoneModifier); + number *= oblitMult; + } else if (game.global.challengeActive == "Frigid") { + number *= game.challenges.Frigid.getEnemyMult(); + } + if (daily) + number = calcDailyAttackMod(number); + } + if (!enemy && game.global.usingShriek) { + number *= game.mapUnlocks.roboTrimp.getShriekValue(); + } + + if (!disableFlucts) { + if (minFluct > 1) minFluct = 1; + if (maxFluct == -1) maxFluct = fluctuation; + if (minFluct == -1) minFluct = fluctuation; + var min = Math.floor(number * (1 - minFluct)); + var max = Math.ceil(number + (number * maxFluct)); + return maxormin ? max : min; + } else + return number; +} + +function calcEnemyBaseHealth(zone, level, name) { + var health = 0; + health += 130 * Math.sqrt(zone) * Math.pow(3.265, zone / 2); + health -= 110; + if (zone == 1 || zone == 2 && level < 10) { + health *= 0.6; + health = (health * 0.25) + ((health * 0.72) * (level / 100)); + } else if (zone < 60) + health = (health * 0.4) + ((health * 0.4) * (level / 110)); + else { + health = (health * 0.5) + ((health * 0.8) * (level / 100)); + health *= Math.pow(1.1, zone - 59); + } + if (zone < 60) { + health *= 0.75; + health *= game.badGuys[name].health; + } + return health; +} + +function calcEnemyHealth(world, map) { + world = !world ? game.global.world : world; + var health = calcEnemyBaseHealth(world, 50, "Snimp"); + var corrupt = mutations.Corruption.active(); + var healthy = mutations.Healthy.active(); + if (map) { + corrupt = false; + healthy = false; + if (game.global.universe == 1) { + health *= 0.5; + } + } + if (corrupt && !healthy) { + var cptnum = getCorruptedCellsNum(); + var cpthlth = getCorruptScale("health"); + var cptpct = cptnum / 100; + var hlthprop = cptpct * cpthlth; + if (hlthprop >= 1) + health *= hlthprop; + } + if (healthy) { + var scales = Math.floor((game.global.world - 150) / 6); + health *= 14 * Math.pow(1.05, scales); + health *= 1.15; + } + if (game.global.challengeActive == "Obliterated" || game.global.challengeActive == "Eradicated") { + var oblitMult = (game.global.challengeActive == "Eradicated") ? game.challenges.Eradicated.scaleModifier : 1e12; + var zoneModifier = Math.floor(game.global.world / game.challenges[game.global.challengeActive].zoneScaleFreq); + oblitMult *= Math.pow(game.challenges[game.global.challengeActive].zoneScaling, zoneModifier); + health *= oblitMult; + } + if (game.global.challengeActive == "Coordinate") { + health *= getBadCoordLevel(); + } + if (challengeActive("Toxicity")) { + health *= 2; + } + if (challengeActive("Lead")) { + health *= (1 + (game.challenges.Lead.stacks * 0.04)); + } + if (challengeActive("Balance")) { + health *= 2; + } + if (challengeActive("Meditate")) { + health *= 2; + } + if (game.global.challengeActive == 'Life') { + health *= 10; + } + if (game.global.challengeActive == "Domination") { + if (game.global.lastClearedCell == 98) { + health *= 7.5; + } else health *= 0.1; + } + if (game.global.challengeActive == "Frigid") { + health *= game.challenges.Frigid.getEnemyMult(); + } + if (game.global.spireActive) { + health = calcSpire(99, game.global.gridArray[99].name, 'health'); + } + return health; +} + +function calcEnemyHealthCore(type, zone, cell, name, customHealth) { + //Pre-Init + if (!type) type = (!game.global.mapsActive) ? "world" : (getCurrentMapObject().location == "Void" ? "void" : "map"); + if (!zone) zone = (type == "world" || !game.global.mapsActive) ? game.global.world : getCurrentMapObject().level; + if (!cell) cell = (type == "world" || !game.global.mapsActive) ? getCurrentWorldCell().level : (getCurrentMapCell() ? getCurrentMapCell().level : 1); + if (!name) name = getCurrentEnemy() ? getCurrentEnemy().name : "Turtlimp"; + + //Init + var health = calcEnemyBaseHealth(zone, cell, name); + + //Spire - Overrides the base health number + if (type == "world" && game.global.spireActive) health = calcSpire(99, "Snimp", "healh"); + + //Map and Void Corruption + if (type != "world") { + //Corruption + var corruptionScale = calcCorruptionScale(game.global.world, 10); + if (mutations.Magma.active()) health *= corruptionScale / (type == "void" ? 1 : 2); + else if (type == "void" && mutations.Corruption.active()) health *= corruptionScale / 2; + } + + //Use a custom value instead + if (customHealth) health = customHealth; + + //Challenges + if (challengeActive("Balance")) health *= 2; + if (challengeActive("Meditate")) health *= 2; + if (challengeActive("Toxicity")) health *= 2; + if (game.global.challengeActive == "Life") health *= 11; + + //Coordinate + if (game.global.challengeActive == "Coordinate") { + var amt = 1; + for (var i=1; i= 1) + ratio = calcEnemyHealth(map, true) / ourBaseDamage; + return ratio; +} + +function calcCurrentStance() { + if (game.global.uberNature == "Wind" && getEmpowerment() == "Wind" && !game.global.mapsActive && + ( + ( + (game.global.challengeActive != "Daily" && calcHDratio() < getPageSetting('WindStackingMinHD')) || + (game.global.challengeActive == "Daily" && calcHDratio() < getPageSetting('dWindStackingMinHD')) + ) && + ( + (game.global.challengeActive != "Daily" && game.global.world >= getPageSetting('WindStackingMin')) || + (game.global.challengeActive == "Daily" && game.global.world >= getPageSetting('dWindStackingMin'))) + ) || + (game.global.uberNature == "Wind" && getEmpowerment() == "Wind" && !game.global.mapsActive && checkIfLiquidZone() && getPageSetting('liqstack') == true) + ) { + return 15; + } else { + + //Base Calc + var ehealth = 1; + if (game.global.fighting) { + ehealth = (getCurrentEnemy().maxHealth - getCurrentEnemy().health); + } + var attacklow = calcOurDmg("max", false, true); + var attackhigh = calcOurDmg("max", false, true); + + //Heirloom Calc + highDamageShield(); + if (getPageSetting('AutoStance') == 3 && getPageSetting('highdmg') != undefined && game.global.challengeActive != "Daily" && game.global.ShieldEquipped.name != getPageSetting('highdmg')) { + attackhigh *= trimpAA; + attackhigh *= getCritMulti(true); + } + if (getPageSetting('use3daily') == true && getPageSetting('dhighdmg') != undefined && game.global.challengeActive == "Daily" && game.global.ShieldEquipped.name != getPageSetting('dhighdmg')) { + attackhigh *= trimpAA; + attackhigh *= getCritMulti(true); + } + + //Heirloom Switch + if (ehealth > 0) { + var hitslow = (ehealth / attacklow); + var hitshigh = (ehealth / attackhigh); + var stacks = 190; + var usehigh = false; + var stacksleft = 1; + + if (game.global.challengeActive != "Daily" && getPageSetting('WindStackingMax') > 0) { + stacks = getPageSetting('WindStackingMax'); + } + if (game.global.challengeActive == "Daily" && getPageSetting('dWindStackingMax') > 0) { + stacks = getPageSetting('dWindStackingMax'); + } + if (game.global.uberNature == "Wind") { + stacks += 100; + } + if (getEmpowerment() == "Wind") { + stacksleft = (stacks - game.empowerments.Wind.currentDebuffPower); + } + + //Use High + if ( + (getEmpowerment() != "Wind") || + (game.empowerments.Wind.currentDebuffPower >= stacks) || + (hitshigh >= stacksleft) || + (game.global.mapsActive) || + (game.global.challengeActive != "Daily" && game.global.world < getPageSetting('WindStackingMin')) || + (game.global.challengeActive == "Daily" && game.global.world < getPageSetting('dWindStackingMin')) + ) { + usehigh = true; + } + if ( + (getPageSetting('wsmax') > 0 && game.global.world >= getPageSetting('wsmax') && !game.global.mapsActive && getEmpowerment() == "Wind" && game.global.challengeActive != "Daily" && getPageSetting('wsmaxhd') > 0 && calcHDratio() < getPageSetting('wsmaxhd')) || + (getPageSetting('dwsmax') > 0 && game.global.world >= getPageSetting('dwsmax') && !game.global.mapsActive && getEmpowerment() == "Wind" && game.global.challengeActive == "Daily" && getPageSetting('dwsmaxhd') > 0 && calcHDratio() < getPageSetting('dwsmaxhd')) + ) { + usehigh = false; + } + + //Low + if (!usehigh) { + if ( + (game.empowerments.Wind.currentDebuffPower >= stacks) || + ((hitslow * 4) > stacksleft) + ) { + return 2; + } else if ((hitslow) > stacksleft) { + return 0; + } else { + return 1; + } + + //High + } else if (usehigh) { + if ( + (getEmpowerment() != "Wind") || + (game.empowerments.Wind.currentDebuffPower >= stacks) || + ((hitshigh * 4) > stacksleft) || + (game.global.mapsActive) || + (game.global.challengeActive != "Daily" && game.global.world < getPageSetting('WindStackingMin')) || + (game.global.challengeActive == "Daily" && game.global.world < getPageSetting('dWindStackingMin')) + ) { + return 12; + } else if ((hitshigh) > stacksleft) { + return 10; + } else { + return 11; + } + } + } + } +} + +function calcBaseDamageInX() { + baseMinDamage = calcOurDmg("min", false, false); + baseMaxDamage = calcOurDmg("max", false, false); + baseDamage = calcOurDmg("avg", false, false); + baseHealth = calcOurHealth(false); + baseBlock = calcOurBlock(false); +} + +//Radon + +function rMutationAttack(cell) { + var baseAttack; + var addAttack = 0; + if (cell.cs) { + baseAttack = RgetEnemyMaxAttack(game.global.world, cell.level, cell.name); + } + else + baseAttack = RgetEnemyMaxAttack(game.global.world, cell.level, cell.name); + if (cell.cc) addAttack = u2Mutations.types.Compression.attack(cell, baseAttack); + if (cell.u2Mutation.indexOf('NVA') != -1) baseAttack *= 0.01; + else if (cell.u2Mutation.indexOf('NVX') != -1) baseAttack *= 10; + baseAttack += addAttack; + baseAttack *= Math.pow(1.01, (game.global.world - 201)); + return baseAttack; +} + +function rCalcMutationAttack() { + var number; + var highest = 1; + + for (var i = 0; i < game.global.gridArray.length; i++) { + var hasRage = game.global.gridArray[i].u2Mutation.includes('RGE'); + if (game.global.gridArray[i].u2Mutation.includes('CMP') && !game.global.gridArray[i].u2Mutation.includes('RGE')) { + for (var y = i + 1; y < i + u2Mutations.types.Compression.cellCount(); y++) { + if (game.global.gridArray[y].u2Mutation.includes('RGE')) { + hasRage = true; + break; + } + } + } + var cell = game.global.gridArray[i]; + if (cell.u2Mutation && cell.u2Mutation.length) { + highest = Math.max(rMutationAttack(cell) * (hasRage ? (u2Mutations.tree.Unrage.purchased ? 4 : 5) : 1), highest); + number = highest; + } + } + + return number; +} + +function rMutationHealth(cell) { + var baseHealth; + var addHealth = 0; + baseHealth = RcalcEnemyBaseHealth(game.global.world, cell.level, cell.name); + if (cell.cc) addHealth = u2Mutations.types.Compression.health(cell, baseHealth); + if (cell.u2Mutation.indexOf('NVA') != -1) baseHealth *= 0.01; + else if (cell.u2Mutation.indexOf('NVX') != -1) baseHealth *= 0.1; + baseHealth += addHealth; + baseHealth *= 2; + baseHealth *= Math.pow(1.02, (game.global.world - 201)); + return baseHealth; +} + +function rCalcMutationHealth() { + var health; + var highest = 1; + for (var i = 0; i < game.global.gridArray.length; i++) { + var cell = game.global.gridArray[i]; + if (cell.u2Mutation && cell.u2Mutation.length) { + highest = Math.max(rMutationHealth(cell), highest); + health = highest; + } + } + return health; +} + +//Radon + +function RgetCritMulti() { + + var critChance = getPlayerCritChance(); + var CritD = getPlayerCritDamageMult(); + + var lowTierMulti = getMegaCritDamageMult(Math.floor(critChance)); + var highTierMulti = getMegaCritDamageMult(Math.ceil(critChance)); + var highTierChance = critChance - Math.floor(critChance) + + return ((1 - highTierChance) * lowTierMulti + highTierChance * highTierMulti) * CritD +} + +function RcalcOurDmg(minMaxAvg, equality) { + + // Base + equipment + var number = 6; + var equipmentList = ["Dagger", "Mace", "Polearm", "Battleaxe", "Greatsword", "Arbalest"]; + for (var i = 0; i < equipmentList.length; i++) { + if (game.equipment[equipmentList[i]].locked !== 0) continue; + var attackBonus = game.equipment[equipmentList[i]].attackCalculated; + var level = game.equipment[equipmentList[i]].level; + number += attackBonus * level; + } + + // Soldiers + number *= game.resources.trimps.maxSoldiers; + + // Smithies + number *= game.buildings.Smithy.getMult(); + + // Achievement bonus + number *= 1 + (game.global.achievementBonus / 100); + + // Power + number += (number * game.portal.Power.radLevel * game.portal.Power.modifier); + + // Map Bonus + var mapBonus = game.global.mapBonus; + if (game.talents.mapBattery.purchased && mapBonus == 10) mapBonus *= 2; + number *= 1 + (mapBonus * .2); + + // Tenacity + number *= game.portal.Tenacity.getMult(); + + // Hunger + number *= game.portal.Hunger.getMult(); + + // Ob + number *= game.portal.Observation.getMult(); + + // Champ + number *= game.portal.Championism.getMult(); + + // Robotrimp + number *= 1 + (0.2 * game.global.roboTrimpLevel); + + // Mayhem Completions + number *= game.challenges.Mayhem.getTrimpMult(); + + // Panda Completions + number *= game.challenges.Pandemonium.getTrimpMult(); + + // Deso Completions + number *= game.challenges.Desolation.getTrimpMult(); + + // Heirloom + number *= 1 + calcHeirloomBonus('Shield', 'trimpAttack', 1, true) / 100; + + // Frenzy perk + if (getPageSetting('Rcalcfrenzy') == true) { + number *= 1 + (0.5 * game.portal.Frenzy.radLevel); + } + + // Golden Upgrade + number *= 1 + game.goldenUpgrades.Battle.currentBonus; + + // Herbalist Mastery + if (game.talents.herbalist.purchased) { + number *= game.talents.herbalist.getBonus(); + } + + // Challenge 2 or 3 reward + number *= 1 + (game.global.totalSquaredReward / 100); + + // Fluffy Modifier + number *= Fluffy.getDamageModifier(); + + // Pspire Strength Towers + number *= 1 + (playerSpireTraps.Strength.getWorldBonus() / 100); + + // Sharp Trimps + if (game.singleRunBonuses.sharpTrimps.owned) { + number *= 1.5; + } + + // Sugar rush event bonus + if (game.global.sugarRush) { + number *= sugarRush.getAttackStrength(); + } + + //Mutations + if (u2Mutations.tree.Attack.purchased) { + number *= 1.5; + } + if (u2Mutations.tree.Brains.purchased) { + number *= u2Mutations.tree.Brains.getBonus(); + } + if (u2Mutations.tree.GeneAttack.purchased) { + number *= 10; + } + + if (game.global.world > 200) { + number *= game.global.novaMutStacks > 0 ? (u2Mutations.types.Nova.trimpAttackMult() * 0.98) : 1; + } + + // Challenges + if (game.global.challengeActive == "Melt") { + number *= 5 * Math.pow(0.99, game.challenges.Melt.stacks); + } + if (game.global.challengeActive == "Unbalance") { + number *= game.challenges.Unbalance.getAttackMult(); + } + if (game.global.challengeActive == "Quagmire") { + number *= game.challenges.Quagmire.getExhaustMult(); + } + if (game.global.challengeActive == "Revenge") { + number *= game.challenges.Revenge.getMult(); + } + if (game.global.challengeActive == "Quest") { + number *= game.challenges.Quest.getAttackMult(); + } + if (game.global.challengeActive == "Archaeology") { + number *= game.challenges.Archaeology.getStatMult("attack"); + } + if (game.global.challengeActive == "Berserk") { + number *= game.challenges.Berserk.getAttackMult(); + } + if (game.challenges.Nurture.boostsActive() == true) { + number *= game.challenges.Nurture.getStatBoost(); + } + if (game.global.challengeActive == "Alchemy") { + number *= alchObj.getPotionEffect("Potion of Strength"); + } + if (game.global.challengeActive === 'Smithless') { + if (game.challenges.Smithless.fakeSmithies > 0) number *= Math.pow(1.25, game.challenges.Smithless.fakeSmithies); + } + if (game.global.challengeActive == "Desolation") { + number *= game.challenges.Desolation.trimpAttackMult(); + } + + // Dailies + var minDailyMod = 1; + var maxDailyMod = 1; + if (game.global.challengeActive == "Daily") { + // Legs for Days mastery + number *= game.talents.daily.purchased ? 1.5 : 1; + // Min damage reduced (additive) + minDailyMod -= typeof game.global.dailyChallenge.minDamage !== 'undefined' ? dailyModifiers.minDamage.getMult(game.global.dailyChallenge.minDamage.strength) : 0; + // Max damage increased (additive) + maxDailyMod += typeof game.global.dailyChallenge.maxDamage !== 'undefined' ? dailyModifiers.maxDamage.getMult(game.global.dailyChallenge.maxDamage.strength) : 0; + // Minus attack on odd zones + number += typeof game.global.dailyChallenge.oddTrimpNerf !== 'undefined' && ((game.global.world % 2) == 1) ? dailyModifiers.oddTrimpNerf.getMult(game.global.dailyChallenge.oddTrimpNerf.strength) : 0; + // Bonus attack on even zones + number -= typeof game.global.dailyChallenge.evenTrimpBuff !== 'undefined' && ((game.global.world % 2) == 0) ? dailyModifiers.evenTrimpBuff.getMult(game.global.dailyChallenge.evenTrimpBuff.strength) : 0; + // Rampage Daily mod + number -= typeof game.global.dailyChallenge.rampage !== 'undefined' ? dailyModifiers.rampage.getMult(game.global.dailyChallenge.rampage.strength, game.global.dailyChallenge.rampage.stacks) : 0; + } + + //Scruffy Level 20 - Dailies + if (game.global.stringVersion >= '5.7.0') { + number *= Fluffy.isRewardActive('SADailies') && game.global.challengeActive == "Daily" ? Fluffy.rewardConfig.SADailies.attackMod() : 1; + } + + // AB + number *= autoBattle.bonuses.Stats.getMult(); + + // Equality + if (getPageSetting('Rcalcmaxequality') == 1 && !equality) { + number *= Math.pow(game.portal.Equality.getModifier(1), game.portal.Equality.scalingCount); + } else if (getPageSetting('Rcalcmaxequality') == 0 && !equality) { + number *= game.portal.Equality.getMult(1); + } else { + number *= 1; + } + + // Gamma Burst + if (autoBattle.oneTimers.Burstier.owned == false) { + if (gammaBurstPct > 0 && (RcalcOurHealth() / (RcalcBadGuyDmg(null, RgetEnemyMaxAttack(game.global.world, 50, 'Snimp', 1.0))) >= 5)) { + number *= (gammaBurstPct + 1) / 5; + } + } + if (autoBattle.oneTimers.Burstier.owned == true) { + if (gammaBurstPct > 0 && (RcalcOurHealth() / (RcalcBadGuyDmg(null, RgetEnemyMaxAttack(game.global.world, 50, 'Snimp', 1.0))) >= 4)) { + number *= (gammaBurstPct + 1) / 4; + } + } + + // Average out crit damage + number *= RgetCritMulti(); + + switch (minMaxAvg) { + case 'min': + return number * (game.portal.Range.radLevel * 0.02 + 0.8) * minDailyMod; + case 'max': + return number * 1.2 * maxDailyMod; + case 'avg': + return number; + } + + return number; +} + +function RcalcOurHealth() { + + //Health + + var health = 50; + + if (game.resources.trimps.maxSoldiers > 0) { + var equipmentList = ["Shield", "Boots", "Helmet", "Pants", "Shoulderguards", "Breastplate", "Gambeson"]; + for (var i = 0; i < equipmentList.length; i++) { + if (game.equipment[equipmentList[i]].locked !== 0) continue; + var healthBonus = game.equipment[equipmentList[i]].healthCalculated; + var level = game.equipment[equipmentList[i]].level; + health += healthBonus * level; + } + } + + health *= game.resources.trimps.maxSoldiers; + if (game.buildings.Smithy.owned > 0) { + health *= game.buildings.Smithy.getMult() + } + + //Antenna Array + health *= game.buildings.Antenna.owned >= 10 ? game.jobs.Meteorologist.getExtraMult() : 1; + + if (game.portal.Toughness.radLevel > 0) { + health *= ((game.portal.Toughness.radLevel * game.portal.Toughness.modifier) + 1); + } + + if (game.portal.Resilience.radLevel > 0) { + health *= (Math.pow(game.portal.Resilience.modifier + 1, game.portal.Resilience.radLevel)); + } + + if (Fluffy.isRewardActive("healthy")) { + health *= 1.5; + } + + if (game.portal.Observation.radLevel > 0) { + health *= game.portal.Observation.getMult(); + } + + if (game.global.mayhemCompletions > 0) { + health *= game.challenges.Mayhem.getTrimpMult(); + } + + if (game.global.pandCompletions > 0) { + health *= game.challenges.Pandemonium.getTrimpMult(); + } + + if (game.global.desoCompletions > 0) { + health *= game.challenges.Desolation.getTrimpMult(); + } + + //AutoBattle + health *= autoBattle.bonuses.Stats.getMult(); + + //Shield + health = calcHeirloomBonus("Shield", "trimpHealth", health); + + if (game.portal.Championism.radLevel > 0) { + health *= game.portal.Championism.getMult(); + } + + if (game.goldenUpgrades.Battle.currentBonus > 0) { + health *= game.goldenUpgrades.Battle.currentBonus + 1; + } + + if (game.global.totalSquaredReward > 0) { + health *= (1 + (game.global.totalSquaredReward / 100)); + } + + //Mutations + if (u2Mutations.tree.Health.purchased) { + health *= 1.5; + } + if (u2Mutations.tree.GeneHealth.purchased) { + health *= 10; + } + + //Challenges + if (game.global.challengeActive == "Revenge" && game.challenges.Revenge.stacks > 0) { + health *= game.challenges.Revenge.getMult(); + } + + if (game.global.challengeActive == "Wither" && game.challenges.Wither.trimpStacks > 0) { + health *= game.challenges.Wither.getTrimpHealthMult(); + } + + if (game.global.challengeActive == "Insanity") { + health *= game.challenges.Insanity.getHealthMult(); + } + + if (game.global.challengeActive == "Berserk") { + if (game.challenges.Berserk.frenzyStacks > 0) { + health *= 0.5; + } + if (game.challenges.Berserk.frenzyStacks <= 0) { + health *= game.challenges.Berserk.getHealthMult(true); + } + } + + if (game.global.challengeActive == "Desolation") { + health *= game.challenges.Desolation.trimpHealthMult(); + } + + if (game.challenges.Nurture.boostsActive() == true) { + health *= game.challenges.Nurture.getStatBoost(); + } + + health *= alchObj.getPotionEffect('Potion of Strength'); + + if (game.global.challengeActive === 'Smithless') { + if (game.challenges.Smithless.fakeSmithies > 0) health *= Math.pow(1.25, game.challenges.Smithless.fakeSmithies); + } + + if (typeof game.global.dailyChallenge.pressure !== 'undefined') { + health *= (dailyModifiers.pressure.getMult(game.global.dailyChallenge.pressure.strength, game.global.dailyChallenge.pressure.stacks)); + } + + //Prismatic Shield and Shield Layer, scales with multiple Scruffy shield layers + health *= Fluffy.isRewardActive('shieldlayer') ? 1 + (getEnergyShieldMult() * (1 + Fluffy.isRewardActive('shieldlayer'))) : 1 + getEnergyShieldMult(); + + return health; +} + +function RcalcDailyAttackMod(number) { + if (game.global.challengeActive == "Daily") { + if (typeof game.global.dailyChallenge.badStrength !== 'undefined') { + number *= dailyModifiers.badStrength.getMult(game.global.dailyChallenge.badStrength.strength); + } + if (typeof game.global.dailyChallenge.badHealth !== 'undefined') { + number *= dailyModifiers.badHealth.getMult(game.global.dailyChallenge.badHealth.strength); + } + if (typeof game.global.dailyChallenge.badMapStrength !== 'undefined' && game.global.mapsActive) { + number *= dailyModifiers.badMapStrength.getMult(game.global.dailyChallenge.badMapStrength.strength); + } + if (typeof game.global.dailyChallenge.empower !== 'undefined') { + number *= dailyModifiers.empower.getMult(game.global.dailyChallenge.empower.strength, game.global.dailyChallenge.empower.stacks); + } + if (typeof game.global.dailyChallenge.bloodthirst !== 'undefined') { + number *= dailyModifiers.bloodthirst.getMult(game.global.dailyChallenge.bloodthirst.strength, game.global.dailyChallenge.bloodthirst.stacks); + } + } + return number; +} + +function RcalcDailyHealthMod(number) { + if (game.global.challengeActive == "Daily") { + if (typeof game.global.dailyChallenge.badHealth !== 'undefined') { + number *= dailyModifiers.badHealth.getMult(game.global.dailyChallenge.badHealth.strength); + } + if (typeof game.global.dailyChallenge.empower !== 'undefined') { + number *= dailyModifiers.empower.getMult(game.global.dailyChallenge.empower.strength, game.global.dailyChallenge.empower.stacks); + } + } + return number; +} + +function RcalcBadGuyDmg(enemy, attack, equality) { + var number; + var highest = 1; + var mute = false; + + if (enemy) + number = enemy.attack; + else + number = attack; + + if (game.global.world > 200 && getPageSetting('Rmutecalc') > 0 && game.global.world >= getPageSetting('Rmutecalc')) { + mute = true; + number = rCalcMutationAttack(); + } + if (game.global.challengeActive == "Extermination" && getPageSetting('Rexterminateon') == true && getPageSetting('Rexterminatecalc') == true) { + number = RgetEnemyMaxAttack(game.global.world, 90, 'Mantimp', 1.0) + } + if (game.portal.Equality.radLevel > 0 && getPageSetting('Rcalcmaxequality') == 0 && !equality) { + number *= game.portal.Equality.getMult(); + } else if (game.portal.Equality.radLevel > 0 && getPageSetting('Rcalcmaxequality') >= 1 && game.portal.Equality.scalingCount > 0 && !equality) { + number *= Math.pow(game.portal.Equality.modifier, game.portal.Equality.scalingCount); + } + if (game.global.challengeActive == "Daily") { + number = RcalcDailyAttackMod(number); + } + if (game.global.challengeActive == "Unbalance") { + number *= 1.5; + } + if (game.global.challengeActive == "Wither" && game.challenges.Wither.enemyStacks > 0) { + number *= game.challenges.Wither.getEnemyAttackMult(); + } + if (game.global.challengeActive == "Archaeology") { + number *= game.challenges.Archaeology.getStatMult("enemyAttack"); + } + if (game.global.challengeActive == "Mayhem") { + number *= game.challenges.Mayhem.getEnemyMult(); + number *= game.challenges.Mayhem.getBossMult(); + } + if (game.global.challengeActive == "Pandemonium") { + number *= game.challenges.Pandemonium.getEnemyMult(); + number *= game.challenges.Pandemonium.getBossMult(); + } + if (game.global.challengeActive == "Desolation") { + number *= game.challenges.Desolation.getEnemyMult(); + } + if (game.global.challengeActive == "Storm") { + number *= game.challenges.Storm.getAttackMult(); + } + if (game.global.challengeActive == "Berserk") { + number *= 1.5; + } + if (game.global.challengeActive == "Exterminate") { + number *= game.challenges.Exterminate.getSwarmMult(); + } + if (game.global.challengeActive == "Nurture") { + number *= 2; + if (game.buildings.Laboratory.owned > 0) { + number *= game.buildings.Laboratory.getEnemyMult(); + } + } + if (game.global.challengeActive == "Alchemy") { + number *= ((alchObj.getEnemyStats(false, false)) + 1); + } + if (game.global.challengeActive == "Hypothermia") { + number *= game.challenges.Hypothermia.getEnemyMult(); + } + if (game.global.challengeActive == "Glass") { + number *= game.challenges.Glass.attackMult(); + } + if (!enemy && game.global.usingShriek) { + number *= game.mapUnlocks.roboTrimp.getShriekValue(); + } + return number; +} + +function RcalcEnemyBaseHealth(world, level, name) { + var amt = 0; + var healthBase = (game.global.universe == 2) ? 10e7 : 130; + amt += healthBase * Math.sqrt(world) * Math.pow(3.265, world / 2); + amt -= 110; + if (world == 1 || world == 2 && level < 10) { + amt *= 0.6; + amt = (amt * 0.25) + ((amt * 0.72) * (level / 100)); + } else if (world < 60) + amt = (amt * 0.4) + ((amt * 0.4) * (level / 110)); + else { + amt = (amt * 0.5) + ((amt * 0.8) * (level / 100)); + amt *= Math.pow(1.1, world - 59); + } + if (world < 60) amt *= 0.75; + if (world > 5 && game.global.mapsActive) amt *= 1.1; + amt *= game.badGuys[name].health; + if (game.global.universe == 2) { + var part1 = (world > 60) ? 60 : world; + var part2 = (world - 60); + if (part2 < 0) part2 = 0; + amt *= Math.pow(1.4, part1); + amt *= Math.pow(1.32, part2); + } + return Math.floor(amt); +} + +function RcalcEnemyHealth(world) { + var highest = 1; + var mute = false; + var health; + if (game.global.world > 200 && getPageSetting('Rmutecalc') > 0 && game.global.world >= getPageSetting('Rmutecalc')) { + mute = true; + health = rCalcMutationHealth(); + } + + if (world == false) world = game.global.world; + + if (!mute) health = RcalcEnemyBaseHealth(world, 50, "Snimp"); + + if (game.global.challengeActive == "Extermination" && getPageSetting('Rexterminateon') == true && getPageSetting('Rexterminatecalc') == true) { + health = RcalcEnemyBaseHealth(world, 90, "Beetlimp"); + } + if (game.global.challengeActive == "Daily") { + health = RcalcDailyHealthMod(health); + } + if (game.global.challengeActive == "Unbalance") { + health *= 2; + } + if (game.global.challengeActive == "Quest") { + health *= game.challenges.Quest.getHealthMult(); + } + if (game.global.challengeActive == "Revenge" && game.global.world % 2 == 0) { + health *= 10; + } + if (game.global.challengeActive == "Archaeology") { + + } + if (game.global.challengeActive == "Mayhem") { + health *= game.challenges.Mayhem.getEnemyMult(); + health *= game.challenges.Mayhem.getBossMult(); + } + if (game.global.challengeActive == "Pandemonium") { + health *= game.challenges.Pandemonium.getBossMult(); + } + if (game.global.challengeActive == "Desolation") { + health *= game.challenges.Desolation.getEnemyMult(); + } + if (game.global.challengeActive == "Storm") { + health *= game.challenges.Storm.getHealthMult(); + } + if (game.global.challengeActive == "Berserk") { + health *= 1.5; + } + if (game.global.challengeActive == "Exterminate") { + health *= game.challenges.Exterminate.getSwarmMult(); + } + if (game.global.challengeActive == "Nurture") { + health *= 2; + if (game.buildings.Laboratory.owned > 0) { + health *= game.buildings.Laboratory.getEnemyMult(); + } + } + if (game.global.challengeActive == "Alchemy") { + health *= ((alchObj.getEnemyStats(false, false)) + 1); + } + if (game.global.challengeActive == "Hypothermia") { + health *= game.challenges.Hypothermia.getEnemyMult(); + } + if (game.global.challengeActive == "Glass") { + health *= 0.01; + health *= game.challenges.Glass.healthMult(); + } + if (game.global.challengeActive === 'Smithless') { + if (game.challenges.Smithless.fakeSmithies > 0) health *= Math.pow(1.25, game.challenges.Smithless.fakeSmithies); + } + + return health; +} + +function RcalcEnemyHealthMod(world, cell, name) { + + var highest = 1; + var mute = false; + var health; + if (game.global.world > 200 && getPageSetting('Rmutecalc') > 0 && game.global.world >= getPageSetting('Rmutecalc')) { + mute = true; + health = rCalcMutationHealth(); + } + + if (world == false) world = game.global.world; + + if (!mute) health = RcalcEnemyBaseHealth(world, cell, name); + + if (game.global.challengeActive == "Daily") { + health = RcalcDailyHealthMod(health); + } + if (game.global.challengeActive == "Unbalance") { + health *= 2; + } + if (game.global.challengeActive == "Quest") { + health *= game.challenges.Quest.getHealthMult(); + } + if (game.global.challengeActive == "Revenge" && game.global.world % 2 == 0) { + health *= 10; + } + if (game.global.challengeActive == "Archaeology") { + + } + if (game.global.challengeActive == "Mayhem") { + health *= game.challenges.Mayhem.getEnemyMult(); + health *= game.challenges.Mayhem.getBossMult(); + } + if (game.global.challengeActive == "Pandemonium") { + health *= game.challenges.Pandemonium.getBossMult(); + } + if (game.global.challengeActive == "Desolation") { + health *= game.challenges.Desolation.getEnemyMult(); + } + if (game.global.challengeActive == "Storm") { + health *= game.challenges.Storm.getHealthMult(); + } + if (game.global.challengeActive == "Berserk") { + health *= 1.5; + } + if (game.global.challengeActive == "Exterminate") { + health *= game.challenges.Exterminate.getSwarmMult(); + } + if (game.global.challengeActive == "Nurture") { + health *= 2; + if (game.buildings.Laboratory.owned > 0) { + health *= game.buildings.Laboratory.getEnemyMult(); + } + } + if (game.global.challengeActive == "Alchemy") { + health *= ((alchObj.getEnemyStats(false, false)) + 1); + } + if (game.global.challengeActive == "Hypothermia") { + health *= game.challenges.Hypothermia.getEnemyMult(); + } + if (game.global.challengeActive == "Glass") { + health *= 0.01; + health *= game.challenges.Glass.healthMult(); + } + if (game.global.challengeActive === 'Smithless') { + if (game.challenges.Smithless.fakeSmithies > 0) health *= Math.pow(1.25, game.challenges.Smithless.fakeSmithies); + } + return health; +} + +function RcalcHDratio() { + var ratio = 0; + var ourBaseDamage = RcalcOurDmg("avg", false, true); + + ratio = (RcalcEnemyHealth(game.global.world) / ourBaseDamage); + return ratio; +} + +function getTotalHealthMod() { + var healthMulti = 1; + + // Smithies + healthMulti *= game.buildings.Smithy.getMult(); + + // Perks + healthMulti *= 1 + (game.portal.Toughness.radLevel * game.portal.Toughness.modifier); + healthMulti *= Math.pow(1 + game.portal.Resilience.modifier, game.portal.Resilience.radLevel); + healthMulti *= game.portal.Observation.getMult(); + healthMulti *= game.portal.Championism.getMult(); + + // Scruffy's +50% health bonus + healthMulti *= (Fluffy.isRewardActive("healthy") ? 1.5 : 1); + + // Heirloom Health bonus + healthMulti *= 1 + calcHeirloomBonus('Shield', 'trimpHealth', 1, true) / 100; + + // Golden Upgrades + healthMulti *= 1 + game.goldenUpgrades.Battle.currentBonus; + + // C2/3 + healthMulti *= 1 + game.global.totalSquaredReward / 100; + + // Challenge Multis + healthMulti *= (game.global.challengeActive == 'Revenge') ? game.challenges.Revenge.getMult() : 1; + healthMulti *= (game.global.challengeActive == 'Wither') ? game.challenges.Wither.getTrimpHealthMult() : 1; + healthMulti *= (game.global.challengeActive == 'Insanity') ? game.challenges.Insanity.getHealthMult() : 1; + healthMulti *= (game.global.challengeActive == 'Berserk') ? + (game.challenges.Berserk.frenzyStacks > 0) ? 0.5 : game.challenges.Berserk.getHealthMult(true) : + 1; + healthMulti *= (game.challenges.Nurture.boostsActive() == true) ? game.challenges.Nurture.getStatBoost() : 1; + healthMulti *= (game.global.challengeActive == 'Alchemy') ? alchObj.getPotionEffect("Potion of Strength") : 1; + healthMulti *= (game.global.challengeActive == 'Desolation') ? game.challenges.Desolation.trimpHealthMult() : 1; + + // Daily mod + healthMulti *= (typeof game.global.dailyChallenge.pressure !== 'undefined') ? dailyModifiers.pressure.getMult(game.global.dailyChallenge.pressure.strength, game.global.dailyChallenge.pressure.stacks) : 1; + + // Mayhem + healthMulti *= game.challenges.Mayhem.getTrimpMult(); + + // Panda + healthMulti *= game.challenges.Pandemonium.getTrimpMult(); + + // Deso + healthMulti *= game.challenges.Desolation.getTrimpMult(); + + + //Mutations + if (u2Mutations.tree.Health.purchased) { + healthMulti *= 1.5; + } + if (u2Mutations.tree.GeneHealth.purchased) { + healthMulti *= 10; + } + + // AB + healthMulti *= autoBattle.bonuses.Stats.getMult(); + + // Prismatic + healthMulti *= 1 + getEnergyShieldMult(); + + return healthMulti; +} + +function stormdynamicHD() { + var stormzone = 0; + var stormHD = 0; + var stormmult = 0; + var stormHDzone = 0; + var stormHDmult = 1; + if (getPageSetting('Rstormon') == true && game.global.world > 5 && (game.global.challengeActive == "Storm" && getPageSetting('Rstormzone') > 0 && getPageSetting('RstormHD') > 0 && getPageSetting('Rstormmult') > 0)) { + stormzone = getPageSetting('Rstormzone'); + stormHD = getPageSetting('RstormHD'); + stormmult = getPageSetting('Rstormmult'); + stormHDzone = (game.global.world - stormzone); + stormHDmult = (stormHDzone == 0) ? stormHD : Math.pow(stormmult, stormHDzone) * stormHD; + } + return stormHDmult; +} + +function desodynamicHD() { + var desozone = 0; + var desoHD = 0; + var desomult = 0; + var desoHDzone = 0; + var desoHDmult = 1; + if (getPageSetting('Rdesoon') == true && game.global.world > 5 && (game.global.challengeActive == "Desolation" && getPageSetting('Rdesozone') > 0 && getPageSetting('RdesoHD') > 0 && getPageSetting('Rdesomult') > 0)) { + desozone = getPageSetting('Rdesozone'); + desoHD = getPageSetting('RdesoHD'); + desomult = getPageSetting('Rdesomult'); + desoHDzone = (game.global.world - desozone); + desoHDmult = (desoHDzone == 0) ? desoHD : Math.pow(desomult, desoHDzone) * desoHD; + } + return desoHDmult; +} diff --git a/modules/client-server.js b/modules/client-server.js deleted file mode 100644 index 988cd7ef1..000000000 --- a/modules/client-server.js +++ /dev/null @@ -1,84 +0,0 @@ -/* - * AutoTrimps Client-Server EndPoint Data Transferance script. - * - * March 4.2018 - Simple AT data save endpoint script -- orig by Swiffy - * -*/ -//MODULES["client-server"] = {}; -//The ATServer{} object has 3 commands: GetID(), SaveData(), Upload() -//All Data is uncompressed, unencrypted, plaintext for clarity. No private info is leaked. - -var ATServer = -{ - //SERVER_IP: '207.246.77.188', - SERVER_HOSTNAME: 'https://autotrimps.site/ATendpoint.php' -} - -ATServer.GetID = function(callback) -{ - var req = new XMLHttpRequest(); - - req.onreadystatechange = function() - { - if (this.readyState == 4 && this.status == 200) - { - callback(JSON.parse(req.responseText).data.id); - } - } - - req.open('GET', ATServer.SERVER_HOSTNAME, true); - req.setRequestHeader('req', 'get_id'); - req.send(); -} - -ATServer.SaveData = function(id, data, callback) -{ - var req = new XMLHttpRequest(); - - req.onreadystatechange = function() - { - if (this.readyState == 4 && this.status == 200) - { - callback(JSON.parse(req.responseText)); - } - } - - req.open('POST', ATServer.SERVER_HOSTNAME + '?id=' + id, true); - req.setRequestHeader('req', 'save_data'); - req.setRequestHeader("Content-Type", "application/json"); - req.send(JSON.stringify(data)); -} - -ATServer.Upload = function(data) -{ - ATServer.GetID(function(id) - { - autoTrimpSettings.analyticsID = autoTrimpSettings.analyticsID || id; - //debug("Server generated ID: " + autoTrimpSettings.analyticsID, "other"); - ATServer.SaveData(autoTrimpSettings.analyticsID, data, function(response) - { - debug("Submitted analytics data w/ ID: " + autoTrimpSettings.analyticsID, "other"); - }); - }); -} - -//Data to be uploaded: The version of AutoTrimps and the list of your settings file. Also list of saved/named profiles. -// note to newbs: typing in autoTrimpSettings into console and expanding the arrow will show you what is all in here. -//------------------------------------------------------------------------------------------------------------------- -//TODO: This is part of the ATsettings variable management:, it might make sense to move to that file, splitting here -//------------------------------------------------------------------------------------------------------------------- - -ATServer.UploadSettings = function() { - var loadLastProfiles = localStorage.getItem('ATSelectedSettingsProfile'); - var allProfiles = loadLastProfiles ? JSON.parse(loadLastProfiles) : new Array(); //load the import. - var ulData = { - settings: JSON.parse(serializeSettings()), //Line 41 utils.js - grabs fresh autoTrimpSettings from localstorage, reduces the length and parses it. - profiles: allProfiles, //every saved profile. - modules: MODULES - }; - ATServer.Upload(ulData); - debug("AutoTrimps Settings File was Uploaded for analytics/usage! This is controlled with a new button on AT's Import/Export tab.","general"); -} -if (getPageSetting('allowSettingsUpload')) { - ATServer.UploadSettings(); -} diff --git a/modules/dimgen.js b/modules/dimgen.js deleted file mode 100644 index 1ebea0697..000000000 --- a/modules/dimgen.js +++ /dev/null @@ -1,34 +0,0 @@ -MODULES["dimgen"] = {}; -//This Dimensional Generator has likely been ==DEPRECATED== in favor of Magmite.js which is a complete Magma management system. -// If you choose to enable the simpler one, replace 'magmite' with 'dimgen' on line 32 of AutoTrimps2.js - var ATmodules = [...] -MODULES["dimgen"].FuelOnlyZone = 250; -MODULES["dimgen"].HybridZone = 250; -MODULES["dimgen"].MagmiteZone = 400; -MODULES["dimgen"].FuelOnlyOverclock = false; - -//Initialize Global Vars (dont mess with these ones, nothing good can come from it). -var mapsForFuel = false; - -function autodimgen() { - mapsForFuel = false; - if (game.global.word < 230) { - return; - } - var customVars = MODULES["dimgen"]; - var fuelCap = getGeneratorFuelCap(); - var autoCurrentFuel = game.global.magmaFuel; - var fuelPerCurrentCell = Math.min(game.generatorUpgrades.Supply.modifier, 0.2 + ((game.global.world - 230) * 0.01)) - var wouldOverFuel = (game.permanentGeneratorUpgrades.Storage.owned) ? (autoCurrentFuel > fuelCap + 2) : (2 * fuelPerCurrentCell + autoCurrentFuel > fuelCap - 0.01); - if (game.global.world < customVars.FuelOnlyZone) { - if (game.global.generatorMode != 1) changeGeneratorState(1); - mapsForFuel = wouldOverFuel && !customVars.FuelOnlyOverclock; - } else if (game.global.world < customVars.HybridZone) { - if (wouldOverFuel) { - changeGeneratorState(0); - } else { - changeGeneratorState(1); - } - } else if (game.global.world < customVars.MagmiteZone) { - if (game.global.generatorMode != 0) changeGeneratorState(0); - } -} diff --git a/modules/dynprestige.js b/modules/dynprestige.js index 96f109d82..41cfbeaac 100644 --- a/modules/dynprestige.js +++ b/modules/dynprestige.js @@ -1,64 +1,37 @@ -//MODULES["dynprestige"] = {}; -//These can be changed (in the console) if you know what you're doing: -// MODULES["dynprestige"] - -//Change prestiges as we go (original idea thanks to Hider) -//The idea is like this. We will stick to Dagger until the end of the run, then we will slowly start grabbing prestiges, so we can hit the Prestige we want by the last zone. -//The keywords below "Dagadder" and "GambesOP" are merely representative of the minimum and maximum values. Toggling these on and off, the script will take care of itself, when set to min (Dagger) or max (Gambeson). -//In this way, we will achieve the desired "maxPrestige" setting (which would be somewhere in the middle, like Polearm) by the end of the run. (instead of like in the past where it was gotten from the beginning and wasting time in early maps.) -//Function originally written by Hyppy (in July 2016) -function prestigeChanging2(){ - //find out the equipment index of the prestige we want to hit at the end. - var maxPrestigeIndex = document.getElementById('Prestige').selectedIndex; - // Cancel dynamic prestige logic if maxPrestigeIndex is less than or equal to 2 (dagger) +function prestigeChanging2(){var a=document.getElementById('Prestige').selectedIndex;if(!(2>=a)){var b=getPageSetting('DynamicPrestige2'),c=10b-h&&(game.global.mapBonusa&&(autoTrimpSettings.Prestige.selected='Dagadder')),(game.global.world<=b-h||10==game.global.mapBonus)&&(autoTrimpSettings.Prestige.selected='Dagadder'))}} +function RprestigeChanging2(){ + var maxPrestigeIndex = document.getElementById('RPrestige').selectedIndex; if (maxPrestigeIndex <= 2) return; - - //find out the last zone - var lastzone = getPageSetting("DynamicPrestige2"); - + var lastzone = getPageSetting("RDynamicPrestige2"); var extra = maxPrestigeIndex > 10 ? maxPrestigeIndex - 10 : 0; - - // Find total prestiges needed by determining current prestiges versus the desired prestiges by the end of the run var neededPrestige = 0; for (i = 1; i <= maxPrestigeIndex ; i++){ - var lastp = game.mapUnlocks[autoTrimpSettings.Prestige.list[i]].last; + var lastp = game.mapUnlocks[autoTrimpSettings.RPrestige.list[i]].last; if (lastp <= lastzone - 5){ var rem = lastzone - lastp; var addto = Math.floor(rem/5); - // For Scientist IV bonus, halve the required prestiges to farm if (game.global.sLevel >= 4) addto = Math.ceil(addto/2); neededPrestige += addto; } } - // For Lead runs, we hack this by doubling the neededPrestige to acommodate odd zone-only farming. This might overshoot a bit - if (game.global.challengeActive == 'Lead') - neededPrestige *= 2; - - // Determine the number of zones we want to farm. We will farm 4 maps per zone, then ramp up to 9 maps by the final zone var zonesToFarm = 0; if (neededPrestige == 0){ - autoTrimpSettings.Prestige.selected = document.getElementById('Prestige').value; //revert to selection after final zone reached + autoTrimpSettings.RPrestige.selected = document.getElementById('RPrestige').value; return; } - zonesToFarm = Math.ceil(neededPrestige/maxPrestigeIndex); - - //If we are in the zonesToFarm threshold, kick off the additional prestige maps if(game.global.world > (lastzone-zonesToFarm)){ if (game.global.mapBonus < maxPrestigeIndex) { - //if player has selected arbalest or gambeson but doesn't have them unlocked, just unselect it for them! It's magic! if(game.global.slowDone == true) - autoTrimpSettings.Prestige.selected = "GambesOP"; + autoTrimpSettings.RPrestige.selected = "GambesOP"; else - autoTrimpSettings.Prestige.selected = "Bestplate"; + autoTrimpSettings.RPrestige.selected = "Bestplate"; } else if (game.global.mapBonus > maxPrestigeIndex) - autoTrimpSettings.Prestige.selected = "Dagadder"; + autoTrimpSettings.RPrestige.selected = "Dagadder"; } - - //If we are not in the prestige farming zone (the beginning of the run), use dagger: if (game.global.world <= lastzone-zonesToFarm || game.global.mapBonus == 10) - autoTrimpSettings.Prestige.selected = "Dagadder"; + autoTrimpSettings.RPrestige.selected = "Dagadder"; } diff --git a/modules/equipment.js b/modules/equipment.js index 1df61fea1..44aad6d1b 100644 --- a/modules/equipment.js +++ b/modules/equipment.js @@ -1,13 +1,12 @@ +//Helium + MODULES["equipment"] = {}; -//These can be changed (in the console) if you know what you're doing: -MODULES["equipment"].numHitsSurvived = 10; //survive X hits in D stance or not enough Health. +MODULES["equipment"].numHitsSurvived = 10; MODULES["equipment"].numHitsSurvivedScry = 80; -MODULES["equipment"].enoughDamageCutoff = 4; //above this the game will buy attack equipment -MODULES["equipment"].capDivisor = 10; //Your Equipment cap divided by this will give you the lower cap for liquified and overkilled zones -MODULES["equipment"].alwaysLvl2 = true; //Always buys the 2nd level of equipment. Its the most effective. -MODULES["equipment"].waitTill60 = true; // 'Skip Gear Level 58&59', 'Dont Buy Gear during level 58 and 59, wait till level 60, when cost drops down to 10% -MODULES["equipment"].equipHealthDebugMessage = false; //this repeats a message when you don't have enough health. set to false to stop the spam. - +MODULES["equipment"].capDivisor = 10; +MODULES["equipment"].alwaysLvl2 = getPageSetting('always2'); +MODULES["equipment"].waitTill60 = true; +MODULES["equipment"].equipHealthDebugMessage = false; var equipmentList = { 'Dagger': { Upgrade: 'Dagadder', @@ -94,42 +93,11 @@ var equipmentList = { Equip: false } }; -var mapresourcetojob = {"food": "Farmer", "wood": "Lumberjack", "metal": "Miner", "science": "Scientist"}; //map of resource to jobs +var mapresourcetojob = {"food": "Farmer", "wood": "Lumberjack", "metal": "Miner", "science": "Scientist"}; +function equipEffect(a,b){if(b.Equip)return a[b.Stat+'Calculated'];var c=a.increase.by*a.owned,d=game.upgrades.Gymystic.done?game.upgrades.Gymystic.modifier+0.01*(game.upgrades.Gymystic.done-1):1,e=a.increase.by*(a.owned+1)*d;return e-c} +function equipCost(a,b){var c=parseFloat(getBuildingItemPrice(a,b.Resource,b.Equip,1));return c=b.Equip?Math.ceil(c*Math.pow(1-game.portal.Artisanistry.modifier,game.portal.Artisanistry.level)):Math.ceil(c*Math.pow(1-game.portal.Resourceful.modifier,game.portal.Resourceful.level)),c} +function PrestigeValue(a){var b=game.upgrades[a].prestiges,c=game.equipment[b],d;d=c.blockNow?"block":"undefined"==typeof c.health?"attack":"health";var e=Math.round(c[d]*Math.pow(1.19,c.prestige*game.global.prestige[d]+1));return e} -//Returns the amount of stats that the equipment (or gym) will give when bought. -function equipEffect(gameResource, equip) { - if (equip.Equip) { - return gameResource[equip.Stat + 'Calculated']; - } else { - //That be Gym - var oldBlock = gameResource.increase.by * gameResource.owned; - var Mod = game.upgrades.Gymystic.done ? (game.upgrades.Gymystic.modifier + (0.01 * (game.upgrades.Gymystic.done - 1))) : 1; - var newBlock = gameResource.increase.by * (gameResource.owned + 1) * Mod; - return newBlock - oldBlock; - } -} -//Returns the cost after Artisanistry of a piece of equipment. -function equipCost(gameResource, equip) { - var price = parseFloat(getBuildingItemPrice(gameResource, equip.Resource, equip.Equip, 1)); - if (equip.Equip) - price = Math.ceil(price * (Math.pow(1 - game.portal.Artisanistry.modifier, game.portal.Artisanistry.level))); - else - price = Math.ceil(price * (Math.pow(1 - game.portal.Resourceful.modifier, game.portal.Resourceful.level))); - return price; -} -//Returns the amount of stats that the prestige will give when bought. -function PrestigeValue(what) { - var name = game.upgrades[what].prestiges; - var equipment = game.equipment[name]; - var stat; - if (equipment.blockNow) stat = "block"; - else stat = (typeof equipment.health !== 'undefined') ? "health" : "attack"; - var toReturn = Math.round(equipment[stat] * Math.pow(1.19, ((equipment.prestige) * game.global.prestige[stat]) + 1)); - return toReturn; -} - - -//evaluateEquipmentEfficiency: Back end function for autoLevelEquipment to determine most cost efficient items, and what color they should be. function evaluateEquipmentEfficiency(equipName) { var equip = equipmentList[equipName]; var gameResource = equip.Equip ? game.equipment[equipName] : game.buildings[equipName]; @@ -146,30 +114,25 @@ function evaluateEquipmentEfficiency(equipName) { var StatusBorder = 'white'; var Wall = false; + var BuyWeaponUpgrades = ((getPageSetting('BuyWeaponsNew') == 1) || (getPageSetting('BuyWeaponsNew') == 2)); + var BuyArmorUpgrades = ((getPageSetting('BuyArmorNew') == 1) || (getPageSetting('BuyArmorNew') == 2)); if (!game.upgrades[equip.Upgrade].locked) { - //Evaluating upgrade! var CanAfford = canAffordTwoLevel(game.upgrades[equip.Upgrade]); if (equip.Equip) { var NextEffect = PrestigeValue(equip.Upgrade); - //Scientist 3 and 4 challenge: set metalcost to Infinity so it can buy equipment levels without waiting for prestige. (fake the impossible science cost) - //also Fake set the next cost to infinity so it doesn't wait for prestiges if you have both options disabled. - if ((game.global.challengeActive == "Scientist" && getScientistLevel() > 2) || ((!getPageSetting('BuyArmorUpgrades') && !getPageSetting('BuyWeaponUpgrades')))) + if ((game.global.challengeActive == "Scientist" && getScientistLevel() > 2) || (!BuyWeaponUpgrades && !BuyArmorUpgrades)) var NextCost = Infinity; else var NextCost = Math.ceil(getNextPrestigeCost(equip.Upgrade) * Math.pow(1 - game.portal.Artisanistry.modifier, game.portal.Artisanistry.level)); Wall = (NextEffect / NextCost > Factor); } - //white - Upgrade is not available - //yellow - Upgrade is not affordable - //orange - Upgrade is affordable, but will lower stats - //red - Yes, do it now! if (!CanAfford) { StatusBorder = 'yellow'; } else { if (!equip.Equip) { - //Gymystic is always cool, f*** shield - lol + StatusBorder = 'red'; } else { var CurrEffect = gameResource.level * Effect; @@ -184,47 +147,36 @@ function evaluateEquipmentEfficiency(equipName) { } } } - //what this means: - //wall (don't buy any more equipment, buy prestige first) - //Factor = 0 sets the efficiency to 0 so that it will be disregarded. if not, efficiency will still be somenumber that is cheaper, - // and the algorithm will get stuck on whatever equipment we have capped, and not buy other equipment. - if (game.jobs[mapresourcetojob[equip.Resource]].locked && (game.global.challengeActive != 'Metal')){ - //cap any equips that we haven't unlocked metal for (new/fresh game/level1/no helium code) + if (game.jobs[mapresourcetojob[equip.Resource]].locked && (challengeActive("Metal") == false)) { + Factor = 0; Wall = true; } -//Detecting the liquification through liquimp + var isLiquified = (game.options.menu.liquification.enabled && game.talents.liquification.purchased && !game.global.mapsActive && game.global.gridArray && game.global.gridArray[0] && game.global.gridArray[0].name == "Liquimp"); -//Run a quick Time estimate and if we complete it in 25 seconds or less, use 1/10th of our cap just so we can continue (MODULES["equipment"].capDivisor=10;) - var time = mapTimeEstimater(); - var isQuick = (time!=0) && (time < 25000); - var cap = getPageSetting('CapEquip2'); - if ((isLiquified || isQuick) && cap > 0 && gameResource.level >= (cap / MODULES["equipment"].capDivisor)) { + var cap = 100; + if (equipmentList[equipName].Stat == 'health') cap = getPageSetting('CapEquiparm'); + if (equipmentList[equipName].Stat == 'attack') cap = getPageSetting('CapEquip2'); + if ((isLiquified) && cap > 0 && gameResource.level >= (cap / MODULES["equipment"].capDivisor)) { Factor = 0; Wall = true; - } - //CapEquip2 - else if (cap > 0 && gameResource.level >= cap) { + } else if (cap > 0 && gameResource.level >= cap) { Factor = 0; Wall = true; } - //WaitTill60 (skip58&59 + wait for breaking the planet reduction) (now default) - if (equipName != 'Gym' && game.global.world < 60 && game.global.world >= 58 && MODULES["equipment"].waitTill60){ + if (equipName != 'Gym' && game.global.world < 60 && game.global.world >= 58 && MODULES["equipment"].waitTill60) { Wall = true; } - //AlwaysLvl2 - Was AlwaysArmorLvl2 (now default) - if (gameResource.level < 2 && MODULES["equipment"].alwaysLvl2) { + if (gameResource.level < 2 && getPageSetting('always2') == true) { Factor = 999 - gameResource.prestige; } - //skip buying shields (w/ shieldblock) if we need gymystics if (equipName == 'Shield' && gameResource.blockNow && - game.upgrades['Gymystic'].allowed - game.upgrades['Gymystic'].done > 0) - { - needGymystic = true; - Factor = 0; - Wall = true; - StatusBorder = 'orange'; - } + game.upgrades['Gymystic'].allowed - game.upgrades['Gymystic'].done > 0) { + needGymystic = true; + Factor = 0; + Wall = true; + StatusBorder = 'orange'; + } return { Stat: equip.Stat, Factor: Factor, @@ -236,12 +188,68 @@ function evaluateEquipmentEfficiency(equipName) { var resourcesNeeded; var Best; -//autoLevelEquipment = "Buy Armor", "Buy Armor Upgrades", "Buy Weapons", "Buy Weapons Upgrades" + +function orangewindstack(){(9 0 && game.global.world >= getPageSetting('WindStackingMin') && calcHDratio() < 5) || + (game.global.challengeActive == "Daily" && getEmpowerment() == "Wind" && getPageSetting('dWindStackingMin') > 0 && game.global.world >= getPageSetting('dWindStackingMin') && calcHDratio() < 5) || + (game.global.challengeActive != "Daily" && getPageSetting('wsmax') > 0 && getPageSetting('wsmaxhd') > 0 && game.global.world >= getPageSetting('wsmax') && calcHDratio() < getPageSetting('wsmaxhd')) || + (game.global.challengeActive == "Daily" && getPageSetting('dwsmax') > 0 && getPageSetting('dwsmaxhd') > 0 && game.global.world >= getPageSetting('dwsmax') && calcHDratio() < getPageSetting('dwsmaxhd')) + ) { + if (game.global.challengeActive != "Daily") orangewindstack(); + if (game.global.challengeActive == "Daily") dorangewindstack(); + return false; + } + else return true; +} + +var preBuyAmt2=1; +var preBuyFiring2=1; +var preBuyTooltip2=false; +var preBuymaxSplit2=1; +var preBuyCustomFirst2=1; +var preBuyCustomLast2=1; + +function preBuy3() { + preBuyAmt2 = game.global.buyAmt; + preBuyFiring2 = game.global.firing; + preBuyTooltip2 = game.global.lockTooltip; + preBuymaxSplit2 = game.global.maxSplit; + preBuyCustomFirst2 = game.global.firstCustomAmt; + preBuyCustomLast2 = game.global.lastCustomAmt; +} + +function postBuy3() { + game.global.buyAmt = preBuyAmt2; + game.global.firing = preBuyFiring2; + game.global.lockTooltip = preBuyTooltip2; + game.global.maxSplit = preBuymaxSplit2; + game.global.firstCustomAmt = preBuyCustomFirst2; + game.global.lastCustomAmt = preBuyCustomLast2; +} + function autoLevelEquipment() { - if (!(baseDamage > 0)) return; //if we have no damage, why bother running anything? (this fixes weird bugs) - //if((game.jobs.Miner.locked && game.global.challengeActive != 'Metal') || (game.jobs.Scientist.locked && game.global.challengeActive != "Scientist")) - //return; - resourcesNeeded = {"food": 0, "wood": 0, "metal": 0, "science": 0, "gems": 0}; //list of amount of resources needed for stuff we want to afford + + var gearamounttobuy = (getPageSetting('gearamounttobuy') > 0) ? getPageSetting('gearamounttobuy') : 1; + + //WS + var enoughDamageCutoff = getPageSetting("dmgcuntoff"); + if (getEmpowerment() == 'Wind' && game.global.challengeActive != "Daily" && !game.global.runningChallengeSquared && getPageSetting("AutoStance") == 3 && getPageSetting("WindStackingMin") > 0 && game.global.world >= getPageSetting("WindStackingMin") && getPageSetting("windcutoff") > 0) + enoughDamageCutoff = getPageSetting("windcutoff"); + if (getEmpowerment() == 'Wind' && game.global.challengeActive == "Daily" && !game.global.runningChallengeSquared && (getPageSetting("AutoStance") == 3 || getPageSetting("use3daily") == true) && getPageSetting("dWindStackingMin") > 0 && game.global.world >= getPageSetting("dWindStackingMin") && getPageSetting("dwindcutoff") > 0) + enoughDamageCutoff = getPageSetting("dwindcutoff"); + + if (calcOurDmg("avg", false, true) <= 0) return; + resourcesNeeded = { + "food": 0, + "wood": 0, + "metal": 0, + "science": 0, + "gems": 0 + }; Best = {}; var keys = ['healthwood', 'healthmetal', 'attackmetal', 'blockwood']; for (var i = 0; i < keys.length; i++) { @@ -253,65 +261,39 @@ function autoLevelEquipment() { Cost: 0 }; } -//EQUIPMENT HAS ITS OWN DAMAGE CALC SECTION: - var enemyDamage = getEnemyMaxAttack(game.global.world + 1, 50, 'Snimp', 1.2); - enemyDamage = calcDailyAttackMod(enemyDamage); //daily mods: badStrength,badMapStrength,bloodthirst - var enemyHealth = getEnemyMaxHealth(game.global.world + 1); - //Take Spire as a special case. - var spirecheck = isActiveSpireAT(); - if (spirecheck) { - var exitcell = getPageSetting('ExitSpireCell'); - var cell = (!game.global.mapsActive && !game.global.preMapsActive) ? game.global.lastClearedCell : 50; - if (exitcell > 1) - cell = exitcell; - enemyDamage = getSpireStats(cell, "Snimp", "attack"); - enemyDamage = calcDailyAttackMod(enemyDamage); //daily mods: badStrength,badMapStrength,bloodthirst - enemyHealth = getSpireStats(cell, "Snimp", "health"); - } - - //below challenge multiplier not necessarily accurate, just fudge factors - if(game.global.challengeActive == "Toxicity") { - //ignore damage changes (which would effect how much health we try to buy) entirely since we die in 20 attacks anyway? - if(game.global.world < 61) - enemyDamage *= 2; - enemyHealth *= 2; - } - if(game.global.challengeActive == 'Lead') { - enemyDamage *= 2.5; - enemyHealth *= 7; + var ourDamage = calcOurDmg("avg", false, true); + var mapbonusmulti = 1 + (0.20 * game.global.mapBonus); + if (game.global.mapBonus > 0) { + ourDamage *= mapbonusmulti; + } + if (challengeActive("Lead")) { + if (game.global.world % 2 == 1 && game.global.world != 179) { + ourDamage /= 1.5; + } } + //Shield + highDamageShield(); + if (getPageSetting('loomswap') > 0 && game.global.challengeActive != "Daily" && game.global.ShieldEquipped.name != getPageSetting('highdmg')) + ourDamage *= trimpAA; + if (getPageSetting('dloomswap') > 0 && game.global.challengeActive == "Daily" && game.global.ShieldEquipped.name != getPageSetting('dhighdmg')) + ourDamage *= trimpAA; + + + var enemyDamage = calcBadGuyDmg(null, getEnemyMaxAttack(game.global.world + 1, 50, 'Snimp', 1.0), true, true); + var enemyHealth = calcEnemyHealth(); var pierceMod = (game.global.brokenPlanet && !game.global.mapsActive) ? getPierceAmt() : 0; - //change name to make sure these are local to the function - var enoughHealthE,enoughDamageE; - const FORMATION_MOD_1 = game.upgrades.Dominance.done ? 2 : 1; - //const FORMATION_MOD_2 = game.upgrades.Dominance.done ? 4 : 1; - var numHits = MODULES["equipment"].numHitsSurvived; //this can be changed. - var numHitsScry = MODULES["equipment"].numHitsSurvivedScry; - var min_zone = getPageSetting('ScryerMinZone'); - var max_zone = getPageSetting('ScryerMaxZone'); - var valid_min = game.global.world >= min_zone; - var valid_max = max_zone <= 0 || game.global.world < max_zone; - //asks if we can survive x number of hits in either D stance or X stance. - enoughHealthE = !(doVoids && voidCheckPercent > 0) && - (baseHealth/FORMATION_MOD_1 > numHits * (enemyDamage - baseBlock/FORMATION_MOD_1 > 0 ? enemyDamage - baseBlock/FORMATION_MOD_1 : enemyDamage * pierceMod)) && - (!(valid_min && valid_max) || (baseHealth/2 > numHitsScry * (enemyDamage - baseBlock/2 > 0 ? enemyDamage - baseBlock/2 : enemyDamage * pierceMod))); - enoughDamageE = (baseDamage * MODULES["equipment"].enoughDamageCutoff > enemyHealth); - if (!enoughHealthE && MODULES["equipment"].equipHealthDebugMessage) - debug("Equipment module thought there was not enough health","equips"); - -//PRESTIGE and UPGRADE SECTION: + var numHits = MODULES["equipment"].numHitsSurvived; + var enoughHealthE = (calcOurHealth(true) > numHits * (enemyDamage - calcOurBlock(true) > 0 ? enemyDamage - calcOurBlock(true) : enemyDamage * pierceMod)); + var enoughDamageE = (ourDamage * enoughDamageCutoff > enemyHealth); + for (var equipName in equipmentList) { var equip = equipmentList[equipName]; - // debug('Equip: ' + equip + ' EquipIndex ' + equipName); var gameResource = equip.Equip ? game.equipment[equipName] : game.buildings[equipName]; - // debug('Game Resource: ' + gameResource); if (!gameResource.locked) { var $equipName = document.getElementById(equipName); - $equipName.style.color = 'white'; //reset + $equipName.style.color = 'white'; var evaluation = evaluateEquipmentEfficiency(equipName); - // debug(equipName + ' evaluation ' + evaluation.StatusBorder); var BKey = equip.Stat + equip.Resource; - // debug(equipName + ' bkey ' + BKey); if (Best[BKey].Factor === 0 || Best[BKey].Factor < evaluation.Factor) { Best[BKey].Factor = evaluation.Factor; @@ -320,14 +302,8 @@ function autoLevelEquipment() { Best[BKey].StatusBorder = evaluation.StatusBorder; } Best[BKey].Cost = evaluation.Cost; - //add up whats needed: resourcesNeeded[equip.Resource] += Best[BKey].Cost; - - //Apply colors from before: - //white - Upgrade is not available - //yellow - Upgrade is not affordable (or capped) - //orange - Upgrade is affordable, but will lower stats - //red - Yes, do it now! + if (evaluation.Wall) $equipName.style.color = 'yellow'; $equipName.style.border = '1px solid ' + evaluation.StatusBorder; @@ -335,7 +311,7 @@ function autoLevelEquipment() { var $equipUpgrade = document.getElementById(equip.Upgrade); if (evaluation.StatusBorder != 'white' && evaluation.StatusBorder != 'yellow' && $equipUpgrade) $equipUpgrade.style.color = evaluation.StatusBorder; - if (evaluation.StatusBorder == 'yellow' && $equipUpgrade) + if (evaluation.StatusBorder == 'yellow' && $equipUpgrade) $equipUpgrade.style.color = 'white'; if (equipName == 'Gym' && needGymystic) { $equipName.style.color = 'white'; @@ -346,33 +322,25 @@ function autoLevelEquipment() { } } - - //Code is Spaced This Way So You Can Read It: - if (evaluation.StatusBorder == 'red' && !(game.global.world < 60 && game.global.world >= 58 && MODULES["equipment"].waitTill60)) { - var BuyWeaponUpgrades = getPageSetting('BuyWeaponUpgrades'); - var BuyArmorUpgrades = getPageSetting('BuyArmorUpgrades'); + if (evaluation.StatusBorder == 'red' && windstackingprestige() && !(game.global.world < 60 && game.global.world >= 58 && MODULES["equipment"].waitTill60)) { + var BuyWeaponUpgrades = ((getPageSetting('BuyWeaponsNew') == 1) || (getPageSetting('BuyWeaponsNew') == 2)); + var BuyArmorUpgrades = ((getPageSetting('BuyArmorNew') == 1) || (getPageSetting('BuyArmorNew') == 2)); var DelayArmorWhenNeeded = getPageSetting('DelayArmorWhenNeeded'); - if - ( - ( BuyWeaponUpgrades && equipmentList[equipName].Stat == 'attack' ) - || - ( BuyWeaponUpgrades && equipmentList[equipName].Stat == 'block' ) - || - ( BuyArmorUpgrades && equipmentList[equipName].Stat == 'health' && - //Only buy Armor prestiges when 'DelayArmorWhenNeeded' is on, IF: + + if ( + (BuyWeaponUpgrades && equipmentList[equipName].Stat == 'attack') || + (BuyWeaponUpgrades && equipmentList[equipName].Stat == 'block') || + (BuyArmorUpgrades && equipmentList[equipName].Stat == 'health' && ( - ( DelayArmorWhenNeeded && !shouldFarm) // not during "Farming" mode - || // or - ( DelayArmorWhenNeeded && enoughDamageE) // has enough damage (not in "Wants more Damage" mode) - || // or - ( DelayArmorWhenNeeded && !enoughDamageE && !enoughHealthE) // if neither enough dmg or health, then tis ok to buy. - || - ( DelayArmorWhenNeeded && equipmentList[equipName].Resource == 'wood') - || - ( !DelayArmorWhenNeeded) //or when its off. + (DelayArmorWhenNeeded && !shouldFarm) || + (DelayArmorWhenNeeded && enoughDamageE) || + (DelayArmorWhenNeeded && !enoughDamageE && !enoughHealthE) || + (DelayArmorWhenNeeded && equipmentList[equipName].Resource == 'wood') || + (!DelayArmorWhenNeeded) ) ) ) + { var upgrade = equipmentList[equipName].Upgrade; if (upgrade != "Gymystic") @@ -380,22 +348,21 @@ function autoLevelEquipment() { else debug('Upgrading ' + upgrade + " # " + game.upgrades[upgrade].allowed, "equips", '*upload'); buyUpgrade(upgrade, true, true); - } - else { + } else { $equipName.style.color = 'orange'; $equipName.style.border = '2px solid orange'; } } } } - //(same function) -//LEVELING EQUIPMENT SECTION: - preBuy(); - game.global.buyAmt = 1; //needed for buyEquipment() + + var BuyWeaponLevels = ((getPageSetting('BuyWeaponsNew') == 1) || (getPageSetting('BuyWeaponsNew') == 3)); + var BuyArmorLevels = ((getPageSetting('BuyArmorNew') == 1) || (getPageSetting('BuyArmorNew') == 3)); + preBuy3(); for (var stat in Best) { var eqName = Best[stat].Name; - var $eqName = document.getElementById(eqName); if (eqName !== '') { + var $eqName = document.getElementById(eqName); var DaThing = equipmentList[eqName]; if (eqName == 'Gym' && needGymystic) { $eqName.style.color = 'white'; @@ -405,45 +372,782 @@ function autoLevelEquipment() { $eqName.style.color = Best[stat].Wall ? 'orange' : 'red'; $eqName.style.border = '2px solid red'; } - //If we are doing the MaxMapBonusAfterZone stuff, equipment should be upgraded to its cap. var maxmap = getPageSetting('MaxMapBonusAfterZone') && doMaxMapBonus; - //If we're considering an attack item, we want to buy weapons if we don't have enough damage, or if we don't need health (so we default to buying some damage) - if (getPageSetting('BuyWeapons') && DaThing.Stat == 'attack' && (!enoughDamageE || enoughHealthE || maxmap || spirecheck)) { + if (BuyArmorLevels && (DaThing.Stat == 'health' || DaThing.Stat == 'block') && (!enoughHealthE || maxmap)) { + game.global.buyAmt = gearamounttobuy; if (DaThing.Equip && !Best[stat].Wall && canAffordBuilding(eqName, null, null, true)) { debug('Leveling equipment ' + eqName, "equips", '*upload3'); buyEquipment(eqName, null, true); } } - //If we're considering a health item, buy it if we don't have enough health, otherwise we default to buying damage - if (getPageSetting('BuyArmor') && (DaThing.Stat == 'health' || DaThing.Stat == 'block') && (!enoughHealthE || maxmap || spirecheck)) { + var aalvl2 = getPageSetting('always2'); + if (BuyArmorLevels && (DaThing.Stat == 'health') && aalvl2 && game.equipment[eqName].level < 2) { + game.global.buyAmt = 1; if (DaThing.Equip && !Best[stat].Wall && canAffordBuilding(eqName, null, null, true)) { - debug('Leveling equipment ' + eqName, "equips", '*upload3'); + debug('Leveling equipment ' + eqName + " (AlwaysLvl2)", "equips", '*upload3'); buyEquipment(eqName, null, true); } } - var aalvl2 = MODULES["equipment"].alwaysLvl2; //getPageSetting('AlwaysArmorLvl2'); - if (getPageSetting('BuyArmor') && (DaThing.Stat == 'health') && aalvl2 && game.equipment[eqName].level < 2){ + if (windstackingprestige() && BuyWeaponLevels && DaThing.Stat == 'attack' && (!enoughDamageE || enoughHealthE || maxmap)) { + game.global.buyAmt = gearamounttobuy; if (DaThing.Equip && !Best[stat].Wall && canAffordBuilding(eqName, null, null, true)) { - debug('Leveling equipment ' + eqName + " (AlwaysLvl2)", "equips", '*upload3'); + debug('Leveling equipment ' + eqName, "equips", '*upload3'); buyEquipment(eqName, null, true); } } } } - postBuy(); + postBuy3(); } +function areWeAttackLevelCapped(){var a=[];for(var b in equipmentList){var c=equipmentList[b],d=c.Equip?game.equipment[b]:game.buildings[b];if(!d.locked){var e=evaluateEquipmentEfficiency(b);"attack"==e.Stat&&a.push(e)}}return a.every(f=>0==f.Factor&&!0==f.Wall)} -//check if we have cap to 10 equip on, and we are capped for all attack weapons -function areWeAttackLevelCapped() { - var attack = []; - for (var equipName in equipmentList) { - var equip = equipmentList[equipName]; - var gameResource = equip.Equip ? game.equipment[equipName] : game.buildings[equipName]; +//Radon + +MODULES["equipment"].RnumHitsSurvived = 10; +MODULES["equipment"].RnumHitsSurvivedScry = 80; +MODULES["equipment"].RcapDivisor = 10; +MODULES["equipment"].RequipHealthDebugMessage = false; +var RequipmentList = { + 'Dagger': { + Upgrade: 'Dagadder', + Stat: 'attack', + Resource: 'metal', + Equip: true + }, + 'Mace': { + Upgrade: 'Megamace', + Stat: 'attack', + Resource: 'metal', + Equip: true + }, + 'Polearm': { + Upgrade: 'Polierarm', + Stat: 'attack', + Resource: 'metal', + Equip: true + }, + 'Battleaxe': { + Upgrade: 'Axeidic', + Stat: 'attack', + Resource: 'metal', + Equip: true + }, + 'Greatsword': { + Upgrade: 'Greatersword', + Stat: 'attack', + Resource: 'metal', + Equip: true + }, + 'Boots': { + Upgrade: 'Bootboost', + Stat: 'health', + Resource: 'metal', + Equip: true + }, + 'Helmet': { + Upgrade: 'Hellishmet', + Stat: 'health', + Resource: 'metal', + Equip: true + }, + 'Pants': { + Upgrade: 'Pantastic', + Stat: 'health', + Resource: 'metal', + Equip: true + }, + 'Shoulderguards': { + Upgrade: 'Smoldershoulder', + Stat: 'health', + Resource: 'metal', + Equip: true + }, + 'Breastplate': { + Upgrade: 'Bestplate', + Stat: 'health', + Resource: 'metal', + Equip: true + }, + 'Arbalest': { + Upgrade: 'Harmbalest', + Stat: 'attack', + Resource: 'metal', + Equip: true + }, + 'Gambeson': { + Upgrade: 'GambesOP', + Stat: 'health', + Resource: 'metal', + Equip: true + }, + 'Shield': { + Upgrade: 'Supershield', + Stat: 'health', + Resource: 'wood', + Equip: true + } +}; + +var Rmapresourcetojob = {"food": "Farmer", "wood": "Lumberjack", "metal": "Miner", "science": "Scientist"}; + +function RequipEffect(gameResource, equip) { + if (equip.Equip) { + return gameResource[equip.Stat + 'Calculated']; + } +} + +function RequipCost(gameResource, equip) { + var price = parseFloat(getBuildingItemPrice(gameResource, equip.Resource, equip.Equip, 1)); + if (equip.Equip) + price = Math.ceil(price * (Math.pow(1 - game.portal.Artisanistry.modifier, game.portal.Artisanistry.radLevel))); + price *= autoBattle.oneTimers.Artisan.owned ? autoBattle.oneTimers.Artisan.getMult() : 1; + if (game.global.challenges == "Pandemonium") price *= game.challenges.Pandemonium.getEnemyMult(); + /*else + price = Math.ceil(price * (Math.pow(1 - game.portal.Resourceful.modifier, game.portal.Resourceful.radLevel)));*/ + return price; +} + +function RPrestigeValue(what) { + var name = game.upgrades[what].prestiges; + var equipment = game.equipment[name]; + var stat; + stat = (typeof equipment.health !== 'undefined') ? "health" : "attack"; + var toReturn = Math.round(equipment[stat] * Math.pow(1.19, ((equipment.prestige) * game.global.prestige[stat]) + 1)); + return toReturn; +} + +function RevaluateEquipmentEfficiency(equipName) { + var equip = RequipmentList[equipName]; + var gameResource = equip.Equip ? game.equipment[equipName] : game.buildings[equipName]; + var Effect = equipEffect(gameResource, equip); + var Cost = equipCost(gameResource, equip); + var Factor = Effect / Cost; + var StatusBorder = 'white'; + var Wall = false; + + var BuyWeaponUpgrades = ((getPageSetting('RBuyWeaponsNew') == 1) || (getPageSetting('RBuyWeaponsNew') == 2)); + var BuyArmorUpgrades = ((getPageSetting('RBuyArmorNew') == 1) || (getPageSetting('RBuyArmorNew') == 2)); + if (!game.upgrades[equip.Upgrade].locked) { + var CanAfford = canAffordTwoLevel(game.upgrades[equip.Upgrade]); + if (equip.Equip) { + var NextEffect = PrestigeValue(equip.Upgrade); + var NextCost = Math.ceil(getNextPrestigeCost(equip.Upgrade) * Math.pow(1 - game.portal.Artisanistry.modifier, game.portal.Artisanistry.radLevel)); + Wall = (NextEffect / NextCost > Factor); + } + + if (!CanAfford) { + StatusBorder = 'yellow'; + } else { + if (!equip.Equip) { + + StatusBorder = 'red'; + } else { + var CurrEffect = gameResource.level * Effect; + var NeedLevel = Math.ceil(CurrEffect / NextEffect); + var Ratio = gameResource.cost[equip.Resource][1]; + var NeedResource = NextCost * (Math.pow(Ratio, NeedLevel) - 1) / (Ratio - 1); + if (game.resources[equip.Resource].owned > NeedResource) { + StatusBorder = 'red'; + } else { + StatusBorder = 'orange'; + } + } + } + } + if (game.jobs[Rmapresourcetojob[equip.Resource]].locked && (game.global.challengeActive != 'Transmute')) { + Factor = 0; + Wall = true; + } + + var isLiquified = (game.options.menu.liquification.enabled && game.talents.liquification.purchased && !game.global.mapsActive && game.global.gridArray && game.global.gridArray[0] && game.global.gridArray[0].name == "Liquimp"); + var cap = 100; + if (RequipmentList[equipName].Stat == 'health') cap = getPageSetting('RCapEquiparm'); + if (RequipmentList[equipName].Stat == 'attack') cap = getPageSetting('RCapEquip2'); + if ((isLiquified) && cap > 0 && gameResource.level >= (cap / MODULES["equipment"].RcapDivisor)) { + Factor = 0; + Wall = true; + } else if (cap > 0 && gameResource.level >= cap) { + Factor = 0; + Wall = true; + } + if (gameResource.level < 2 && getPageSetting('Ralways2')) { + Factor = 999 - gameResource.prestige; + } + return { + Stat: equip.Stat, + Factor: Factor, + StatusBorder: StatusBorder, + Wall: Wall, + Cost: Cost + }; +} + +var RresourcesNeeded; +var RBest; +var RpreBuyAmt2=1; +var RpreBuyFiring2=1; +var RpreBuyTooltip2=false; +var RpreBuymaxSplit2=1; +var RpreBuyCustomFirst2=1; +var RpreBuyCustomLast2=1; + +function RpreBuy3() { + RpreBuyAmt2 = game.global.buyAmt; + RpreBuyFiring2 = game.global.firing; + RpreBuyTooltip2 = game.global.lockTooltip; + RpreBuymaxSplit2 = game.global.maxSplit; + RpreBuyCustomFirst2 = game.global.firstCustomAmt; + RpreBuyCustomLast2 = game.global.lastCustomAmt; +} + +function RpostBuy3() { + game.global.buyAmt = RpreBuyAmt2; + game.global.firing = RpreBuyFiring2; + game.global.lockTooltip = RpreBuyTooltip2; + game.global.maxSplit = RpreBuymaxSplit2; + game.global.firstCustomAmt = RpreBuyCustomFirst2; + game.global.lastCustomAmt = RpreBuyCustomLast2; +} + +function RautoLevelEquipment() { + var Rgearamounttobuy = (getPageSetting('Rgearamounttobuy') > 0) ? getPageSetting('Rgearamounttobuy') : 1; + + if (RcalcOurDmg("avg", false, true) <= 0) return; + RresourcesNeeded = { + "food": 0, + "wood": 0, + "metal": 0, + "science": 0, + "gems": 0 + }; + RBest = {}; + var keys = ['healthwood', 'healthmetal', 'attackmetal']; + for (var i = 0; i < keys.length; i++) { + RBest[keys[i]] = { + Factor: 0, + Name: '', + Wall: false, + StatusBorder: 'white', + Cost: 0 + }; + } + var enemyDamage = RcalcBadGuyDmg(null, RgetEnemyMaxAttack(game.global.world, 50, 'Snimp', 1.0)); + var enoughDamageCutoff = getPageSetting("Rdmgcuntoff"); + var numHits = getPageSetting('Rhitssurvived'); + var enoughHealthE = (RcalcOurHealth(true) > numHits * enemyDamage); + var enoughDamageE = (RcalcHDratio() <= enoughDamageCutoff); + + for (var equipName in RequipmentList) { + var equip = RequipmentList[equipName]; + var gameResource = game.equipment[equipName]; if (!gameResource.locked) { - var evaluation = evaluateEquipmentEfficiency(equipName); - if (evaluation.Stat == "attack") - attack.push(evaluation); + var $equipName = document.getElementById(equipName); + $equipName.style.color = 'white'; + var evaluation = RevaluateEquipmentEfficiency(equipName); + var BKey = equip.Stat + equip.Resource; + + if (RBest[BKey].Factor === 0 || RBest[BKey].Factor < evaluation.Factor) { + RBest[BKey].Factor = evaluation.Factor; + RBest[BKey].Name = equipName; + RBest[BKey].Wall = evaluation.Wall; + RBest[BKey].StatusBorder = evaluation.StatusBorder; + } + RBest[BKey].Cost = evaluation.Cost; + RresourcesNeeded[equip.Resource] += RBest[BKey].Cost; + + if (evaluation.Wall) + $equipName.style.color = 'yellow'; + $equipName.style.border = '1px solid ' + evaluation.StatusBorder; + + var $equipUpgrade = document.getElementById(equip.Upgrade); + if (evaluation.StatusBorder != 'white' && evaluation.StatusBorder != 'yellow' && $equipUpgrade) + $equipUpgrade.style.color = evaluation.StatusBorder; + if (evaluation.StatusBorder == 'yellow' && $equipUpgrade) + $equipUpgrade.style.color = 'white'; + if (evaluation.StatusBorder == 'red') { + var BuyWeaponUpgrades = ((getPageSetting('RBuyWeaponsNew') == 1) || (getPageSetting('RBuyWeaponsNew') == 2)); + var BuyArmorUpgrades = ((getPageSetting('RBuyArmorNew') == 1) || (getPageSetting('RBuyArmorNew') == 2)); + var DelayArmorWhenNeeded = getPageSetting('RDelayArmorWhenNeeded'); + + if ( + (BuyWeaponUpgrades && RequipmentList[equipName].Stat == 'attack') || + (BuyArmorUpgrades && RequipmentList[equipName].Stat == 'health' && + ( + (DelayArmorWhenNeeded && !shouldFarm) || + (DelayArmorWhenNeeded && enoughDamageE) || + (DelayArmorWhenNeeded && !enoughDamageE && !enoughHealthE) || + (DelayArmorWhenNeeded && RequipmentList[equipName].Resource == 'wood') || + (!DelayArmorWhenNeeded) + ) + ) + ) + + { + var upgrade = RequipmentList[equipName].Upgrade; + debug('Upgrading ' + upgrade + " - Prestige " + game.equipment[equipName].prestige, "equips", '*upload'); + buyUpgrade(upgrade, true, true); + } else { + $equipName.style.color = 'orange'; + $equipName.style.border = '2px solid orange'; + } + } + } + } + + var BuyWeaponLevels = ((getPageSetting('RBuyWeaponsNew') == 1) || (getPageSetting('RBuyWeaponsNew') == 3)); + var BuyArmorLevels = ((getPageSetting('RBuyArmorNew') == 1) || (getPageSetting('RBuyArmorNew') == 3)); + RpreBuy3(); + for (var stat in RBest) { + var eqName = RBest[stat].Name; + if (eqName !== '') { + var $eqName = document.getElementById(eqName); + var DaThing = RequipmentList[eqName]; + $eqName.style.color = RBest[stat].Wall ? 'orange' : 'red'; + $eqName.style.border = '2px solid red'; + var maxmap = getPageSetting('RMaxMapBonusAfterZone') && RdoMaxMapBonus; + if (BuyArmorLevels && DaThing.Stat == 'health' && (!enoughHealthE || maxmap)) { + game.global.buyAmt = Rgearamounttobuy + if (smithylogic(eqName, 'metal', true) && DaThing.Equip && !RBest[stat].Wall && canAffordBuilding(eqName, null, null, true)) { + debug('Leveling equipment ' + eqName, "equips", '*upload3'); + buyEquipment(eqName, null, true); + } + } + var aalvl2 = getPageSetting('Ralways2'); + if (BuyArmorLevels && (DaThing.Stat == 'health') && aalvl2 && game.equipment[eqName].level < 2) { + game.global.buyAmt = 1; + if (smithylogic(eqName, 'metal', true) && DaThing.Equip && !RBest[stat].Wall && canAffordBuilding(eqName, null, null, true)) { + debug('Leveling equipment ' + eqName + " (AlwaysLvl2)", "equips", '*upload3'); + buyEquipment(eqName, null, true); + } + } + if (BuyWeaponLevels && DaThing.Stat == 'attack' && (!enoughDamageE || enoughHealthE || maxmap)) { + game.global.buyAmt = Rgearamounttobuy + if (smithylogic(eqName, 'metal', true) && DaThing.Equip && !RBest[stat].Wall && canAffordBuilding(eqName, null, null, true)) { + debug('Leveling equipment ' + eqName, "equips", '*upload3'); + buyEquipment(eqName, null, true); + } + } + } + } + RpostBuy3(); +} + +function RareWeAttackLevelCapped(){var a=[];for(var b in RequipmentList){var c=RequipmentList[b],d=c.Equip?game.equipment[b]:game.buildings[b];if(!d.locked){var e=RevaluateEquipmentEfficiency(b);"attack"==e.Stat&&a.push(e)}}return a.every(f=>0==f.Factor&&!0==f.Wall)} + +function Rgetequips(map, special) { //(level, p b or false) + var specialCount = 0; + var unlocksObj; + var world; + var prestigeArray = []; + var hasPrestigious = false; + unlocksObj = game.mapUnlocks; + if (special == 'p' || (special == 'b' && game.talents.bionic2.purchased)) { + hasPrestigious = true; + } + var Rlocation; + if (special == 'p' || special == false) { + Rlocation = "Plentiful"; + } + if (special == 'b') { + Rlocation = "Bionic"; + } + world = map; + var canLast = 1; + var prestigeItemsAvailable = []; + for (var item in unlocksObj) { + var special = unlocksObj[item]; + if (!special.prestige) continue; + if (special.locked) continue; + if (game.global.universe == 2 && special.blockU2) continue; + if (game.global.universe == 1 && special.blockU1) continue; + if (special.brokenPlanet && ((special.brokenPlanet == 1 && !game.global.brokenPlanet) || special.brokenPlanet == -1 && game.global.brokenPlanet)) continue; + if (special.startAt < 0) continue; + if (special.lastAt < game.global.world) continue; + if ((special.filterUpgrade)) { + var mapConfigLoc = game.mapConfig.locations[Rlocation]; + if (typeof mapConfigLoc.upgrade === 'object') { + var usable = false; + for (var x = 0; x < mapConfigLoc.upgrade.length; x++) { + if (mapConfigLoc.upgrade[x] != item) continue; + usable = true; + break; + } + if (!usable) continue; + } else if (mapConfigLoc.upgrade != item) continue; + } + if ((special.level == "last" && canLast > 0 && special.world <= world && (special.canRunOnce || special.canRunWhenever))) { + if (canLast == 2 && !special.prestige) continue; + if (typeof special.specialFilter !== 'undefined') { + if (!special.specialFilter(world)) continue; + } + if (special.startAt > world) continue; + specialCount++; + continue; + if (hasPrestigious && canLast == 1 && item == "roboTrimp") + canLast = 3; + else + canLast = 0; + continue; + } + + if (special.world != world && special.world > 0) continue; + if ((special.world == -2) && ((world % 2) !== 0)) continue; + if ((special.world == -3) && ((world % 2) != 1)) continue; + if ((special.world == -5) && ((world % 5) !== 0)) continue; + if ((special.world == -33) && ((world % 3) !== 0)) continue; + if ((special.world == -10) && ((world % 10) !== 0)) continue; + if ((special.world == -20) && ((world % 20) !== 0)) continue; + if ((special.world == -25) && ((world % 25) !== 0)) continue; + if (typeof special.specialFilter !== 'undefined') { + if (!special.specialFilter(world)) continue; + } + if ((typeof special.startAt !== 'undefined') && (special.startAt > world)) continue; + if (typeof special.canRunOnce === 'undefined' && (special.level == "last") && canLast > 0 && (special.last <= (world - 5))) { + specialCount += Math.floor((world - special.last) / 5); + continue; + } + if (special.level == "last") continue; + if (special.canRunOnce === true) { + specialCount++; + continue; + } else if (special.addToCount) specialCount++; + } + return specialCount; +} + +//barakatx2 +const prestigeZones = [["Supershield","Dagadder","Bootboost"], ["Megamace", "Hellishmet"], ["Polierarm", "Pantastic"], ["Axeidic", "Smoldershoulder"], ["Greatersword", "Harmbalest", "Bestplate", "GambesOP"]] + function attainablePrestiges(zone) { + const baseExpectedPrestigesAvailable = Math.floor(zone / 10) * 2 - 1 + const prestigeZoneOffset = Math.floor(Math.min(zone % 10, 5)) + var attainablePrestiges = 0 + for (var i = 1; i <= prestigeZoneOffset; i++) { + prestigeZones[i-1].forEach(prestige => { + attainablePrestiges += baseExpectedPrestigesAvailable + 2 - game.upgrades[prestige].allowed + }) + } + return attainablePrestiges / 2 + } + +//Shol Territory + +function mostEfficientEquipment(fakeLevels = {}) { + + for (var i in RequipmentList) { + if (typeof fakeLevels[i] === 'undefined') { + fakeLevels[i] = 0; + } + } + + var mostEfficient = [ + { + name: "", + statPerResource: -Infinity, + }, + { + name: "", + statPerResource: -Infinity, + } + ]; + + var artBoost = Math.pow(1 - game.portal.Artisanistry.modifier, game.portal.Artisanistry.radLevel); + artBoost *= autoBattle.oneTimers.Artisan.owned ? autoBattle.oneTimers.Artisan.getMult() : 1; + if (game.global.challenges == "Pandemonium") artBoost *= game.challenges.Pandemonium.getEnemyMult(); + + for (var i in RequipmentList) { + var nextLevelCost = game.equipment[i].cost[RequipmentList[i].Resource][0] * Math.pow(game.equipment[i].cost[RequipmentList[i].Resource][1], game.equipment[i].level + fakeLevels[i]) * artBoost; + if (game.global.challengeActive == "Pandemonium" && game.challenges.Pandemonium.isEquipBlocked(i)) { + continue; + } + + var nextLevelValue = game.equipment[i][RequipmentList[i].Stat + "Calculated"]; + + var isAttack = (RequipmentList[i].Stat === 'attack' ? 0 : 1); + + var safeRatio = Math.log(nextLevelValue + 1) / Math.log(nextLevelCost + 1); + if (safeRatio > mostEfficient[isAttack].statPerResource) { + mostEfficient[isAttack].name = i; + mostEfficient[isAttack].statPerResource = safeRatio; + } + + } + + return [mostEfficient[0].name, mostEfficient[1].name]; + +} + +function Requipcalc(capattack, caphealth, level2, zonego, attack, health, name, resource, stat, source, amount, percent) { + + if (canAffordBuilding(name, null, null, true, false, amount) && smithylogic(name, resource, true) && + ( + (stat == 'a' && game.equipment[name].level < capattack) || + (stat == 'h' && game.equipment[name].level < caphealth) + ) && + ( + (level2 && game.equipment[name].level == 1) || + (zonego) || + (Rgetequipcost(name, resource, amount) <= (percent * source)) || + ((stat == 'a' && !attack) || (stat == 'h' && !health)) + ) + ) { + RpreBuy3(); + + if (level2 && game.equipment[name].level == 1) { + buyEquipment(name, null, true, 1); + } + + var mostEfficientStuff = mostEfficientEquipment(); + + if (mostEfficientStuff != undefined) { + buyEquipment(mostEfficientStuff[0], null, true, amount); + buyEquipment(mostEfficientStuff[1], null, true, amount); + } + + RpostBuy3(); + } +} + +function getMaxAffordable(baseCost, totalResource, costScaling, isCompounding) { + + if (!isCompounding) { + return Math.floor( + (costScaling - (2 * baseCost) + Math.sqrt(Math.pow(2 * baseCost - costScaling, 2) + (8 * costScaling * totalResource))) / 2 + ); + } else { + return Math.floor(Math.log(1 - (1 - costScaling) * totalResource / baseCost) / Math.log(costScaling)); + } +} + +function buyPrestigeMaybe(equipName) { + + if (game.global.challengeActive == "Pandemonium" && game.challenges.Pandemonium.isEquipBlocked(equipName)) { + return false; + } + + var equipment = game.equipment[equipName]; + var resource = (equipName == "Shield") ? 'wood' : 'metal' + var equipStat = (typeof equipment.attack !== 'undefined') ? 'attack' : 'health'; + + var artBoost = Math.pow(1 - game.portal.Artisanistry.modifier, game.portal.Artisanistry.radLevel); + artBoost *= autoBattle.oneTimers.Artisan.owned ? autoBattle.oneTimers.Artisan.getMult() : 1; + if (game.global.challenges == "Pandemonium") artBoost *= game.challenges.Pandemonium.getEnemyMult(); + + var prestigeUpgradeName = ""; + var allUpgradeNames = Object.getOwnPropertyNames(game.upgrades); + for (var upgrade of allUpgradeNames) { + if (game.upgrades[upgrade].prestiges === equipName) { + prestigeUpgradeName = upgrade; + break; + } + } + + if (game.upgrades[prestigeUpgradeName].locked) return false;; + + if (game.upgrades[prestigeUpgradeName].cost.resources.science[0] * + Math.pow(game.upgrades[prestigeUpgradeName].cost.resources.science[1], game.equipment[equipName].prestige - 1) + > game.resources.science.owned) { + return false; + } + + if (game.upgrades[prestigeUpgradeName].cost.resources.gems[0] * + Math.pow(game.upgrades[prestigeUpgradeName].cost.resources.gems[1], game.equipment[equipName].prestige - 1) + > game.resources.gems.owned) { + return false; + } + + var levelOnePrestige = getNextPrestigeCost(prestigeUpgradeName) * artBoost; + + if (levelOnePrestige > game.resources[resource].owned) return false; + + var newLevel = Math.floor(getMaxAffordable(levelOnePrestige * 1.2,game.resources[resource].owned,1.2,true)) + 1; + + var newStatValue = (newLevel) * Math.round(equipment[equipStat] * Math.pow(1.19, ((equipment.prestige + 1) * game.global.prestige[equipStat]) + 1)); + var currentStatValue = equipment.level * equipment[equipStat + 'Calculated']; + + return newStatValue > currentStatValue + +} + +function RautoEquip() { + + if (!getPageSetting('Requipon')) return; + + var prestigeLeft = false; + do { + prestigeLeft = false; + for (var equipName in game.equipment) { + if (buyPrestigeMaybe(equipName)) { + if(!game.equipment[equipName].locked) { + if (buyUpgrade(RequipmentList[equipName].Upgrade, true, true)) { + prestigeLeft = true; + } + } + } } + } while (prestigeLeft) + + // Gather settings + var alwaysLvl2 = getPageSetting('Requip2'); + var attackEquipCap = ((getPageSetting('Requipcapattack') <= 0) ? Infinity : getPageSetting('Requipcapattack')); + var healthEquipCap = ((getPageSetting('Requipcaphealth') <= 0) ? Infinity : getPageSetting('Requipcaphealth')); + var zoneGo = game.global.world >= getPageSetting('Requipzone'); + var resourceMaxPercent = getPageSetting('Requippercent') / 100; + + // Always 2 + if (alwaysLvl2 && game.global.challengeActive != 'Pandemonium') { + for (var equip in game.equipment) { + if (game.equipment[equip].level < 2) { + buyEquipment(equip, null, true, 1); + } + } + } + + // Loop through actually getting equips + var keepBuying = false; + do { + keepBuying = false; + var bestBuys = mostEfficientEquipment(); + + // Set up for attack + var equipName = bestBuys[0]; + var resourceUsed = resourceUsed = (equipName == 'Shield') ? 'wood' : 'metal'; + var equipCap = attackEquipCap; + var underStats = RcalcHDratio() >= getPageSetting('Rdmgcuntoff'); + + for (var i = 0; i < 2; i++){ + if (canAffordBuilding(equipName, null, null, true, false, 1)) { + if (smithylogic(equipName,resourceUsed,true)) { + if (game.equipment[equipName].level < equipCap) { + // Check any of the overrides + if ( + zoneGo || + underStats || + Rgetequipcost(equipName, resourceUsed, 1) <= resourceMaxPercent * game.resources[resourceUsed].owned + ) { + if (game.global.challengeActive == "Hypothermia" && equipName == 'Shield' && !Rhyposhouldwood) return; + else if (!game.equipment[equipName].locked) { + if (buyEquipment(equipName, null, true, 1)){ + keepBuying = true; + } +} + } + } + } + } + + // Set up for Health + equipName = bestBuys[1]; + resourceUsed = (equipName == 'Shield') ? 'wood' : 'metal'; + equipCap = healthEquipCap; + underStats = RcalcOurHealth(true) < getPageSetting('Rhitssurvived') * RcalcBadGuyDmg(null, RgetEnemyMaxAttack(game.global.world, 50, 'Snimp', 1.0)); + + } + + } while (keepBuying) + +} + +function getTotalMultiCost(baseCost, multiBuyCount, costScaling, isCompounding) { + if (!isCompounding) { + return multiBuyCount * (multiBuyCount * costScaling - costScaling + 2 * baseCost) / 2; + } else { + return baseCost * ((1 - Math.pow(costScaling, multiBuyCount)) / (1 - costScaling)); } - return attack.every(evaluation => (evaluation.Factor == 0 && evaluation.Wall == true)); +} + +function equipfarmdynamicHD() { + var equipfarmzone = 0; + var equipfarmHD = 0; + var equipfarmmult = 0; + var equipfarmHDzone = 0; + var equipfarmHDmult = RcalcHDratio() - 1; + if (getPageSetting('Requipfarmon') == true && game.global.world > 5 && game.global.world >= (getPageSetting('Requipfarmzone') && getPageSetting('RequipfarmHD') > 0 && getPageSetting('Requipfarmmult') > 0)) { + equipfarmzone = getPageSetting('Requipfarmzone'); + equipfarmHD = getPageSetting('RequipfarmHD'); + equipfarmmult = getPageSetting('Requipfarmmult'); + equipfarmHDzone = (game.global.world - equipfarmzone); + equipfarmHDmult = (equipfarmHDzone == 0) ? equipfarmHD : Math.pow(equipfarmmult, equipfarmHDzone) * equipfarmHD; + } + return equipfarmHDmult; +} + +function estimateEquipsForZone() { + var artBoost = Math.pow(1 - game.portal.Artisanistry.modifier, game.portal.Artisanistry.radLevel); + artBoost *= autoBattle.oneTimers.Artisan.owned ? autoBattle.oneTimers.Artisan.getMult() : 1; + if (game.global.challengeActive == "Pandemonium") artBoost *= game.challenges.Pandemonium.getEnemyMult(); + var MAX_EQUIP_DELTA = 700; + + // calculate stats needed pass zone + var enemyDamageBeforeEquality = RcalcBadGuyDmg(null, RgetEnemyMaxAttack(game.global.world, 100, 'Improbability'), true); //game.global.getEnemyAttack(100, 'Snimp', true); + var ourHealth = RcalcOurHealth(); + var hits = (getPageSetting("Rhitssurvived") > 0) ? getPageSetting("Rhitssurvived") : 1; + + var healthNeededMulti = (enemyDamageBeforeEquality * hits) / ourHealth; // The multiplier we need to apply to our health to survive + + // Get a fake ratio pretending that we don't have any equality in. + var fakeHDRatio = RgetEnemyMaxHealth(game.global.world, 100) / (RcalcOurDmg('avg', true)); // game.global.getEnemyHealth(100, 'Snimp', true) + var attackNeededMulti = fakeHDRatio / (game.global.mapBonus < 10 ? (equipfarmdynamicHD() * 5) : equipfarmdynamicHD()); + + //console.log("Health needed no equality: " + healthNeededMulti); + //console.log("Attack Needed no equality: " + attackNeededMulti); + + // Something something figure out equality vs health farming + var tempEqualityUse = 0; + while ( + (healthNeededMulti > 1 || attackNeededMulti > 1) // If it's below 1 we don't actually need more + && + (healthNeededMulti * game.portal.Equality.modifier > attackNeededMulti / game.portal.Equality.modifier) // Need more health proportionally + && + tempEqualityUse < game.portal.Equality.radLevel + ) { + tempEqualityUse++; + healthNeededMulti *= game.portal.Equality.modifier; + attackNeededMulti /= game.portal.Equality.modifier; + } + + if (healthNeededMulti < 1 && attackNeededMulti < 1) {return [0, {}]}; + + var ourAttack = 6; + for(var i in RequipmentList){ + if(game.equipment[i].locked !== 0) continue; + var attackBonus = game.equipment[i].attackCalculated; + var level = game.equipment[i].level; + ourAttack += (attackBonus !== undefined ? attackBonus : 0)*level; + } + + // Amount of stats needed directly from equipment + var attackNeeded = ourAttack * attackNeededMulti; + var healthNeeded = ourHealth * healthNeededMulti / (getTotalHealthMod() * game.resources.trimps.maxSoldiers); + + var bonusLevels = {}; // How many levels you'll be getting in each shield-gambeson armor slots + + while (healthNeeded > 0) { + var bestArmor = mostEfficientEquipment(bonusLevels)[1]; + healthNeeded -= game.equipment[bestArmor][RequipmentList[bestArmor].Stat + "Calculated"]; + if (typeof bonusLevels[bestArmor] === 'undefined') { + bonusLevels[bestArmor] = 0; + } + if (bonusLevels[bestArmor]++ > MAX_EQUIP_DELTA) { + return [Infinity, bonusLevels]; + } + } + while (attackNeeded > 0) { + var bestWeapon = mostEfficientEquipment(bonusLevels)[0]; + attackNeeded -= game.equipment[bestWeapon][RequipmentList[bestWeapon].Stat + "Calculated"]; + if (typeof bonusLevels[bestWeapon] === 'undefined') { + bonusLevels[bestWeapon] = 0; + } + if (bonusLevels[bestWeapon]++ >= MAX_EQUIP_DELTA) { + return [Infinity, bonusLevels]; + } + } + + var totalCost = 0; + for (var equip in bonusLevels) { + var equipCost = game.equipment[equip].cost[RequipmentList[equip].Resource]; + totalCost += getTotalMultiCost(equipCost[0],bonusLevels[equip],equipCost[1],true) * artBoost; + } + + return [totalCost, bonusLevels, tempEqualityUse]; + } diff --git a/modules/fight-info.js b/modules/fight-info.js index 8923b769b..445f519d0 100644 --- a/modules/fight-info.js +++ b/modules/fight-info.js @@ -27,13 +27,31 @@ "Titimp", "Chronoimp" ]; + + // Fast imps + M["fightinfo"].fast = + [ + "Snimp", + "Kittimp", + "Gorillimp", + "Squimp", + "Shrimp", + "Chickimp", + "Frimp", + "Slagimp", + "Lavimp", + "Kangarimp", + "Entimp", + "Carbimp", + ]; //Colors for special imps (This has been disabled) M["fightinfo"].colors = { bone: '#ffffff', exotic: '#000000', - powerful: '#000000' + powerful: '#000000', + fast : '#000000' } M["fightinfo"].lastProcessedWorld = null; @@ -123,6 +141,16 @@ //$cell.style.color = M["fightinfo"].colors.powerful; //(This changes the colour of the glyph - bad bc it overrides trimps and looks bad against corruption etc) $cell.style.textShadow = '0px 0px 10px #8c0000'; } + + else if(M["fightinfo"].fast.indexOf(cell.name) > -1) // Fast imp + { + //if(cell.special.length === 0) + $cell.innerHTML = " "; + + $cell.title = cell.name; + //$cell.style.color = M["fightinfo"].colors.fast; //(This changes the colour of the glyph - bad bc it overrides trimps and looks bad against corruption etc) + $cell.style.textShadow = '0px 0px 10px #ffffff'; + } //This shit doesn't work and I don't know why (What is the celltitle??? is it the name of the nature? Imps are labelled Toxic/Gusty/Frozen but that didin't work either) if(cell.name.toLowerCase().indexOf('poison') > -1) // Poison Token cell diff --git a/modules/fight.js b/modules/fight.js index 4368395ea..12df1b674 100644 --- a/modules/fight.js +++ b/modules/fight.js @@ -1,96 +1,30 @@ MODULES["fight"] = {}; -//These can be changed (in the console) if you know what you're doing: MODULES["fight"].breedTimerCutoff1 = 2; MODULES["fight"].breedTimerCutoff2 = 0.5; -MODULES["fight"].enableDebug = true; //controls whether betterAutoFight2 is Spammy or not. +MODULES["fight"].enableDebug = true; -//selector function, called from main. -var BAFsetting, oldBAFsetting; -function ATselectAutoFight() { - BAFsetting = getPageSetting('BetterAutoFight'); - if (BAFsetting==1) betterAutoFight(); //"Better Auto Fight" (autofight.js) - else if (BAFsetting==2) betterAutoFight2(); //"Better Auto Fight2" (") - else if (BAFsetting==0 && BAFsetting!=oldBAFsetting && game.global.autoBattle && game.global.pauseFight) pauseFight(); //turn on autofight on once when BAF is toggled off. - else if (BAFsetting==0 && game.global.world == 1 && game.global.autoBattle && game.global.pauseFight) pauseFight(); //turn on autofight on lvl 1 if its off. - else if (BAFsetting==0 && !game.global.autoBattle && game.global.soldierHealth == 0) betterAutoFight(); //use BAF as a backup for pre-Battle situations - oldBAFsetting = BAFsetting; //enables built-in autofight once when disabled -} - -//old: Handles manual fighting automatically, in a different way. function betterAutoFight() { var customVars = MODULES["fight"]; if (game.global.autoBattle && !game.global.pauseFight) - pauseFight(); //Disable built-in autofight - if (game.global.gridArray.length === 0 || game.global.preMapsActive || !game.upgrades.Battle.done) return; //sanity check. stops error message on z1 right after portal - var targetBreed = getPageSetting('GeneticistTimer'); - var breeding = (game.resources.trimps.owned - game.resources.trimps.employed); + pauseFight(); + if (game.global.gridArray.length === 0 || game.global.preMapsActive || !game.upgrades.Battle.done) return; + var breeding = (game.resources.trimps.owned - trimpsEffectivelyEmployed()); var newSquadRdy = game.resources.trimps.realMax() <= game.resources.trimps.owned + 1; var lowLevelFight = game.resources.trimps.maxSoldiers < breeding * 0.5 && breeding > game.resources.trimps.realMax() * 0.1 && game.global.world < 5; - //Manually fight instead of using builtin auto-fight if (!game.global.fighting) { - if (newSquadRdy || game.global.soldierHealth > 0 || lowLevelFight || game.global.challengeActive == 'Watch') { + if (newSquadRdy || game.global.soldierHealth > 0 || lowLevelFight || challengeActive("Watch")) { fightManual(); } - //Click Fight if we are dead and already have enough for our breed timer, and fighting would not add a significant amount of time - else if (getBreedTime() < customVars.breedTimerCutoff1 && (game.global.lastBreedTime/1000) > targetBreed && game.global.soldierHealth == 0) - fightManual(); - //AutoFight will now send Trimps to fight if it takes less than 0.5 seconds to create a new group of soldiers, if we havent bred fully yet - else if (getBreedTime() <= customVars.breedTimerCutoff2) - fightManual(); } } -//NEW:: 2nd algorithm for Better Auto Fight -function betterAutoFight2() { +function betterAutoFight3() { var customVars = MODULES["fight"]; - if (game.global.autoBattle && !game.global.pauseFight) - pauseFight(); //Disable built-in autofight - if (game.global.gridArray.length === 0 || game.global.preMapsActive || !game.upgrades.Battle.done || game.global.fighting) - return; //sanity check. - var targetBreed = getPageSetting('GeneticistTimer'); - var breeding = (game.resources.trimps.owned - game.resources.trimps.employed); - var newSquadRdy = game.resources.trimps.realMax() <= game.resources.trimps.owned + 1; - var adjustedMax = (game.portal.Coordinated.level) ? game.portal.Coordinated.currentSend : trimps.maxSoldiers; - var potencyMod = getPotencyMod(); - var tps = breeding * potencyMod; - var addTime = adjustedMax / tps; - //if armySend is less than half of what you have breeding, and what you have breeding is more than 10% of your total trimps. (when scientist I is incompleted) - var lowLevelFight = game.resources.trimps.maxSoldiers < 0.5*breeding && breeding > 0.1*game.resources.trimps.realMax() && game.global.world <= 6 && game.global.sLevel < 1; - - var breedTimerLimit = game.talents.patience.purchased && getPageSetting('UsePatience') ? 46 : 31; - - //Manually fight if: //game.global.soldierHealth > 0 //just fight if we're alive,or if == 0; we're dead, and also fight :P - if (!game.global.fighting) { - if (game.global.soldierHealth > 0) - battle(true); //just fight, dont speak. - else if (newSquadRdy || lowLevelFight || game.global.challengeActive == 'Watch') { - battle(true); - if (MODULES["fight"].enableDebug) - debug("AutoFight Default: New squad ready", "other"); - } - //Click Fight if we are dead and already have enough for our breed timer, and fighting would not add a significant amount of time - else if (getBreedTime() < customVars.breedTimerCutoff1 && (game.global.lastBreedTime/1000) > targetBreed) { - battle(true); - if (MODULES["fight"].enableDebug) - debug("AutoFight: BAF2 #1, breed < " + customVars.breedTimerCutoff1 + " && HiddenNextGroup > GeneTimer", "other"); - } - //AutoFight will now send Trimps to fight if it takes less than 0.5 seconds to create a new group of soldiers, if we havent bred fully yet - else if (getBreedTime() <= customVars.breedTimerCutoff2) { - battle(true); - if (MODULES["fight"].enableDebug) - debug("AutoFight: BAF2 #2, breed <= " + customVars.breedTimerCutoff2 + " s", "other"); - } - //Click fight anyway if we are dead and stuck in a loop due to Dimensional Generator and we can get away with adding time to it. - else if (getBreedTime(true)+addTime <= targetBreed && breeding>=adjustedMax && !(game.global.mapsActive && getCurrentMapObject().location == "Void")) { - battle(true); - if (MODULES["fight"].enableDebug) - debug("AutoFight: BAF2 #3, RemainingTime + ArmyAdd.Time < GeneTimer", "other"); - } - //Clicks fight anyway if we are dead and have >=breedTimerLimit NextGroupTimer and deal with the consequences by firing geneticists afterwards. - else if (game.global.soldierHealth == 0 && (game.global.lastBreedTime/1000)>=breedTimerLimit && targetBreed >= 0 && !game.jobs.Geneticist.locked && game.jobs.Geneticist.owned > 10 ) { - battle(true); - if (MODULES["fight"].enableDebug) - debug("AutoFight: BAF2 #4, NextGroupBreedTimer went over " + breedTimerLimit + " and we arent fighting.", "other"); + if (game.global.autoBattle && game.global.pauseFight && !game.global.spireActive) + pauseFight(); + if (game.global.gridArray.length === 0 || game.global.preMapsActive || !game.upgrades.Battle.done || game.global.fighting || game.global.spireActive) + return; + if (game.global.world == 1 && !game.global.fighting) { + fightManual(); } - } } diff --git a/modules/gather.js b/modules/gather.js index 54299d885..49f13d53f 100644 --- a/modules/gather.js +++ b/modules/gather.js @@ -1,245 +1,386 @@ +//updated MODULES["gather"] = {}; //These can be changed (in the console) if you know what you're doing: -MODULES["gather"].minTraps = 100; +MODULES["gather"].minTraps = 5; MODULES["gather"].minScienceAmount = 100; MODULES["gather"].minScienceSeconds = 60; +//Global flags +var trapBuffering = false, maxTrapBuffering = false; +var maxZoneDuration = 0; + +//Traps per second +function calcTPS() { + return Math.min(10, game.global.playerModifier / 5); +} + +function calcMaxTraps() { + //Tries to keep in mind the longest duration any zone has lasted in this portal + var time = getZoneSeconds(); + if (game.global.world == 1) maxZoneDuration = time; + if (time > maxZoneDuration) maxZoneDuration = time; + + //Return enough traps to last 1/4 of the longest duration zone we've seen so far + return Math.ceil(calcTPS() * maxZoneDuration/4); +} + //OLD: "Auto Gather/Build" -function manualLabor() { - if (getPageSetting('ManualGather2')==0) return; - //vars - var breedingTrimps = game.resources.trimps.owned - game.resources.trimps.employed; - var lowOnTraps = game.buildings.Trap.owned < MODULES["gather"].minTraps; - var notFullPop = game.resources.trimps.owned < game.resources.trimps.realMax(); - var trapTrimpsOK = getPageSetting('TrapTrimps'); - var targetBreed = getPageSetting('GeneticistTimer'); - var trapperTrapUntilFull = game.global.challengeActive == "Trapper" && notFullPop; - var watchJumpstartTraps = game.global.challengeActive == "Watch" && notFullPop; - var hasTurkimp = game.talents.turkimp4.purchased || game.global.turkimpTimer > 0; - - //FRESH GAME NO HELIUM CODE. - if (game.global.world <=3 && game.global.totalHeliumEarned<=5000) { - if (game.global.buildingsQueue.length == 0 && (game.global.playerGathering != 'trimps' || game.buildings.Trap.owned == 0)){ +function manualLabor2() { + //If not using auto-gather, return + if (getPageSetting('ManualGather2') == 0) return; + + //Init - Traps config + var notFullPop = game.resources.trimps.owned < game.resources.trimps.realMax(); + var trapperTrapUntilFull = game.global.challengeActive == "Trapper" && notFullPop; + var trapTrimpsOK = getPageSetting('TrapTrimps') && (trapperTrapUntilFull || game.jobs.Geneticist.owned == 0); + var minTraps = Math.ceil(calcTPS()); + var trapsBufferSize = Math.ceil(5 * calcTPS()); + var maxTraps = calcMaxTraps(); + + //Init - Traps control + var lowOnTraps = game.buildings.Trap.owned < minTraps; + var trapsReady = game.buildings.Trap.owned >= minTraps + trapsBufferSize; + var fullOfTraps = game.buildings.Trap.owned >= maxTraps; + var maxTrapsReady = game.buildings.Trap.owned >= maxTraps + trapsBufferSize; + if (lowOnTraps) trapBuffering = true; + if (trapsReady) trapBuffering = false; + if (maxTrapsReady) maxTrapBuffering = false; + + // Init - Science + var firstFightOK = game.global.world > 1 || game.global.lastClearedCell >= 0; + var researchAvailable = document.getElementById('scienceCollectBtn').style.display != 'none' && document.getElementById('science').style.visibility != 'hidden'; + var scienceAvailable = document.getElementById('science').style.visibility != 'hidden'; + var needBattle = !game.upgrades.Battle.done && game.resources.science.owned < 10; + var needScience = game.resources.science.owned < scienceNeeded; + var needScientists = firstFightOK && game.global.challengeActive != 'Scientist' && !game.upgrades.Scientists.done && game.resources.science.owned < 100 && scienceAvailable; + + + //Init - Others + var needMiner = firstFightOK && challengeActive("Metal") == false && !game.upgrades.Miners.done; + var breedingTrimps = game.resources.trimps.owned - trimpsEffectivelyEmployed(); + var hasTurkimp = game.talents.turkimp2.purchased || game.global.turkimpTimer > 0; + + //Verifies if trapping is still relevant + //Relevant means we gain at least 10% more trimps per sec while trapping (which basically stops trapping during later zones) + //And there is enough breed time remaining to open an entire trap (prevents wasting time and traps during early zones) + var trappingIsRelevant = trapperTrapUntilFull || breedingPS().div(10).lt(calcTPS() * (game.portal.Bait.level + 1)); + var trapWontBeWasted = breedTimeRemaining().gte(1 / calcTPS()) || game.global.playerGathering == "trimps" && breedTimeRemaining().lte(DecimalBreed(0.1)); + + //Highest Priority Food/Wood for traps (Early Game, when trapping is mandatory) + if (game.global.world <= 3 && game.global.totalHeliumEarned <= 500000) { + //If not building and not trapping + if (!trapsReady && game.global.buildingsQueue.length == 0 && (game.global.playerGathering != 'trimps' || game.buildings.Trap.owned == 0)) { + //Gather food or wood + if (game.resources.food.owned < 10) { setGather('food'); return; } + if (game.triggers.wood.done && game.resources.wood.owned < 10) { setGather('wood'); return; } + } + } + + //High Priority Trapping (doing Trapper or without breeding trimps) + if (trapTrimpsOK && trappingIsRelevant && trapWontBeWasted && ((notFullPop && breedingTrimps < 4) || trapperTrapUntilFull)) { + //Bait trimps if we have traps + if (!lowOnTraps && !trapBuffering) { setGather('trimps'); return; } + + //Or build them, if they are on the queue + else if (isBuildingInQueue('Trap') || safeBuyBuilding('Trap')) { + trapBuffering = true; + setGather('buildings'); + return; + } + } + + //Build if we don't have foremany, there are 2+ buildings in the queue, or if we can speed up something other than a trap + if (!bwRewardUnlocked("Foremany") && game.global.buildingsQueue.length && (game.global.buildingsQueue.length > 1 || game.global.autoCraftModifier == 0 || (getPlayerModifier() > 100 && game.global.buildingsQueue[0] != 'Trap.1'))) { + setGather('buildings'); + return; + } + + //Also Build if we have storage buildings on top of the queue + if (!bwRewardUnlocked("Foremany") && game.global.buildingsQueue.length && game.global.buildingsQueue[0] == 'Barn.1' || game.global.buildingsQueue[0] == 'Shed.1' || game.global.buildingsQueue[0] == 'Forge.1') { + setGather('buildings'); + return; + } + + //Highest Priority Research if we have less science than needed to buy Battle, Miner and Scientists + if (getPageSetting('ManualGather2') != 2 && researchAvailable && (needBattle || needScientists || needMiner && game.resources.science.owned < 60)) { + setGather('science'); + return; + } + + //Gather resources for Miner + if (needMiner && (game.resources.metal.owned < 100 || game.resources.wood.owned < 300)) { + setGather(game.resources.metal.owned < 100 ? "metal" : "wood"); + return; + } + + //High Priority Metal gathering for Metal Challenge + if (challengeActive("Metal") && !game.global.mapsUnlocked) { + setGather('metal'); + return; + } + + //Mid Priority Trapping + if (trapTrimpsOK && trappingIsRelevant && trapWontBeWasted && notFullPop && !lowOnTraps && !trapBuffering) { setGather('trimps'); return; } + + //High Priority Research - When manual research still has more impact than scientists + if (getPageSetting('ManualGather2') != 2 && researchAvailable && needScience && getPlayerModifier() > getPerSecBeforeManual('Scientist')) { + setGather('science'); + return; + } + + //High Priority Trap Building + if (trapTrimpsOK && trappingIsRelevant && canAffordBuilding('Trap') && (lowOnTraps || trapBuffering)) { + trapBuffering = true; + safeBuyBuilding('Trap'); + setGather('buildings'); + return; + } + + //Metal if Turkimp is active + if (hasTurkimp) { setGather('metal'); return; } + + //Mid Priority Research + if (getPageSetting('ManualGather2') != 2 && researchAvailable && needScience) { setGather('science'); return; } + + //Low Priority Trap Building + if (trapTrimpsOK && trappingIsRelevant && canAffordBuilding('Trap') && (!fullOfTraps || maxTrapBuffering)) { + trapBuffering = !fullOfTraps; + maxTrapBuffering = true; + safeBuyBuilding('Trap'); + setGather('buildings'); + return; + } + + //Untouched mess + var manualResourceList = { + 'food': 'Farmer', + 'wood': 'Lumberjack', + 'metal': 'Miner', + }; + var lowestResource = 'food'; + var lowestResourceRate = -1; + var haveWorkers = true; + for (var resource in manualResourceList) { + var job = manualResourceList[resource]; + var currentRate = game.jobs[job].owned * game.jobs[job].modifier; + // debug('Current rate for ' + resource + ' is ' + currentRate + ' is hidden? ' + (document.getElementById(resource).style.visibility == 'hidden')); + if (document.getElementById(resource).style.visibility != 'hidden') { + //find the lowest resource rate + if (currentRate === 0) { + currentRate = game.resources[resource].owned; + // debug('Current rate for ' + resource + ' is ' + currentRate + ' lowest ' + lowestResource + lowestResourceRate); + if ((haveWorkers) || (currentRate < lowestResourceRate)) { + // debug('New Lowest1 ' + resource + ' is ' + currentRate + ' lowest ' + lowestResource + lowestResourceRate+ ' haveworkers ' +haveWorkers); + haveWorkers = false; + lowestResource = resource; + lowestResourceRate = currentRate; + } + } + if ((currentRate < lowestResourceRate || lowestResourceRate == -1) && haveWorkers) { + // debug('New Lowest2 ' + resource + ' is ' + currentRate + ' lowest ' + lowestResource + lowestResourceRate); + lowestResource = resource; + lowestResourceRate = currentRate; + } + } + } + + //High Priority Gathering - No workers for this resource + if (game.global.playerGathering != lowestResource && !haveWorkers && !breedFire) {setGather(lowestResource); return;} + + //Low Priority Research + if (getPageSetting('ManualGather2') != 2 && researchAvailable && haveWorkers) { + if (game.resources.science.owned < getPsString('science', true) * MODULES["gather"].minScienceSeconds) { + setGather('science'); + return; + } + } + + //Just gather whatever has lowest rate + setGather(lowestResource); +} + +function autogather3() { + if ((game.global.buildingsQueue.length <= 1 && getPageSetting('gathermetal') == false) || (getPageSetting('gathermetal') == true)) setGather('metal'); + else setGather('buildings') +} + +//RGather + +MODULES["gather"].RminScienceAmount = 200; + +function RmanualLabor2() { + + //Vars + var lowOnTraps = game.buildings.Trap.owned < 5; + var trapTrimpsOK = getPageSetting('RTrapTrimps'); + var hasTurkimp = game.talents.turkimp2.purchased || game.global.turkimpTimer > 0; + var needToTrap = (game.resources.trimps.max - game.resources.trimps.owned >= game.resources.trimps.max * 0.05) || (game.resources.trimps.getCurrentSend() > game.resources.trimps.owned - trimpsEffectivelyEmployed()); + var fresh = false; + + //ULTRA FRESH + if (!game.upgrades.Battle.done) { + fresh = true; + if (game.resources.food.owned < 10) { + setGather('food'); + } + if (game.resources.wood.owned < 10 && game.resources.food.owned >= 10) { + setGather('wood'); + } + if (game.resources.food.owned >= 10 && game.resources.wood.owned >= 10) { + safeBuyBuilding('Trap'); + } + if (game.buildings.Trap.owned > 0 && game.resources.trimps.owned < 1) { + setGather('trimps'); + } + if (game.resources.trimps.owned >= 1) { + setGather('science'); + } + return; + } + if (game.upgrades.Battle.done && game.upgrades.Scientists.allowed && !game.upgrades.Scientists.done && game.resources.science.owned < 100) { + fresh = true; + setGather('science'); + return; + } + if (game.upgrades.Battle.done && game.upgrades.Miners.allowed && !game.upgrades.Miners.done && game.resources.science.owned < 60) { + fresh = true; + setGather('science'); + return; + } + + //FRESH GAME NO RADON CODE + if (!fresh && game.global.world <= 3 && game.global.totalRadonEarned <= 5000) { + if (game.global.buildingsQueue.length == 0 && (game.global.playerGathering != 'trimps' || game.buildings.Trap.owned == 0)) { if (!game.triggers.wood.done || game.resources.food.owned < 10 || Math.floor(game.resources.food.owned) < Math.floor(game.resources.wood.owned)) setGather('food'); else setGather('wood'); } + return; } - - if(watchJumpstartTraps || trapTrimpsOK && (breedingTrimps < 5 || trapperTrapUntilFull) && game.buildings.Trap.owned == 0 && canAffordBuilding('Trap')) { - //safeBuyBuilding returns false if item is already in queue - if(!safeBuyBuilding('Trap')) - setGather('buildings'); - } - else if (watchJumpstartTraps || trapTrimpsOK && (breedingTrimps < 5 || trapperTrapUntilFull) && game.buildings.Trap.owned > 0) { - setGather('trimps'); - if (trapperTrapUntilFull && (game.global.buildingsQueue.length == 0 || game.buildings.Trap.owned == 1) && !game.global.trapBuildAllowed && canAffordBuilding('Trap')) - safeBuyBuilding('Trap'); //get ahead on trap building since it is always needed for Trapper + + //QUEST + if (game.global.challengeActive == "Quest") { + if (questcheck() == 10 || questcheck() == 20) { + setGather('food'); + } + if (questcheck() == 11 || questcheck() == 21) { + setGather('wood'); + } + if (questcheck() == 12 || questcheck() == 22) { + setGather('metal'); + } + if (questcheck() == 14 || questcheck() == 24) { + setGather('science'); + } } - else if (getPageSetting('ManualGather2') != 2 && game.resources.science.owned < MODULES["gather"].minScienceAmount && document.getElementById('scienceCollectBtn').style.display != 'none' && document.getElementById('science').style.visibility != 'hidden') - setGather('science'); - //if we have more than 2 buildings in queue, or (our modifier is real fast and trapstorm is off), build - else if (!game.talents.foreman.purchased && (game.global.buildingsQueue.length ? (game.global.buildingsQueue.length > 1 || game.global.autoCraftModifier == 0 || (getPlayerModifier() > 1000 && game.global.buildingsQueue[0] != 'Trap.1')) : false)) { - setGather('buildings'); + + //HYPO + else if (Rshouldhypofarm) { + setGather('wood'); } - //if trapstorm is off (likely we havent gotten it yet, the game is still early, buildings take a while to build ), then Prioritize Storage buildings when they hit the front of the queue (should really be happening anyway since the queue should be >2(fits the clause above this), but in case they are the only object in the queue.) - else if (!game.global.trapBuildToggled && (game.global.buildingsQueue[0] == 'Barn.1' || game.global.buildingsQueue[0] == 'Shed.1' || game.global.buildingsQueue[0] == 'Forge.1')){ - setGather('buildings'); + + //SHIP + else if (Rshouldshipfarm) { + setGather('food'); } - //if we have some upgrades sitting around which we don't have enough science for, gather science - else if (game.resources.science.owned < scienceNeeded && document.getElementById('scienceCollectBtn').style.display != 'none' && document.getElementById('science').style.visibility != 'hidden') { - // debug('Science needed ' + scienceNeeded); - if ((getPlayerModifier() < getPerSecBeforeManual('Scientist') && hasTurkimp)||getPageSetting('ManualGather2') == 2){ - //if manual is less than science production, switch on turkimp + + //TIMEFARM + else if (Rshouldtimefarm) { + var timefarmzone = getPageSetting('Rtimefarmzone'); + var timefarmlevelindex = timefarmzone.indexOf(game.global.world); + if (autoTrimpSettings.Rtimefarmgather.value[timefarmlevelindex] == "food") { + setGather('food'); + } + if (autoTrimpSettings.Rtimefarmgather.value[timefarmlevelindex] == "wood") { + setGather('wood'); + } + if (autoTrimpSettings.Rtimefarmgather.value[timefarmlevelindex] == "metal") { setGather('metal'); } - else if (getPageSetting('ManualGather2') != 2){ + if (autoTrimpSettings.Rtimefarmgather.value[timefarmlevelindex] == "science") { setGather('science'); } + } + + //SMITHY + else if (Rshouldsmithyfarm) { + setGather(RsmithyCalc(false, false, false, true)); } - else if (trapTrimpsOK && targetBreed < getBreedTime(true)){ - //combined to optimize code. - if (game.buildings.Trap.owned < 100 && canAffordBuilding('Trap')) { - safeBuyBuilding('Trap'); - setGather('buildings'); + + //SHIP + else if (Rshouldshipfarm) { + var shipfarmzone = getPageSetting('Rtributefarmzone'); + var tributefarmlevelindex = tributefarmzone.indexOf(game.global.world); + if (autoTrimpSettings.Rtributegatherselection.value[tributefarmlevelindex] == "food") { + setGather('food'); } - else if (game.buildings.Trap.owned > 0) - setGather('trimps'); - } - else { - var manualResourceList = { - 'food': 'Farmer', - 'wood': 'Lumberjack', - 'metal': 'Miner', - }; - var lowestResource = 'food'; - var lowestResourceRate = -1; - var haveWorkers = true; - for (var resource in manualResourceList) { - var job = manualResourceList[resource]; - var currentRate = game.jobs[job].owned * game.jobs[job].modifier; - // debug('Current rate for ' + resource + ' is ' + currentRate + ' is hidden? ' + (document.getElementById(resource).style.visibility == 'hidden')); - if (document.getElementById(resource).style.visibility != 'hidden') { - //find the lowest resource rate - if (currentRate === 0) { - currentRate = game.resources[resource].owned; - // debug('Current rate for ' + resource + ' is ' + currentRate + ' lowest ' + lowestResource + lowestResourceRate); - if ((haveWorkers) || (currentRate < lowestResourceRate)) { - // debug('New Lowest1 ' + resource + ' is ' + currentRate + ' lowest ' + lowestResource + lowestResourceRate+ ' haveworkers ' +haveWorkers); - haveWorkers = false; - lowestResource = resource; - lowestResourceRate = currentRate; - } - } - if ((currentRate < lowestResourceRate || lowestResourceRate == -1) && haveWorkers) { - // debug('New Lowest2 ' + resource + ' is ' + currentRate + ' lowest ' + lowestResource + lowestResourceRate); - lowestResource = resource; - lowestResourceRate = currentRate; - } - } - // debug('Current Stats ' + resource + ' is ' + currentRate + ' lowest ' + lowestResource + lowestResourceRate+ ' haveworkers ' +haveWorkers); - } - if (game.global.playerGathering != lowestResource && !haveWorkers && !breedFire) { - if (hasTurkimp) - setGather('metal'); - else - setGather(lowestResource);//gather the lowest resource - //This stuff seems to be repeated from above. Should be refactored and fixed so this is not confusing. - } else if (getPageSetting('ManualGather2') != 2 && document.getElementById('scienceCollectBtn').style.display != 'none' && document.getElementById('science').style.visibility != 'hidden') { - if (game.resources.science.owned < getPsString('science', true) * MODULES["gather"].minScienceSeconds && game.global.turkimpTimer < 1 && haveWorkers) - setGather('science'); - else if (hasTurkimp) - setGather('metal'); - else - setGather(lowestResource); + if (autoTrimpSettings.Rtributegatherselection.value[tributefarmlevelindex] == "wood") { + setGather('wood'); + } + if (autoTrimpSettings.Rtributegatherselection.value[tributefarmlevelindex] == "metal") { + setGather('metal'); + } + if (autoTrimpSettings.Rtributegatherselection.value[tributefarmlevelindex] == "science") { + setGather('science'); } - //Build more traps if we have TrapTrimps on, and we own less than (100) traps. - else if(trapTrimpsOK && game.global.trapBuildToggled == true && lowOnTraps) - setGather('buildings'); - else - setGather(lowestResource); } -} - -//NEW: #2 "Auto Gather/Build" -function manualLabor2() { - if (getPageSetting('ManualGather2')==0) return; - //vars - var breedingTrimps = game.resources.trimps.owned - game.resources.trimps.employed; - var lowOnTraps = game.buildings.Trap.owned < MODULES["gather"].minTraps; - var notFullPop = game.resources.trimps.owned < game.resources.trimps.realMax(); - var trapTrimpsOK = getPageSetting('TrapTrimps'); - var targetBreed = getPageSetting('GeneticistTimer'); - var trapperTrapUntilFull = game.global.challengeActive == "Trapper" && notFullPop; - var watchJumpstartTraps = game.global.challengeActive == "Watch" && notFullPop; - var hasTurkimp = game.talents.turkimp4.purchased || game.global.turkimpTimer > 0; - - //FRESH GAME LOWLEVEL NOHELIUM CODE. - if (game.global.world <=3 && game.global.totalHeliumEarned<=5000) { - if (game.global.buildingsQueue.length == 0 && (game.global.playerGathering != 'trimps' || game.buildings.Trap.owned == 0)){ - if (!game.triggers.wood.done || game.resources.food.owned < 10 || Math.floor(game.resources.food.owned) < Math.floor(game.resources.wood.owned)) { - setGather('food'); - return; - } - else { - setGather('wood'); - return; - } + + //TRIBUTE + else if (Rshouldtributefarm) { + var tributefarmzone = getPageSetting('Rtributefarmzone'); + var tributefarmlevelindex = tributefarmzone.indexOf(game.global.world); + if (autoTrimpSettings.Rtributegatherselection.value[tributefarmlevelindex] == "food") { + setGather('food'); + } + if (autoTrimpSettings.Rtributegatherselection.value[tributefarmlevelindex] == "wood") { + setGather('wood'); + } + if (autoTrimpSettings.Rtributegatherselection.value[tributefarmlevelindex] == "metal") { + setGather('metal'); + } + if (autoTrimpSettings.Rtributegatherselection.value[tributefarmlevelindex] == "science") { + setGather('science'); } } - - //Traps and Trimps: - if(trapTrimpsOK && (breedingTrimps < 5 || trapperTrapUntilFull || watchJumpstartTraps) && game.buildings.Trap.owned == 0 && canAffordBuilding('Trap')) { - //safeBuyBuilding returns false if item is already in queue - if(!safeBuyBuilding('Trap')) + + //MISC. + else if (getPageSetting('RManualGather2') != 2 && game.resources.science.owned < MODULES["gather"].RminScienceAmount && document.getElementById('scienceCollectBtn').style.display != 'none' && document.getElementById('science').style.visibility != 'hidden') { + setGather('science'); + } + else if (game.resources.science.owned < (RscienceNeeded * 0.8) && document.getElementById('scienceCollectBtn').style.display != 'none' && document.getElementById('science').style.visibility != 'hidden') { + setGather('science'); + } + else if (trapTrimpsOK && needToTrap && game.buildings.Trap.owned == 0 && canAffordBuilding('Trap')) { + if (!safeBuyBuilding('Trap')) setGather('buildings'); - return; } - else if (trapTrimpsOK && (breedingTrimps < 5 || trapperTrapUntilFull || watchJumpstartTraps) && game.buildings.Trap.owned > 0) { + else if (trapTrimpsOK && needToTrap && game.buildings.Trap.owned > 0) { setGather('trimps'); - if (trapperTrapUntilFull && (game.global.buildingsQueue.length == 0 || game.buildings.Trap.owned == 1) && !game.global.trapBuildAllowed && canAffordBuilding('Trap')) - safeBuyBuilding('Trap'); //get ahead on trap building since it is always needed for Trapper - return; } - - //Buildings: - var manualBuildSpeedAdvantage = getPlayerModifier() / game.global.autoCraftModifier; - //pre-requisites for all: have something in the build queue, and playerCraftmod does actually speed it up. - if ((game.global.buildingsQueue.length && manualBuildSpeedAdvantage > 1) && //AND: - //if we have 2 or more buildings in queue, and playerCraftmod is high enough (>3x autoCraftmod) to speed it up. - ((game.global.buildingsQueue.length >= 2 && manualBuildSpeedAdvantage > 3) || - //Prioritize Storage buildings when they hit the front of the queue (in case they are the only object in the queue). - (game.global.buildingsQueue[0] == 'Barn.1' || game.global.buildingsQueue[0] == 'Shed.1' || game.global.buildingsQueue[0] == 'Forge.1') || - //manualBuild traps if we have TrapTrimps on, AutoTraps on, and we own less than (100) traps. - (trapTrimpsOK && game.global.trapBuildAllowed && game.global.trapBuildToggled && lowOnTraps))) { - setGather('buildings');//buildBuildings = true; - return; + else if (game.global.buildingsQueue.length > 2) { + setGather('buildings'); } - - //Sciencey: - //if we have some upgrades sitting around which we don't have enough science for, gather science - if (document.getElementById('scienceCollectBtn').style.display != 'none' && document.getElementById('science').style.visibility != 'hidden') { - //if we have less than (100) science or less than a minute of science - if (game.resources.science.owned < MODULES["gather"].minScienceAmount || - (game.resources.science.owned < getPsString('science', true) * MODULES["gather"].minScienceSeconds && game.global.turkimpTimer < 1)) - if (getPageSetting('ManualGather2') != 2) { - setGather('science'); - return; - } - if (game.resources.science.owned < scienceNeeded) { - //if manual is less than science production and turkimp, metal. (or science is set as disallowed) - if ((getPlayerModifier() < getPerSecBeforeManual('Scientist') && hasTurkimp) || getPageSetting('ManualGather2') == 2) - setGather('metal'); - else if (getPageSetting('ManualGather2') != 2) { - setGather('science'); - return; - } - } - } - - //If we got here, without exiting, gather Normal Resources: - var manualResourceList = { - 'food': 'Farmer', - 'wood': 'Lumberjack', - 'metal': 'Miner', - }; - var lowestResource = 'food'; - var lowestResourceRate = -1; - var haveWorkers = true; - for (var resource in manualResourceList) { - var job = manualResourceList[resource]; - var currentRate = game.jobs[job].owned * game.jobs[job].modifier; - // debug('Current rate for ' + resource + ' is ' + currentRate + ' is hidden? ' + (document.getElementById(resource).style.visibility == 'hidden')); - if (document.getElementById(resource).style.visibility != 'hidden') { - //find the lowest resource rate - if (currentRate === 0) { - currentRate = game.resources[resource].owned; - // debug('Current rate for ' + resource + ' is ' + currentRate + ' lowest ' + lowestResource + lowestResourceRate); - if ((haveWorkers) || (currentRate < lowestResourceRate)) { - // debug('New Lowest1 ' + resource + ' is ' + currentRate + ' lowest ' + lowestResource + lowestResourceRate+ ' haveworkers ' +haveWorkers); - haveWorkers = false; - lowestResource = resource; - lowestResourceRate = currentRate; - } - } - if ((currentRate < lowestResourceRate || lowestResourceRate == -1) && haveWorkers) { - // debug('New Lowest2 ' + resource + ' is ' + currentRate + ' lowest ' + lowestResource + lowestResourceRate); - lowestResource = resource; - lowestResourceRate = currentRate; - } - } - // debug('Current Stats ' + resource + ' is ' + currentRate + ' lowest ' + lowestResource + lowestResourceRate+ ' haveworkers ' +haveWorkers); - } - if (game.global.playerGathering != lowestResource && !haveWorkers && !breedFire) { - if (hasTurkimp) + else if (!game.global.trapBuildToggled && (game.global.buildingsQueue[0] == 'Barn.1' || game.global.buildingsQueue[0] == 'Shed.1' || game.global.buildingsQueue[0] == 'Forge.1')) { + setGather('buildings'); + } + else if (game.resources.science.owned >= RscienceNeeded && document.getElementById('scienceCollectBtn').style.display != 'none' && document.getElementById('science').style.visibility != 'hidden') { + if (game.global.challengeActive != "Transmute" && (getPlayerModifier() < getPerSecBeforeManual('Scientist') && hasTurkimp) || getPageSetting('RManualGather2') == 2) { setGather('metal'); - else - setGather(lowestResource);//gather the lowest resource - } else if (hasTurkimp) - setGather('metal'); - else - setGather(lowestResource); - //ok - return true; + } else if (getPageSetting('RManualGather2') != 2) { + setGather('science'); + } + } + else if (trapTrimpsOK) { + if (game.buildings.Trap.owned < 5 && canAffordBuilding('Trap')) { + safeBuyBuilding('Trap'); + setGather('buildings'); + } else if (game.buildings.Trap.owned > 0) + setGather('trimps'); + } + + //ALL FAIL + else { + setGather('metal'); + } } diff --git a/modules/heirlooms.js b/modules/heirlooms.js index 9c4dd20de..8cc860478 100644 --- a/modules/heirlooms.js +++ b/modules/heirlooms.js @@ -1,518 +1,436 @@ -//MODULES["heirlooms"] = {}; -//////////////////////////////////////// -//Heirloom Functions//////////////////// -//////////////////////////////////////// - -//OLD: -//renamed from sortHeirlooms to worthOfHeirlooms -var worth = {'Shield': {}, 'Staff': {}}; -function worthOfHeirlooms(){ - worth = {'Shield': {}, 'Staff': {}}; - for (var loom in game.global.heirloomsExtra) { - var theLoom = game.global.heirloomsExtra[loom]; - worth[theLoom.type][loom] = theLoom.rarity; - } +var animated = (game.options.menu.showHeirloomAnimations.enabled) ? "animated " : ""; +var hrlmProtBtn1=document.createElement('DIV');hrlmProtBtn1.setAttribute('class','noselect heirloomBtnActive heirBtn'),hrlmProtBtn1.setAttribute('onclick','protectHeirloom(this, true)'),hrlmProtBtn1.innerHTML='Protect/Unprotect',hrlmProtBtn1.id='protectHeirloomBTN1';var hrlmProtBtn2=document.createElement('DIV');hrlmProtBtn2.setAttribute('class','noselect heirloomBtnActive heirBtn'),hrlmProtBtn2.setAttribute('onclick','protectHeirloom(this, true)'),hrlmProtBtn2.innerHTML='Protect/Unprotect',hrlmProtBtn2.id='protectHeirloomBTN2';var hrlmProtBtn3=document.createElement('DIV');hrlmProtBtn3.setAttribute('class','noselect heirloomBtnActive heirBtn'),hrlmProtBtn3.setAttribute('onclick','protectHeirloom(this, true)'),hrlmProtBtn3.innerHTML='Protect/Unprotect',hrlmProtBtn3.id='protectHeirloomBTN3',document.getElementById('equippedHeirloomsBtnGroup').appendChild(hrlmProtBtn1),document.getElementById('carriedHeirloomsBtnGroup').appendChild(hrlmProtBtn2),document.getElementById('extraHeirloomsBtnGroup').appendChild(hrlmProtBtn3); +function protectHeirloom(a,b){var c=game.global.selectedHeirloom,d=c[1],e=game.global[d];if(-1!=c[0])var e=e[c[0]];b&&(e.protected=!e.protected),a||(d.includes("Equipped")?a=document.getElementById("protectHeirloomBTN1"):"heirloomsCarried"==d?a=document.getElementById("protectHeirloomBTN2"):"heirloomsExtra"==d&&(a=document.getElementById("protectHeirloomBTN3"))),a&&(a.innerHTML=e.protected?"UnProtect":"Protect")} +function newSelectHeirloom(a,b,c){selectHeirloom(a,b,c),protectHeirloom()} +function highdmgshield(){for(loom of game.global.heirloomsCarried)if(loom.name==getPageSetting('highdmg'))return loom;} +function lowdmgshield(){for(loom of game.global.heirloomsCarried)if(loom.name==getPageSetting('lowdmg'))return loom;} +function dhighdmgshield(){for(loom of game.global.heirloomsCarried)if(loom.name==getPageSetting('dhighdmg'))return loom;} +function dlowdmgshield(){for(loom of game.global.heirloomsCarried)if(loom.name==getPageSetting('dlowdmg'))return loom;} - //sort high to low value, priority on rarity, followed by mod evaluation - for (var x in worth){ - worth[x] = Object.keys(worth[x]).sort(function(a, b) { - if(worth[x][b] == worth[x][a]) { - return evaluateHeirloomMods(b, 'heirloomsExtra') - evaluateHeirloomMods(a, 'heirloomsExtra'); - } - else - return worth[x][b] - worth[x][a]; - }); - } +function getHeirloomEff(name, type) { + if (type == "staff") { + if (getPageSetting('slot1modst') == name) return 5; + else if (getPageSetting('slot2modst') == name) return 5; + else if (getPageSetting('slot3modst') == name) return 5; + else if (getPageSetting('slot4modst') == name) return 5; + else if (getPageSetting('slot5modst') == name) return 5; + else if (getPageSetting('slot6modst') == name) return 5; + else if (getPageSetting('slot7modst') == name) return 5; + else return 0; + } + else if (type == "shield") { + if (getPageSetting('slot1modsh') == name) return 5; + else if (getPageSetting('slot2modsh') == name) return 5; + else if (getPageSetting('slot3modsh') == name) return 5; + else if (getPageSetting('slot4modsh') == name) return 5; + else if (getPageSetting('slot5modsh') == name) return 5; + else if (getPageSetting('slot6modsh') == name) return 5; + else if (getPageSetting('slot7modsh') == name) return 5; + else return 0; + } + else if (type == "core") { + if (getPageSetting('slot1modcr') == name) return 5; + else if (getPageSetting('slot2modcr') == name) return 5; + else if (getPageSetting('slot3modcr') == name) return 5; + else if (getPageSetting('slot4modcr') == name) return 5; + else return 0; + } } +function evaluateHeirloomMods2(loom, location) { + + var index = loom; + var eff = 0; + var name; + var type; + var rarity; + var raretokeep = getPageSetting('raretokeep'); + if (raretokeep == 'Any' || raretokeep == 'Common') raretokeep = 0; + else if (raretokeep == 'Uncommon') raretokeep = 1; + else if (raretokeep == 'Rare') raretokeep = 2; + else if (raretokeep == 'Epic') raretokeep = 3; + else if (raretokeep == 'Legendary') raretokeep = 4; + else if (raretokeep == 'Magnificent') raretokeep = 5; + else if (raretokeep == 'Ethereal') raretokeep = 6; + else if (raretokeep == 'Magmatic') raretokeep = 7; + else if (raretokeep == 'Plagued') raretokeep = 8; + else if (raretokeep == 'Radiating') raretokeep = 9; + else if (raretokeep == 'Hazardous') raretokeep = 10; + else if (raretokeep == 'Enigmatic') raretokeep = 11; -//NEW: -//makes an array of heirlooms sitting in the temporary extra area to indicate to the autoHeirlooms2() function which to Carry/Drop -var worth2 = {'Shield': [], 'Staff': []}; -function worthOfHeirlooms2(){ - worth2 = {'Shield': [], 'Staff': []}; + if (location.includes('Equipped')) + loom = game.global[location]; + else + loom = game.global[location][loom]; + + for (var m in loom.mods) { + name = loom.mods[m][0]; + type = loom.type; + rarity = loom.rarity; + if (type == "Shield") { + eff += getHeirloomEff(name, "shield"); + } + if (type == "Staff") { + eff += getHeirloomEff(name, "staff"); + } + if (type == "Core") { + eff += getHeirloomEff(name, "core"); + } + if (rarity >= raretokeep) { + eff += 1000; + } + if (name == "empty" && type == "Shield") { + eff *= 4; + } + if (name == "empty" && type == "Staff") { + eff *= 4; + } + if (name == "empty" && type == "Core") { + eff *= 4; + } + if (rarity >= raretokeep) { + eff *= 10000; + } + else if (rarity < raretokeep) { + eff /= 10000; + } + } + return eff; +} + +var worth3 = {'Shield': [], 'Staff': [], 'Core': []}; +function worthOfHeirlooms3(){ + worth3 = {'Shield': [], 'Staff': [], 'Core': []}; for (var index in game.global.heirloomsExtra) { var theLoom = game.global.heirloomsExtra[index]; - var data = {'location': 'heirloomsExtra', 'index': index, 'rarity': theLoom.rarity, 'eff': evaluateHeirloomMods(index, 'heirloomsExtra')}; - worth2[theLoom.type].push(data); - } - //sort algorithm: high to low value, priority on rarity, followed by mod evaluation - var valuesort = function(a, b) { - if(b.rarity == a.rarity) { - return b.eff - a.eff; - } - else - return b.rarity - a.rarity; - }; - // sort shield - worth2['Shield'].sort(valuesort); - // sort staff - worth2['Staff'].sort(valuesort); - - //Output each carried Heirlooms worth to console (or say heirloomsExtra instead) - /* - for(var index in game.global.heirloomsCarried) { - console.log(evaluateHeirloomMods(index, 'heirloomsCarried')); + var data = {'location': 'heirloomsExtra', 'index': index, 'rarity': theLoom.rarity, 'eff': evaluateHeirloomMods2(index, 'heirloomsExtra')}; + worth3[theLoom.type].push(data); } - */ + var valuesort = function(a, b){return b.eff - a.eff;}; + worth3['Shield'].sort(valuesort); + worth3['Staff'].sort(valuesort); + worth3['Core'].sort(valuesort); } -//Automatically evaluate and carry the best heirlooms, and recommend upgrades for equipped items. AutoHeirlooms will only change carried items when the heirlooms window is not open. Carried items will be compared and swapped with the types that are already carried. If a carry spot is empty, it will be filled with the best shield (if available). Evaluation is based ONLY on the following mods (listed in order of priority, high to low): Void Map Drop Chance/Trimp Attack, Crit Chance/Crit Damage, Miner Efficiency/Metal Drop, Gem Drop/Dragimp Efficiency, Farmer/Lumberjack Efficiency. For the purposes of carrying, rarity trumps all of the stat evaluations. Empty mod slots are valued at the average value of the best missing mod. -//NEW: -function autoHeirlooms2() { +function autoheirlooms3() { + if(!heirloomsShown && game.global.heirloomsExtra.length > 0){ - //PART 1: start by dropping ALL carried heirlooms var originalLength = game.global.heirloomsCarried.length; for(var index=0; index < originalLength; index++) { selectHeirloom(0, 'heirloomsCarried'); stopCarryHeirloom(); } - //PART 2: immediately begin carrying any protected heirlooms. + + //CARRY var originalLength = game.global.heirloomsExtra.length; for(var index=0; index < originalLength; index++) { var theLoom = game.global.heirloomsExtra[index]; - if ((theLoom.protected) && (game.global.heirloomsCarried.length < game.global.maxCarriedHeirlooms)){ + if ((theLoom.protected) && (game.global.heirloomsCarried.length < getMaxCarriedHeirlooms())){ selectHeirloom(index, 'heirloomsExtra'); carryHeirloom(); - index--; originalLength--; //stop index-skipping/re-ordering (idk how else to do it). + index--; originalLength--; } } - worthOfHeirlooms2(); - //now start by re-filling any empty carried slots with the most highly evaluated heirlooms - //Alternates EQUALLY between Shield and Staff, putting the best ones of each. - //PART 3: - while ((game.global.heirloomsCarried.length < game.global.maxCarriedHeirlooms) && game.global.heirloomsExtra.length > 0){ - //re-evaluate their worth (needed to refresh the worth array since we for sure re-arranged everything.) - worthOfHeirlooms2(); - if (worth2["Shield"].length > 0){ - var carryshield = worth2["Shield"].shift(); - selectHeirloom(carryshield.index, 'heirloomsExtra'); - carryHeirloom(); - } - worthOfHeirlooms2(); - if (worth2["Staff"].length > 0){ - var carrystaff = worth2["Staff"].shift(); - selectHeirloom(carrystaff.index, 'heirloomsExtra'); - carryHeirloom(); - } - } - worthOfHeirlooms(); - // Doing the Alternating Shield/Staff method above can cause good heirlooms to remain un-carried, just because the above was trying to hard to balance. - // example: It picks up 4 ethereal shields and 2 ethereal staffs and 2 bad rare staffs, but there was actually a 5th good ethereal shield that it skipped. - // this will replace the lesser rarity or stat with the higher rarity or stat, either shield or staff. - //PART 4: - //Check each carried heirloom.... - for(var carried in game.global.heirloomsCarried) { - var theLoom = game.global.heirloomsCarried[carried]; - //... against the Opposite type - var opposite = {"Shield":"Staff", "Staff":"Shield"}; - if(worth[opposite[theLoom.type]].length == 0) continue; //end loop quick if absolutely nothin to swap in - var index = worth[opposite[theLoom.type]][0]; - //... and compare the carried against the best worth opposite type in the extra pile. (since part 3 above took care of the bests of each same type) - if(theLoom.rarity < game.global.heirloomsExtra[index].rarity) { - if (!theLoom.protected){ - selectHeirloom(carried, 'heirloomsCarried'); - stopCarryHeirloom(); - selectHeirloom(index, 'heirloomsExtra'); - carryHeirloom(); - worthOfHeirlooms(); + + //SHIELD + if (getPageSetting('typetokeep') == 1) { + while ((game.global.heirloomsCarried.length < getMaxCarriedHeirlooms()) && game.global.heirloomsExtra.length > 0){ + worthOfHeirlooms3(); + if (worth3["Shield"].length > 0){ + var carryshield = worth3["Shield"].shift(); + selectHeirloom(carryshield.index, 'heirloomsExtra'); + carryHeirloom(); + } + else break; } - //do nothing if the carried thing was protected. - } - } - } - else if(heirloomsShown && game.global.selectedHeirloom.length > 0){ - heirloomUpgradeHighlighting(); - } -} + } -//OLD: -function autoHeirlooms() { - if(!heirloomsShown && game.global.heirloomsExtra.length > 0){ - //start by immediately carrying any protected heirlooms. - for(var extra in game.global.heirloomsExtra) { - var theLoom = game.global.heirloomsExtra[extra]; - if ((theLoom.protected) && (game.global.heirloomsCarried.length < game.global.maxCarriedHeirlooms)){ - selectHeirloom(extra, 'heirloomsExtra'); - carryHeirloom(); - } - } - //re-evaluate their worth (needed to refresh the worth array since we possibly moved the extras) - worthOfHeirlooms(); - for(var carried in game.global.heirloomsCarried) { - var theLoom = game.global.heirloomsCarried[carried]; - if(worth[theLoom.type].length == 0) continue; - var index = worth[theLoom.type][0]; - if(theLoom.rarity < game.global.heirloomsExtra[index].rarity || (theLoom.rarity == game.global.heirloomsExtra[index].rarity && evaluateHeirloomMods(carried, 'heirloomsCarried') < evaluateHeirloomMods(index, 'heirloomsExtra'))) { - if (!theLoom.protected){ - selectHeirloom(carried, 'heirloomsCarried'); - stopCarryHeirloom(); - selectHeirloom(index, 'heirloomsExtra'); - carryHeirloom(); - worthOfHeirlooms(); + //STAFF + else if (getPageSetting('typetokeep') == 2) { + while ((game.global.heirloomsCarried.length < getMaxCarriedHeirlooms()) && game.global.heirloomsExtra.length > 0){ + worthOfHeirlooms3(); + if (worth3["Staff"].length > 0){ + var carrystaff = worth3["Staff"].shift(); + selectHeirloom(carrystaff.index, 'heirloomsExtra'); + carryHeirloom(); + } + else break; } - } - } - if (game.global.heirloomsCarried.length < game.global.maxCarriedHeirlooms){ - if(worth.Shield.length > 0) - selectHeirloom(worth.Shield[0], 'heirloomsExtra'); - else if(worth.Staff.length > 0) - selectHeirloom(worth.Staff[0], 'heirloomsExtra'); - carryHeirloom(); - } - } - else if(heirloomsShown && game.global.selectedHeirloom.length > 0){ - heirloomUpgradeHighlighting(); - } -} + } -//common to both autoheirloom1 and 2 -//Shows you which Mod you would be best off upgrading in the heirloom window by highlighting it in blueish gray and a tooltip. -function heirloomUpgradeHighlighting() { - var bestUpgrade; - if(game.global.selectedHeirloom[1].includes('Equipped')) { - var loom = game.global[game.global.selectedHeirloom[1]]; - bestUpgrade = evaluateHeirloomMods(0, game.global.selectedHeirloom[1], true); - if(bestUpgrade.index) { - bestUpgrade.effect *= getModUpgradeCost(loom, bestUpgrade.index); - bestUpgrade.effect = bestUpgrade.effect.toFixed(6); - var styleIndex = 4 + (bestUpgrade.index * 3); - //enclose in backtic ` for template string $ stuff - document.getElementById('selectedHeirloom').childNodes[0].childNodes[styleIndex].style.backgroundColor = "lightblue"; - document.getElementById('selectedHeirloom').childNodes[0].childNodes[styleIndex].setAttribute("onmouseover", `tooltip(\'Heirloom\', \"customText\", event, \'
AutoTrimps recommended upgrade for this item.
\' )`); - document.getElementById('selectedHeirloom').childNodes[0].childNodes[styleIndex].setAttribute("onmouseout", 'tooltip(\'hide\')'); - //lightblue = greyish - //swapClass("tooltipExtra", "tooltipExtraHeirloom", document.getElementById("tooltipDiv")); - //document.getElementById("tooltipDiv"); - } + //CORE + else if (getPageSetting('typetokeep') == 3) { + while ((game.global.heirloomsCarried.length < getMaxCarriedHeirlooms()) && game.global.heirloomsExtra.length > 0){ + worthOfHeirlooms3(); + if (worth3["Core"].length > 0){ + var carrycore = worth3["Core"].shift(); + selectHeirloom(carrycore.index, 'heirloomsExtra'); + carryHeirloom(); + } + else break; + } + } + + //ALL + else if (getPageSetting('typetokeep') == 4) { + while ((game.global.heirloomsCarried.length < getMaxCarriedHeirlooms()) && game.global.heirloomsExtra.length > 0){ + worthOfHeirlooms3(); + if (worth3["Shield"].length > 0){ + var carryshield = worth3["Shield"].shift(); + selectHeirloom(carryshield.index, 'heirloomsExtra'); + carryHeirloom(); + } + worthOfHeirlooms3(); + if (worth3["Staff"].length > 0){ + var carrystaff = worth3["Staff"].shift(); + selectHeirloom(carrystaff.index, 'heirloomsExtra'); + carryHeirloom(); + } + worthOfHeirlooms3(); + if (worth3["Core"].length > 0){ + var carrycore = worth3["Core"].shift(); + selectHeirloom(carrycore.index, 'heirloomsExtra'); + carryHeirloom(); + } + } + } } } -//Automatically upgrades the best mod on the equipped shield and equipped staff. Runs until you run out of nullifium. -//Do not tamper with this. -function autoNull(){try { - for(var e,d=[game.global.ShieldEquipped,game.global.StaffEquipped],o=0;2>o;o++){var l=d[o];if(e=evaluateHeirloomMods(0,l.type+"Equipped",!0),e.index){selectedMod=e.index;var a=getModUpgradeCost(l,selectedMod);if(game.global.nullifium 300){ - unequipHeirloom(game.global.ShieldEquipped, "heirloomsCarried"); - game.global.ShieldEquipped = heirloom; - game.global.heirloomsCarried.splice(count, 1); - } - } - count++; - } - for (var item in heirloom.mods){ - game.heirlooms[heirloom.type][heirloom.mods[item][0]].currentBonus += heirloom.mods[item][1]; - } - populateHeirloomWindow(); - //-------OK------ +//Nu + +function calcLoomNu(slot) { + nuloom(); + var heirloom = getSelectedHeirloom(); + var tot = 0; + var thisMod = heirloom.mods[slot]; + var dummyHeirloom = setupDummyHeirloom(heirloom, thisMod); + tot = countPriceOfUpgrades(dummyHeirloom, heirloom.mods[slot][3]); + var result = Math.floor(tot) + Math.floor(game.heirlooms.values[heirloom.rarity] / 2); + if (isNumberBad(result)) return 0; + return result; } -*/ -//Heirloom helper function -function checkForMod(what, loom, location){ - var heirloom = game.global[location][loom]; - for (var mod in heirloom.mods){ - if (heirloom.mods[mod][0] == what) return true; - } - return false; +function calcLoomNuInfinity(slot) { + nuloom(); + var heirloom = getSelectedHeirloom(); + if (Math.ceil(getModUpgradeCost(heirloom, slot, 1)) != "Infinity") { + return true; + } else { + return false; + } } -//Determines the best heirloom mods -function evaluateHeirloomMods(loom, location, upgrade) { - var index = loom; - var bestUpgrade = { - 'index': null, - 'name': '', - 'effect': 0 - }; - var tempEff; - var steps; - if(location.includes('Equipped')) - loom = game.global[location]; - else - loom = game.global[location][loom]; - // return loom.rarity; - var eff = 0; - for(var m in loom.mods) { - var critmult = getPlayerCritDamageMult(); - var critchance = getPlayerCritChance(); - var cmb = (critmult - game.heirlooms.Shield.critDamage.currentBonus/100); - var ccb = (critchance - game.heirlooms.Shield.critChance.currentBonus/100); - switch(loom.mods[m][0]) { - case 'critChance': - tempEff = ((loom.mods[m][1]/100) * cmb)/(ccb * cmb + 1 - ccb); - eff += tempEff; - if(upgrade){ - if(loom.mods[m][1] >= 30) break; - steps = game.heirlooms.Shield.critChance.steps[loom.rarity]; - tempEff = ((steps[2]/100) * critmult)/((critchance * critmult) + 1 - critchance); - tempEff = tempEff / getModUpgradeCost(loom, m); - if(tempEff > bestUpgrade.effect) { - bestUpgrade.effect = tempEff; - bestUpgrade.name = 'critChance'; - bestUpgrade.index = m; - } - } - break; - case 'critDamage': - tempEff = ((loom.mods[m][1]/100) * ccb)/(cmb * ccb + 1 - ccb); - eff += tempEff; - if(upgrade){ - steps = game.heirlooms.Shield.critDamage.steps[loom.rarity]; - tempEff = ((steps[2]/100)* critchance)/((critchance * critmult) + 1 - critchance); - tempEff = tempEff / getModUpgradeCost(loom, m); - if(tempEff > bestUpgrade.effect) { - bestUpgrade.effect = tempEff; - bestUpgrade.name = 'critDamage'; - bestUpgrade.index = m; - } - } - break; - case 'trimpAttack': - tempEff = loom.mods[m][1]/100; - eff += tempEff; - if(upgrade){ - steps = game.heirlooms.Shield.trimpAttack.steps[loom.rarity]; - tempEff = (steps[2]/100)/((game.heirlooms.Shield.trimpAttack.currentBonus/100) + 1); - tempEff = tempEff / getModUpgradeCost(loom, m); - if(tempEff > bestUpgrade.effect) { - bestUpgrade.effect = tempEff; - bestUpgrade.name = 'trimpAttack'; - bestUpgrade.index = m; - } - } - break; - case 'voidMaps': - tempEff = loom.mods[m][1]/100; - eff += tempEff; - if(upgrade){ - steps = game.heirlooms.Shield.voidMaps.steps[loom.rarity]; - tempEff = (steps[2]/100)/((game.heirlooms.Shield.voidMaps.currentBonus/100) + 1); - tempEff = tempEff / getModUpgradeCost(loom, m); - if(tempEff > bestUpgrade.effect) { - bestUpgrade.effect = tempEff; - bestUpgrade.name = 'voidMaps'; - bestUpgrade.index = m; - } - } - break; - case 'MinerSpeed': - tempEff = 0.75*loom.mods[m][1]/100; - eff += tempEff; - if(upgrade) { - steps = game.heirlooms.defaultSteps[loom.rarity]; - tempEff = (0.75*steps[2]/100)/((game.heirlooms.Staff.MinerSpeed.currentBonus/100) + 1); - tempEff = tempEff / getModUpgradeCost(loom, m); - if(tempEff > bestUpgrade.effect) { - bestUpgrade.effect = tempEff; - bestUpgrade.name = 'MinerSpeed'; - bestUpgrade.index = m; - } - } - break; - case 'metalDrop': - tempEff = 0.75*loom.mods[m][1]/100; - eff += tempEff; - if(upgrade) { - steps = game.heirlooms.defaultSteps[loom.rarity]; - tempEff = (0.75*steps[2]/100)/((game.heirlooms.Staff.metalDrop.currentBonus/100) + 1); - tempEff = tempEff / getModUpgradeCost(loom, m); - if(tempEff > bestUpgrade.effect) { - bestUpgrade.effect = tempEff; - bestUpgrade.name = 'metalDrop'; - bestUpgrade.index = m; - } - } - break; - case 'DragimpSpeed': - tempEff = 0.75*loom.mods[m][1]/100; - eff += tempEff; - if(upgrade) { - steps = game.heirlooms.defaultSteps[loom.rarity]; - tempEff = (0.75*steps[2]/100)/((game.heirlooms.Staff.DragimpSpeed.currentBonus/100) + 1); - tempEff = tempEff / getModUpgradeCost(loom, m); - if(tempEff > bestUpgrade.effect) { - bestUpgrade.effect = tempEff; - bestUpgrade.name = 'DragimpSpeed'; - bestUpgrade.index = m; - } - } - break; - case 'gemsDrop': - tempEff = 0.75*loom.mods[m][1]/100; - eff += tempEff; - if(upgrade) { - steps = game.heirlooms.defaultSteps[loom.rarity]; - tempEff = (0.75*steps[2]/100)/((game.heirlooms.Staff.gemsDrop.currentBonus/100) + 1); - tempEff = tempEff / getModUpgradeCost(loom, m); - if(tempEff > bestUpgrade.effect) { - bestUpgrade.effect = tempEff; - bestUpgrade.name = 'gemsDrop'; - bestUpgrade.index = m; - } - } - break; - case 'FarmerSpeed': - tempEff = 0.5*loom.mods[m][1]/100; - eff += tempEff; - if(upgrade) { - steps = game.heirlooms.defaultSteps[loom.rarity]; - tempEff = (0.5*steps[2]/100)/((game.heirlooms.Staff.FarmerSpeed.currentBonus/100) + 1); - tempEff = tempEff / getModUpgradeCost(loom, m); - if(tempEff > bestUpgrade.effect) { - bestUpgrade.effect = tempEff; - bestUpgrade.name = 'FarmerSpeed'; - bestUpgrade.index = m; - } - } - break; - case 'LumberjackSpeed': - tempEff = 0.5*loom.mods[m][1]/100; - eff += tempEff; - if(upgrade) { - steps = game.heirlooms.defaultSteps[loom.rarity]; - tempEff = (0.5*steps[2]/100)/((game.heirlooms.Staff.LumberjackSpeed.currentBonus/100) + 1); - tempEff = tempEff / getModUpgradeCost(loom, m); - if(tempEff > bestUpgrade.effect) { - bestUpgrade.effect = tempEff; - bestUpgrade.name = 'LumberjackSpeed'; - bestUpgrade.index = m; - } - } - break; - case 'empty': - var av; - if(upgrade) break; - //value empty mod as the average of the best mod it doesn't have. If it has all good mods, empty slot has no value - if(loom.type == 'Shield') { - if(!checkForMod('trimpAttack', index, location)){ - steps = game.heirlooms[loom.type].trimpAttack.steps[loom.rarity]; - av = steps[0] + ((steps[1] - steps[0])/2); - tempEff = av/100; - eff += tempEff; - } - else if(!checkForMod('voidMaps', index, location)){ - steps = game.heirlooms[loom.type].voidMaps.steps[loom.rarity]; - av = steps[0] + ((steps[1] - steps[0])/2); - tempEff = (steps[2]/100); - eff += tempEff; - } - else if(!checkForMod('critChance', index, location)){ - steps = game.heirlooms[loom.type].critChance.steps[loom.rarity]; - av = steps[0] + ((steps[1] - steps[0])/2); - tempEff = (av * cmb)/(ccb * cmb + 1 - ccb); - eff += tempEff; - } - else if(!checkForMod('critDamage', index, location)){ - steps = game.heirlooms[loom.type].critDamage.steps[loom.rarity]; - av = steps[0] + ((steps[1] - steps[0])/2); - tempEff = (av * ccb)/(cmb * ccb + 1 - ccb); - eff += tempEff; - } - } - if(loom.type == 'Staff') { - steps = game.heirlooms.defaultSteps[loom.rarity]; - av = steps[0] + ((steps[1] - steps[0])/2); - if(!checkForMod('MinerSpeed', index, location) || !checkForMod('metalDrop', index, location) || !checkForMod('DragimpSpeed', index, location) || !checkForMod('gemsDrop', index, location)){ - eff += 0.75*av/100; - } - else if(!checkForMod('FarmerSpeed', index, location) || !checkForMod('LumberjackSpeed', index, location)) { - eff += 0.5*av/100; - } - } - break; - //trimpHealth? - } - } - if(upgrade) return bestUpgrade; - return eff; +function calcAutoNuRatio(slot) { + nuloom(); + var heirloom = getSelectedHeirloom(); + + //Shield + if (heirloom.mods[slot][0] == "critChance") + return 100; + else if (heirloom.mods[slot][0] == "voidMaps") + return 95; + else if (heirloom.mods[slot][0] == "plaguebringer") + return 85; + else if (heirloom.mods[slot][0] == "trimpAttack") + return 75; + else if (heirloom.mods[slot][0] == "critDamage") + return 54; + else if (heirloom.mods[slot][0] == "trimpHealth") + return 50; + else if (heirloom.mods[slot][0] == "storageSize") + return 7; + else if (heirloom.mods[slot][0] == "trimpBlock") + return 4; + else if (heirloom.mods[slot][0] == "trainerEfficiency") + return 2.8; + else if (heirloom.mods[slot][0] == "breedSpeed") + return 2; + else if (heirloom.mods[slot][0] == "playerEfficiency") + return 0.3; + else if (heirloom.mods[slot][0] == "prismatic") + return 50; + else if (heirloom.mods[slot][0] == "gammaBurst") + return 25; + + //Staff + else if (heirloom.mods[slot][0] == "FluffyExp") + return 100; + else if (heirloom.mods[slot][0] == "fragmentsDrop") + return 8; + else if (heirloom.mods[slot][0] == "ExplorerSpeed") + return 7; + else if (heirloom.mods[slot][0] == "metalDrop") + return 6; + else if (heirloom.mods[slot][0] == "minerSpeed") + return 5; + else if (heirloom.mods[slot][0] == "woodDrop") + return 1; + else if (heirloom.mods[slot][0] == "LumberjackSpeed") + return 0.8; + else if (heirloom.mods[slot][0] == "foodDrop") + return 0.2; + else if (heirloom.mods[slot][0] == "FarmerSpeed") + return 0.05; + else if (heirloom.mods[slot][0] == "DragimpSpeed") + return 0.04; + else if (heirloom.mods[slot][0] == "gemsDrop") + return 0.03; + else if (heirloom.mods[slot][0] == "ScientistSpeed") + return 0.03; + + //Core + else if (heirloom.mods[slot][0] == "fireTrap") + return 50; + else if (heirloom.mods[slot][0] == "poisonTrap") + return 50; + else if (heirloom.mods[slot][0] == "lightningTrap") + return 100; + else if (heirloom.mods[slot][0] == "runestones") + return 85; + else if (heirloom.mods[slot][0] == "strengthEffect") + return 50; + else if (heirloom.mods[slot][0] == "condenserEffect") + return 150; } +function nuRatio() { + + //Find Nu Ratio + var slot1, slot1r, slot2, slot2r, slot3, slot3r, slot4, slot4r, slot5, slot6, slot5r, slot6r, slot1spend, slot1spendr, slot2spend, slot2spendr, slot3spend, slot3spendr, slot4spend, slot4spendr, slot5spend, slot5spendr, slot6spend, slot6spendr; + + slot1 = calcLoomNuInfinity(0) ? calcLoomNu(0) : 0; + slot2 = calcLoomNuInfinity(1) ? calcLoomNu(1) : 0; + slot3 = calcLoomNuInfinity(2) ? calcLoomNu(2) : 0; + slot4 = calcLoomNuInfinity(3) ? calcLoomNu(3) : 0; + slot5 = calcLoomNuInfinity(4) ? calcLoomNu(4) : 0; + slot6 = calcLoomNuInfinity(5) ? calcLoomNu(5) : 0; + + var total = (slot1 + slot2 + slot3 + slot4 + slot5 + slot6); + + slot1r = (slot1 != 0 && calcLoomNuInfinity(0)) ? ((slot1 / total)*100) : 1; + slot2r = (slot2 != 0 && calcLoomNuInfinity(1)) ? ((slot2 / total)*100) : 1; + slot3r = (slot3 != 0 && calcLoomNuInfinity(2)) ? ((slot3 / total)*100) : 1; + slot4r = (slot4 != 0 && calcLoomNuInfinity(3)) ? ((slot4 / total)*100) : 1; + slot5r = (slot5 != 0 && calcLoomNuInfinity(4)) ? ((slot5 / total)*100) : 1; + slot5r = (slot6 != 0 && calcLoomNuInfinity(5)) ? ((slot6 / total)*100) : 1; + + //Find Player ratio + if (getPageSetting('autonu') == true && getPageSetting('rationu') == 0 && getPageSetting('heirloomnu') != undefined) { + slot1spend = (getPageSetting('slot1nu') > 0 && calcLoomNuInfinity(0)) ? getPageSetting('slot1nu') : 0; + slot2spend = (getPageSetting('slot2nu') > 0 && calcLoomNuInfinity(1)) ? getPageSetting('slot2nu') : 0; + slot3spend = (getPageSetting('slot3nu') > 0 && calcLoomNuInfinity(2)) ? getPageSetting('slot3nu') : 0; + slot4spend = (getPageSetting('slot4nu') > 0 && calcLoomNuInfinity(3)) ? getPageSetting('slot4nu') : 0; + slot5spend = (getPageSetting('slot5nu') > 0 && calcLoomNuInfinity(4)) ? getPageSetting('slot5nu') : 0; + slot5spend = (getPageSetting('slot6nu') > 0 && calcLoomNuInfinity(5)) ? getPageSetting('slot6nu') : 0; + } + + if (getPageSetting('autonu') == true && getPageSetting('rationu') == 1 && getPageSetting('heirloomnu') != undefined) { + slot1spend = (calcLoomNuInfinity(0)) ? calcAutoNuRatio(0) : 0; + slot2spend = (calcLoomNuInfinity(1)) ? calcAutoNuRatio(1) : 0; + slot3spend = (calcLoomNuInfinity(2)) ? calcAutoNuRatio(2) : 0; + slot4spend = (calcLoomNuInfinity(3)) ? calcAutoNuRatio(3) : 0; + slot5spend = (calcLoomNuInfinity(4)) ? calcAutoNuRatio(4) : 0; + slot5spend = (calcLoomNuInfinity(5)) ? calcAutoNuRatio(5) : 0; + } + + var totalspend = (slot1spend + slot2spend + slot3spend + slot4spend + slot5spend + slot6spend); + + slot1spendr = (slot1spend > 0) ? ((slot1spend / totalspend)*100) : 0; + slot2spendr = (slot2spend > 0) ? ((slot2spend / totalspend)*100) : 0; + slot3spendr = (slot3spend > 0) ? ((slot3spend / totalspend)*100) : 0; + slot4spendr = (slot4spend > 0) ? ((slot4spend / totalspend)*100) : 0; + slot5spendr = (slot5spend > 0) ? ((slot5spend / totalspend)*100) : 0; + slot6spendr = (slot6spend > 0) ? ((slot6spend / totalspend)*100) : 0; + + //Find Next Spend + var slot1final = slot1spendr - slot1r; + var slot2final = slot2spendr - slot2r; + var slot3final = slot3spendr - slot3r; + var slot4final = slot4spendr - slot4r; + var slot5final = slot5spendr - slot5r; + var slot6final = slot6spendr - slot6r; + + var ratios = []; + if (slot1final != -1) { + ratios.push(slot1final); + } + if (slot2final != -1) { + ratios.push(slot2final); + } + if (slot3final != -1) { + ratios.push(slot3final); + } + if (slot4final != -1) { + ratios.push(slot4final); + } + if (slot5final != -1) { + ratios.push(slot5final); + } + if (slot6final != -1) { + ratios.push(slot6final); + } -var hrlmProtBtn1 = document.createElement("DIV"); -hrlmProtBtn1.setAttribute('class', 'noselect heirloomBtnActive heirBtn'); -hrlmProtBtn1.setAttribute('onclick', 'protectHeirloom(this, true)'); -hrlmProtBtn1.innerHTML = 'Protect/Unprotect'; //since we cannot detect the selected heirloom on load, ambiguous name -hrlmProtBtn1.id='protectHeirloomBTN1'; -var hrlmProtBtn2 = document.createElement("DIV"); -hrlmProtBtn2.setAttribute('class', 'noselect heirloomBtnActive heirBtn'); -hrlmProtBtn2.setAttribute('onclick', 'protectHeirloom(this, true)'); -hrlmProtBtn2.innerHTML = 'Protect/Unprotect'; -hrlmProtBtn2.id='protectHeirloomBTN2'; -var hrlmProtBtn3 = document.createElement("DIV"); -hrlmProtBtn3.setAttribute('class', 'noselect heirloomBtnActive heirBtn'); -hrlmProtBtn3.setAttribute('onclick', 'protectHeirloom(this, true)'); -hrlmProtBtn3.innerHTML = 'Protect/Unprotect'; -hrlmProtBtn3.id='protectHeirloomBTN3'; -document.getElementById('equippedHeirloomsBtnGroup').appendChild(hrlmProtBtn1); -document.getElementById('carriedHeirloomsBtnGroup').appendChild(hrlmProtBtn2); -document.getElementById('extraHeirloomsBtnGroup').appendChild(hrlmProtBtn3); - - -function protectHeirloom(element, modify){ - var selheirloom = game.global.selectedHeirloom; //[number, location] - var heirloomlocation = selheirloom[1]; - var heirloom = game.global[heirloomlocation]; - if (selheirloom[0] != -1) - var heirloom = heirloom[selheirloom[0]]; - //hard way ^^, easy way>> - //var heirloom = getSelectedHeirloom(); - if (modify) //sent by onclick of protect button, to toggle the state. - heirloom.protected = !heirloom.protected; - - if (!element) { //then we came from newSelectHeirloom - if (heirloomlocation.includes("Equipped")) - element = document.getElementById('protectHeirloomBTN1'); - else if (heirloomlocation == "heirloomsCarried") - element = document.getElementById('protectHeirloomBTN2'); - else if (heirloomlocation == "heirloomsExtra") - element = document.getElementById('protectHeirloomBTN3'); + if (ratios.length > 0) { + ratios.sort(function(a, b){return b-a;}); } - if (element) - element.innerHTML = heirloom.protected ? 'UnProtect' : 'Protect'; + + //Return Next Spend + if (ratios[0] == slot1final) + return 0; + if (ratios[0] == slot2final) + return 1; + if (ratios[0] == slot3final) + return 2; + if (ratios[0] == slot4final) + return 3; + if (ratios[0] == slot5final) + return 4; + if (ratios[0] == slot6final) + return 5; } -//wrapper for selectHeirloom, to handle the protect button -function newSelectHeirloom(number, location, elem){ - selectHeirloom(number, location, elem); - protectHeirloom(); +function spendNu() { + nuloom(); + var slot = nuRatio(); + if (game.global.nullifium >= (getModUpgradeCost(getSelectedHeirloom(), slot, 1))) { + selectMod(slot); + upgradeMod(true, 1); + } } -//replacement function that inserts a new onclick action into the heirloom icons so it can populate the proper Protect icon. (yes this is the best way to do it.) function generateHeirloomIcon(heirloom, location, number){ if (typeof heirloom.name === 'undefined') return ""; - var icon = (heirloom.type == "Shield") ? 'icomoon icon-shield3' : 'glyphicon glyphicon-grain'; - var html = ' '; return html; } + +//Radon +function Rhsshield1(){for(loom of game.global.heirloomsCarried)if(loom.name==getPageSetting('Rhs1'))return loom;} +function Rhsshield2(){for(loom of game.global.heirloomsCarried)if(loom.name==getPageSetting('Rhs2'))return loom;} +function Rdhsshield1(){for(loom of game.global.heirloomsCarried)if(loom.name==getPageSetting('Rdhs1'))return loom;} +function Rdhsshield2(){for(loom of game.global.heirloomsCarried)if(loom.name==getPageSetting('Rdhs2'))return loom;} +function Rhsworldstaff(){for(loom of game.global.heirloomsCarried)if(loom.name==getPageSetting('Rhsworldstaff'))return loom;} +function Rhsmapstaff(){for(loom of game.global.heirloomsCarried)if(loom.name==getPageSetting('Rhsmapstaff'))return loom;} +function Rhstributestaff(){for(loom of game.global.heirloomsCarried)if(loom.name==getPageSetting('Rhstributestaff'))return loom;} +function Rdhsworldstaff(){for(loom of game.global.heirloomsCarried)if(loom.name==getPageSetting('Rdhsworldstaff'))return loom;} +function Rdhsmapstaff(){for(loom of game.global.heirloomsCarried)if(loom.name==getPageSetting('Rdhsmapstaff'))return loom;} +function Rdhstributestaff(){for(loom of game.global.heirloomsCarried)if(loom.name==getPageSetting('Rdhstributestaff'))return loom;} + +function Rhsequip1() { + if (Rhsshield1() != "undefined" && game.global.ShieldEquipped.name != getPageSetting('Rhs1')) { + selectHeirloom(game.global.heirloomsCarried.indexOf(loom), "heirloomsCarried", true); + equipHeirloom(); + } +} +function Rhsequip2() { + if (Rhsshield2() != "undefined" && game.global.ShieldEquipped.name != getPageSetting('Rhs2')) { + selectHeirloom(game.global.heirloomsCarried.indexOf(loom), "heirloomsCarried", true); + equipHeirloom(); + } +} +function Rdhsequip1() { + if (Rdhsshield1() != "undefined" && game.global.ShieldEquipped.name != getPageSetting('Rdhs1')) { + selectHeirloom(game.global.heirloomsCarried.indexOf(loom), "heirloomsCarried", true); + equipHeirloom(); + } +} +function Rdhsequip2() { + if (Rdhsshield2() != "undefined" && game.global.ShieldEquipped.name != getPageSetting('Rdhs2')) { + selectHeirloom(game.global.heirloomsCarried.indexOf(loom), "heirloomsCarried", true); + equipHeirloom(); + } +} +function Rhsworldstaffequip() { + if (Rhsworldstaff() != "undefined" && game.global.StaffEquipped.name != getPageSetting('Rhsworldstaff')) { + selectHeirloom(game.global.heirloomsCarried.indexOf(loom), "heirloomsCarried", true); + equipHeirloom(); + } +} +function Rhsmapstaffequip() { + if (Rhsmapstaff() != "undefined" && game.global.StaffEquipped.name != getPageSetting('Rhsmapstaff')) { + selectHeirloom(game.global.heirloomsCarried.indexOf(loom), "heirloomsCarried", true); + equipHeirloom(); + } +} + +function Rhstributestaffequip() { + if (Rhstributestaff() != "undefined" && game.global.StaffEquipped.name != getPageSetting('Rhstributestaff')) { + selectHeirloom(game.global.heirloomsCarried.indexOf(loom), "heirloomsCarried", true); + equipHeirloom(); + } +} +function Rdhsworldstaffequip() { + if (Rdhsworldstaff() != "undefined" && game.global.StaffEquipped.name != getPageSetting('Rdhsworldstaff')) { + selectHeirloom(game.global.heirloomsCarried.indexOf(loom), "heirloomsCarried", true); + equipHeirloom(); + } +} +function Rdhsmapstaffequip() { + if (Rdhsmapstaff() != "undefined" && game.global.StaffEquipped.name != getPageSetting('Rdhsmapstaff')) { + selectHeirloom(game.global.heirloomsCarried.indexOf(loom), "heirloomsCarried", true); + equipHeirloom(); + } +} + +function Rdhstributestaffequip() { + if (Rdhstributestaff() != "undefined" && game.global.StaffEquipped.name != getPageSetting('Rdhstributestaff')) { + selectHeirloom(game.global.heirloomsCarried.indexOf(loom), "heirloomsCarried", true); + equipHeirloom(); + } +} + +function Rheirloomswap() { + + //Swapping Shields + if (getPageSetting('Rhsshield') != false) { + if (getPageSetting('Rhsz') > 0 && game.global.world < getPageSetting('Rhsz')) { + Rhsequip1(); + } + if (getPageSetting('Rhsz') > 0 && game.global.world >= getPageSetting('Rhsz')) { + Rhsequip2(); + } + } + //Swapping Staffs + if (getPageSetting('Rhsstaff') != false) { + if (getPageSetting('Rhsworldstaff') != "undefined" && game.global.mapsActive == false) { + Rhsworldstaffequip(); + } + if (getPageSetting('Rhsmapstaff') != "undefined" && (Rshouldtributefarm == false || getPageSetting('Rhstributestaff') == "undefined") && game.global.mapsActive == true) { + Rhsmapstaffequip(); + } + if (getPageSetting('Rhstributestaff') != "undefined" && getPageSetting('Rhsstaff') && Rshouldtributefarm == true && game.global.mapsActive == true) { + Rhstributestaffequip(); + } + } +} + +function Rdheirloomswap() { + + //Swapping Shields + if (getPageSetting('Rdhsshield') != false) { + if (getPageSetting('Rdhsz') > 0 && game.global.world < getPageSetting('Rdhsz')) { + Rhsequip1(); + } + if (getPageSetting('Rdhsz') > 0 && game.global.world >= getPageSetting('Rdhsz')) { + Rhsequip2(); + } + } + //Swapping Staffs + if (getPageSetting('Rdhsstaff') != false) { + if (getPageSetting('Rdhsworldstaff') != "undefined" && game.global.mapsActive == false) { + Rhsworldstaffequip(); + } + if (getPageSetting('Rdhsmapstaff') != "undefined" && (Rdshouldtributefarm == false || getPageSetting('Rdhstributestaff') == "undefined") && game.global.mapsActive == true) { + Rhsmapstaffequip(); + } + if (getPageSetting('Rdhstributestaff') != "undefined" && getPageSetting('Rdhsstaff') && Rdshouldtributefarm == true && game.global.mapsActive == true) { + Rhstributestaffequip(); + } + } +} + +function HeirloomShieldSwapped() { + if (!game.global.ShieldEquipped.rarity >= 10) return; + gammaBurstPct = (getHeirloomBonus("Shield", "gammaBurst") / 100) > 0 ? (getHeirloomBonus("Shield", "gammaBurst") / 100) : 1; + shieldEquipped = game.global.ShieldEquipped.id; +} diff --git a/modules/import-export.js b/modules/import-export.js index ba64e18dc..8f480eb81 100644 --- a/modules/import-export.js +++ b/modules/import-export.js @@ -1,7 +1,4 @@ MODULES["import-export"] = {}; - -//2018 AutoTrimps - genBTC, copied from SettingsGUI.js -//Create settings profile selection dropdown box in DOM. (import/export section) var $settingsProfiles; function settingsProfileMakeGUI() { var $settingsProfilesLabel = document.createElement("Label"); @@ -156,14 +153,12 @@ function onDeleteProfile() { debug("Successfully deleted profile #: " + target, "profile"); } - -//Handler for the popup/tooltip window for Import/Export/Default function ImportExportTooltip(what, event) { if (game.global.lockTooltip) return; var $elem = document.getElementById("tooltipDiv"); swapClass("tooltipExtra", "tooltipExtraNone", $elem); - var ondisplay = null; // if non-null, called after the tooltip is displayed + var ondisplay = null; var tooltipText; var costText = ""; var titleText = what; @@ -189,13 +184,57 @@ function ImportExportTooltip(what, event) { }; } costText += ""; + } else if (what == "Export550") { + tooltipText = "This is your AUTOTRIMPS z550+ save string. Use this string to import the settings.

"; + costText = "
Got it
"; + if (document.queryCommandSupported('copy')) { + costText += "
Copy to Clipboard
"; + ondisplay = function() { + document.getElementById('exportArea').select(); + document.getElementById('clipBoardBtn').addEventListener('click', function(event) { + document.getElementById('exportArea').select(); + try { + document.execCommand('copy'); + } catch (err) { + document.getElementById('clipBoardBtn').innerHTML = "Error, not copied"; + } + }); + }; + } + } else if (what == "Export60") { + tooltipText = "This is your AUTOTRIMPS z60 save string. Use this string to import the settings.

"; + costText = "
Got it
"; + if (document.queryCommandSupported('copy')) { + costText += "
Copy to Clipboard
"; + ondisplay = function() { + document.getElementById('exportArea').select(); + document.getElementById('clipBoardBtn').addEventListener('click', function(event) { + document.getElementById('exportArea').select(); + try { + document.execCommand('copy'); + } catch (err) { + document.getElementById('clipBoardBtn').innerHTML = "Error, not copied"; + } + }); + }; + } else { + ondisplay = function() { + document.getElementById('exportArea').select(); + }; + } + costText += "
"; } else if (what == "ImportAutoTrimps") { - //runs the loadAutoTrimps() function. tooltipText = "Import your AUTOTRIMPS save string! It'll be fine, I promise.

"; costText = "
Import
Cancel
"; ondisplay = function() { document.getElementById('importBox').focus(); }; + } else if (what == "spireImport") { + tooltipText = "Import your SPIRE string!

"; + costText = "
Import
Cancel
"; + ondisplay = function() { + document.getElementById('importBox').focus(); + }; } else if (what == "CleanupAutoTrimps") { cleanupAutoTrimps(); tooltipText = "Autotrimps saved-settings have been attempted to be cleaned up. If anything broke, refreshing will fix it, but check that your settings are correct! (prestige in particular)"; @@ -235,7 +274,6 @@ function ImportExportTooltip(what, event) { var $item = mods.selectedOptions[script]; if ($item.value != null) { ATscriptLoad(modulepath, $item.value); - //console.log($item.value); modnames += $item.value + " "; } } @@ -248,7 +286,6 @@ function ImportExportTooltip(what, event) { var $item = mods.selectedOptions[script]; if ($item.value != null) { ATscriptUnload($item.value); - //console.log($item.value); modnames += $item.value + " "; } } @@ -261,18 +298,563 @@ function ImportExportTooltip(what, event) { } else if (what == 'MagmiteExplain') { tooltipText = ""; costText = "
Thats all the help you get.
"; + } else if (what == 'c2table') { + var c2list = { + Size: { + number: 1, + percent: getIndividualSquaredReward('Size') + '%', + zone: game.c2.Size, + percentzone: (100 * (game.c2.Size / (game.global.highestLevelCleared + 1))).toFixed(2) + '%', + color: 0 + }, + Slow: { + number: 2, + percent: getIndividualSquaredReward('Slow') + '%', + zone: game.c2.Slow, + percentzone: (100 * (game.c2.Slow / (game.global.highestLevelCleared + 1))).toFixed(2) + '%', + color: 0 + }, + Watch: { + number: 3, + percent: getIndividualSquaredReward('Watch') + '%', + zone: game.c2.Watch, + percentzone: (100 * (game.c2.Watch / (game.global.highestLevelCleared + 1))).toFixed(2) + '%', + color: 0 + }, + Discipline: { + number: 4, + percent: getIndividualSquaredReward('Discipline') + '%', + zone: game.c2.Discipline, + percentzone: (100 * (game.c2.Discipline / (game.global.highestLevelCleared + 1))).toFixed(2) + '%', + color: 0 + }, + Balance: { + number: 5, + percent: getIndividualSquaredReward('Balance') + '%', + zone: game.c2.Balance, + percentzone: (100 * (game.c2.Balance / (game.global.highestLevelCleared + 1))).toFixed(2) + '%', + color: 0 + }, + Meditate: { + number: 6, + percent: getIndividualSquaredReward('Meditate') + '%', + zone: game.c2.Meditate, + percentzone: (100 * (game.c2.Meditate / (game.global.highestLevelCleared + 1))).toFixed(2) + '%', + color: 0 + }, + Metal: { + number: 7, + percent: getIndividualSquaredReward('Metal') + '%', + zone: game.c2.Metal, + percentzone: (100 * (game.c2.Metal / (game.global.highestLevelCleared + 1))).toFixed(2) + '%', + color: 0 + }, + Lead: { + number: 8, + percent: getIndividualSquaredReward('Lead') + '%', + zone: game.c2.Lead, + percentzone: (100 * (game.c2.Lead / (game.global.highestLevelCleared + 1))).toFixed(2) + '%', + color: 0 + }, + Nom: { + number: 9, + percent: getIndividualSquaredReward('Nom') + '%', + zone: game.c2.Nom, + percentzone: (100 * (game.c2.Nom / (game.global.highestLevelCleared + 1))).toFixed(2) + '%', + color: 0 + }, + Toxicity: { + number: 10, + percent: getIndividualSquaredReward('Toxicity') + '%', + zone: game.c2.Toxicity, + percentzone: (100 * (game.c2.Toxicity / (game.global.highestLevelCleared + 1))).toFixed(2) + '%', + color: 0 + }, + Electricity: { + number: 11, + percent: getIndividualSquaredReward('Electricity') + '%', + zone: game.c2.Electricity, + percentzone: (100 * (game.c2.Electricity / (game.global.highestLevelCleared + 1))).toFixed(2) + '%', + color: 0 + }, + Coordinate: { + number: 12, + percent: getIndividualSquaredReward('Coordinate') + '%', + zone: game.c2.Coordinate, + percentzone: (100 * (game.c2.Coordinate / (game.global.highestLevelCleared + 1))).toFixed(2) + '%', + color: 0 + }, + Trimp: { + number: 13, + percent: getIndividualSquaredReward('Trimp') + '%', + zone: game.c2.Trimp, + percentzone: (100 * (game.c2.Trimp / (game.global.highestLevelCleared + 1))).toFixed(2) + '%', + color: 0 + }, + Obliterated: { + number: 14, + percent: getIndividualSquaredReward('Obliterated') + '%', + zone: game.c2.Obliterated, + percentzone: (100 * (game.c2.Obliterated / (game.global.highestLevelCleared + 1))).toFixed(2) + '%', + color: 0 + }, + Eradicated: { + number: 15, + percent: getIndividualSquaredReward('Eradicated') + '%', + zone: game.c2.Eradicated, + percentzone: (100 * (game.c2.Eradicated / (game.global.highestLevelCleared + 1))).toFixed(2) + '%', + color: 0 + }, + Mapology: { + number: 16, + percent: getIndividualSquaredReward('Mapology') + '%', + zone: game.c2.Mapology, + percentzone: (100 * (game.c2.Mapology / (game.global.highestLevelCleared + 1))).toFixed(2) + '%', + color: 0 + }, + Trapper: { + number: 17, + percent: getIndividualSquaredReward('Trapper') + '%', + zone: game.c2.Trapper, + percentzone: (100 * (game.c2.Trapper / (game.global.highestLevelCleared + 1))).toFixed(2) + '%', + color: 0 + }, + C3s: { + number: 'Difficulty', + percent: '%C3', + zone: 'Zone', + percentzone: '%HZE', + color: 0 + }, + Unbalance: { + number: 18, + percent: getIndividualSquaredReward('Unbalance') + '%', + zone: game.c2.Unbalance, + percentzone: (100 * (game.c2.Unbalance / (game.global.highestRadonLevelCleared + 1))).toFixed(2) + '%', + color: 0 + }, + Unlucky: { + number: 19, + percent: getIndividualSquaredReward('Unlucky') + '%', + zone: game.c2.Unlucky, + percentzone: (100 * (game.c2.Unlucky / (game.global.highestRadonLevelCleared + 1))).toFixed(2) + '%', + color: 0 + }, + Duel: { + number: 20, + percent: getIndividualSquaredReward('Duel') + '%', + zone: game.c2.Duel, + percentzone: (100 * (game.c2.Duel / (game.global.highestRadonLevelCleared + 1))).toFixed(2) + '%', + color: 0 + }, + Storm: { + number: 21, + percent: getIndividualSquaredReward('Storm') + '%', + zone: game.c2.Storm, + percentzone: (100 * (game.c2.Storm / (game.global.highestRadonLevelCleared + 1))).toFixed(2) + '%', + color: 0 + }, + Transmute: { + number: 22, + percent: getIndividualSquaredReward('Transmute') + '%', + zone: game.c2.Transmute, + percentzone: (100 * (game.c2.Transmute / (game.global.highestRadonLevelCleared + 1))).toFixed(2) + '%', + color: 0 + }, + Quest: { + number: 23, + percent: getIndividualSquaredReward('Quest') + '%', + zone: game.c2.Quest, + percentzone: (100 * (game.c2.Quest / (game.global.highestRadonLevelCleared + 1))).toFixed(2) + '%', + color: 0 + }, + Downsize: { + number: 24, + percent: getIndividualSquaredReward('Downsize') + '%', + zone: game.c2.Downsize, + percentzone: (100 * (game.c2.Downsize / (game.global.highestRadonLevelCleared + 1))).toFixed(2) + '%', + color: 0 + }, + Smithless: { + number: 25, + percent: getIndividualSquaredReward('Smithless') + '%', + zone: game.c2.Smithless, + percentzone: (100 * (game.c2.Smithless / (game.global.highestRadonLevelCleared + 1))).toFixed(2) + '%', + color: 0 + }, + Glass: { + number: 26, + percent: getIndividualSquaredReward('Glass') + '%', + zone: game.c2.Glass, + percentzone: (100 * (game.c2.Glass / (game.global.highestRadonLevelCleared + 1))).toFixed(2) + '%', + color: 0 + }, + Trappapalooza: { + number: 27, + percent: getIndividualSquaredReward('Trappapalooza') + '%', + zone: game.c2.Trappapalooza, + percentzone: (100 * (game.c2.Trappapalooza / (game.global.highestRadonLevelCleared + 1))).toFixed(2) + '%', + color: 0 + }, + Berserk: { + number: 28, + percent: getIndividualSquaredReward('Berserk') + '%', + zone: game.c2.Berserk, + percentzone: (100 * (game.c2.Berserk / (game.global.highestRadonLevelCleared + 1))).toFixed(2) + '%', + color: 0 + }, + Wither: { + number: 29, + percent: getIndividualSquaredReward('Wither') + '%', + zone: game.c2.Wither, + percentzone: (100 * (game.c2.Wither / (game.global.highestRadonLevelCleared + 1))).toFixed(2) + '%', + color: 0 + } + +}; + function c2listcolor(){ + function a(b,c,d){ + var e=100*(game.c2[b]/(game.global.highestLevelCleared+1)); + c2list[b].color=e>=c?"LIMEGREEN":e=d?"GOLD":e=c?"LIMEGREEN":e=d?"GOLD":e + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDifficulty%C2Zone%HZE
Size` + c2list.Size.number + `` + c2list.Size.percent + `` + c2list.Size.zone + ` + ` + c2list.Size.percentzone + ` +
Slow` + c2list.Slow.number + `` + c2list.Slow.percent + `` + c2list.Slow.zone + ` + ` + c2list.Slow.percentzone + ` +
Watch` + c2list.Watch.number + `` + c2list.Watch.percent + `` + c2list.Watch.zone + ` + ` + c2list.Watch.percentzone + ` +
Discipline` + c2list.Discipline.number + `` + c2list.Discipline.percent + `` + c2list.Discipline.zone + ` + ` + c2list.Discipline.percentzone + ` +
Balance` + c2list.Balance.number + `` + c2list.Balance.percent + `` + c2list.Balance.zone + ` + ` + c2list.Balance.percentzone + ` +
Meditate` + c2list.Meditate.number + `` + c2list.Meditate.percent + `` + c2list.Meditate.zone + ` + ` + c2list.Meditate.percentzone + ` +
Metal` + c2list.Metal.number + `` + c2list.Metal.percent + `` + c2list.Metal.zone + ` + ` + c2list.Metal.percentzone + ` +
Lead` + c2list.Lead.number + `` + c2list.Lead.percent + `` + c2list.Lead.zone + ` + ` + c2list.Lead.percentzone + ` +
Nom` + c2list.Nom.number + `` + c2list.Nom.percent + `` + c2list.Nom.zone + ` + ` + c2list.Nom.percentzone + ` +
Toxicity` + c2list.Toxicity.number + `` + c2list.Toxicity.percent + `` + c2list.Toxicity.zone + ` + ` + c2list.Toxicity.percentzone + ` +
Electricity` + c2list.Electricity.number + `` + c2list.Electricity.percent + `` + c2list.Electricity.zone + ` + ` + c2list.Electricity.percentzone + ` +
Coordinate` + c2list.Coordinate.number + `` + c2list.Coordinate.percent + `` + c2list.Coordinate.zone + ` + ` + c2list.Coordinate.percentzone + ` +
Trimp` + c2list.Trimp.number + `` + c2list.Trimp.percent + `` + c2list.Trimp.zone + ` + ` + c2list.Trimp.percentzone + ` +
Obliterated` + c2list.Obliterated.number + `` + c2list.Obliterated.percent + `` + c2list.Obliterated.zone + ` + ` + c2list.Obliterated.percentzone + ` +
Eradicated` + c2list.Eradicated.number + `` + c2list.Eradicated.percent + `` + c2list.Eradicated.zone + ` + ` + c2list.Eradicated.percentzone + ` +
Mapology` + c2list.Mapology.number + `` + c2list.Mapology.percent + `` + c2list.Mapology.zone + ` + ` + c2list.Mapology.percentzone + ` +
Trapper` + c2list.Trapper.number + `` + c2list.Trapper.percent + `` + c2list.Trapper.zone + ` + ` + c2list.Trapper.percentzone + ` +
C3sDifficulty%C3Zone%HZE
Unbalance` + c2list.Unbalance.number + `` + c2list.Unbalance.percent + `` + c2list.Unbalance.zone + ` + ` + c2list.Unbalance.percentzone + ` +
Unlucky` + c2list.Unlucky.number + `` + c2list.Unlucky.percent + `` + c2list.Unlucky.zone + ` + ` + c2list.Unlucky.percentzone + ` +
Duel` + c2list.Duel.number + `` + c2list.Duel.percent + `` + c2list.Duel.zone + ` + ` + c2list.Duel.percentzone + ` +
Storm` + c2list.Storm.number + `` + c2list.Storm.percent + `` + c2list.Storm.zone + ` + ` + c2list.Storm.percentzone + ` +
Transmute` + c2list.Transmute.number + `` + c2list.Transmute.percent + `` + c2list.Transmute.zone + ` + ` + c2list.Transmute.percentzone + ` +
Quest` + c2list.Quest.number + `` + c2list.Quest.percent + `` + c2list.Quest.zone + ` + ` + c2list.Quest.percentzone + ` +
Downsize` + c2list.Downsize.number + `` + c2list.Downsize.percent + `` + c2list.Downsize.zone + ` + ` + c2list.Downsize.percentzone + ` +
Smithless` + c2list.Smithless.number + `` + c2list.Smithless.percent + `` + c2list.Smithless.zone + ` + ` + c2list.Smithless.percentzone + ` +
Glass` + c2list.Glass.number + `` + c2list.Glass.percent + `` + c2list.Glass.zone + ` + ` + c2list.Glass.percentzone + ` +
Trappapalooza` + c2list.Trappapalooza.number + `` + c2list.Trappapalooza.percent + `` + c2list.Trappapalooza.zone + ` + ` + c2list.Trappapalooza.percentzone + ` +
Berserk` + c2list.Berserk.number + `` + c2list.Berserk.percent + `` + c2list.Berserk.zone + ` + ` + c2list.Berserk.percentzone + ` +
Wither` + c2list.Wither.number + `` + c2list.Wither.percent + `` + c2list.Wither.zone + ` + ` + c2list.Wither.percentzone + ` +
Total ` + game.global.totalSquaredReward + `%
+
`; + costText = "
Close
"; } else if (what == 'ReadSettingsProfiles') { - //Shows a Question Popup to READ the profile: titleText = 'Loading New AutoTrimps Profile...

Current Settings will be lost'; tooltipText = 'NOTICE: Switching to new AutoTrimps settings profile!!!!
All current settings WILL be lost after this point.
You might want to cancel, to go back and save your existing settings first....'; costText = "

Confirm and Switch Profiles
Cancel
"; } else if (what == 'ResetDefaultSettingsProfiles') { - //Shows a Question Popup to RESET to DEFAULT the profile: titleText = 'Loading AutoTrimps Default Profile...

Current Settings will be lost!'; tooltipText = 'NOTICE: Switching to Default AutoTrimps settings profile!!!!
All current settings WILL be lost after this point.
You might want to cancel, to go back and save your existing settings first....
This will Reset the script to factory settings.'; costText = "

Reset to Default Profile
Cancel
"; } else if (what == 'NameSettingsProfiles') { - //Shows a Question Popup to NAME the profile titleText = "Enter New Settings Profile Name"; tooltipText = "What would you like the name of the Settings Profile to be?

"; costText = "
Import
Cancel
"; @@ -280,7 +862,6 @@ function ImportExportTooltip(what, event) { document.getElementById('setSettingsNameTooltip').focus(); }; } else if (what == 'DeleteSettingsProfiles') { - //Shows a Question Popup to DELETE the profile: titleText = "WARNING: Delete Profile???" tooltipText = "You are about to delete the "+`${settingsProfiles.value}`+" settings profile.
This will not switch your current settings though. Continue ?
"; costText = "
Delete Profile
Cancel
"; @@ -289,7 +870,6 @@ function ImportExportTooltip(what, event) { tooltipText = event; costText = "
OK
"; } - //Common: game.global.lockTooltip = true; $elem.style.left = "33.75%"; $elem.style.top = "25%"; @@ -300,72 +880,12 @@ function ImportExportTooltip(what, event) { if (ondisplay !== null) ondisplay(); } -//reset autotrimps to defaults (also handles imports) -function resetAutoTrimps(imported,profname) { - ATrunning = false; //stop AT, wait, remove - function waitRemoveLoad(imported) { - localStorage.removeItem('autoTrimpSettings'); - //delete,remake,init defaults, recreate everything: - autoTrimpSettings = imported ? imported : new Object(); //load the import. - var $settingsRow = document.getElementById("settingsRow"); - $settingsRow.removeChild(document.getElementById("autoSettings")); - $settingsRow.removeChild(document.getElementById("autoTrimpsTabBarMenu")); - automationMenuSettingsInit(); - initializeAllTabs(); - initializeAllSettings(); - initializeSettingsProfiles(); - updateCustomButtons(); - saveSettings(); - checkPortalSettings(); - ATrunning = true; //restart AT. - } - setTimeout(waitRemoveLoad(imported),101); - if (imported) { - debug("Successfully imported new AT settings...", "profile"); - if (profname) //pass in existing profile name to use: - ImportExportTooltip("message", "Successfully Imported Autotrimps Settings File!: " + profname); - else //or prompt to create a new name: - ImportExportTooltip('NameSettingsProfiles'); - } else { - debug("Successfully reset AT settings to Defaults...", "profile"); - ImportExportTooltip("message", "Autotrimps has been successfully reset to its defaults!"); - } -} -//import autotrimps settings from a textbox -//For importing a new AT Config on the fly and reloading/applying all the settings. -function loadAutoTrimps() { - //try the import - try { - var thestring = document.getElementById("importBox").value.replace(/[\n\r]/gm, ""); - var tmpset = JSON.parse(thestring); - if (tmpset == null) { - debug("Error importing AT settings, the string is empty.", "profile"); - return; - } - } catch (err) { - debug("Error importing AT settings, the string is bad." + err.message, "profile"); - return; - } - debug("Importing new AT settings file...", "profile"); - resetAutoTrimps(tmpset); -} - -//remove stale values from past autotrimps versions -function cleanupAutoTrimps() { - for (var setting in autoTrimpSettings) { - var $elem = document.getElementById(autoTrimpSettings[setting].id); - if ($elem == null) - delete autoTrimpSettings[setting]; - } -} +function resetAutoTrimps(a,b){ATrunning=!1,setTimeout(function(d){localStorage.removeItem("autoTrimpSettings"),autoTrimpSettings=d?d:{};var e=document.getElementById("settingsRow");e.removeChild(document.getElementById("autoSettings")),e.removeChild(document.getElementById("autoTrimpsTabBarMenu")),automationMenuSettingsInit(),initializeAllTabs(),initializeAllSettings(),initializeSettingsProfiles(),updateCustomButtons(),saveSettings(),checkPortalSettings(),ATrunning=!0}(a),101),a?(debug("Successfully imported new AT settings...","profile"),b?ImportExportTooltip("message","Successfully Imported Autotrimps Settings File!: "+b):ImportExportTooltip("NameSettingsProfiles")):(debug("Successfully reset AT settings to Defaults...","profile"),ImportExportTooltip("message","Autotrimps has been successfully reset to its defaults!"))} +function loadAutoTrimps(){try{var a=document.getElementById("importBox").value.replace(/[\n\r]/gm,""),b=JSON.parse(a);if(null==b)return void debug("Error importing AT settings, the string is empty.","profile")}catch(c){return void debug("Error importing AT settings, the string is bad."+c.message,"profile")}debug("Importing new AT settings file...","profile"),resetAutoTrimps(b)} +function cleanupAutoTrimps(){for(var a in autoTrimpSettings){var b=document.getElementById(autoTrimpSettings[a].id);null==b&&delete autoTrimpSettings[a]}} +function exportModuleVars(){return JSON.stringify(compareModuleVars())} -//export MODULE variables to a textbox -function exportModuleVars() { - return JSON.stringify(compareModuleVars()); -} - -//diff two modules to find the difference; function compareModuleVars() { var diffs = {}; var mods = Object.keys(MODULES); @@ -386,40 +906,7 @@ function compareModuleVars() { return diffs; } -//import MODULE variables from a textbox -function importModuleVars() { - //try the import - try { - var thestring = document.getElementById("importBox").value; - var strarr = thestring.split(/\n/); - for (var line in strarr) { - var s = strarr[line]; - s = s.substring(0, s.indexOf(';')+1); //cut after the ; - s = s.replace(/\s/g,''); //regexp remove ALL(/g) whitespaces(\s) - eval(s); - strarr[line] = s; - } - var tmpset = compareModuleVars(); - } catch (err) { - debug("Error importing MODULE vars, the string is bad." + err.message, "profile"); - return; - } - localStorage.removeItem('storedMODULES'); - safeSetItems('storedMODULES', JSON.stringify(tmpset)); -} - -//reset MODULE variables to default, (and/or then import) -function resetModuleVars(imported) { - ATrunning = false; //stop AT, wait, remove - function waitRemoveLoad(imported) { - localStorage.removeItem('storedMODULES'); - MODULES = JSON.parse(JSON.stringify(MODULESdefault)); - //load everything again, anew - safeSetItems('storedMODULES', JSON.stringify(storedMODULES)); - ATrunning = true; //restart AT. - } - setTimeout(waitRemoveLoad(imported),101); -} - -settingsProfileMakeGUI(); //runs at the bottom now: -initializeSettingsProfiles(); //populate dropdown. \ No newline at end of file +function importModuleVars(){try{var thestring=document.getElementById('importBox').value,strarr=thestring.split(/\n/);for(var line in strarr){var s=strarr[line];s=s.substring(0,s.indexOf(';')+1),s=s.replace(/\s/g,''),eval(s),strarr[line]=s}var tmpset=compareModuleVars()}catch(a){return void debug('Error importing MODULE vars, the string is bad.'+a.message,'profile')}localStorage.removeItem('storedMODULES'),safeSetItems('storedMODULES',JSON.stringify(tmpset))} +function resetModuleVars(a){ATrunning=!1,setTimeout(function(){localStorage.removeItem('storedMODULES'),MODULES=JSON.parse(JSON.stringify(MODULESdefault)),safeSetItems('storedMODULES',JSON.stringify(storedMODULES)),ATrunning=!0}(a),101)} +settingsProfileMakeGUI(); +initializeSettingsProfiles(); diff --git a/modules/jobs.js b/modules/jobs.js index 73cee637a..6accb24c8 100644 --- a/modules/jobs.js +++ b/modules/jobs.js @@ -1,20 +1,23 @@ MODULES["jobs"] = {}; -//These can be changed (in the console) if you know what you're doing: -MODULES["jobs"].scientistRatio = 25; //ratio for scientists. (totalRatios / this) -MODULES["jobs"].scientistRatio2 = 10; //used for lowlevel and Watch challenge -MODULES["jobs"].magmamancerRatio = 0.1; //buys 10% of your gem resources per go. + +//Helium + +MODULES["jobs"].scientistRatio = 25; +MODULES["jobs"].scientistRatio2 = 10; +MODULES["jobs"].scientistRatio3 = 100; +MODULES["jobs"].magmamancerRatio = 0.1; //Worker Ratios = [Farmer,Lumber,Miner] -MODULES["jobs"].autoRatio6 = [1,12,12]; -MODULES["jobs"].autoRatio5 = [1,2,22]; -MODULES["jobs"].autoRatio4 = [1,1,10]; -MODULES["jobs"].autoRatio3 = [3,1,4]; -MODULES["jobs"].autoRatio2 = [3,3,5]; -MODULES["jobs"].autoRatio1 = [1,1,1]; -MODULES["jobs"].customRatio; //set this like above and it will Auto use it. +MODULES["jobs"].autoRatio7 = [1, 1, 98]; +MODULES["jobs"].autoRatio6 = [1, 7, 12]; +MODULES["jobs"].autoRatio5 = [1, 2, 22]; +MODULES["jobs"].autoRatio4 = [1, 1.1, 10]; +MODULES["jobs"].autoRatio3 = [3, 1, 4]; +MODULES["jobs"].autoRatio2 = [3, 3.1, 5]; +MODULES["jobs"].autoRatio1 = [1.1, 1.15, 1.2]; +MODULES["jobs"].customRatio; function safeBuyJob(jobTitle, amount) { if (!Number.isFinite(amount) || amount === 0 || typeof amount === 'undefined' || Number.isNaN(amount)) { - //debug("Exiting out of buyjob early " + jobTitle + " " + amount,"jobs"); return false; } var old = preBuy2(); @@ -25,16 +28,14 @@ function safeBuyJob(jobTitle, amount) { game.global.firing = true; game.global.buyAmt = amount; result = true; - } else{ + } else { game.global.firing = false; game.global.buyAmt = amount; - //if can afford, buy what we wanted, - result = canAffordJob(jobTitle, false) && freeWorkers>0; + result = canAffordJob(jobTitle, false) && freeWorkers > 0; if (!result) { game.global.buyAmt = 'Max'; game.global.maxSplit = 1; - //if we can't afford it, try to use 'Max' and try again. - result = canAffordJob(jobTitle, false) && freeWorkers>0; + result = canAffordJob(jobTitle, false) && freeWorkers > 0; } } if (result) { @@ -45,8 +46,7 @@ function safeBuyJob(jobTitle, amount) { return true; } -function safeFireJob(job,amount) { - //do some jiggerypokery in case jobs overflow and firing -1 worker does 0 (java integer overflow) +function safeFireJob(job, amount) { var oldjob = game.jobs[job].owned; if (oldjob == 0 || amount == 0) return 0; @@ -54,10 +54,10 @@ function safeFireJob(job,amount) { var x = 1; if (amount != null) x = amount; - if (!Number.isFinite(oldjob)){ + if (!Number.isFinite(oldjob)) { while (oldjob == test) { - test-=x; - x*=2; + test -= x; + x *= 2; } } var old = preBuy2(); @@ -66,89 +66,81 @@ function safeFireJob(job,amount) { while (x >= 1 && freeWorkers == Math.ceil(game.resources.trimps.realMax() / 2) - game.resources.trimps.employed) { game.global.buyAmt = x; buyJob(job, true, true); - x*=2; + x *= 2; } postBuy2(old); - return x/2; + return x / 2; } - -//Hires and Fires all workers (farmers/lumberjacks/miners/scientists/trainers/explorers) function buyJobs() { var freeWorkers = Math.ceil(game.resources.trimps.realMax() / 2) - game.resources.trimps.employed; var breeding = (game.resources.trimps.owned - game.resources.trimps.employed); var totalDistributableWorkers = freeWorkers + game.jobs.Farmer.owned + game.jobs.Miner.owned + game.jobs.Lumberjack.owned; - var farmerRatio = parseInt(getPageSetting('FarmerRatio')); - var lumberjackRatio = parseInt(getPageSetting('LumberjackRatio')); - var minerRatio = parseInt(getPageSetting('MinerRatio')); + var farmerRatio = parseFloat(getPageSetting('FarmerRatio')); + var lumberjackRatio = parseFloat(getPageSetting('LumberjackRatio')); + var minerRatio = parseFloat(getPageSetting('MinerRatio')); var totalRatio = farmerRatio + lumberjackRatio + minerRatio; var scientistRatio = totalRatio / MODULES["jobs"].scientistRatio; if (game.jobs.Farmer.owned < 100) { scientistRatio = totalRatio / MODULES["jobs"].scientistRatio2; } + if (game.global.world >= 300) { + scientistRatio = totalRatio / MODULES["jobs"].scientistRatio3; + } - //FRESH GAME LOWLEVEL NOHELIUM CODE. - if (game.global.world == 1 && game.global.totalHeliumEarned<=5000){ - if (game.resources.trimps.owned < game.resources.trimps.realMax() * 0.9){ - if (game.resources.food.owned > 5 && freeWorkers > 0){ + if (game.global.world == 1 && game.global.totalHeliumEarned <= 5000) { + if (game.resources.trimps.owned < game.resources.trimps.realMax() * 0.9) { + if (game.resources.food.owned > 5 && freeWorkers > 0) { if (game.jobs.Farmer.owned == game.jobs.Lumberjack.owned) safeBuyJob('Farmer', 1); else if (game.jobs.Farmer.owned > game.jobs.Lumberjack.owned && !game.jobs.Lumberjack.locked) safeBuyJob('Lumberjack', 1); } freeWorkers = Math.ceil(game.resources.trimps.realMax() / 2) - game.resources.trimps.employed; - if (game.resources.food.owned > 20 && freeWorkers > 0){ - if (game.jobs.Farmer.owned == game.jobs.Lumberjack.owned && !game.jobs.Miner.locked) + if (game.resources.food.owned > 20 && freeWorkers > 0) { + if (game.jobs.Farmer.owned == game.jobs.Lumberjack.owned && !game.jobs.Miner.locked && challengeActive("Metal") == false) safeBuyJob('Miner', 1); } } return; - //make sure the game always buys at least 1 farmer, so we can unlock lumberjacks. } else if (game.jobs.Farmer.owned == 0 && game.jobs.Lumberjack.locked && freeWorkers > 0) { safeBuyJob('Farmer', 1); - //make sure the game always buys 10 scientists. - } else if (getPageSetting('MaxScientists')!=0 && game.jobs.Scientist.owned < 10 && scienceNeeded > 100 && freeWorkers > 0 && game.jobs.Farmer.owned >= 10) { + } else if (getPageSetting('MaxScientists') != 0 && game.jobs.Scientist.owned < 10 && scienceNeeded > 100 && freeWorkers > 0 && game.jobs.Farmer.owned >= 10) { safeBuyJob('Scientist', 1); } freeWorkers = Math.ceil(game.resources.trimps.realMax() / 2) - game.resources.trimps.employed; totalDistributableWorkers = freeWorkers + game.jobs.Farmer.owned + game.jobs.Miner.owned + game.jobs.Lumberjack.owned; - if (game.global.challengeActive == 'Watch'){ + if (challengeActive("Watch")) { scientistRatio = totalRatio / MODULES["jobs"].scientistRatio2; - if (game.resources.trimps.owned < game.resources.trimps.realMax() * 0.9 && !breedFire){ - //so the game buys scientists first while we sit around waiting for breed timer. + if (game.resources.trimps.owned < game.resources.trimps.realMax() * 0.9 && !breedFire) { var buyScientists = Math.floor((scientistRatio / totalRatio * totalDistributableWorkers) - game.jobs.Scientist.owned); - if (game.jobs.Scientist.owned < buyScientists && game.resources.trimps.owned > game.resources.trimps.realMax() * 0.1){ - var toBuy = buyScientists-game.jobs.Scientist.owned; + if (game.jobs.Scientist.owned < buyScientists && game.resources.trimps.owned > game.resources.trimps.realMax() * 0.1) { + var toBuy = buyScientists - game.jobs.Scientist.owned; var canBuy = Math.floor(game.resources.trimps.owned - game.resources.trimps.employed); - if((buyScientists > 0 && freeWorkers > 0) && (getPageSetting('MaxScientists') > game.jobs.Scientist.owned || getPageSetting('MaxScientists') == -1)) + if ((buyScientists > 0 && freeWorkers > 0) && (getPageSetting('MaxScientists') > game.jobs.Scientist.owned || getPageSetting('MaxScientists') == -1)) safeBuyJob('Scientist', toBuy <= canBuy ? toBuy : canBuy); - } - else + } else return; } - } - else - { //exit if we are havent bred to at least 90% breedtimer yet... + } else { var breeding = (game.resources.trimps.owned - game.resources.trimps.employed); if (!(game.global.challengeActive == "Trapper") && game.resources.trimps.owned < game.resources.trimps.realMax() * 0.9 && !breedFire) { if (breeding > game.resources.trimps.realMax() * 0.33) { freeWorkers = Math.ceil(game.resources.trimps.realMax() / 2) - game.resources.trimps.employed; - //only hire if we have less than 300k trimps (dont spam up the late game with meaningless 1's) if (freeWorkers > 0 && game.resources.trimps.realMax() <= 3e5) { - //do Something tiny, so earlygame isnt stuck on 0 (down to 33% trimps. stops getting stuck from too low.) - safeBuyJob('Miner', 1); + if (challengeActive("Metal") == false) { + safeBuyJob('Miner', 1); + } safeBuyJob('Farmer', 1); safeBuyJob('Lumberjack', 1); } } - //standard quit routine if <90% breed: return; } - //continue if we have >90% breedtimer: } var subtract = 0; - //used multiple times below: (good job javascript for allowing functions in functions) - function checkFireandHire(job,amount) { + + function checkFireandHire(job, amount) { freeWorkers = Math.ceil(game.resources.trimps.realMax() / 2) - game.resources.trimps.employed; if (amount == null) amount = 1; @@ -158,48 +150,38 @@ function buyJobs() { safeBuyJob(job, amount); } } - //Scientists: freeWorkers = Math.ceil(game.resources.trimps.realMax() / 2) - game.resources.trimps.employed; totalDistributableWorkers = freeWorkers + game.jobs.Farmer.owned + game.jobs.Miner.owned + game.jobs.Lumberjack.owned; var ms = getPageSetting('MaxScientists'); - if (ms!=0 && !game.jobs.Scientist.locked && !breedFire) { + if (ms != 0 && !game.jobs.Scientist.locked && !breedFire) { var buyScientists = Math.floor((scientistRatio / totalRatio) * totalDistributableWorkers) - game.jobs.Scientist.owned - subtract; var sci = game.jobs.Scientist.owned; - if((buyScientists > 0 && freeWorkers > 0) && (ms > sci || ms == -1)) { + if ((buyScientists > 0 && freeWorkers > 0) && (ms > sci || ms == -1)) { var n = ms - sci; if (ms == -1) - n=buyScientists; + n = buyScientists; else if (n < 0) - n=0; + n = 0; if (buyScientists > n) buyScientists = n; safeBuyJob('Scientist', buyScientists); } } - //Trainers: if (getPageSetting('MaxTrainers') > game.jobs.Trainer.owned || getPageSetting('MaxTrainers') == -1) { - // capped to tributes percentage. - var trainerpercent = getPageSetting('TrainerCaptoTributes'); - if (trainerpercent > 0 && !game.buildings.Tribute.locked) { - var curtrainercost = game.jobs.Trainer.cost.food[0]*Math.pow(game.jobs.Trainer.cost.food[1], game.jobs.Trainer.owned); + if (!game.buildings.Tribute.locked) { + var curtrainercost = game.jobs.Trainer.cost.food[0] * Math.pow(game.jobs.Trainer.cost.food[1], game.jobs.Trainer.owned); var curtributecost = getBuildingItemPrice(game.buildings.Tribute, "food", false, 1) * Math.pow(1 - game.portal.Resourceful.modifier, game.portal.Resourceful.level); - if (curtrainercost < curtributecost * (trainerpercent/100)) + if (curtrainercost < curtributecost) checkFireandHire('Trainer'); - } - // regular - else + } else checkFireandHire('Trainer'); } - //Explorers: if (getPageSetting('MaxExplorers') > game.jobs.Explorer.owned || getPageSetting('MaxExplorers') == -1) { checkFireandHire('Explorer'); } - //Buy Farmers: - //Buy/Fire Miners: - //Buy/Fire Lumberjacks: function ratiobuy(job, jobratio) { - if(!game.jobs[job].locked && !breedFire) { + if (!game.jobs[job].locked && !breedFire) { freeWorkers = Math.ceil(game.resources.trimps.realMax() / 2) - game.resources.trimps.employed; totalDistributableWorkers = freeWorkers + game.jobs.Farmer.owned + game.jobs.Miner.owned + game.jobs.Lumberjack.owned; var toBuy = Math.floor((jobratio / totalRatio) * totalDistributableWorkers) - game.jobs[job].owned - subtract; @@ -207,36 +189,33 @@ function buyJobs() { var amount = toBuy <= canBuy ? toBuy : canBuy; if (amount != 0) { safeBuyJob(job, amount); - //debug("Ratio Buying Job: " + job + " " + amount + " " + jobratio, "jobs"); } return true; - } - else + } else return false; } ratiobuy('Farmer', farmerRatio); - if (!ratiobuy('Miner', minerRatio) && breedFire && game.global.turkimpTimer === 0) + if (!ratiobuy('Miner', minerRatio) && breedFire && game.global.turkimpTimer === 0 && challengeActive("Metal") == false) safeBuyJob('Miner', game.jobs.Miner.owned * -1); if (!ratiobuy('Lumberjack', lumberjackRatio) && breedFire) safeBuyJob('Lumberjack', game.jobs.Lumberjack.owned * -1); - //Magmamancers code: if (game.jobs.Magmamancer.locked) return; - //game.jobs.Magmamancer.getBonusPercent(true); var timeOnZone = Math.floor((new Date().getTime() - game.global.zoneStarted) / 60000); - // Add 5 minutes for zone-time for magmamancer mastery - if (game.talents.magmamancer.purchased) + if (game.talents.magmamancer.purchased) { timeOnZone += 5; + } + if (game.talents.stillMagmamancer.purchased) { + timeOnZone = Math.floor(timeOnZone + game.global.spireRows); + } var stacks2 = Math.floor(timeOnZone / 10); if (getPageSetting('AutoMagmamancers') && stacks2 > tierMagmamancers) { var old = preBuy2(); game.global.firing = false; game.global.buyAmt = 'Max'; - game.global.maxSplit = MODULES["jobs"].magmamancerRatio; // (10%) - //fire dudes to make room. + game.global.maxSplit = MODULES["jobs"].magmamancerRatio; // (10%) var firesomedudes = calculateMaxAfford(game.jobs['Magmamancer'], false, false, true); - //fire (10x) as many workers as we need so "Max" (0.1) can work, because FreeWorkers are considered as part of the (10%) calc - var inverse = (1 / MODULES["jobs"].magmamancerRatio); + var inverse = (1 / MODULES["jobs"].magmamancerRatio); firesomedudes *= inverse; if (game.jobs.Farmer.owned > firesomedudes) safeFireJob('Farmer', firesomedudes); @@ -244,32 +223,29 @@ function buyJobs() { safeFireJob('Lumberjack', firesomedudes); else if (game.jobs.Miner.owned > firesomedudes) safeFireJob('Miner', firesomedudes); - //buy the Magmamancers game.global.firing = false; game.global.buyAmt = 'Max'; game.global.maxSplit = MODULES["jobs"].magmamancerRatio; buyJob('Magmamancer', true, true); postBuy2(old); - debug("Bought " + (firesomedudes/inverse) + ' Magmamancers. Total Owned: ' + game.jobs['Magmamancer'].owned, "magmite", "*users"); + debug("Bought " + (firesomedudes / inverse) + ' Magmamancers. Total Owned: ' + game.jobs['Magmamancer'].owned, "magmite", "*users"); tierMagmamancers += 1; - } - else if (stacks2 < tierMagmamancers) { + } else if (stacks2 < tierMagmamancers) { tierMagmamancers = 0; } - - //Some kind of Protection or error checking. not needed much? + if ((game.resources.trimps.owned - game.resources.trimps.employed) < 2) { - var a = (game.jobs.Farmer.owned > 2) + var a = (game.jobs.Farmer.owned > 2); if (a) safeFireJob('Farmer', 2); - var b = (game.jobs.Lumberjack.owned > 2) + var b = (game.jobs.Lumberjack.owned > 2); if (b) safeFireJob('Lumberjack', 2); - var c = (game.jobs.Miner.owned > 2) + var c = (game.jobs.Miner.owned > 2); if (c) safeFireJob('Miner', 2); if (a || b || c) - debug("Job Protection Triggered, Number Rounding Error: [f,l,m]= " + a + " " + b + " " + c,"other"); + debug("Job Protection Triggered, Number Rounding Error: [f,l,m]= " + a + " " + b + " " + c, "other"); } } var tierMagmamancers = 0; @@ -279,6 +255,8 @@ function workerRatios() { var ratioSet; if (MODULES["jobs"].customRatio) { ratioSet = MODULES["jobs"].customRatio; + } else if (game.global.world >= 300) { + ratioSet = MODULES["jobs"].autoRatio7; } else if (game.buildings.Tribute.owned > 3000 && mutations.Magma.active()) { ratioSet = MODULES["jobs"].autoRatio6; } else if (game.buildings.Tribute.owned > 1500) { @@ -292,14 +270,429 @@ function workerRatios() { } else { ratioSet = MODULES["jobs"].autoRatio1; } - //Override normal ratios with challenge specific ones - if (game.global.challengeActive == 'Watch'){ + if (challengeActive("Watch")) { ratioSet = MODULES["jobs"].autoRatio1; - } else if (game.global.challengeActive == 'Metal'){ - ratioSet = [4,5,0]; //this challenge likes workers split half and half between farmers and lumbers (idk why) + } else if (challengeActive("Metal")) { + ratioSet = [4, 5, 0]; + } + setPageSetting('FarmerRatio', ratioSet[0]); + setPageSetting('LumberjackRatio', ratioSet[1]); + setPageSetting('MinerRatio', ratioSet[2]); +} + +//Radon + +MODULES["jobs"].RscientistRatio = 8; +MODULES["jobs"].RscientistRatio2 = 4; +MODULES["jobs"].RscientistRatio3 = 16; +MODULES["jobs"].RscientistRatio4 = 64; +//Worker Ratios = [Farmer,Lumber,Miner] +MODULES["jobs"].RautoRatio7 = [1, 1, 98]; +MODULES["jobs"].RautoRatio6 = [1, 7, 12]; +MODULES["jobs"].RautoRatio5 = [1, 2, 22]; +MODULES["jobs"].RautoRatio4 = [1, 1.1, 10]; +MODULES["jobs"].RautoRatio3 = [3, 1, 4]; +MODULES["jobs"].RautoRatio2 = [3, 3.1, 5]; +MODULES["jobs"].RautoRatio1 = [1.1, 1.15, 1.2]; +MODULES["jobs"].RcustomRatio; + +function RsafeBuyJob(jobTitle, amount) { + if (!Number.isFinite(amount) || amount === 0 || typeof amount === 'undefined' || Number.isNaN(amount)) { + return false; + } + var old = preBuy2(); + var freeWorkers = Math.ceil(game.resources.trimps.realMax() / 2) - game.resources.trimps.employed; + var result; + if (amount < 0) { + amount = Math.abs(amount); + game.global.firing = true; + game.global.buyAmt = amount; + result = true; + } else { + game.global.firing = false; + game.global.buyAmt = amount; + result = canAffordJob(jobTitle, false) && freeWorkers > 0; + if (!result) { + game.global.buyAmt = 'Max'; + game.global.maxSplit = 1; + result = canAffordJob(jobTitle, false) && freeWorkers > 0; + } + } + if (result) { + debug((game.global.firing ? 'Firing ' : 'Hiring ') + prettify(game.global.buyAmt) + ' ' + jobTitle + 's', "jobs", "*users"); + buyJob(jobTitle, true, true); + } + postBuy2(old); + return true; +} + +function RsafeFireJob(job, amount) { + var oldjob = game.jobs[job].owned; + if (oldjob == 0 || amount == 0) + return 0; + var test = oldjob; + var x = 1; + if (amount != null) + x = amount; + if (!Number.isFinite(oldjob)) { + while (oldjob == test) { + test -= x; + x *= 2; + } + } + var old = preBuy2(); + game.global.firing = true; + var freeWorkers = Math.ceil(game.resources.trimps.realMax() / 2) - game.resources.trimps.employed; + while (x >= 1 && freeWorkers == Math.ceil(game.resources.trimps.realMax() / 2) - game.resources.trimps.employed) { + game.global.buyAmt = x; + buyJob(job, true, true); + x *= 2; + } + postBuy2(old); + return x / 2; +} + +function RworkerRatios() { + var ratioSet; + if (MODULES["jobs"].RcustomRatio) { + ratioSet = MODULES["jobs"].RcustomRatio; + } else if (game.global.world >= 300) { + ratioSet = MODULES["jobs"].RautoRatio7; + } else if (game.buildings.Tribute.owned > 3000 && mutations.Magma.active()) { + ratioSet = MODULES["jobs"].RautoRatio6; + } else if (game.buildings.Tribute.owned > 1500) { + ratioSet = MODULES["jobs"].RautoRatio5; + } else if (game.buildings.Tribute.owned > 1000) { + ratioSet = MODULES["jobs"].RautoRatio4; + } else if (game.resources.trimps.realMax() > 3000000) { + ratioSet = MODULES["jobs"].RautoRatio3; + } else if (game.resources.trimps.realMax() > 300000) { + ratioSet = MODULES["jobs"].RautoRatio2; + } else if (game.global.challengeActive == 'Transmute') { + ratioSet = [4, 5, 0]; + } else { + ratioSet = MODULES["jobs"].RautoRatio1; + } + setPageSetting('RFarmerRatio', ratioSet[0]); + setPageSetting('RLumberjackRatio', ratioSet[1]); + setPageSetting('RMinerRatio', ratioSet[2]); +} + +function RquestbuyJobs() { + + var freeWorkers = Math.ceil(game.resources.trimps.realMax() / 2) - game.resources.trimps.employed; + var totalDistributableWorkers = freeWorkers + game.jobs.Farmer.owned + game.jobs.Miner.owned + game.jobs.Lumberjack.owned; + totalDistributableWorkers = totalDistributableWorkers / 5; + + var farmerRatio = 0; + var lumberjackRatio = 0; + var minerRatio = 0; + var scientistNumber = (totalDistributableWorkers * 0.00001); + if (scientistNumber <= 0) { + scientistNumber = 1; + } + + if (game.global.world > 5) { + if (questcheck() == 7 && !canAffordBuilding('Smithy')) { + farmerRatio = 10; + lumberjackRatio = 10; + minerRatio = 10; + totalDistributableWorkers *= 5; + } + else if (questcheck() == 10 || questcheck() == 20) { + farmerRatio = 10; + totalDistributableWorkers *= 5; + } + else if (questcheck() == 11 || questcheck() == 21) { + lumberjackRatio = 10; + totalDistributableWorkers *= 5; + } + else if (questcheck() == 12 || questcheck() == 22) { + minerRatio = 10; + totalDistributableWorkers *= 5; + } + else if (questcheck() == 14 || questcheck() == 24) { + totalDistributableWorkers *= 5; + scientistNumber = (totalDistributableWorkers * 0.5); + } + else { + farmerRatio = 10; + lumberjackRatio = 10; + minerRatio = 10; + } + } + + if (scientistNumber > (totalDistributableWorkers * 0.00001) && !game.jobs.Scientist.locked) { + if (freeWorkers > 0 && scientistNumber > game.jobs.Scientist.owned) { + var n = scientistNumber - game.jobs.Scientist.owned; + RsafeBuyJob('Scientist', n); + } + } else if (game.jobs.Scientist.owned > scientistNumber && !game.jobs.Scientist.locked) { + var n = game.jobs.Scientist.owned - scientistNumber; + RsafeFireJob('Scientist', n); + } + + if (getPageSetting('RMaxExplorers') > game.jobs.Explorer.owned || getPageSetting('RMaxExplorers') == -1) { + RsafeBuyJob("Explorer", 1); + } + + var farmerkeep = totalDistributableWorkers * 0.01; + if (farmerkeep < 1) { + farmerkeep = 100; + if (totalDistributableWorkers <= 100) { + farmerkeep = 1; + } + } + + totalDistributableWorkers = totalDistributableWorkers - farmerkeep; + + if (farmerRatio > 0 && lumberjackRatio <= 0 && minerRatio <= 0) { + RsafeFireJob('Lumberjack', game.jobs.Lumberjack.owned); + RsafeFireJob('Miner', game.jobs.Miner.owned); + RsafeBuyJob('Farmer', totalDistributableWorkers); + } else if (lumberjackRatio > 0 && farmerRatio <= 0 && minerRatio <= 0) { + RsafeFireJob('Farmer', game.jobs.Farmer.owned - farmerkeep); + RsafeFireJob('Miner', game.jobs.Miner.owned); + RsafeBuyJob('Lumberjack', totalDistributableWorkers); + } else if (minerRatio > 0 && farmerRatio <= 0 && lumberjackRatio <= 0) { + RsafeFireJob('Farmer', game.jobs.Farmer.owned - farmerkeep); + RsafeFireJob('Lumberjack', game.jobs.Lumberjack.owned); + RsafeBuyJob('Miner', totalDistributableWorkers); + } else if (farmerRatio <= 0 && lumberjackRatio <= 0 && minerRatio <= 0) { + RsafeFireJob('Farmer', game.jobs.Farmer.owned - farmerkeep); + RsafeFireJob('Lumberjack', game.jobs.Lumberjack.owned); + RsafeFireJob('Miner', game.jobs.Miner.owned); + } else if (farmerRatio > 0 && lumberjackRatio > 0 && minerRatio > 0) { + RsafeBuyJob('Farmer', totalDistributableWorkers * 0.15); + RsafeBuyJob('Lumberjack', totalDistributableWorkers * 0.35); + RsafeBuyJob('Miner', totalDistributableWorkers * 0.45); + } +} + +var reservedJobs = 100; + +function RbuyJobs() { + + if (game.jobs.Farmer.locked || game.resources.trimps.owned == 0) return; + + var freeWorkers = Math.ceil(Math.min(game.resources.trimps.realMax() / 2), game.resources.trimps.owned) - game.resources.trimps.employed; + if (freeWorkers <= 0) return; + + // Do non-ratio/limited jobs first + // Explorers + var maxExplorers = (getPageSetting('RMaxExplorers') == -1) ? Infinity : getPageSetting('RMaxExplorers'); + if (maxExplorers > game.jobs.Explorer.owned && !game.jobs.Explorer.locked) { + var affordableExplorers = Math.min(maxExplorers - game.jobs.Explorer.owned, + getMaxAffordable( + game.jobs.Explorer.cost.food[0] * Math.pow(game.jobs.Explorer.cost.food[1], game.jobs.Explorer.owned), + game.resources.food.owned, + game.jobs.Explorer.cost.food[1], + true + ) + ); + + if (affordableExplorers > 0) { + var buyAmountStore = game.global.buyAmt; + game.global.buyAmt = affordableExplorers; + + buyJob('Explorer', true, true); + + freeWorkers -= affordableExplorers; + game.global.buyAmt = buyAmountStore; + } + } + + // Meteorologists + var affordableMets = getMaxAffordable( + game.jobs.Meteorologist.cost.food[0] * Math.pow(game.jobs.Meteorologist.cost.food[1], game.jobs.Meteorologist.owned), + game.resources.food.owned, + game.jobs.Meteorologist.cost.food[1], + true + ); + + if (affordableMets > 0 && !game.jobs.Meteorologist.locked) { + var buyAmountStore = game.global.buyAmt; + game.global.buyAmt = affordableMets; + + buyJob('Meteorologist', true, true); + + freeWorkers -= affordableMets; + game.global.buyAmt = buyAmountStore; + } + + // Ships + var affordableShips = Math.floor(game.resources.food.owned / game.jobs.Worshipper.getCost()); + if (affordableShips > 0 && !game.jobs.Worshipper.locked) { + var buyAmountStore = game.global.buyAmt; + game.global.buyAmt = affordableShips; + + buyJob('Worshipper', true, true); + + freeWorkers -= affordableShips; + game.global.buyAmt = buyAmountStore; + } + + // Gather up the total number of workers available to be distributed across ratio workers + // In the process store how much of each for later. + var ratioWorkers = ['Farmer', 'Lumberjack', 'Miner', 'Scientist']; + var currentworkers = []; + for (var worker of ratioWorkers) { + currentworkers.push(game.jobs[worker].owned); + } + + freeWorkers += currentworkers.reduce((a, b) => { + return a + b; + }); + + // Explicit firefox handling because Ff specifically reduces free workers to 0. + var isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1; + + var reserveMod = isFirefox || typeof(isSteam) !== 'undefined' ? 1 + (game.resources.trimps.owned / 1e10) : 1; + + freeWorkers -= (game.resources.trimps.owned > 1e6) ? reservedJobs * reserveMod : 0; + + // Calculate how much of each worker we should have + // If focused farming go all in for caches + var allIn = ""; + if (Rshouldtimefarm) { + var timefarmzone = getPageSetting('Rtimefarmzone'); + var timefarmlevelindex = timefarmzone.indexOf(game.global.world); + if (autoTrimpSettings.Rtimefarmspecial.value[timefarmlevelindex].includes('wc')) { + allIn = "Lumberjack"; + } else if (autoTrimpSettings.Rtimefarmspecial.value[timefarmlevelindex].includes('sc')) { + allIn = "Farmer"; + } else if (autoTrimpSettings.Rtimefarmspecial.value[timefarmlevelindex].includes('mc')) { + allIn = "Miner"; + } else if (autoTrimpSettings.Rtimefarmspecial.value[timefarmlevelindex].includes('rc')) { + allIn = "Scientist"; + } + } + if (Rdshouldtimefarm) { + var dtimefarmzone = getPageSetting('Rdtimefarmzone'); + var dtimefarmlevelindex = dtimefarmzone.indexOf(game.global.world); + if (autoTrimpSettings.Rdtimefarmspecial.value[dtimefarmlevelindex].includes('wc')) { + allIn = "Lumberjack"; + } else if (autoTrimpSettings.Rdtimefarmspecial.value[dtimefarmlevelindex].includes('sc')) { + allIn = "Farmer"; + } else if (autoTrimpSettings.Rdtimefarmspecial.value[dtimefarmlevelindex].includes('mc')) { + allIn = "Miner"; + } else if (autoTrimpSettings.Rdtimefarmspecial.value[dtimefarmlevelindex].includes('rc')) { + allIn = "Scientist"; + } + } + if (Rshouldsmithyfarm) { + var special = RsmithyCalc(false, false, true, false); + if (special == "swc" || special == "lwc") { + allIn = "Lumberjack"; + } else if (special == "smc" || special == "lmc") { + allIn = "Miner"; + } + } + if (Rshouldtributefarm) { + var tributefarmzone = getPageSetting('Rtributefarmzone'); + var tributefarmlevelindex = tributefarmzone.indexOf(game.global.world); + if (autoTrimpSettings.Rtributespecialselection.value[tributefarmlevelindex].includes('wc')) { + allIn = "Lumberjack"; + } else if (autoTrimpSettings.Rtributespecialselection.value[tributefarmlevelindex].includes('sc')) { + allIn = "Farmer"; + } else if (autoTrimpSettings.Rtributespecialselection.value[tributefarmlevelindex].includes('mc')) { + allIn = "Miner"; + } else if (autoTrimpSettings.Rtributespecialselection.value[tributefarmlevelindex].includes('rc')) { + allIn = "Scientist"; + } + } + if (Rshouldshipfarm) { + allIn = "Farmer"; + } else if (Rshouldhypofarm) { + allIn = "Lumberjack"; + } + var desiredRatios = [0, 0, 0, 0]; + if (allIn != "") { + desiredRatios[ratioWorkers.indexOf(allIn)] = 1; + } else { + // Weird scientist ratio hack. Based on previous AJ, I don't know why it's like this. + var scientistMod = MODULES["jobs"].RscientistRatio; + if (game.jobs.Farmer.owned < 100) { + scientistMod = MODULES["jobs"].RscientistRatio2; + } + if (game.global.world >= 50) { + scientistMod = MODULES["jobs"].RscientistRatio3; + } + if (game.global.world >= 65) { + scientistMod = MODULES["jobs"].RscientistRatio4; + } + + for (var worker of ratioWorkers) { + if (!game.jobs[worker].locked) { + + if (worker == "Scientist") { + desiredRatios[ratioWorkers.indexOf(worker)] = 1; + continue; + } + + // get ratio from AT + desiredRatios[ratioWorkers.indexOf(worker)] = scientistMod * parseFloat(getPageSetting('R' + worker + 'Ratio')); + } + } + } + + var totalFraction = desiredRatios.reduce((a, b) => { + return a + b; + }); + + var desiredWorkers = [0, 0, 0, 0]; + var totalWorkerCost = 0; + for (var i = 0; i < ratioWorkers.length; i++) { + desiredWorkers[i] = Math.floor(freeWorkers * desiredRatios[i] / totalFraction - currentworkers[i]); + if (desiredWorkers[i] > 0) totalWorkerCost += game.jobs[ratioWorkers[i]].cost.food * desiredWorkers[i]; + } + // Check for negative values, in case we need to fire. + + // Safe check total worker costs, almost never going to be an issue + // Or another reason that we're unable to buy everything we want + if (totalWorkerCost > game.resources.food.owned /* or breeding/available stuff */ ) { + // Buy max on food and then let the next frame take care of the rest. + var buyAmountStore = game.global.buyAmt; + game.global.buyAmt = "Max"; + + buyJob('Farmer', true, true); + + game.global.buyAmt = buyAmountStore; + } else { + //buy everything + + // Fire anything that we need to fire to free up workers + for (var i = 0; i < desiredWorkers.length; i++) { + + if (desiredWorkers[i] > 0) continue; + + var buyAmountStore = game.global.buyAmt; + var fireState = game.global.firing; + + game.global.firing = (desiredWorkers[i] < 0); + game.global.buyAmt = Math.abs(desiredWorkers[i]); + + buyJob(ratioWorkers[i], true, true); + + game.global.firing = fireState; + game.global.buyAmt = buyAmountStore; + } + + // Buy up workers that we need to + for (var i = 0; i < desiredWorkers.length; i++) { + + if (desiredWorkers[i] <= 0) continue; + + var buyAmountStore = game.global.buyAmt; + var fireState = game.global.firing; + + game.global.firing = (desiredWorkers[i] < 0); + game.global.buyAmt = Math.abs(desiredWorkers[i]); + + buyJob(ratioWorkers[i], true, true); + + game.global.firing = fireState; + game.global.buyAmt = buyAmountStore; + } } - //Install the new ratios into active settings - setPageSetting('FarmerRatio',ratioSet[0]); - setPageSetting('LumberjackRatio',ratioSet[1]); - setPageSetting('MinerRatio',ratioSet[2]); } diff --git a/modules/magmite.js b/modules/magmite.js index 5ac9684ca..24ac6ebc3 100644 --- a/modules/magmite.js +++ b/modules/magmite.js @@ -1,195 +1,218 @@ MODULES["magmite"] = {}; -//These can be changed (in the console) if you know what you're doing: -MODULES["magmite"].algorithm = 2; //2 is advanced cost/benefit calculation between capacity/efficiency. 1 is buy-cheapest-upgrade. +MODULES["magmite"].algorithm = 2; -//Auto Magmite spender before portal -function autoMagmiteSpender() { - try { - var didSpend = false; -//Part #1: - //list of available permanent one-and-done upgrades - var permanames = ["Slowburn", "Shielding", "Storage", "Hybridization"]; - //cycle through: - for (var i=0; i < permanames.length; i++) { - var item = permanames[i]; - var upgrade = game.permanentGeneratorUpgrades[item]; - if (typeof upgrade === 'undefined') - return; //error-resistant - //skip owned perma-upgrades - if (upgrade.owned) - continue; - var cost = upgrade.cost; - //if we can afford anything, buy it: - if (game.global.magmite >= cost) { - buyPermanentGeneratorUpgrade(item); - debug("Auto Spending " + cost + " Magmite on: " + item, "magmite"); - didSpend = true; - } - } - // then consider overclocker if we can afford it - var hasOv = game.permanentGeneratorUpgrades.Hybridization.owned && game.permanentGeneratorUpgrades.Storage.owned; - var ovclock = game.generatorUpgrades.Overclocker; - if (hasOv && (getPageSetting('BuyOvclock') || !ovclock.upgrades) && (game.global.magmite >= ovclock.cost())) { - debug("Auto Spending " + ovclock.cost() + " Magmite on: Overclocker" + (ovclock.upgrades ? " #" + (ovclock.upgrades + 1) : ""), "magmite"); - buyGeneratorUpgrade('Overclocker'); +var priceIncreases = { + Efficiency: 8, + Capacity: 32, + Supply: 64, + Overclocker: 32 +}; + +function calcMiSpent(upgrade) { + var total = 0; + if (game.generatorUpgrades[upgrade].cost() <= game.generatorUpgrades[upgrade].baseCost || game.generatorUpgrades[upgrade].upgrades <= 0) return 0; + else { + total = game.generatorUpgrades[upgrade].upgrades * (game.generatorUpgrades[upgrade].baseCost + (priceIncreases[upgrade] / 2) * (game.generatorUpgrades[upgrade].upgrades - 1)); + return total; } +} + +function miRatio() { + + //Find Mi Ratio + var eff, cap, sup, oc, effr, capr, supr, ocr, effspend, effspendr, capspend, capspendr, supspend, supspendr, ocspend, ocspendr; + + eff = calcMiSpent('Efficiency'); + cap = calcMiSpent('Capacity'); + sup = calcMiSpent('Supply'); + oc = calcMiSpent('Overclocker'); + + var total = (eff + cap + sup + oc); + + effr = (eff > 0) ? ((eff / total)*100) : 1; + capr = (cap > 0) ? ((cap / total)*100) : 1; + supr = (sup > 0) ? ((sup / total)*100) : 1; + ocr = (oc > 0) ? ((oc / total)*100) : 1; + + //Find Player ratio + effspend = (getPageSetting('effratio') > 0) ? getPageSetting('effratio') : 0; + capspend = (getPageSetting('capratio') > 0) ? getPageSetting('capratio') : 0; + supspend = (getPageSetting('supratio') > 0) ? getPageSetting('supratio') : 0; + ocspend = (getPageSetting('ocratio') > 0) ? getPageSetting('ocratio') : 0; + + var totalspend = (effspend + capspend + supspend + ocspend); + + effspendr = (effspend > 0) ? ((totalspend / effspend)*100) : 0; + capspendr = (capspend > 0) ? ((totalspend / capspend)*100) : 0; + supspendr = (supspend > 0) ? ((totalspend / supspend)*100) : 0; + ocspendr = (ocspend > 0) ? ((totalspend / ocspend)*100) : 0; -//Part #2 - var repeat = !getPageSetting('OneTimeOnly'); - while (repeat) { - if (MODULES["magmite"].algorithm == 2) { - //Method 2: - //calculate cost-efficiency of "Efficiency"&"Capacity" - var eff = game.generatorUpgrades["Efficiency"]; - var cap = game.generatorUpgrades["Capacity"]; - var sup = game.generatorUpgrades["Supply"]; - if ((typeof eff === 'undefined')||(typeof cap === 'undefined')||(typeof sup === 'undefined')) - return; //error-resistant - var EffObj = {}; - EffObj.name= "Efficiency"; - EffObj.lvl = eff.upgrades + 1; //Calc for next level - EffObj.cost= eff.cost(); //EffObj.lvl*8; //cost= 8mi/lvl - EffObj.benefit= EffObj.lvl*0.1; //benefit= +10%/lvl - EffObj.effInc= (((1+EffObj.benefit)/(1+((EffObj.lvl-1)*0.1))-1)*100); //eff. % inc. - EffObj.miCostPerPct= EffObj.cost / EffObj.effInc; - var CapObj = {}; - CapObj.name= "Capacity"; - CapObj.lvl = cap.upgrades + 1; //Calc for next level - CapObj.cost= cap.cost(); //CapObj.lvl*32; //cost= 32mi/lvl - CapObj.totalCap= 3+(0.4*CapObj.lvl); - CapObj.benefit= Math.sqrt(CapObj.totalCap); - CapObj.effInc= ((CapObj.benefit/Math.sqrt(3+(0.4*(CapObj.lvl-1)))-1)*100); //eff. % inc. - CapObj.miCostPerPct= CapObj.cost / CapObj.effInc; - var upgrade,item; - //(try to) Buy Efficiency if its cheaper than Capacity in terms of Magmite cost per percent. - if (EffObj.miCostPerPct <= CapObj.miCostPerPct) - item = EffObj.name; - //if not, (try to) Buy Capacity if its cheaper than the cost of Supply. - else { - const supCost = sup.cost(); - var wall = getPageSetting('SupplyWall'); - // If no wall, try to buy Capacity if it's cheaper. - if (!wall) - item = (CapObj.cost <= supCost) - ? CapObj.name : "Supply"; - // If 1, disable Supply - else if (wall == 1) - item = "Capacity"; - // If negative, prioritize Supply after applying cap. - else if (wall < 0) - item = (supCost <= (CapObj.cost * -wall)) - ? "Supply" : "Capacity"; - // If positive, throttle Supply after applying cap. - else - item = (CapObj.cost <= (supCost * wall)) - ? "Capacity" : "Supply"; - } - upgrade = game.generatorUpgrades[item]; - //IF we can afford anything, buy it: - if (game.global.magmite >= upgrade.cost()) { - debug("Auto Spending " + upgrade.cost() + " Magmite on: " + item + " #" + (game.generatorUpgrades[item].upgrades+1), "magmite"); - buyGeneratorUpgrade(item); - didSpend = true; - } - //if we can't, exit the loop - else - repeat = false; + //Find Next Spend + var efffinal = effspendr - effr; + var capfinal = capspendr - capr; + var supfinal = supspendr - supr; + var ocfinal = ocspendr - ocr; + + var ratios = []; + if (efffinal != -1) + ratios.push(efffinal); + if (capfinal != -1) + ratios.push(capfinal); + if (supfinal != -1) + ratios.push(supfinal); + if (ocfinal != -1) + ratios.push(ocfinal); + + ratios.sort(function(a, b){return b-a;}); + + //Return Next Spend + if (ratios[0] == efffinal) + return "Efficiency"; + if (ratios[0] == capfinal) + return "Capacity"; + if (ratios[0] == supfinal) + return "Supply"; + if (ratios[0] == ocfinal) + return "Overclocker"; +} + +function autoMagmiteSpender() { + if (getPageSetting('ratiospend') == true) { + var tospend = miRatio(); + var upgrader = game.generatorUpgrades[tospend]; + if (game.global.magmite >= upgrader.cost()) { + debug("Auto Spending " + upgrader.cost() + " Magmite on: " + tospend + " #" + (game.generatorUpgrades[tospend].upgrades + 1), "magmite"); + buyGeneratorUpgrade(tospend); } - else if (MODULES["magmite"].algorithm == 1) { - //Method 1(old): - //list of available multi upgrades - var names = ["Efficiency","Capacity","Supply"]; - var lowest = [null,null]; //keep track of cheapest one - //cycle through: - for (var i=0; i < names.length; i++) { - var item = names[i]; - var upgrade = game.generatorUpgrades[item]; + } else { + try { + var didSpend = false; + var permanames = ["Slowburn", "Shielding", "Storage", "Hybridization", "Supervision", "Simulacrum"]; + for (var i = 0; i < permanames.length; i++) { + var item = permanames[i]; + var upgrade = game.permanentGeneratorUpgrades[item]; if (typeof upgrade === 'undefined') - return; //error-resistant - var cost = upgrade.cost(); - //store the first upgrade once - if (lowest[1] == null) - lowest = [item,cost]; - //always load cheapest one in. - else if (cost < lowest[1]) - lowest = [item,cost]; + return; + if (upgrade.owned) + continue; + var cost = upgrade.cost; + if (game.global.magmite >= cost) { + buyPermanentGeneratorUpgrade(item); + debug("Auto Spending " + cost + " Magmite on: " + item, "magmite"); + didSpend = true; + } + } + var hasOv = game.permanentGeneratorUpgrades.Hybridization.owned && game.permanentGeneratorUpgrades.Storage.owned; + var ovclock = game.generatorUpgrades.Overclocker; + if (hasOv && ((getPageSetting('spendmagmitesetting') == 0 || getPageSetting('spendmagmitesetting') == 3) || !ovclock.upgrades) && (game.global.magmite >= ovclock.cost())) { + debug("Auto Spending " + ovclock.cost() + " Magmite on: Overclocker" + (ovclock.upgrades ? " #" + (ovclock.upgrades + 1) : ""), "magmite"); + buyGeneratorUpgrade('Overclocker'); } - //if we can afford anything, buy it: - if (game.global.magmite >= lowest[1]) { - buyGeneratorUpgrade(lowest[0]); - debug("Auto Spending " + lowest[1] + " Magmite on: " + lowest[0] + " #" + game.generatorUpgrades[lowest[0]].upgrades, "magmite"); - didSpend = true; + + var repeat = (getPageSetting('spendmagmitesetting') == 0 || getPageSetting('spendmagmitesetting') == 1); + while (repeat) { + if (MODULES["magmite"].algorithm == 2) { + var eff = game.generatorUpgrades["Efficiency"]; + var cap = game.generatorUpgrades["Capacity"]; + var sup = game.generatorUpgrades["Supply"]; + if ((typeof eff === 'undefined') || (typeof cap === 'undefined') || (typeof sup === 'undefined')) + return; + var EffObj = {}; + EffObj.name = "Efficiency"; + EffObj.lvl = eff.upgrades + 1; + EffObj.cost = eff.cost(); + EffObj.benefit = EffObj.lvl * 0.1; + EffObj.effInc = (((1 + EffObj.benefit) / (1 + ((EffObj.lvl - 1) * 0.1)) - 1) * 100); + EffObj.miCostPerPct = EffObj.cost / EffObj.effInc; + var CapObj = {}; + CapObj.name = "Capacity"; + CapObj.lvl = cap.upgrades + 1; + CapObj.cost = cap.cost(); + CapObj.totalCap = 3 + (0.4 * CapObj.lvl); + CapObj.benefit = Math.sqrt(CapObj.totalCap); + CapObj.effInc = ((CapObj.benefit / Math.sqrt(3 + (0.4 * (CapObj.lvl - 1))) - 1) * 100); + CapObj.miCostPerPct = CapObj.cost / CapObj.effInc; + var upgrade, item; + if (EffObj.miCostPerPct <= CapObj.miCostPerPct) + item = EffObj.name; + else { + const supCost = sup.cost(); + var wall = getPageSetting('SupplyWall'); + if (!wall) + item = (CapObj.cost <= supCost) ? + CapObj.name : "Supply"; + else if (wall == 1) + item = "Capacity"; + else if (wall < 0) + item = (supCost <= (CapObj.cost * -wall)) ? + "Supply" : "Capacity"; + else + item = (CapObj.cost <= (supCost * wall)) ? + "Capacity" : "Supply"; + } + upgrade = game.generatorUpgrades[item]; + if (game.global.magmite >= upgrade.cost()) { + debug("Auto Spending " + upgrade.cost() + " Magmite on: " + item + " #" + (game.generatorUpgrades[item].upgrades + 1), "magmite"); + buyGeneratorUpgrade(item); + didSpend = true; + } else + repeat = false; + } + } - //if we can't, exit the loop - else - repeat = false; + } catch (err) { + debug("AutoSpendMagmite Error encountered: " + err.message, "magmite"); } + if (didSpend) + debug("Leftover magmite: " + game.global.magmite, "magmite"); } - } - //dont get trapped in a while loop cause something stupid happened. - catch (err) { - debug("AutoSpendMagmite Error encountered: " + err.message,"magmite"); - } - //print the result - if (didSpend) - debug("Leftover magmite: " + game.global.magmite,"magmite"); } -/** - * Auto Generator: - * [Early Mode (autogen2)] - * -> (Reach Z / optimal fuel from Supply) -> - * [Late Mode (for now: switch to primary mode)] // soon: autogen3 - */ function autoGenerator() { - const world = game.global.world; - if (world < 230) - return; // Magma only - - const endZ = getPageSetting('AutoGen2End'); - const endS = getPageSetting('AutoGen2SupplyEnd'); - var endEarly = (endZ > 0 && world >= endZ) || (endS && world >= (230 + 2 * game.generatorUpgrades.Supply.upgrades)); - if (endEarly) { - //if (autoGenerator3); - if (!autoGenOverrides()) { - const lateMode = getPageSetting('AutoGen3'); - if (game.global.generatorMode != lateMode) - changeGeneratorState(lateMode); - } - } else autoGenerator2(); +var defaultgenstate = getPageSetting('defaultgen'); +var beforefuelstate = getPageSetting('beforegen'); +var hybrid = game.permanentGeneratorUpgrades.Hybridization.owned; +if (!hybrid && defaultgenstate == 2) { + defaultgenstate = 0; } - -/** Early Mode */ -function autoGenerator2() { - const MI = 0, FUEL = 1, HYBRID = 2; - // Respect overrides first. - if (getPageSetting('AutoGen2Override') && autoGenOverrides()) - return; - - const mode = getPageSetting('AutoGen2'); // None : Microtick : Cap - if (!mode) // Default: move on - return; - else if (mode == 3 && game.generatorUpgrades["Overclocker"].upgrades > 0) { // Only trigger overclock if we have Overclocker upgrades. - changeGeneratorState(FUEL); - return; - } - - const fuel = game.global.magmaFuel; - const want = mode == 1 ? getFuelBurnRate() : getGeneratorFuelCap(); - if (!game.global.generatorMode) { // Currently: Gain Mi - if (fuel < want) - changeGeneratorState(game.permanentGeneratorUpgrades.Hybridization.owned ? HYBRID : FUEL); - } else if (fuel >= want) // Not gaining Mi when we should - changeGeneratorState(MI); -} - -/** - * Apply the necessary tweaks the user wants. - * @return false or 0 if unnecessary; 1 fuel; 2 hybrid - */ -function autoGenOverrides() { - const overriden = (game.global.runningChallengeSquared && getPageSetting('AutoGenC2')) || (game.global.dailyChallenge.seed && getPageSetting('AutoGenDC')); - if (overriden && (game.global.generatorMode != overriden)) - changeGeneratorState(overriden); - return overriden; +if (!hybrid && beforefuelstate == 2) { + beforefuelstate = 0; } + if (game.global.world < 230) return; + if (game.global.dailyChallenge.seed && getPageSetting('AutoGenDC') == 1 && game.global.generatorMode != 1) + changeGeneratorState(1); + if (game.global.dailyChallenge.seed && getPageSetting('AutoGenDC') == 1 && game.global.generatorMode == 1) + return; + if (hybrid && game.global.dailyChallenge.seed && getPageSetting('AutoGenDC') == 2 && game.global.generatorMode != 2) + changeGeneratorState(2); + if (game.global.dailyChallenge.seed && getPageSetting('AutoGenDC') == 2 && game.global.generatorMode == 2) + return; + if (game.global.runningChallengeSquared && getPageSetting('AutoGenC2') == 1 && game.global.generatorMode != 1) + changeGeneratorState(1); + if (game.global.runningChallengeSquared && getPageSetting('AutoGenC2') == 1 && game.global.generatorMode == 1) + return; + if (hybrid && game.global.runningChallengeSquared && getPageSetting('AutoGenC2') == 2 && game.global.generatorMode != 2) + changeGeneratorState(2); + if (game.global.runningChallengeSquared && getPageSetting('AutoGenC2') == 2 && game.global.generatorMode == 2) + return; + if (getPageSetting('fuellater') < 1 && game.global.generatorMode != beforefuelstate) + changeGeneratorState(beforefuelstate); + if (getPageSetting('fuellater') < 1 && game.global.generatorMode == beforefuelstate) + return; + if (getPageSetting('fuellater') >= 1 && game.global.world < getPageSetting('fuellater') && game.global.generatorMode != beforefuelstate) + changeGeneratorState(beforefuelstate); + if (getPageSetting('fuellater') >= 1 && game.global.world < getPageSetting('fuellater') && game.global.generatorMode == beforefuelstate) + return; + if (getPageSetting('fuellater') >= 1 && game.global.world >= getPageSetting('fuellater') && game.global.world < getPageSetting('fuelend') && game.global.generatorMode != 1) + changeGeneratorState(1); + if (getPageSetting('fuellater') >= 1 && game.global.world >= getPageSetting('fuellater') && game.global.world < getPageSetting('fuelend') && game.global.generatorMode == 1) + return; + if (getPageSetting('fuelend') < 1 && game.global.world >= getPageSetting('fuellater') && game.global.generatorMode != 1) + changeGeneratorState(1); + if (getPageSetting('fuelend') < 1 && game.global.world >= getPageSetting('fuellater') && game.global.generatorMode == 1) + return; + if (getPageSetting('fuelend') >= 1 && game.global.world >= getPageSetting('fuelend') && game.global.generatorMode != defaultgenstate) + changeGeneratorState(defaultgenstate); + if (getPageSetting('fuelend') >= 1 && game.global.world >= getPageSetting('fuelend') && game.global.generatorMode == defaultgenstate) + return; + } diff --git a/modules/mapfunctions.js b/modules/mapfunctions.js new file mode 100644 index 000000000..ec79ba081 --- /dev/null +++ b/modules/mapfunctions.js @@ -0,0 +1,2779 @@ +//### RAutoMap Global VarsRshouldDoMaps +var RshouldFarm = false; +var RdoVoids = false; +var RneedToVoid = false; +var RneedPrestige = false; +var RshouldDoMaps = false; +var RlastMapWeWereIn = null; +var RdoMaxMapBonus = false; +var RvanillaMAZ = false; +var contractVoid = false; +var RadditionalCritMulti = 2 < getPlayerCritChance() ? 25 : 5; + +//### Quest +var Rshoulddoquest = false; +var Rquestequalityscale = false; +var Rquestshieldzone = 0; + +//### Map Module Vars + +//Frag Farm +var Rshouldfragfarm = false; + +//Time Farm +var Rtimefarm = false; +var Rshouldtimefarm = false; + +//dTime Farm +var Rdtimefarm = false; +var Rdshouldtimefarm = false; + +//Smithy Farm +var Rsmithyfarm = false; +var Rshouldsmithyfarm = false; + +//Tribute +var Rshouldtributefarm = false; + +//Bog +var Rshoulddobogs = false; + +//Frozen Castle +var Rshouldcastle = false; + +//Praid +var Rshoulddopraid = false; +var RAMPpMap1 = undefined; +var RAMPpMap2 = undefined; +var RAMPpMap3 = undefined; +var RAMPpMap4 = undefined; +var RAMPpMap5 = undefined; +var RAMPfragmappy = undefined; +var RAMPrepMap1 = undefined; +var RAMPrepMap2 = undefined; +var RAMPrepMap3 = undefined; +var RAMPrepMap4 = undefined; +var RAMPrepMap5 = undefined; +var RAMPprefragmappy = undefined; +var RAMPmapbought1 = false; +var RAMPmapbought2 = false; +var RAMPmapbought3 = false; +var RAMPmapbought4 = false; +var RAMPmapbought5 = false; +var RAMPfragmappybought = false; +var RAMPdone = false; +var RAMPfragfarming = false; + +//dPraid +var Rdshoulddopraid = false; +var RdAMPpMap1 = undefined; +var RdAMPpMap2 = undefined; +var RdAMPpMap3 = undefined; +var RdAMPpMap4 = undefined; +var RdAMPpMap5 = undefined; +var RdAMPfragmappy = undefined; +var RdAMPrepMap1 = undefined; +var RdAMPrepMap2 = undefined; +var RdAMPrepMap3 = undefined; +var RdAMPrepMap4 = undefined; +var RdAMPrepMap5 = undefined; +var RdAMPprefragmappy = undefined; +var RdAMPmapbought1 = false; +var RdAMPmapbought2 = false; +var RdAMPmapbought3 = false; +var RdAMPmapbought4 = false; +var RdAMPmapbought5 = false; +var RdAMPfragmappybought = false; +var RdAMPdone = false; +var RdAMPfragfarming = false; + +//Mayhem +var Rshouldmayhem = 0; +var Rmayhemextraglobal = -1; + +//Panda +var Rshouldpanda = 0; +var Rpandaextraglobal = 1; + +//Insanity +var Rinsanityfarm = false; +var Rshouldinsanityfarm = false; +var Rinsanityfragfarming = false; +var insanityfragmappy = undefined; +var insanityprefragmappy = undefined; +var insanityfragmappybought = false; + +//Storm +var Rstormfarm = false; +var Rshouldstormfarm = false; + +//Desolation +var Rdesofarm = false; +var Rshoulddesofarm = false; +var Rdesoextraglobal = 1; + +//Equip Farm +var Requipfarm = false; +var Rshouldequipfarm = false; +var Requipminusglobal = -1; + +//Ships +var Rshipfarm = false; +var Rshouldshipfarm = false; +var Rshipfragfarming = false; +var shipfragmappy = undefined; +var shipprefragmappy = undefined; +var shipfragmappybought = false; + +//Alch +var Ralchfarm = false; +var Rshouldalchfarm = false; +var Rshouldhypofarm = false; +var Ralchfragfarming = false; +var alchfragmappy = undefined; +var alchprefragmappy = undefined; +var alchfragmappybought = false; + +//Hypo +var Rhypofarm = false; +var Rhyposhouldwood = true; +var Rshouldhypofarm = false; +var Rhypofragfarming = false; +var hypofragmappy = undefined; +var hypoprefragmappy = undefined; +var hypofragmappybought = false; + +function RresetVars() { + RshouldFarm = false; + RdoVoids = false; + RneedToVoid = false; + RneedPrestige = false; + RshouldDoMaps = false; + RlastMapWeWereIn = null; + RdoMaxMapBonus = false; + RvanillaMAZ = false; + contractVoid = false; + RadditionalCritMulti = 2 < getPlayerCritChance() ? 25 : 5; + + //### Quest + Rshoulddoquest = false; + Rquestequalityscale = false; + Rquestshieldzone = 0; + + //### Map Modules + + //Frag Farm + Rshouldfragfarm = false; + + //Time Farm + Rtimefarm = false; + Rshouldtimefarm = false; + + //dTime Farm + Rdtimefarm = false; + Rdshouldtimefarm = false; + + //Smithy Farm + Rsmithyfarm = false; + Rshouldsmithyfarm = false; + + //Tribute + Rshouldtributefarm = false; + + //Bog + Rshoulddobogs = false; + + //Frozen Castle + Rshouldcastle = false; + + //Praid + Rshoulddopraid = false; + RAMPpMap1 = undefined; + RAMPpMap2 = undefined; + RAMPpMap3 = undefined; + RAMPpMap4 = undefined; + RAMPpMap5 = undefined; + RAMPfragmappy = undefined; + RAMPrepMap1 = undefined; + RAMPrepMap2 = undefined; + RAMPrepMap3 = undefined; + RAMPrepMap4 = undefined; + RAMPrepMap5 = undefined; + RAMPprefragmappy = undefined; + RAMPmapbought1 = false; + RAMPmapbought2 = false; + RAMPmapbought3 = false; + RAMPmapbought4 = false; + RAMPmapbought5 = false; + RAMPfragmappybought = false; + RAMPdone = false; + RAMPfragfarming = false; + + //dPraid + Rdshoulddopraid = false; + RdAMPpMap1 = undefined; + RdAMPpMap2 = undefined; + RdAMPpMap3 = undefined; + RdAMPpMap4 = undefined; + RdAMPpMap5 = undefined; + RdAMPfragmappy = undefined; + RdAMPrepMap1 = undefined; + RdAMPrepMap2 = undefined; + RdAMPrepMap3 = undefined; + RdAMPrepMap4 = undefined; + RdAMPrepMap5 = undefined; + RdAMPprefragmappy = undefined; + RdAMPmapbought1 = false; + RdAMPmapbought2 = false; + RdAMPmapbought3 = false; + RdAMPmapbought4 = false; + RdAMPmapbought5 = false; + RdAMPfragmappybought = false; + RdAMPdone = false; + RdAMPfragfarming = false; + + //Mayhem + Rshouldmayhem = 0; + Rmayhemextraglobal = -1; + + //Panda + Rshouldpanda = 0; + Rpandaextraglobal = 1; + + //Insanity + Rinsanityfarm = false; + Rshouldinsanityfarm = false; + Rinsanityfragfarming = false; + insanityfragmappy = undefined; + insanityprefragmappy = undefined; + insanityfragmappybought = false; + + //Storm + Rstormfarm = false; + Rshouldstormfarm = false; + + //Desolation + Rdesofarm = false; + Rshoulddesofarm = false; + Rdesoextraglobal = 1; + + //Equip Farm + Requipfarm = false; + Rshouldequipfarm = false; + Requipminusglobal = -1; + + //Ships + Rshipfarm = false; + Rshouldshipfarm = false; + Rshipfragfarming = false; + shipfragmappy = undefined; + shipprefragmappy = undefined; + shipfragmappybought = false; + + //Alch + Ralchfarm = false; + Rshouldalchfarm = false; + Rshouldhypofarm = false; + Ralchfragfarming = false; + alchfragmappy = undefined; + alchprefragmappy = undefined; + alchfragmappybought = false; + + //Hypo + Rhypofarm = false; + Rhyposhouldwood = true; + Rshouldhypofarm = false; + Rhypofragfarming = false; + hypofragmappy = undefined; + hypoprefragmappy = undefined; + hypofragmappybought = false; +} + +//###Other Functions - were in other.js but moved over + +function RfragMap() { + document.getElementById("biomeAdvMapsSelect").value = "Plentiful"; + document.getElementById("advExtraLevelSelect").value = 0; + document.getElementById("advSpecialSelect").value = "fa"; + document.getElementById("lootAdvMapsRange").value = 9; + document.getElementById("difficultyAdvMapsRange").value = 9; + document.getElementById("sizeAdvMapsRange").value = 9; + document.getElementById("advPerfectCheckbox").checked = true; + document.getElementById("mapLevelInput").value = (game.global.world - 1); + updateMapCost(); + + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("biomeAdvMapsSelect").value = "Random"; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("advPerfectCheckbox").checked = false; + updateMapCost(); + } + var fragsOwned = game.resources.fragments.owned; + for (var i = 8; i >= 0; i--) { + if (updateMapCost(true) > fragsOwned) { + document.getElementById("difficultyAdvMapsRange").value = i; + } else break; + if (updateMapCost(true) > fragsOwned) { + document.getElementById("sizeAdvMapsRange").value = i; + } else break; + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("advSpecialSelect").value = "0"; + updateMapCost(); + } +} + +function RfragCalc(frag) { + if (frag > game.resources.fragments.owned) Rshouldfragfarm = true; + else Rshouldfragfarm = false; +} + +function RselectFrag() { + var selectedMap = "create"; + if (Rshouldfragfarm) { + for (var map in game.global.mapsOwnedArray) { + if (!game.global.mapsOwnedArray[map].noRecycle && (game.global.world - 1) == game.global.mapsOwnedArray[map].level) { + selectedMap = game.global.mapsOwnedArray[map].id; + break; + } else { + selectedMap = "create"; + } + } + } + return selectedMap; +} + +function RminFragMap(selection, number, special) { + + document.getElementById("biomeAdvMapsSelect").value = selection; + document.getElementById("advExtraLevelSelect").value = number; + document.getElementById("advSpecialSelect").value = special; + document.getElementById("lootAdvMapsRange").value = 9; + document.getElementById("difficultyAdvMapsRange").value = 9; + document.getElementById("sizeAdvMapsRange").value = 9; + document.getElementById("advPerfectCheckbox").checked = true; + document.getElementById("mapLevelInput").value = game.global.world; + updateMapCost(); + + if (updateMapCost(true) <= game.resources.fragments.owned) { + return updateMapCost(true); + } + + //Nobodys perfect + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("advPerfectCheckbox").checked = false; + updateMapCost(); + if (updateMapCost(true) <= game.resources.fragments.owned) { + return updateMapCost(true); + } + } + + //Check minimum loot first + for (var i = 8; i >= 0; i--) { + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("lootAdvMapsRange").value = i; + updateMapCost(); + if (updateMapCost(true) <= game.resources.fragments.owned) { + return updateMapCost(true); + } + } + } + + //Uh-oh ok lets try a bigger map + for (var i = 8; i >= 0; i--) { + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = i; + updateMapCost(); + if (updateMapCost(true) <= game.resources.fragments.owned) { + return updateMapCost(true); + } + } + } + + //Bugger, looks like we're truly scraping the barrel now + for (var i = 8; i >= 0; i--) { + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = i; + updateMapCost(); + if (updateMapCost(true) <= game.resources.fragments.owned) { + return updateMapCost(true); + } + } + } + + //The bottom, you cannot afford lower than this so tough + if (document.getElementById("difficultyAdvMapsRange").value == 0) { + return updateMapCost(true); + } +} + +function RfragCheck(what) { + var cost = 0; + var frag = false; + var farmzone = 0; + var farmlevel = 0; + var selection = "Farmlands"; + var special = "fa"; + + if (what == "insanity") { + frag = getPageSetting('Rinsanityfarmfrag'); + farmzone = getPageSetting('Rinsanityfarmzone'); + farmlevel = getPageSetting('Rinsanityfarmlevel'); + selection = "Plentiful"; + } + else if (what == "ship") { + frag = getPageSetting('Rshipfarmfrag'); + farmzone = getPageSetting('Rshipfarmzone'); + farmlevel = getPageSetting('Rshipfarmlevel'); + special = game.global.highestRadonLevelCleared > 83 ? "lsc" : "ssc"; + selection = game.global.farmlandsUnlocked ? "Farmlands" : "Plentiful"; + } + else if (what == "alch") { + frag = getPageSetting('Ralchfarmfrag'); + farmzone = getPageSetting('Ralchfarmzone'); + farmlevel = getPageSetting('Ralchfarmlevel'); + } + else if (what == "hypo") { + frag = getPageSetting('Rhypofarmfrag'); + farmzone = getPageSetting('Rhypofarmzone'); + farmlevel = getPageSetting('Rhypofarmlevel'); + sepcial = "lwc"; + } + + var farmlevelindex = farmzone.indexOf(game.global.world); + var levelzones = farmlevel[farmlevelindex]; + + if (what == "alch") { + selection = getPageSetting('Ralchfarmselection')[farmlevelindex]; + } + + if (frag) cost = RminFragMap(selection, levelzones, special); + + if (game.resources.fragments.owned >= cost) return true; + + else return false; +} + +function RAMPplusMapToRun(daily, number) { + var map; + var praidzone = daily ? getPageSetting('RdAMPraidzone') : getPageSetting('RAMPraidzone'); + var raidzone = daily ? getPageSetting('RdAMPraidraid') : getPageSetting('RAMPraidraid'); + + var praidindex = praidzone.indexOf(game.global.world); + var raidzones = raidzone[praidindex]; + + map = (raidzones - game.global.world - number); + + return map; +} + +function RAMPshouldrunmap(daily, number) { + var go = false; + var praidzone = daily ? getPageSetting('RdAMPraidzone') : getPageSetting('RAMPraidzone'); + var raidzone = daily ? getPageSetting('RdAMPraidraid') : getPageSetting('RAMPraidraid'); + + var praidindex = praidzone.indexOf(game.global.world); + var raidzones = raidzone[praidindex]; + + var actualraidzone = (raidzones - number); + + if (Rgetequips(actualraidzone, false) > 0) { + go = true; + } + return go; +} + +function RAMPplusPres(daily, number) { + document.getElementById("biomeAdvMapsSelect").value = "Plentiful"; + document.getElementById("advExtraLevelSelect").value = daily ? RAMPplusMapToRun(true, number) : RAMPplusMapToRun(false, number); + document.getElementById("advSpecialSelect").value = "p"; + document.getElementById("lootAdvMapsRange").value = 0; + document.getElementById("difficultyAdvMapsRange").value = 9; + document.getElementById("sizeAdvMapsRange").value = 9; + document.getElementById("advPerfectCheckbox").checked = false; + document.getElementById("mapLevelInput").value = game.global.world; + updateMapCost(); + + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("biomeAdvMapsSelect").value = "Random"; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 8; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 8; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 7; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 7; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 6; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 6; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 5; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 5; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 4; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 4; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 3; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 3; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 2; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 2; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 1; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 1; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 0; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 0; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("advSpecialSelect").value = "fa"; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("advSpecialSelect").value = "0"; + updateMapCost(); + } +} + +function RAMPplusPresfragmax(daily, number) { + document.getElementById("biomeAdvMapsSelect").value = "Plentiful"; + document.getElementById("advExtraLevelSelect").value = daily ? RAMPplusMapToRun(true, number) : RAMPplusMapToRun(false, number); + document.getElementById("advSpecialSelect").value = "p"; + document.getElementById("lootAdvMapsRange").value = 0; + document.getElementById("difficultyAdvMapsRange").value = 9; + document.getElementById("sizeAdvMapsRange").value = 9; + document.getElementById("advPerfectCheckbox").checked = false; + document.getElementById("mapLevelInput").value = game.global.world; + updateMapCost(); + return updateMapCost(true); +} + +function RAMPplusPresfragmin(daily, number) { + document.getElementById("biomeAdvMapsSelect").value = "Plentiful"; + document.getElementById("advExtraLevelSelect").value = daily ? RAMPplusMapToRun(true, number) : RAMPplusMapToRun(false, number); + document.getElementById("advSpecialSelect").value = "p"; + document.getElementById("lootAdvMapsRange").value = 0; + document.getElementById("difficultyAdvMapsRange").value = 9; + document.getElementById("sizeAdvMapsRange").value = 9; + document.getElementById("advPerfectCheckbox").checked = false; + document.getElementById("mapLevelInput").value = game.global.world; + updateMapCost(); + if (updateMapCost(true) <= game.resources.fragments.owned) { + return updateMapCost(true); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("biomeAdvMapsSelect").value = "Random"; + updateMapCost(); + if (updateMapCost(true) <= game.resources.fragments.owned) { + return updateMapCost(true); + } + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 8; + updateMapCost(); + if (updateMapCost(true) <= game.resources.fragments.owned) { + return updateMapCost(true); + } + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 8; + updateMapCost(); + if (updateMapCost(true) <= game.resources.fragments.owned) { + return updateMapCost(true); + } + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 7; + updateMapCost(); + if (updateMapCost(true) <= game.resources.fragments.owned) { + return updateMapCost(true); + } + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 7; + updateMapCost(); + if (updateMapCost(true) <= game.resources.fragments.owned) { + return updateMapCost(true); + } + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 6; + updateMapCost(); + if (updateMapCost(true) <= game.resources.fragments.owned) { + return updateMapCost(true); + } + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 6; + updateMapCost(); + if (updateMapCost(true) <= game.resources.fragments.owned) { + return updateMapCost(true); + } + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 5; + updateMapCost(); + if (updateMapCost(true) <= game.resources.fragments.owned) { + return updateMapCost(true); + } + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 5; + updateMapCost(); + if (updateMapCost(true) <= game.resources.fragments.owned) { + return updateMapCost(true); + } + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 4; + updateMapCost(); + if (updateMapCost(true) <= game.resources.fragments.owned) { + return updateMapCost(true); + } + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 4; + updateMapCost(); + if (updateMapCost(true) <= game.resources.fragments.owned) { + return updateMapCost(true); + } + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 3; + updateMapCost(); + if (updateMapCost(true) <= game.resources.fragments.owned) { + return updateMapCost(true); + } + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 3; + updateMapCost(); + if (updateMapCost(true) <= game.resources.fragments.owned) { + return updateMapCost(true); + } + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 2; + updateMapCost(); + if (updateMapCost(true) <= game.resources.fragments.owned) { + return updateMapCost(true); + } + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 2; + updateMapCost(); + if (updateMapCost(true) <= game.resources.fragments.owned) { + return updateMapCost(true); + } + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 1; + updateMapCost(); + if (updateMapCost(true) <= game.resources.fragments.owned) { + return updateMapCost(true); + } + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 1; + updateMapCost(); + if (updateMapCost(true) <= game.resources.fragments.owned) { + return updateMapCost(true); + } + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 0; + updateMapCost(); + if (updateMapCost(true) <= game.resources.fragments.owned) { + return updateMapCost(true); + } + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 0; + updateMapCost(); + if (updateMapCost(true) <= game.resources.fragments.owned) { + return updateMapCost(true); + } + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("advSpecialSelect").value = "fa"; + updateMapCost(); + if (updateMapCost(true) <= game.resources.fragments.owned) { + return updateMapCost(true); + } + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("advSpecialSelect").value = "0"; + updateMapCost(); + } + if (document.getElementById("advSpecialSelect").value == "0") { + return updateMapCost(true); + } +} + +function RAMPfrag(daily) { + var cost = 0; + var praidzone = daily ? getPageSetting('RdAMPraidzone') : getPageSetting('RAMPraidzone'); + var raidzone = daily ? getPageSetting('RdAMPraidraid') : getPageSetting('RAMPraidraid'); + var frag = daily ? getPageSetting('RdAMPraidfrag') : getPageSetting('RAMPraidfrag'); + + var praidindex = praidzone.indexOf(game.global.world); + var raidzones = raidzone[praidindex]; + + if (Rgetequips(raidzones, false)) { + if (frag == 1) cost += (daily ? RAMPplusPresfragmin(true, 0) : RAMPplusPresfragmin(false, 0)); + else if (frag == 2) cost += (daily ? RAMPplusPresfragmax(true, 0) : RAMPplusPresfragmax(false, 0)); + } + if (Rgetequips((raidzones - 1), false)) { + if (frag == 1) cost += (daily ? RAMPplusPresfragmin(true, 1) : RAMPplusPresfragmin(false, 1)); + else if (frag == 2) cost += (daily ? RAMPplusPresfragmax(true, 1) : RAMPplusPresfragmax(false, 1)); + } + if (Rgetequips((raidzones - 2), false)) { + if (frag == 1) cost += (daily ? RAMPplusPresfragmin(true, 2) : RAMPplusPresfragmin(false, 2)); + else if (frag == 2) cost += (daily ? RAMPplusPresfragmax(true, 2) : RAMPplusPresfragmax(false, 2)); + } + if (Rgetequips((raidzones - 3), false)) { + if (frag == 1) cost += (daily ? RAMPplusPresfragmin(true, 3) : RAMPplusPresfragmin(false, 3)); + else if (frag == 2) cost += (daily ? RAMPplusPresfragmax(true, 3) : RAMPplusPresfragmax(false, 3)); + } + if (Rgetequips((raidzones - 4), false)) { + if (frag == 1) cost += (daily ? RAMPplusPresfragmin(true, 4) : RAMPplusPresfragmin(false, 4)); + else if (frag == 2) cost += (daily ? RAMPplusPresfragmax(true, 4) : RAMPplusPresfragmax(false, 4)); + } + + if (game.resources.fragments.owned >= cost) return true; + else return false; +} + +//###RAutoMap Functions + +//Time Farm + +function RtimeFarm(should, level, map, special, daily) { + var timefarmzone = daily ? getPageSetting('Rdtimefarmzone') : getPageSetting('Rtimefarmzone'); + var timefarmindex = timefarmzone.indexOf(game.global.world); + + var timefarmlevel = daily ? getPageSetting('Rdtimefarmlevel')[timefarmindex] : getPageSetting('Rtimefarmlevel')[timefarmindex]; + if (level) return timefarmlevel; + + var timefarmmap = daily ? autoTrimpSettings.Rdtimefarmmap.value[timefarmindex] : autoTrimpSettings.Rtimefarmmap.value[timefarmindex]; + if (map) return timefarmmap; + + var timefarmspecial = daily ? autoTrimpSettings.Rdtimefarmspecial.value[timefarmindex] : autoTrimpSettings.Rtimefarmspecial.value[timefarmindex]; + if (special) return timefarmspecial; + + var timefarmcell = daily ? getPageSetting('Rdtimefarmcell')[timefarmindex] : getPageSetting('Rtimefarmcell')[timefarmindex]; + var timefarmtime = daily ? getPageSetting('Rdtimefarmtime') : getPageSetting('Rtimefarmtime'); + var time = ((new Date().getTime() - game.global.zoneStarted) / 1000 / 60); + var timezones = timefarmtime[timefarmindex]; + + if (should && timefarmzone.includes(game.global.world)) { + if (game.global.lastClearedCell + 2 >= timefarmcell && timezones > time && timezones > 0) { + if (daily) { + Rdshouldtimefarm = true; + } else Rshouldtimefarm = true; + } + if (!daily && game.global.challengeActive == 'Daily' && getPageSetting('Rdtimefarm') != 2) { + Rshouldtimefarm = false; + } + } +} + +function RtimeFarmMap(daily) { + if (getPageSetting('Rtimefarmlevel') != 0 || (daily && getPageSetting('Rdtimefarmlevel') != 0)) { + levelzones = daily ? RtimeFarm(false, true, false, false, true) : RtimeFarm(false, true, false, false, false); + if (levelzones > 0) { + document.getElementById("mapLevelInput").value = game.global.world; + document.getElementById("advExtraLevelSelect").value = levelzones; + } else if (levelzones < 0) { + document.getElementById("mapLevelInput").value = (game.global.world + levelzones); + } + } + + biomeAdvMapsSelect.value = daily ? RtimeFarm(false, false, true, false, true) : RtimeFarm(false, false, true, false, false); + document.getElementById("advSpecialSelect").value = daily ? RtimeFarm(false, false, false, true, true) : RtimeFarm(false, false, false, true, false); + updateMapCost(); +} + +//Smithy Farm + +function RsmithyFarm(amount) { + var smithyfarmzone = getPageSetting('Rsmithyfarmzone'); + var smithyfarmindex = smithyfarmzone.indexOf(game.global.world); + + var smithyfarmcell = getPageSetting('Rsmithyfarmcell')[smithyfarmindex]; + var smithyfarmsmithy = getPageSetting('Rsmithyfarmamount'); + var smithys = game.buildings.Smithy.owned; + var smithyzones = smithyfarmsmithy[smithyfarmindex]; + + if (amount) return smithyzones; + + if (smithyfarmzone.includes(game.global.world)) { + if (game.global.lastClearedCell + 2 >= smithyfarmcell && smithyzones > smithys && smithyzones > 0) { + Rshouldsmithyfarm = true; + } + } +} + +function RmapLevelCalc() { + var HD = (RcalcHDratio() / 1.5); + var level = 0; + + if (HD >= 10000) level = -3; + if (HD >= 5000) level = -2; + if (HD >= 500) level = -1; + if (HD <= 40) level = 0; + if (HD <= 1) level = 1; + if (HD <= 0.5) level = 2; + if (HD <= 0.1) level = 3; + if (HD <= 0.05) level = 4; + if (HD <= 0.01) level = 5; + if (HD <= 0.005) level = 6; + if (HD <= 0.0001) level = 7; + if (HD <= 0.00005) level = 8; + + return level; +} + +function RsmithyCalc(level, selection, special, gather) { + var smithys = game.buildings.Smithy.owned; + var goal = RsmithyFarm(true) - smithys; + var afford = true; + if (goal > 0) afford = canAffordBuilding("Smithy", false, false, false, false, goal); + var smithywood, smithymetal, smithygems; + + if (!afford) { + smithywood = game.resources.wood.owned - getBuildingItemPrice(game.buildings.Smithy, "wood", false, goal); + smithymetal = game.resources.metal.owned - getBuildingItemPrice(game.buildings.Smithy, "metal", false, goal); + smithygems = game.resources.gems.owned - getBuildingItemPrice(game.buildings.Smithy, "gems", false, goal); + } + + if (level) return RmapLevelCalc(); + + if (!afford && smithygems < 0) { + if (selection) return "Depths"; + else if (special) return getHighestLevelCleared(true) > 65 ? "hc" : "lc"; + else if (gather) return "metal"; + } + + if (!afford && smithymetal < 0 && smithywood < 0) { + if (selection) return game.global.farmlandsUnlocked ? "Farmlands" : "Plentiful"; + else if (special) return getHighestLevelCleared(true) > 65 ? "hc" : "lc"; + else if (gather) return "metal"; + } + + if (!afford && smithywood < 0) { + if (selection) return game.global.farmlandsUnlocked ? "Farmlands" : "Plentiful"; + else if (special) return getHighestLevelCleared(true) > 85 ? "lwc" : "swc"; + else if (gather) return "wood"; + } + + if (!afford && smithymetal < 0) { + if (selection) return game.global.farmlandsUnlocked ? "Farmlands" : "Plentiful"; + else if (special) return getHighestLevelCleared(true) > 85 ? "lmc" : "smc"; + else if (gather) return "metal"; + } +} + +function RsmithyFarmMap() { + var levelzones = RsmithyCalc(true, false, false, false); + if (levelzones > 0) { + document.getElementById("mapLevelInput").value = game.global.world; + document.getElementById("advExtraLevelSelect").value = levelzones; + } else if (levelzones < 0) { + document.getElementById("mapLevelInput").value = (game.global.world + levelzones); + } + + biomeAdvMapsSelect.value = RsmithyCalc(false, true, false, false); + document.getElementById("advSpecialSelect").value = RsmithyCalc(false, false, true, false); + updateMapCost(); + if (updateMapCost(true) > game.resources.fragments.owned) { + RfragCalc(updateMapCost(true)); + } +} + +//Tribute Farm + +function RtributeFarm(should, level, map, special) { + var tributefarmzone = getPageSetting('Rtributefarmzone'); + var tributefarmindex = tributefarmzone.indexOf(game.global.world); + + var tributefarmlevel = getPageSetting('Rtributefarmlevel')[tributefarmindex]; + if (level) return tributefarmlevel; + + var tributefarmmap = autoTrimpSettings.Rtributemapselection.value[tributefarmindex]; + if (map) return tributefarmmap; + + var tributefarmspecial = autoTrimpSettings.Rtributespecialselection.value[tributefarmindex]; + if (special) return tributefarmspecial; + + var tributefarmcell = getPageSetting('Rtributefarmcell')[tributefarmindex]; + var tributefarmtribute = getPageSetting('Rtributefarmamount'); + var tributes = game.buildings.Tribute.owned; + var tributezones = tributefarmtribute[tributefarmindex]; + + if (should && tributefarmzone.includes(game.global.world)) { + if (game.global.lastClearedCell + 2 >= tributefarmcell && tributezones > tributes && tributezones > 0) { + Rshouldtributefarm = true; + } + } +} + +function RtributeFarmMap() { + if (getPageSetting('Rtributefarmlevel') != 0) { + levelzones = RtributeFarm(false, true, false, false); + if (levelzones > 0) { + document.getElementById("mapLevelInput").value = game.global.world; + document.getElementById("advExtraLevelSelect").value = levelzones; + } else if (levelzones < 0) { + document.getElementById("mapLevelInput").value = (game.global.world + levelzones); + } + } + + biomeAdvMapsSelect.value = RtributeFarm(false, false, true, false); + document.getElementById("advSpecialSelect").value = RtributeFarm(false, false, false, true); + updateMapCost(); +} + +//Bogs + +function Rbogs() { + var bogzone = getPageSetting('Rblackbogzone'); + var bogamount = getPageSetting('Rblackbogamount'); + var bogindex = bogzone.indexOf(game.global.world); + var stacks = 100; + var stacksum = 0; + + for (var i = 0; i < (bogindex + 1); i++) { + stacksum += parseInt(bogamount[i]); + } + + var totalstacks = stacks - stacksum; + + if (bogzone.includes(game.global.world) && game.challenges.Quagmire.motivatedStacks > totalstacks) { + Rshoulddobogs = true; + } +} + +//Praiding + +function RPraid(daily) { + var praidzone = daily ? getPageSetting('RdAMPraidzone') : getPageSetting('RAMPraidzone'); + var raidzone = daily ? getPageSetting('RdAMPraidraid') : getPageSetting('RAMPraidraid'); + + var praidindex = praidzone.indexOf(game.global.world); + var raidzones = raidzone[praidindex]; + + var cell; + cell = daily ? ((getPageSetting('RdAMPraidcell') != 0) ? getPageSetting('RdAMPraidcell')[praidindex] : 1) : ((getPageSetting('RAMPraidcell') != 0) ? getPageSetting('RAMPraidcell')[praidindex] : 1); + + if (praidzone.includes(game.global.world) && ((cell <= 1) || (cell > 1 && (game.global.lastClearedCell + 1) >= cell)) && Rgetequips(raidzones, false) > 0) { + if (daily) { + Rdshoulddopraid = true; + } else Rshoulddopraid = true; + } +} + +function RAMPreset(daily) { + + if (!daily) { + RAMPpMap1 = undefined; + RAMPpMap2 = undefined; + RAMPpMap3 = undefined; + RAMPpMap4 = undefined; + RAMPpMap5 = undefined; + RAMPfragmappy = undefined; + RAMPprefragmappy = undefined; + RAMPmapbought1 = false; + RAMPmapbought2 = false; + RAMPmapbought3 = false; + RAMPmapbought4 = false; + RAMPmapbought5 = false; + RAMPfragmappybought = false; + } else { + RdAMPpMap1 = undefined; + RdAMPpMap2 = undefined; + RdAMPpMap3 = undefined; + RdAMPpMap4 = undefined; + RdAMPpMap5 = undefined; + RdAMPfragmappy = undefined; + RdAMPprefragmappy = undefined; + RdAMPmapbought1 = false; + RdAMPmapbought2 = false; + RdAMPmapbought3 = false; + RdAMPmapbought4 = false; + RdAMPmapbought5 = false; + RdAMPfragmappybought = false; + } + + var recycle = daily ? getPageSetting('RdAMPraidrecycle') : getPageSetting('RAMPraidrecycle'); + + if (!daily) { + + if (RAMPrepMap1 != undefined) { + if (recycle) { + recycleMap(getMapIndex(RAMPrepMap1)); + } + RAMPrepMap1 = undefined; + } + if (RAMPrepMap2 != undefined) { + if (recycle) { + recycleMap(getMapIndex(RAMPrepMap2)); + } + RAMPrepMap2 = undefined; + } + if (RAMPrepMap3 != undefined) { + if (recycle) { + recycleMap(getMapIndex(RAMPrepMap3)); + } + RAMPrepMap3 = undefined; + } + if (RAMPrepMap4 != undefined) { + if (recycle) { + recycleMap(getMapIndex(RAMPrepMap4)); + } + RAMPrepMap4 = undefined; + } + if (RAMPrepMap5 != undefined) { + if (recycle) { + recycleMap(getMapIndex(RAMPrepMap5)); + } + RAMPrepMap5 = undefined; + } + } else { + + if (RdAMPrepMap1 != undefined) { + if (recyle) { + recycleMap(getMapIndex(RdAMPrepMap1)); + } + RdAMPrepMap1 = undefined; + } + if (RdAMPrepMap2 != undefined) { + if (recyle) { + recycleMap(getMapIndex(RdAMPrepMap2)); + } + RdAMPrepMap2 = undefined; + } + if (RdAMPrepMap3 != undefined) { + if (recyle) { + recycleMap(getMapIndex(RdAMPrepMap3)); + } + RdAMPrepMap3 = undefined; + } + if (RdAMPrepMap4 != undefined) { + if (recyle) { + recycleMap(getMapIndex(RdAMPrepMap4)); + } + RdAMPrepMap4 = undefined; + } + if (RdAMPrepMap5 != undefined) { + if (recyle) { + recycleMap(getMapIndex(RdAMPrepMap5)); + } + RdAMPrepMap5 = undefined; + } + } +} + +function RAMP() { + RAMPdone = false; + var RAMPfragcheck = true; + if (getPageSetting('RAMPraidfrag') > 0) { + if (RAMPfrag(false) == true) { + RAMPfragcheck = true; + RAMPfragfarming = false; + } else if (RAMPfrag(false) == false && !RAMPmapbought1 && !RAMPmapbought2 && !RAMPmapbought3 && !RAMPmapbought4 && !RAMPmapbought5 && Rshoulddopraid) { + RAMPfragfarming = true; + RAMPfragcheck = false; + if (!RAMPfragcheck && RAMPfragmappy == undefined && !RAMPfragmappybought && game.global.preMapsActive && Rshoulddopraid) { + debug("Check complete for frag map"); + RfragMap(); + if ((updateMapCost(true) <= game.resources.fragments.owned)) { + buyMap(); + RAMPfragmappybought = true; + if (RAMPfragmappybought) { + RAMPfragmappy = game.global.mapsOwnedArray[game.global.mapsOwnedArray.length - 1].id; + debug("frag map bought"); + } + } + } + if (!RAMPfragcheck && game.global.preMapsActive && !game.global.mapsActive && RAMPfragmappybought && RAMPfragmappy != undefined && Rshoulddopraid) { + debug("running frag map"); + selectedMap = RAMPfragmappy; + selectMap(RAMPfragmappy); + runMap(); + RlastMapWeWereIn = getCurrentMapObject(); + RAMPprefragmappy = RAMPfragmappy; + RAMPfragmappy = undefined; + } + if (!RAMPfragcheck && game.global.mapsActive && RAMPfragmappybought && RAMPprefragmappy != undefined && Rshoulddopraid) { + if (RAMPfrag(false) == false) { + if (!game.global.repeatMap) { + repeatClicked(); + } + } else if (RAMPfrag(false) == true) { + if (game.global.repeatMap) { + repeatClicked(); + mapsClicked(); + } + if (game.global.preMapsActive && RAMPfragmappybought && RAMPprefragmappy != undefined && Rshoulddopraid) { + RAMPfragmappybought = false; + } + if (RAMPprefragmappy != undefined) { + recycleMap(getMapIndex(RAMPprefragmappy)); + RAMPprefragmappy = undefined; + } + RAMPfragcheck = true; + RAMPfragfarming = false; + } + } + } else { + RAMPfragcheck = true; + RAMPfragfarming = false; + } + } + if (RAMPfragcheck && RAMPpMap5 == undefined && !RAMPmapbought5 && game.global.preMapsActive && Rshoulddopraid && RAMPshouldrunmap(false, 0)) { + debug("Check complete for 5th map"); + RAMPplusPres(false, 0); + if ((updateMapCost(true) <= game.resources.fragments.owned)) { + buyMap(); + RAMPmapbought5 = true; + if (RAMPmapbought5) { + RAMPpMap5 = game.global.mapsOwnedArray[game.global.mapsOwnedArray.length - 1].id; + debug("5th map bought"); + } + } + } + if (RAMPfragcheck && RAMPpMap4 == undefined && !RAMPmapbought4 && game.global.preMapsActive && Rshoulddopraid && RAMPshouldrunmap(false, 1)) { + debug("Check complete for 4th map"); + RAMPplusPres(false, 1); + if ((updateMapCost(true) <= game.resources.fragments.owned)) { + buyMap(); + RAMPmapbought4 = true; + if (RAMPmapbought4) { + RAMPpMap4 = game.global.mapsOwnedArray[game.global.mapsOwnedArray.length - 1].id; + debug("4th map bought"); + } + } + } + if (RAMPfragcheck && RAMPpMap3 == undefined && !RAMPmapbought3 && game.global.preMapsActive && Rshoulddopraid && RAMPshouldrunmap(false, 2)) { + debug("Check complete for 3rd map"); + RAMPplusPres(false, 2); + if ((updateMapCost(true) <= game.resources.fragments.owned)) { + buyMap(); + RAMPmapbought3 = true; + if (RAMPmapbought3) { + RAMPpMap3 = game.global.mapsOwnedArray[game.global.mapsOwnedArray.length - 1].id; + debug("3rd map bought"); + } + } + } + if (RAMPfragcheck && RAMPpMap2 == undefined && !RAMPmapbought2 && game.global.preMapsActive && Rshoulddopraid && RAMPshouldrunmap(false, 3)) { + debug("Check complete for 2nd map"); + RAMPplusPres(false, 3); + if ((updateMapCost(true) <= game.resources.fragments.owned)) { + buyMap(); + RAMPmapbought2 = true; + if (RAMPmapbought2) { + RAMPpMap2 = game.global.mapsOwnedArray[game.global.mapsOwnedArray.length - 1].id; + debug("2nd map bought"); + } + } + } + if (RAMPfragcheck && RAMPpMap1 == undefined && !RAMPmapbought1 && game.global.preMapsActive && Rshoulddopraid && RAMPshouldrunmap(false, 4)) { + debug("Check complete for 1st map"); + RAMPplusPres(false, 4); + if ((updateMapCost(true) <= game.resources.fragments.owned)) { + buyMap(); + RAMPmapbought1 = true; + if (RAMPmapbought1) { + RAMPpMap1 = game.global.mapsOwnedArray[game.global.mapsOwnedArray.length - 1].id; + debug("1st map bought"); + } + } + } + if (RAMPfragcheck && !RAMPmapbought1 && !RAMPmapbought2 && !RAMPmapbought3 && !RAMPmapbought4 && !RAMPmapbought5) { + RAMPpMap1 = undefined; + RAMPpMap2 = undefined; + RAMPpMap3 = undefined; + RAMPpMap4 = undefined; + RAMPpMap5 = undefined; + debug("Failed to Prestige Raid. Looks like you can't afford to or have no equips to get!"); + Rshoulddopraid = false; + autoTrimpSettings["RAutoMaps"].value = 0; + } + if (RAMPfragcheck && game.global.preMapsActive && !game.global.mapsActive && RAMPmapbought1 && RAMPpMap1 != undefined && Rshoulddopraid) { + debug("running map 1"); + selectedMap = RAMPpMap1; + selectMap(RAMPpMap1); + runMap(); + RlastMapWeWereIn = getCurrentMapObject(); + RAMPrepMap1 = RAMPpMap1; + RAMPpMap1 = undefined; + } + if (RAMPfragcheck && game.global.preMapsActive && !game.global.mapsActive && RAMPmapbought2 && RAMPpMap2 != undefined && Rshoulddopraid) { + debug("running map 2"); + selectedMap = RAMPpMap2; + selectMap(RAMPpMap2); + runMap(); + RlastMapWeWereIn = getCurrentMapObject(); + RAMPrepMap2 = RAMPpMap2; + RAMPpMap2 = undefined; + } + if (RAMPfragcheck && game.global.preMapsActive && !game.global.mapsActive && RAMPmapbought3 && RAMPpMap3 != undefined && Rshoulddopraid) { + debug("running map 3"); + selectedMap = RAMPpMap3; + selectMap(RAMPpMap3); + runMap(); + RlastMapWeWereIn = getCurrentMapObject(); + RAMPrepMap3 = RAMPpMap3; + RAMPpMap3 = undefined; + } + if (RAMPfragcheck && game.global.preMapsActive && !game.global.mapsActive && RAMPmapbought4 && RAMPpMap4 != undefined && Rshoulddopraid) { + debug("running map 4"); + selectedMap = RAMPpMap4; + selectMap(RAMPpMap4); + runMap(); + RlastMapWeWereIn = getCurrentMapObject(); + RAMPrepMap4 = RAMPpMap4; + RAMPpMap4 = undefined; + } + if (RAMPfragcheck && game.global.preMapsActive && !game.global.mapsActive && RAMPmapbought5 && RAMPpMap5 != undefined && Rshoulddopraid) { + debug("running map 5"); + selectedMap = RAMPpMap5; + selectMap(RAMPpMap5); + runMap(); + RlastMapWeWereIn = getCurrentMapObject(); + RAMPrepMap5 = RAMPpMap5; + RAMPpMap5 = undefined; + } +} + +function dRAMP() { + RdAMPdone = false; + debug("dcreatep selected"); + var RdAMPfragcheck = true; + if (getPageSetting('RdAMPraidfrag') > 0) { + if (RAMPfrag(true) == true) { + RdAMPfragcheck = true; + RdAMPfragfarming = false; + } else if (RAMPfrag(true) == false && !RdAMPmapbought1 && !RdAMPmapbought2 && !RdAMPmapbought3 && !RdAMPmapbought4 && !RdAMPmapbought5 && Rdshoulddopraid) { + RdAMPfragfarming = true; + RdAMPfragcheck = false; + if (!RdAMPfragcheck && RdAMPfragmappy == undefined && !RdAMPfragmappybought && game.global.preMapsActive && Rdshoulddopraid) { + debug("Check complete for frag map"); + RfragMap(); + if ((updateMapCost(true) <= game.resources.fragments.owned)) { + buyMap(); + RdAMPfragmappybought = true; + if (RdAMPfragmappybought) { + RdAMPfragmappy = game.global.mapsOwnedArray[game.global.mapsOwnedArray.length - 1].id; + debug("frag map bought"); + } + } + } + if (!RdAMPfragcheck && game.global.preMapsActive && !game.global.mapsActive && RdAMPfragmappybought && RdAMPfragmappy != undefined && Rdshoulddopraid) { + debug("running frag map"); + selectedMap = RdAMPfragmappy; + selectMap(RdAMPfragmappy); + runMap(); + RlastMapWeWereIn = getCurrentMapObject(); + RdAMPprefragmappy = RdAMPfragmappy; + RdAMPfragmappy = undefined; + } + if (!RdAMPfragcheck && game.global.mapsActive && RdAMPfragmappybought && RdAMPprefragmappy != undefined && Rdshoulddopraid) { + if (RAMPfrag(true) == false) { + if (!game.global.repeatMap) { + repeatClicked(); + } + } else if (RAMPfrag(true) == true) { + if (game.global.repeatMap) { + repeatClicked(); + mapsClicked(); + } + if (game.global.preMapsActive && RdAMPfragmappybought && RdAMPprefragmappy != undefined && Rdshoulddopraid) { + RdAMPfragmappybought = false; + } + if (RdAMPprefragmappy != undefined) { + recycleMap(getMapIndex(RdAMPprefragmappy)); + RdAMPprefragmappy = undefined; + } + RdAMPfragcheck = true; + RdAMPfragfarming = false; + } + } + } else { + RdAMPfragcheck = true; + RdAMPfragfarming = false; + } + } + if (RdAMPfragcheck && RdAMPpMap5 == undefined && !RdAMPmapbought5 && game.global.preMapsActive && Rdshoulddopraid && RAMPshouldrunmap(true, 0)) { + debug("Check complete for 5th map"); + RAMPplusPres(true, 0); + if ((updateMapCost(true) <= game.resources.fragments.owned)) { + buyMap(); + RdAMPmapbought5 = true; + if (RdAMPmapbought5) { + RdAMPpMap5 = game.global.mapsOwnedArray[game.global.mapsOwnedArray.length - 1].id; + debug("5th map bought"); + } + } + } + if (RdAMPfragcheck && RdAMPpMap4 == undefined && !RdAMPmapbought4 && game.global.preMapsActive && Rdshoulddopraid && RAMPshouldrunmap(true, 1)) { + debug("Check complete for 4th map"); + RAMPplusPres(true, 1); + if ((updateMapCost(true) <= game.resources.fragments.owned)) { + buyMap(); + RdAMPmapbought4 = true; + if (RdAMPmapbought4) { + RdAMPpMap4 = game.global.mapsOwnedArray[game.global.mapsOwnedArray.length - 1].id; + debug("4th map bought"); + } + } + } + if (RdAMPfragcheck && RdAMPpMap3 == undefined && !RdAMPmapbought3 && game.global.preMapsActive && Rdshoulddopraid && RAMPshouldrunmap(true, 2)) { + debug("Check complete for 3rd map"); + RAMPplusPres(true, 2); + if ((updateMapCost(true) <= game.resources.fragments.owned)) { + buyMap(); + RdAMPmapbought3 = true; + if (RdAMPmapbought3) { + RdAMPpMap3 = game.global.mapsOwnedArray[game.global.mapsOwnedArray.length - 1].id; + debug("3rd map bought"); + } + } + } + if (RdAMPfragcheck && RdAMPpMap2 == undefined && !RdAMPmapbought2 && game.global.preMapsActive && Rdshoulddopraid && RAMPshouldrunmap(true, 3)) { + debug("Check complete for 2nd map"); + RAMPplusPres(true, 3); + if ((updateMapCost(true) <= game.resources.fragments.owned)) { + buyMap(); + RdAMPmapbought2 = true; + if (RdAMPmapbought2) { + RdAMPpMap2 = game.global.mapsOwnedArray[game.global.mapsOwnedArray.length - 1].id; + debug("2nd map bought"); + } + } + } + if (RdAMPfragcheck && RdAMPpMap1 == undefined && !RdAMPmapbought1 && game.global.preMapsActive && Rdshoulddopraid && RAMPshouldrunmap(true, 4)) { + debug("Check complete for 1st map"); + RAMPplusPres(true, 4); + if ((updateMapCost(true) <= game.resources.fragments.owned)) { + buyMap(); + RdAMPmapbought1 = true; + if (RdAMPmapbought1) { + RdAMPpMap1 = game.global.mapsOwnedArray[game.global.mapsOwnedArray.length - 1].id; + debug("1st map bought"); + } + } + } + if (RdAMPfragcheck && !RdAMPmapbought1 && !RdAMPmapbought2 && !RdAMPmapbought3 && !RdAMPmapbought4 && !RdAMPmapbought5) { + RdAMPpMap1 = undefined; + RdAMPpMap2 = undefined; + RdAMPpMap3 = undefined; + RdAMPpMap4 = undefined; + RdAMPpMap5 = undefined; + debug("Failed to Prestige Raid. Looks like you can't afford to or have no equips to get!"); + Rdshoulddopraid = false; + autoTrimpSettings["RAutoMaps"].value = 0; + } + if (RdAMPfragcheck && game.global.preMapsActive && !game.global.mapsActive && RdAMPmapbought1 && RdAMPpMap1 != undefined && Rdshoulddopraid) { + debug("running map 1"); + selectedMap = RdAMPpMap1; + selectMap(RdAMPpMap1); + runMap(); + RlastMapWeWereIn = getCurrentMapObject(); + RdAMPrepMap1 = RdAMPpMap1; + RdAMPpMap1 = undefined; + } + if (RdAMPfragcheck && game.global.preMapsActive && !game.global.mapsActive && RdAMPmapbought2 && RdAMPpMap2 != undefined && Rdshoulddopraid) { + debug("running map 2"); + selectedMap = RdAMPpMap2; + selectMap(RdAMPpMap2); + runMap(); + RlastMapWeWereIn = getCurrentMapObject(); + RdAMPrepMap2 = RdAMPpMap2; + RdAMPpMap2 = undefined; + } + if (RdAMPfragcheck && game.global.preMapsActive && !game.global.mapsActive && RdAMPmapbought3 && RdAMPpMap3 != undefined && Rdshoulddopraid) { + debug("running map 3"); + selectedMap = RdAMPpMap3; + selectMap(RdAMPpMap3); + runMap(); + RlastMapWeWereIn = getCurrentMapObject(); + RdAMPrepMap3 = RdAMPpMap3; + RdAMPpMap3 = undefined; + } + if (RdAMPfragcheck && game.global.preMapsActive && !game.global.mapsActive && RdAMPmapbought4 && RdAMPpMap4 != undefined && Rdshoulddopraid) { + debug("running map 4"); + selectedMap = RdAMPpMap4; + selectMap(RdAMPpMap4); + runMap(); + RlastMapWeWereIn = getCurrentMapObject(); + RdAMPrepMap4 = RdAMPpMap4; + RdAMPpMap4 = undefined; + } + if (RdAMPfragcheck && game.global.preMapsActive && !game.global.mapsActive && RdAMPmapbought5 && RdAMPpMap5 != undefined && Rdshoulddopraid) { + debug("running map 5"); + selectedMap = RdAMPpMap5; + selectMap(RdAMPpMap5); + runMap(); + RlastMapWeWereIn = getCurrentMapObject(); + RdAMPrepMap5 = RdAMPpMap5; + RdAMPpMap5 = undefined; + } +} + +//Mayhem + +function Rmayhem() { + var hits = (getPageSetting('Rmayhemacut') > 0) ? getPageSetting('Rmayhemabcut') : 100; + var hitssurv = (getPageSetting('Rmayhemhcut') > 0) ? getPageSetting('Rmayhemhcut') : 1; + var enemyDamage = RcalcBadGuyDmg(null, RgetEnemyMaxAttack(game.global.world, 50, 'Snimp', 1.0)); + if (game.challenges.Mayhem.stacks > 0 && getPageSetting('Rmayhemattack') == true && (RcalcHDratio() > hits)) { + Rshouldmayhem = 1; + } + if (game.challenges.Mayhem.stacks > 0 && getPageSetting('Rmayhemhealth') == true && (RcalcOurHealth() < (hitssurv * enemyDamage))) { + Rshouldmayhem = 2; + } +} + +function RmayhemExtra() { + var mayhemextra = 0; + if (Rshouldmayhem > 0 && getPageSetting('Rmayhemmap') == 2) { + mayhemextra = 0; + var health = (RcalcOurHealth() * 2); + var attack = RcalcOurDmg("avg", false, true); + var boss = game.challenges.Mayhem.getBossMult(); + var hitsmap = (getPageSetting('Rmayhemamcut') > 0) ? getPageSetting('Rmayhemamcut') : 100; + var hitssurv = (getPageSetting('Rmayhemhcut') > 0) ? getPageSetting('Rmayhemhcut') : 1; + var mlevels = 6; + var go = false; + if ( + (((RcalcEnemyHealth(game.global.world + mlevels) / boss)) <= (attack * (hitsmap * (mlevels + 1)))) && + ((((RcalcBadGuyDmg(null, RgetEnemyMaxAttack((game.global.world + mlevels), 20, 'Snimp', 1.0))) / boss * 1.3) * (hitssurv)) <= health) + ) { + mayhemextra = mlevels; + go = true; + } + if (!go) { + mlevels = 5; + if ( + (((RcalcEnemyHealth(game.global.world + mlevels) / boss)) <= (attack * (hitsmap * (mlevels + 1)))) && + ((((RcalcBadGuyDmg(null, RgetEnemyMaxAttack((game.global.world + mlevels), 20, 'Snimp', 1.0))) / boss * 1.3) * (hitssurv)) <= health) + ) { + mayhemextra = mlevels; + go = true; + } + } + if (!go) { + mlevels = 4; + if ( + (((RcalcEnemyHealth(game.global.world + mlevels) / boss)) <= (attack * (hitsmap * (mlevels + 1)))) && + ((((RcalcBadGuyDmg(null, RgetEnemyMaxAttack((game.global.world + mlevels), 20, 'Snimp', 1.0))) / boss * 1.3) * (hitssurv)) <= health) + ) { + mayhemextra = mlevels; + go = true; + } + } + if (!go) { + mlevels = 3; + if ( + (((RcalcEnemyHealth(game.global.world + mlevels) / boss)) <= (attack * (hitsmap * (mlevels + 1)))) && + ((((RcalcBadGuyDmg(null, RgetEnemyMaxAttack((game.global.world + mlevels), 20, 'Snimp', 1.0))) / boss * 1.3) * (hitssurv)) <= health) + ) { + mayhemextra = mlevels; + go = true; + } + } + if (!go) { + mlevels = 2; + if ( + (((RcalcEnemyHealth(game.global.world + mlevels) / boss)) <= (attack * (hitsmap * (mlevels + 1)))) && + ((((RcalcBadGuyDmg(null, RgetEnemyMaxAttack((game.global.world + mlevels), 20, 'Snimp', 1.0))) / boss * 1.3) * (hitssurv)) <= health) + ) { + mayhemextra = mlevels; + go = true; + } + } + if (!go) { + mlevels = 1; + if ( + (((RcalcEnemyHealth(game.global.world + mlevels) / boss)) <= (attack * (hitsmap * (mlevels + 1)))) && + ((((RcalcBadGuyDmg(null, RgetEnemyMaxAttack((game.global.world + mlevels), 20, 'Snimp', 1.0))) / boss * 1.3) * (hitssurv)) <= health) + ) { + mayhemextra = mlevels; + go = true; + } + } + if (!go) { + mayhemextra = 0; + go = true; + } + } + return mayhemextra; +} + +//Panda + +function RpandaExtra() { + var pandaextra = 1; + if (Rshouldpanda == true && getPageSetting('Rpandamaps') == true) { + pandaextra = 1; + var health = (RcalcOurHealth() * 2); + var attack = RcalcOurDmg("avg", false, true); + var mult = (game.challenges.Pandemonium.getEnemyMult() * game.challenges.Pandemonium.getPandMult()); + var boss = game.challenges.Pandemonium.getBossMult(); + var hitsmap = (getPageSetting('Rpandahits') > 0) ? getPageSetting('Rpandahits') : 10; + var hitssurv = 1; + var mlevels = 6; + var go = false; + if ( + (((RcalcEnemyHealth(game.global.world + mlevels) / boss) * mult) <= (attack * (hitsmap * (mlevels + 1)))) && + ((((((RcalcBadGuyDmg(null, RgetEnemyMaxAttack((game.global.world + mlevels), 20, 'Snimp', 1.0))) / boss) * mult) * 1.3) * (hitssurv)) <= health) + ) { + pandaextra = mlevels; + go = true; + } + if (!go) { + mlevels = 5; + if ( + (((RcalcEnemyHealth(game.global.world + mlevels) / boss) * mult) <= (attack * (hitsmap * (mlevels + 1)))) && + ((((((RcalcBadGuyDmg(null, RgetEnemyMaxAttack((game.global.world + mlevels), 20, 'Snimp', 1.0))) / boss) * mult) * 1.3) * (hitssurv)) <= health) + ) { + pandaextra = mlevels; + go = true; + } + } + if (!go) { + mlevels = 4; + if ( + (((RcalcEnemyHealth(game.global.world + mlevels) / boss) * mult) <= (attack * (hitsmap * (mlevels + 1)))) && + ((((((RcalcBadGuyDmg(null, RgetEnemyMaxAttack((game.global.world + mlevels), 20, 'Snimp', 1.0))) / boss) * mult) * 1.3) * (hitssurv)) <= health) + ) { + pandaextra = mlevels; + go = true; + } + } + if (!go) { + mlevels = 3; + if ( + (((RcalcEnemyHealth(game.global.world + mlevels) / boss) * mult) <= (attack * (hitsmap * (mlevels + 1)))) && + ((((((RcalcBadGuyDmg(null, RgetEnemyMaxAttack((game.global.world + mlevels), 20, 'Snimp', 1.0))) / boss) * mult) * 1.3) * (hitssurv)) <= health) + ) { + pandaextra = mlevels; + go = true; + } + } + if (!go) { + mlevels = 2; + if ( + (((RcalcEnemyHealth(game.global.world + mlevels) / boss) * mult) <= (attack * (hitsmap * (mlevels + 1)))) && + ((((((RcalcBadGuyDmg(null, RgetEnemyMaxAttack((game.global.world + mlevels), 20, 'Snimp', 1.0))) / boss) * mult) * 1.3) * (hitssurv)) <= health) + ) { + pandaextra = mlevels; + go = true; + } + } + if (!go) { + mlevels = 1; + pandaextra = mlevels; + go = true; + } + } + return pandaextra; +} + +//Insanity + +function Rinsanity(should, level, reset) { + var insanityfarmzone = getPageSetting('Rinsanityfarmzone'); + var insanitystacksfarmindex = insanityfarmzone.indexOf(game.global.world); + + var insanityfarmlevel = getPageSetting('Rinsanityfarmlevel'); + if (level) return insanityfarmlevel[insanitystacksfarmindex]; + + var insanityfarmstacks; + var insanitystacks = game.challenges.Insanity.insanity; + var maxinsanity = game.challenges.Insanity.maxInsanity; + + insanityfarmzone = getPageSetting('Rinsanityfarmzone'); + insanityfarmstacks = getPageSetting('Rinsanityfarmstack'); + + var insanitystacksfarmindex = insanityfarmzone.indexOf(game.global.world); + var insanitystackszones = insanityfarmstacks[insanitystacksfarmindex]; + if (insanitystackszones > maxinsanity) { + insanitystackszones = maxinsanity; + } + + if (should && insanityfarmzone.includes(game.global.world) && insanitystackszones != insanitystacks) { + Rshouldinsanityfarm = true; + } + + if (reset && !Rshouldinsanityfarm) { + insanityfragmappy = undefined; + insanityprefragmappy = undefined; + insanityfragmappybought = false; + } +} + +function RinsanityMap() { + var insanityfragcheck = true; + if (getPageSetting('Rinsanityfarmfrag') == true) { + if (RfragCheck("insanity") == true) { + insanityfragcheck = true; + Rinsanityfragfarming = false; + } else if (RfragCheck("insanity") == false && Rshouldinsanityfarm) { + Rinsanityfragfarming = true; + insanityfragcheck = false; + if (!insanityfragcheck && insanityfragmappy == undefined && !insanityfragmappybought && game.global.preMapsActive && Rshouldinsanityfarm) { + debug("Check complete for insanity frag map"); + RfragMap(); + if ((updateMapCost(true) <= game.resources.fragments.owned)) { + buyMap(); + insanityfragmappybought = true; + if (insanityfragmappybought) { + insanityfragmappy = game.global.mapsOwnedArray[game.global.mapsOwnedArray.length - 1].id; + debug("insanity frag map bought"); + } + } + } + if (!insanityfragcheck && game.global.preMapsActive && !game.global.mapsActive && insanityfragmappybought && insanityfragmappy != undefined && Rshouldinsanityfarm) { + debug("running insanity frag map"); + selectedMap = insanityfragmappy; + selectMap(insanityfragmappy); + runMap(); + RlastMapWeWereIn = getCurrentMapObject(); + insanityprefragmappy = insanityfragmappy; + insanityfragmappy = undefined; + } + if (!insanityfragcheck && game.global.mapsActive && insanityfragmappybought && insanityprefragmappy != undefined && Rshouldinsanityfarm) { + if (RfragCheck("insanity") == false) { + if (!game.global.repeatMap) { + repeatClicked(); + } + } else if (RfragCheck("insanity") == true) { + if (game.global.repeatMap) { + repeatClicked(); + mapsClicked(); + } + if (game.global.preMapsActive && insanityfragmappybought && insanityprefragmappy != undefined && Rshouldinsanityfarm) { + insanityfragmappybought = false; + } + if (insanityprefragmappy != undefined) { + recycleMap(getMapIndex(insanityprefragmappy)); + insanityprefragmappy = undefined; + } + insanityfragcheck = true; + Rinsanityfragfarming = false; + } + } + } else { + insanityfragcheck = true; + Rinsanityfragfarming = false; + } + } + if (insanityfragcheck && getPageSetting('Rinsanityfarmlevel') != 0) { + + var insanitylevelzones = Rinsanity(false, true, false); + if (insanitylevelzones > 0) { + RminFragMap("Plentiful", insanitylevelzones, "fa") + document.getElementById("mapLevelInput").value = game.global.world; + document.getElementById("advExtraLevelSelect").value = insanitylevelzones; + } else if (insanitylevelzones < 0) { + RminFragMap("Plentiful", insanitylevelzones, "fa") + document.getElementById("mapLevelInput").value = (game.global.world + insanitylevelzones); + document.getElementById("advExtraLevelSelect").value = 0; + } + } + updateMapCost(); +} + +//Storm + +function Rstorm(should) { + var stormzone = getPageSetting('Rstormzone'); + var stormHD = getPageSetting('RstormHD'); + var stormmult = getPageSetting('Rstormmult'); + var stormHDzone = (game.global.world - stormzone); + var stormHDmult = (stormHDzone == 0) ? stormHD : Math.pow(stormmult, stormHDzone) * stormHD; + + if (should && game.global.world >= stormzone && RcalcHDratio() > stormHDmult) { + Rshouldstormfarm = true; + } +} + +//Desolation + +function Rdeso(should) { + var desozone = getPageSetting('Rdesozone'); + var desoHD = getPageSetting('RdesoHD'); + var desomult = getPageSetting('Rdesomult'); + var desoHDzone = (game.global.world - desozone); + var desoHDmult = (desoHDzone == 0) ? desoHD : Math.pow(desomult, desoHDzone) * desoHD; + + if (should && game.global.world >= desozone && RcalcHDratio() > desoHDmult) { + Rshoulddesofarm = true; + } +} + +function RdesoExtra() { + var desoextra = 1; + if (Rshoulddesofarm == true) { + desoextra = 1; + var health = (RcalcOurHealth() * 2); + var attack = RcalcOurDmg("avg", false, true); + var hitsmap = 10; + var hitssurv = 1; + var mlevels = 6; + var go = false; + if ( + ((RcalcEnemyHealth(game.global.world + mlevels)) <= (attack * (hitsmap * (mlevels + 1)))) && + (((RcalcBadGuyDmg(null, RgetEnemyMaxAttack((game.global.world + mlevels), 20, 'Snimp', 1.0)) * 1.3) * (hitssurv)) <= health) + ) { + desoextra = mlevels; + go = true; + } + if (!go) { + mlevels = 5; + if ( + ((RcalcEnemyHealth(game.global.world + mlevels)) <= (attack * (hitsmap * (mlevels + 1)))) && + (((RcalcBadGuyDmg(null, RgetEnemyMaxAttack((game.global.world + mlevels), 20, 'Snimp', 1.0)) * 1.3) * (hitssurv)) <= health) + ) { + desoextra = mlevels; + go = true; + } + } + if (!go) { + mlevels = 4; + if ( + ((RcalcEnemyHealth(game.global.world + mlevels)) <= (attack * (hitsmap * (mlevels + 1)))) && + (((RcalcBadGuyDmg(null, RgetEnemyMaxAttack((game.global.world + mlevels), 20, 'Snimp', 1.0)) * 1.3) * (hitssurv)) <= health) + ) { + desoextra = mlevels; + go = true; + } + } + if (!go) { + mlevels = 3; + if ( + ((RcalcEnemyHealth(game.global.world + mlevels)) <= (attack * (hitsmap * (mlevels + 1)))) && + (((RcalcBadGuyDmg(null, RgetEnemyMaxAttack((game.global.world + mlevels), 20, 'Snimp', 1.0)) * 1.3) * (hitssurv)) <= health) + ) { + desoextra = mlevels; + go = true; + } + } + if (!go) { + mlevels = 2; + if ( + ((RcalcEnemyHealth(game.global.world + mlevels)) <= (attack * (hitsmap * (mlevels + 1)))) && + (((RcalcBadGuyDmg(null, RgetEnemyMaxAttack((game.global.world + mlevels), 20, 'Snimp', 1.0)) * 1.3) * (hitssurv)) <= health) + ) { + desoextra = mlevels; + go = true; + } + } + if (!go) { + mlevels = 1; + desoextra = mlevels; + go = true; + } + } + return desoextra; +} + +//Ships + +function Rship(should, level, reset) { + + var shipfarmzone = getPageSetting('Rshipfarmzone'); + var shipamountfarmindex = shipfarmzone.indexOf(game.global.world); + + var shipfarmlevel = getPageSetting('Rshipfarmlevel'); + if (level) return shipfarmlevel[shipamountfarmindex]; + + var shipfarmamount = getPageSetting('Rshipfarmamount'); + var ships = game.jobs.Worshipper.owned; + var shipamountzones = shipfarmamount[shipamountfarmindex]; + + if (getPageSetting('Rshipfarmamount') == 50) shipamountzones = 50; + + if (should && shipfarmzone.includes(game.global.world) && shipamountzones > ships) { + Rshouldshipfarm = true; + } + + if (reset && !Rshouldshipfarm) { + shipfragmappy = undefined; + shipprefragmappy = undefined; + shipfragmappybought = false; + } +} + +function RshipMap() { + var shipfragcheck = true; + if (getPageSetting('Rshipfarmfrag') == true) { + if (RfragCheck("ship") == true) { + shipfragcheck = true; + Rshipfragfarming = false; + } else if (RfragCheck("ship") == false && Rshouldshipfarm) { + Rshipfragfarming = true; + shipfragcheck = false; + if (!shipfragcheck && shipfragmappy == undefined && !shipfragmappybought && game.global.preMapsActive && Rshouldshipfarm) { + debug("Check complete for ship frag map"); + RfragMap(); + if ((updateMapCost(true) <= game.resources.fragments.owned)) { + buyMap(); + shipfragmappybought = true; + if (shipfragmappybought) { + shipfragmappy = game.global.mapsOwnedArray[game.global.mapsOwnedArray.length - 1].id; + debug("ship frag map bought"); + } + } + } + if (!shipfragcheck && game.global.preMapsActive && !game.global.mapsActive && shipfragmappybought && shipfragmappy != undefined && Rshouldshipfarm) { + debug("running ship frag map"); + selectedMap = shipfragmappy; + selectMap(shipfragmappy); + runMap(); + RlastMapWeWereIn = getCurrentMapObject(); + shipprefragmappy = shipfragmappy; + shipfragmappy = undefined; + } + if (!shipfragcheck && game.global.mapsActive && shipfragmappybought && shipprefragmappy != undefined && Rshouldshipfarm) { + if (RfragCheck("ship") == false) { + if (!game.global.repeatMap) { + repeatClicked(); + } + } else if (RfragCheck("ship") == true) { + if (game.global.repeatMap) { + repeatClicked(); + mapsClicked(); + } + if (game.global.preMapsActive && shipfragmappybought && shipprefragmappy != undefined && Rshouldshipfarm) { + shipfragmappybought = false; + } + if (shipprefragmappy != undefined) { + recycleMap(getMapIndex(shipprefragmappy)); + shipprefragmappy = undefined; + } + shipfragcheck = true; + Rshipfragfarming = false; + } + } + } else { + shipfragcheck = true; + Rshipfragfarming = false; + } + } + if (shipfragcheck && getPageSetting('Rshipfarmlevel') != 0) { + + var shiplevelzones = Rship(false, true, false); + + if (Rshouldshipfarm) { + var special = game.global.highestRadonLevelCleared > 83 ? "lsc" : "ssc"; + var selection = game.global.farmlandsUnlocked ? "Farmlands" : "Plentiful"; + if (shiplevelzones > 0) { + RminFragMap(selection, shiplevelzones, special); + document.getElementById("mapLevelInput").value = game.global.world; + document.getElementById("advExtraLevelSelect").value = shiplevelzones; + } else if (shiplevelzones == 0) { + RminFragMap(selection, shiplevelzones, special); + document.getElementById("mapLevelInput").value = game.global.world; + document.getElementById("advExtraLevelSelect").value = 0; + } else if (shiplevelzones < 0) { + document.getElementById("mapLevelInput").value = (game.global.world + shiplevelzones); + document.getElementById("advExtraLevelSelect").value = 0; + } + } + } + + updateMapCost(); +} + +//Alch + +function Ralch(should, level, reset) { + var alchfarmzone = getPageSetting('Ralchfarmzone'); + var alchstacksfarmindex = alchfarmzone.indexOf(game.global.world); + + var alchfarmlevel = getPageSetting('Ralchfarmlevel'); + if (level) return alchfarmlevel[alchstacksfarmindex]; + + var alchfarmstacks = getPageSetting('Ralchfarmstack'); + + var alchstackszones = alchfarmstacks[alchstacksfarmindex]; + if (alchstackszones != undefined) { + var potion; + var potionletter = alchstackszones[0]; + if (potionletter == 'h') { + potion = alchObj.getPotionCount('Herby Brew'); + potionletter = "Herby Brew"; + } else if (potionletter == 'f') { + potion = alchObj.getPotionCount('Potion of Finding'); + potionletter = "Potion of Finding"; + } else if (potionletter == 'g') { + potion = alchObj.getPotionCount('Gaseous Brew'); + potionletter = "Gaseous Brew"; + } else if (potionletter == 'v') { + potion = alchObj.getPotionCount('Potion of the Void'); + potionletter = "Potion of the Void"; + } else if (potionletter == 's') { + potion = alchObj.getPotionCount('Potion of Strength'); + potionletter = "Potion of Strength"; + } + + if (alchstackszones.substring(1) > potion) { + alchObj.craftPotion(potionletter); + } + + if (should && alchfarmzone.includes(game.global.world) && alchstackszones.substring(1) > potion) { + Rshouldalchfarm = true; + } + } + + if (reset && !Rshouldalchfarm) { + alchfragmappy = undefined; + alchprefragmappy = undefined; + alchfragmappybought = false; + } +} + +function RalchMap() { + var alchfragcheck = true; + if (getPageSetting('Ralchfarmfrag') == true) { + if (RfragCheck("alch") == true) { + alchfragcheck = true; + Ralchfragfarming = false; + } else if (RfragCheck("alch") == false && Rshouldalchfarm) { + Ralchfragfarming = true; + alchfragcheck = false; + if (!alchfragcheck && alchfragmappy == undefined && !alchfragmappybought && game.global.preMapsActive && Rshouldalchfarm) { + debug("Check complete for alch frag map"); + RfragMap(); + if ((updateMapCost(true) <= game.resources.fragments.owned)) { + buyMap(); + alchfragmappybought = true; + if (alchfragmappybought) { + alchfragmappy = game.global.mapsOwnedArray[game.global.mapsOwnedArray.length - 1].id; + debug("alch frag map bought"); + } + } + } + if (!alchfragcheck && game.global.preMapsActive && !game.global.mapsActive && alchfragmappybought && alchfragmappy != undefined && Rshouldalchfarm) { + debug("running alch frag map"); + selectedMap = alchfragmappy; + selectMap(alchfragmappy); + runMap(); + RlastMapWeWereIn = getCurrentMapObject(); + alchprefragmappy = alchfragmappy; + alchfragmappy = undefined; + } + if (!alchfragcheck && game.global.mapsActive && alchfragmappybought && alchprefragmappy != undefined && Rshouldalchfarm) { + if (RfragCheck("alch") == false) { + if (!game.global.repeatMap) { + repeatClicked(); + } + } else if (RfragCheck("alch") == true) { + if (game.global.repeatMap) { + repeatClicked(); + mapsClicked(); + } + if (game.global.preMapsActive && alchfragmappybought && alchprefragmappy != undefined && Rshouldalchfarm) { + alchfragmappybought = false; + } + if (alchprefragmappy != undefined) { + recycleMap(getMapIndex(alchprefragmappy)); + alchprefragmappy = undefined; + } + alchfragcheck = true; + Ralchfragfarming = false; + } + } + } else { + alchfragcheck = true; + Ralchfragfarming = false; + } + } + if (alchfragcheck && getPageSetting('Ralchfarmlevel') != 0) { + if (Rshouldalchfarm) { + + var alchfarmzone = getPageSetting('Ralchfarmzone'); + var alchfarmselection = getPageSetting('Ralchfarmselection') + var alchlevelzones = Ralch(false, true, false); + var alchfarmselectionindex = alchfarmzone.indexOf(game.global.world); + var selection = alchfarmselection[alchfarmselectionindex]; + if (selection == 'Mountain') selection = "Mountain"; + else if (selection == 'Forest') selection = "Forest"; + else if (selection == 'Sea') selection = "Sea"; + else if (selection == 'Depths') selection = "Depths"; + else if (selection == 'Plentiful') selection = "Plentiful"; + else if (selection == 'Farmlands') selection = "Farmlands"; + + RminFragMap(selection, alchlevelzones, "fa"); + } + } + updateMapCost(); +} + +//Hypo + +function Rhypo(should, level, reset) { + var hypofarmzone = getPageSetting('Rhypofarmzone'); + var hypoamountfarmindex = hypofarmzone.indexOf(game.global.world); + + var hypofarmlevel = getPageSetting('Rhypofarmlevel'); + if (level) return hypofarmlevel[hypoamountfarmindex]; + + var bonfire = game.challenges.Hypothermia.totalBonfires; + var wood = game.resources.wood.max; + var woodmax = wood * (1 + game.portal.Packrat.radLevel * game.portal.Packrat.modifier); + woodmax = calcHeirloomBonus("Shield", "storageSize", woodmax, false); + + var hypofarmamount = getPageSetting('Rhypofarmstack'); + var hypoamountzones = hypofarmamount[hypoamountfarmindex]; + + var currentprice = (1e10 * Math.pow(100, bonfire)); + var targetprice = (currentprice * Math.pow(100, ((hypoamountzones - bonfire) - 1))) * 1.05; + targetprice += (targetprice / 1000) + var gofarmbonfire = false; + if (game.resources.wood.owned < targetprice) { + gofarmbonfire = true; + } + + if (should && hypofarmzone.includes(game.global.world) && gofarmbonfire) { + Rshouldhypofarm = true; + Rhyposhouldwood = false; + } + if (should && hypofarmzone.includes(game.global.world)) { + Rhyposhouldwood = false; + } + + if (reset && !Rshouldhypofarm) { + hypofragmappy = undefined; + hypoprefragmappy = undefined; + hypofragmappybought = false; + } + + if (reset && (gofarmbonfire || bonfire > (getPageSetting('Rhypofarmstack').slice(-1)))) Rhyposhouldwood = false; + +} + +function RhypoMap() { + var hypofragcheck = true; + if (getPageSetting('Rhypofarmfrag') == true) { + if (RfragCheck("hypo") == true) { + hypofragcheck = true; + Rhypofragfarming = false; + } else if (RfragCheck("hypo") == false && Rshouldhypofarm) { + Rhypofragfarming = true; + hypofragcheck = false; + if (!hypofragcheck && hypofragmappy == undefined && !hypofragmappybought && game.global.preMapsActive && Rshouldhypofarm) { + debug("Check complete for hypo frag map"); + RfragMap(); + if ((updateMapCost(true) <= game.resources.fragments.owned)) { + buyMap(); + hypofragmappybought = true; + if (hypofragmappybought) { + hypofragmappy = game.global.mapsOwnedArray[game.global.mapsOwnedArray.length - 1].id; + debug("hypo frag map bought"); + } + } + } + if (!hypofragcheck && game.global.preMapsActive && !game.global.mapsActive && hypofragmappybought && hypofragmappy != undefined && Rshouldhypofarm) { + debug("running hypo frag map"); + selectedMap = hypofragmappy; + selectMap(hypofragmappy); + runMap(); + RlastMapWeWereIn = getCurrentMapObject(); + hypoprefragmappy = hypofragmappy; + hypofragmappy = undefined; + } + if (!hypofragcheck && game.global.mapsActive && hypofragmappybought && hypoprefragmappy != undefined && Rshouldhypofarm) { + if (RfragCheck("hypo") == false) { + if (!game.global.repeatMap) { + repeatClicked(); + } + } else if (RfragCheck("hypo") == true) { + if (game.global.repeatMap) { + repeatClicked(); + mapsClicked(); + } + if (game.global.preMapsActive && hypofragmappybought && hypoprefragmappy != undefined && Rshouldhypofarm) { + hypofragmappybought = false; + } + if (hypoprefragmappy != undefined) { + recycleMap(getMapIndex(hypoprefragmappy)); + hypoprefragmappy = undefined; + } + hypofragcheck = true; + Rhypofragfarming = false; + } + } + } else { + hypofragcheck = true; + Rhypofragfarming = false; + } + } + if (hypofragcheck && getPageSetting('Rhypofarmlevel') != 0) { + + var hypolevelzones = Rhypo(false, true, false); + + if (hypolevelzones > 0) { + RminFragMap("Farmlands", hypolevelzones, "lwc") + document.getElementById("mapLevelInput").value = game.global.world; + document.getElementById("advExtraLevelSelect").value = hypolevelzones; + } else if (hypolevelzones == 0) { + RminFragMap("Farmlands", hypolevelzones, "lwc") + document.getElementById("mapLevelInput").value = game.global.world; + document.getElementById("advExtraLevelSelect").value = 0; + } else if (hypolevelzones < 0) { + RminFragMap("Farmlands", hypolevelzones, "lwc") + document.getElementById("mapLevelInput").value = (game.global.world + hypolevelzones); + document.getElementById("advExtraLevelSelect").value = 0; + } + } + updateMapCost(); +} + +//Equip Farm + +function RequipExtra() { + var equipminus = 0; + if (Rshouldequipfarm) { + equipminus = 0; + var health = (RcalcOurHealth() * 2); + var attack = RcalcOurDmg("avg", false, true); + var hits = (getPageSetting('Requipfarmhits') > 0) ? getPageSetting('Requipfarmhits') : 10; + var hitssurv = (getPageSetting('Rhitssurvived') > 0) ? getPageSetting('Rhitssurvived') : 1; + var mlevels = 0; + var go = false; + if ( + ((RcalcEnemyHealth(game.global.world + mlevels)) <= (attack * hits)) && + ((((RcalcBadGuyDmg(null, RgetEnemyMaxAttack((game.global.world + mlevels), 20, 'Snimp', 1.0))) * 0.8) * (hitssurv)) <= (health)) + ) { + equipminus = mlevels; + go = true; + } + if (!go) { + mlevels = -1; + if ( + ((RcalcEnemyHealth(game.global.world + mlevels)) <= (attack * hits)) && + ((((RcalcBadGuyDmg(null, RgetEnemyMaxAttack((game.global.world + mlevels), 20, 'Snimp', 1.0))) * 0.8) * (hitssurv)) <= (health)) + ) { + equipminus = mlevels; + go = true; + } + } + if (!go) { + mlevels = -2; + if ( + ((RcalcEnemyHealth(game.global.world + mlevels)) <= (attack * hits)) && + ((((RcalcBadGuyDmg(null, RgetEnemyMaxAttack((game.global.world + mlevels), 20, 'Snimp', 1.0))) * 0.8) * (hitssurv)) <= (health)) + ) { + equipminus = mlevels; + go = true; + } + } + if (!go) { + mlevels = -3; + if ( + ((RcalcEnemyHealth(game.global.world + mlevels)) <= (attack * hits)) && + ((((RcalcBadGuyDmg(null, RgetEnemyMaxAttack((game.global.world + mlevels), 20, 'Snimp', 1.0))) * 0.8) * (hitssurv)) <= (health)) + ) { + equipminus = mlevels; + go = true; + } + } + if (!go) { + mlevels = -4; + if ( + ((RcalcEnemyHealth(game.global.world + mlevels)) <= (attack * hits)) && + ((((RcalcBadGuyDmg(null, RgetEnemyMaxAttack((game.global.world + mlevels), 20, 'Snimp', 1.0))) * 0.8) * (hitssurv)) <= (health)) + ) { + equipminus = mlevels; + go = true; + } + } + if (!go) { + mlevels = -5; + if ( + ((RcalcEnemyHealth(game.global.world + mlevels)) <= (attack * hits)) && + ((((RcalcBadGuyDmg(null, RgetEnemyMaxAttack((game.global.world + mlevels), 20, 'Snimp', 1.0))) * 0.8) * (hitssurv)) <= (health)) + ) { + equipminus = mlevels; + go = true; + } + } + if (!go) { + equipminus = -6; + go = true; + } + } + return equipminus; +} + +function Rshould(any, one) { + if (any) { + if (!Rshoulddopraid && !Rdshoulddopraid && + (RshouldDoMaps || + RdoVoids || + Rshouldfragfarm || + Rshouldtimefarm || + Rdshouldtimefarm || + Rshouldsmithyfarm || + Rshouldtributefarm || + Rshoulddoquest > 0 || + Rshouldmayhem > 0 || + Rshouldpanda || + Rshouldinsanityfarm || + Rshouldstormfarm || + Rshoulddesofarm || + Rshouldequipfarm || + Rshouldshipfarm || + Rshouldalchfarm || + Rshouldhypofarm) + ) return true; + else return false; + } + + var should = "no"; + if (one && !Rshoulddopraid && !Rdshoulddopraid) { + if (Rshouldfragfarm) should = "frag"; + else if (Rshouldmayhem) should = "mayhem"; + else if (Rshouldpanda) should = "panda"; + else if (Rshoulddesofarm) should = "deso"; + else if (Rshouldinsanityfarm) should = "insanity"; + else if (Rshouldalchfarm) should = "alch"; + else if (Rshouldhypofarm) should = "hypo"; + else if (Rshouldshipfarm) should = "ship"; + else if (Rshouldtimefarm) should = "time"; + else if (Rdshouldtimefarm) should = "dtime"; + else if (Rshouldsmithyfarm) should = "smithy"; + else if (Rshouldtributefarm) should = "tribute"; + else if (Rshouldequipfarm) should = "equip"; + else if (Rshoulddoquest) should = "quest"; + } + if (should != "no") return should; +} + +function RselectMayhem() { + var selectedMap = "create"; + if (getPageSetting('Rmayhemmap') == 2) { + for (var map in game.global.mapsOwnedArray) { + if (!game.global.mapsOwnedArray[map].noRecycle && RmayhemExtra() >= 0 && ((game.global.world + RmayhemExtra()) == game.global.mapsOwnedArray[map].level)) { + selectedMap = game.global.mapsOwnedArray[map].id; + break; + } else { + selectedMap = "create"; + } + } + } else { + for (var map in game.global.mapsOwnedArray) { + if (!game.global.mapsOwnedArray[map].noRecycle && game.global.world == game.global.mapsOwnedArray[map].level) { + selectedMap = game.global.mapsOwnedArray[map].id; + break; + } else { + selectedMap = "create"; + } + } + } + return selectedMap; +} + +function RselectPanda() { + var selectedMap = "create"; + if (getPageSetting('Rpandamaps') == true) { + for (var map in game.global.mapsOwnedArray) { + if (!game.global.mapsOwnedArray[map].noRecycle && RpandaExtra() >= 0 && ((game.global.world + RpandaExtra()) == game.global.mapsOwnedArray[map].level)) { + selectedMap = game.global.mapsOwnedArray[map].id; + break; + } else { + selectedMap = "create"; + } + } + } + return selectedMap; +} + +function RselectDeso() { + var selectedMap = "create"; + for (var map in game.global.mapsOwnedArray) { + if (!game.global.mapsOwnedArray[map].noRecycle && RdesoExtra() >= 0 && ((game.global.world + RdesoExtra()) == game.global.mapsOwnedArray[map].level)) { + selectedMap = game.global.mapsOwnedArray[map].id; + break; + } else { + selectedMap = "create"; + } + } + return selectedMap; +} + +function RselectQuest() { + var selectedMap = "create"; + if (Rshoulddoquest) { + for (var map in game.global.mapsOwnedArray) { + if (!game.global.mapsOwnedArray[map].noRecycle && game.global.world == game.global.mapsOwnedArray[map].level) { + selectedMap = game.global.mapsOwnedArray[map].id; + break; + } else { + selectedMap = "create"; + } + } + } + return selectedMap; +} + +function RselectShip() { + var selectedMap = "create"; + var level = getPageSetting('Rshipfarmlevel'); + var levelzones = Rship(false, true, false); + var special = game.global.highestRadonLevelCleared > 83 ? "lsc" : "ssc"; + + if (level == 0) { + for (var map in game.global.mapsOwnedArray) { + if (!game.global.mapsOwnedArray[map].noRecycle && game.global.world == game.global.mapsOwnedArray[map].level && game.global.mapsOwnedArray[map].bonus == special) { + selectedMap = game.global.mapsOwnedArray[map].id; + break; + } else { + selectedMap = "create"; + } + } + } else if (level != 0) { + if (levelzones != 0) { + for (var map in game.global.mapsOwnedArray) { + if (!game.global.mapsOwnedArray[map].noRecycle && ((game.global.world + levelzones) == game.global.mapsOwnedArray[map].level) && game.global.mapsOwnedArray[map].bonus == special) { + selectedMap = game.global.mapsOwnedArray[map].id; + break; + } else { + selectedMap = "create"; + } + } + } else if (levelzones == 0) { + for (var map in game.global.mapsOwnedArray) { + if (!game.global.mapsOwnedArray[map].noRecycle && game.global.world == game.global.mapsOwnedArray[map].level && game.global.mapsOwnedArray[map].bonus == special) { + selectedMap = game.global.mapsOwnedArray[map].id; + break; + } else { + selectedMap = "create"; + } + } + } + } + return selectedMap; +} + +function RselectSmithy() { + var selectedMap = "create"; + var levelzones = RsmithyCalc(true, false, false, false); + var special = RsmithyCalc(false, false, true, false); + + if (levelzones != 0) { + for (var map in game.global.mapsOwnedArray) { + if (!game.global.mapsOwnedArray[map].noRecycle && ((game.global.world + levelzones) == game.global.mapsOwnedArray[map].level) && game.global.mapsOwnedArray[map].bonus == special) { + selectedMap = game.global.mapsOwnedArray[map].id; + break; + } else { + selectedMap = "create"; + } + } + } else if (levelzones == 0) { + for (var map in game.global.mapsOwnedArray) { + if (!game.global.mapsOwnedArray[map].noRecycle && game.global.world == game.global.mapsOwnedArray[map].level && game.global.mapsOwnedArray[map].bonus == special) { + selectedMap = game.global.mapsOwnedArray[map].id; + break; + } else { + selectedMap = "create"; + } + } + } + return selectedMap; +} + +function RselectOther(other) { + var selectedMap = "create"; + var level = 0; + var levelzones = 0; + if (other == "insanity") { + level = getPageSetting('Rinsanityfarmlevel'); + levelzones = Rinsanity(false, true, false); + } else if (other == "alch") { + level = getPageSetting('Ralchfarmlevel'); + levelzones = Ralch(false, true, false); + } else if (other == "hypo") { + level = getPageSetting('Rhypofarmlevel'); + levelzones = Rhypo(false, true, false); + } else if (other == "time") { + level = getPageSetting('Rtimefarmlevel'); + levelzones = RtimeFarm(false, true, false, false, false); + } else if (other == "dtime") { + level = getPageSetting('Rdtimefarmlevel'); + levelzones = RtimeFarm(false, true, false, false, true); + } else if (other == "tribute") { + level = getPageSetting('Rtributefarmlevel'); + levelzones = RtributeFarm(false, true, false, false); + } + + if (level == 0) { + for (var map in game.global.mapsOwnedArray) { + if (!game.global.mapsOwnedArray[map].noRecycle && game.global.world == game.global.mapsOwnedArray[map].level) { + selectedMap = game.global.mapsOwnedArray[map].id; + break; + } else { + selectedMap = "create"; + } + } + } else if (level != 0) { + if (levelzones != 0) { + for (var map in game.global.mapsOwnedArray) { + if (!game.global.mapsOwnedArray[map].noRecycle && ((game.global.world + levelzones) == game.global.mapsOwnedArray[map].level)) { + selectedMap = game.global.mapsOwnedArray[map].id; + break; + } else { + selectedMap = "create"; + } + } + } else if (levelzones == 0) { + for (var map in game.global.mapsOwnedArray) { + if (!game.global.mapsOwnedArray[map].noRecycle && game.global.world == game.global.mapsOwnedArray[map].level) { + selectedMap = game.global.mapsOwnedArray[map].id; + break; + } else { + selectedMap = "create"; + } + } + } + } + return selectedMap; +} + +function RselectMap(selectedMap) { + if (Rshould(true, false) && selectedMap == "world") { + + if (Rshould(false, true) == "frag") { + selectedMap = RselectFrag(); + } else if (Rshould(false, true) == "mayhem") { + selectedMap = RselectMayhem(); + } else if (Rshould(false, true) == "panda") { + selectedMap = RselectPanda(); + } else if (Rshould(false, true) == "deso") { + selectedMap = RselectDeso(); + } else if (Rshould(false, true) == "insanity") { + selectedMap = RselectOther("insanity"); + } else if (Rshould(false, true) == "alch") { + selectedMap = RselectOther("alch"); + } else if (Rshould(false, true) == "hypo") { + selectedMap = RselectOther("hypo"); + } else if (Rshould(false, true) == "ship") { + selectedMap = RselectShip(); + } else if (Rshould(false, true) == "time") { + selectedMap = RselectOther("time"); + } else if (Rshould(false, true) == "dtime") { + selectedMap = RselectOther("dtime"); + } else if (Rshould(false, true) == "smithy") { + selectedMap = RselectSmithy(); + } else if (Rshould(false, true) == "tribute") { + selectedMap = RselectOther("tribute"); + } else if (Rshould(false, true) == "quest") { + selectedMap = RselectQuest(); + } else if (Rshould(false, true) == "equip") { + for (var map in game.global.mapsOwnedArray) { + if (!game.global.mapsOwnedArray[map].noRecycle && RequipExtra() <= 0 && ((game.global.world + RequipExtra()) == game.global.mapsOwnedArray[map].level)) { + selectedMap = game.global.mapsOwnedArray[map].id; + break; + } else { + selectedMap = "create"; + } + } + } else { + for (var map in game.global.mapsOwnedArray) { + if (!game.global.mapsOwnedArray[map].noRecycle && game.global.world == game.global.mapsOwnedArray[map].level) { + selectedMap = game.global.mapsOwnedArray[map].id; + break; + } else { + selectedMap = "create"; + } + } + } + } + return selectedMap; +} + +function RmapRepeat(selectedMap, shouldDoHealthMaps, restartVoidMap) { + var doDefaultMapBonus = game.global.mapBonus < getPageSetting('RMaxMapBonuslimit') - 1; + if ( + (RvanillaMAZ) || + (Rshoulddopraid || (Rshoulddopraid && RAMPfragfarming)) || + (Rdshoulddopraid || (Rdshoulddopraid && RdAMPfragfarming)) || + (Rshouldinsanityfarm || (Rshouldinsanityfarm && Rinsanityfragfarming)) || + (Rshouldalchfarm || (Rshouldalchfarm && Ralchfragfarming)) || + (Rshouldhypofarm || (Rshouldhypofarm && Rhypofragfarming)) || + (Rshouldshipfarm || (Rshouldshipfarm && Rshipfragfarming)) || + (selectedMap == game.global.currentMapId && + (!getCurrentMapObject().noRecycle && + (doDefaultMapBonus || + RvanillaMAZ || + RdoMaxMapBonus || + RshouldFarm || + Rshouldfragfarm || + Rshouldtimefarm || + Rdshouldtimefarm || + Rshouldsmithyfarm || + Rshouldtributefarm || + Rshoulddobogs || + (Rshoulddoquest > 0) || + (Rshouldmayhem > 0) || + Rshouldpanda || + Rshouldstormfarm || + Rshoulddesofarm || + Rshouldequipfarm + ) + ) + ) + ) { + if (!game.global.repeatMap) { + repeatClicked(); + } + if ( + (Rshoulddopraid && !RAMPfragfarming) || + (Rdshoulddopraid && !RdAMPfragfarming) + ) { + if (game.options.menu.repeatUntil.enabled != 2) { + game.options.menu.repeatUntil.enabled = 2; + } + + } else if ( + ((Rshoulddopraid && RAMPfragfarming) || (Rdshoulddopraid && RdAMPfragfarming)) || + (Rshouldinsanityfarm && Rinsanityfragfarming) || + (Rshouldalchfarm && Ralchfragfarming) || + (Rshouldhypofarm && Rhypofragfarming) || + (Rshouldshipfarm && Rshipfragfarming) + ) { + if (game.options.menu.repeatUntil.enabled != 0) { + game.options.menu.repeatUntil.enabled = 0; + } + } + + if ( + !Rshoulddopraid && + !RAMPfragfarming && + !Rshouldfragfarm && + !Rdshoulddopraid && + !RdAMPfragfarming && + !Rshouldinsanityfarm && + !Rinsanityfragfarming && + !Rshouldalchfarm && + !Rshouldhypofarm && + !Rhypofragfarming && + !Ralchfragfarming && + !Rshoulddobogs && + !RshouldDoMaps && + !Rshouldtimefarm && + !Rdshouldtimefarm && + !Rshouldsmithyfarm && + !Rshouldtributefarm && + Rshoulddoquest <= 0 && + Rshouldmayhem <= 0 && + !Rshouldpanda && + !Rshouldstormfarm && + !Rshoulddesofarm && + !Rshouldequipfarm && + !Rshouldshipfarm && + !Rshipfragfarming + ) { + repeatClicked(); + } + if (shouldDoHealthMaps && game.global.mapBonus >= getPageSetting('RMaxMapBonushealth')) { + repeatClicked(); + shouldDoHealthMaps = false; + } + if (RdoMaxMapBonus && game.global.mapBonus < getPageSetting('RMaxMapBonuslimit')) { + repeatClicked(); + RdoMaxMapBonus = false; + } + if (game.global.repeatMap && + (Rshoulddoquest == 3 && game.global.mapBonus >= 4) || + (Rshoulddopraid && RAMPfragfarming && RAMPfrag(false) == true) || + (Rdshoulddopraid && RdAMPfragfarming && RAMPfrag(true) == true) || + (Rshouldinsanityfarm && Rinsanityfragfarming && RfragCheck("insanity") == true) || + (Rshouldalchfarm && Ralchfragfarming && RfragCheck("alch") == true) || + (Rshouldhypofarm && Rhypofragfarming && RfragCheck("hypo") == true) || + (Rshouldshipfarm && Rshipfragfarming && RfragCheck("ship") == true) + ) { + repeatClicked(); + } + + } else { + if (game.global.repeatMap) { + repeatClicked(); + } + if (restartVoidMap) { + mapsClicked(true); + } + } +} + +function RquestMap(quest) { + biomeAdvMapsSelect.value = "Plentiful"; + if (quest == 4) { + document.getElementById("advSpecialSelect").value = "hc"; + updateMapCost(); + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("advSpecialSelect").value = "fa"; + updateMapCost(); + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("advSpecialSelect").value = 0; + updateMapCost(); + } + } + } + if (quest == 7) { + document.getElementById("advSpecialSelect").value = "hc"; + updateMapCost(); + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("advSpecialSelect").value = "lc"; + updateMapCost(); + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("advSpecialSelect").value = "fa"; + updateMapCost(); + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("advSpecialSelect").value = 0; + updateMapCost(); + } + } + } + } + if (quest == 10) { + document.getElementById("advSpecialSelect").value = "lsc"; + updateMapCost(); + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("advSpecialSelect").value = "ssc"; + updateMapCost(); + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("advSpecialSelect").value = "fa"; + updateMapCost(); + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("advSpecialSelect").value = 0; + updateMapCost(); + } + } + } + } + if (quest == 11) { + document.getElementById("advSpecialSelect").value = "lwc"; + updateMapCost(); + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("advSpecialSelect").value = "swc"; + updateMapCost(); + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("advSpecialSelect").value = "fa"; + updateMapCost(); + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("advSpecialSelect").value = 0; + updateMapCost(); + } + } + } + } + if (quest == 12) { + document.getElementById("advSpecialSelect").value = "lmc"; + updateMapCost(); + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("advSpecialSelect").value = "smc"; + updateMapCost(); + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("advSpecialSelect").value = "fa"; + updateMapCost(); + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("advSpecialSelect").value = 0; + updateMapCost(); + } + } + } + } + if (quest == 13) { + document.getElementById("advSpecialSelect").value = "fa"; + updateMapCost(); + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("advSpecialSelect").value = 0; + updateMapCost(); + } + } + if (quest == 14) { + document.getElementById("advSpecialSelect").value = "fa"; + updateMapCost(); + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("advSpecialSelect").value = 0; + updateMapCost(); + } + } + if (updateMapCost(true) > game.resources.fragments.owned) { + biomeAdvMapsSelect.value = "Random"; + updateMapCost(); + } +} + +function RlevelMap(what) { + var extra = 0; + var globalextra = 0; + if (what == "mayhem") { + extra = RmayhemExtra(); + } else if (what == "panda") { + extra = RpandaExtra(); + } else if (what == "equip") { + globalextra = RequipExtra(); + } else if (what == "deso") { + extra = RdesoExtra(); + } + mapLevelInput.value = (game.global.world + globalextra); + biomeAdvMapsSelect.value = "Random"; + document.getElementById("advSpecialSelect").value = (what == "equip") ? "lmc" : "fa"; + document.getElementById("advExtraLevelSelect").value = extra; + updateMapCost(); +} diff --git a/modules/maps.js b/modules/maps.js index 92c50b197..2e41c5eaa 100644 --- a/modules/maps.js +++ b/modules/maps.js @@ -1,105 +1,248 @@ -MODULES["maps"] = {}; -//These can be changed (in the console) if you know what you're doing: -MODULES["maps"].enoughDamageCutoff = 4; //above this the game will do maps for map bonus stacks -MODULES["maps"].farmingCutoff = 16; //above this the game will farm. -MODULES["maps"].numHitsSurvived = 8; //survive X hits in D stance or not enough Health. -MODULES["maps"].LeadfarmingCutoff = 10; //lead has its own farmingCutoff -MODULES["maps"].NomfarmingCutoff = 10; //nom has its own farmingCutoff -MODULES["maps"].NurseryMapLevel = 50; //with blacksmithery, run map for nursery on this level -//if FarmWhenNomStacks7 setting is on = [x, y, z]; -MODULES["maps"].NomFarmStacksCutoff = [7,30,100]; -//[x] get maxMapBonus (10) if we go above (7) stacks on Improbability (boss) -//[y] go into maps on (30) stacks on Improbability (boss), farm until we fall under the 'NomfarmingCutoff' (10) -//[z] restarts your voidmap if you hit (100) stacks -MODULES["maps"].MapTierZone = [72,47,16]; //descending order for these. -// .MapTier?Sliders = [size,difficulty,loot,biome]; -MODULES["maps"].MapTier0Sliders = [9,9,9,'Mountain']; //Zone 72+ (old: 9/9/9 Metal) -MODULES["maps"].MapTier1Sliders = [9,9,9,'Depths']; //Zone 47-72 (old: 9/9/4 Metal) -MODULES["maps"].MapTier2Sliders = [9,9,9,'Random']; //Zone 16-47 (old: 9/9/0 Random) -MODULES["maps"].MapTier3Sliders = [9,9,9,'Random']; //Zone 6-16 (old: 9/0/0 Random) -MODULES["maps"].preferGardens = !getPageSetting('PreferMetal'); //prefer run Garden maps instead of ^^ if we have Decay done -MODULES["maps"].maxMapBonus = 10; //cap how many maps are run during Want More Damage mode -MODULES["maps"].wantHealthMapBonus = 10;//cap how many maps are run during Want More Health mode -MODULES["maps"].SpireFarm199Maps = true; //this will farm spire on 199 maps instead of 200 maps when Map Reducer is bought -MODULES["maps"].watchChallengeMaps = [15, 25, 35, 50]; //during 'watch' challenge, run maps on these levels: -MODULES["maps"].shouldFarmCell = 59; -MODULES["maps"].SkipNumUnboughtPrestiges = 2; //exceeding this number of unbought prestiges will trigger a skip of prestige mode. -MODULES["maps"].UnearnedPrestigesRequired = 2; -MODULES["maps"].maxMapBonusAfterZ = MODULES["maps"].maxMapBonus; //Max Map Bonus After Zone uses this many stacks - //- init as default value (10). user can set if they want. - -//Initialize Global Vars (dont mess with these ones, nothing good can come from it). -var stackingTox = false; -var doVoids = false; -var needToVoid = false; -var needPrestige = false; -var skippedPrestige = false; -var voidCheckPercent = 0; -var HDratio = 0; -var ourBaseDamage = 0; -var ourBaseDamage2 = 0; -var scryerStuck = false; -var shouldDoMaps = false; +//Helium +MODULES.maps = {}; +MODULES.maps.numHitsSurvived = 8; +MODULES.maps.LeadfarmingCutoff = 10; +MODULES.maps.NomfarmingCutoff = 10; +MODULES.maps.NomFarmStacksCutoff = [7, 30, 100]; +MODULES.maps.MapTierZone = [72, 47, 16]; +MODULES.maps.MapTier0Sliders = [9, 9, 9, "Mountain"]; +MODULES.maps.MapTier1Sliders = [9, 9, 9, "Depths"]; +MODULES.maps.MapTier2Sliders = [9, 9, 9, "Random"]; +MODULES.maps.MapTier3Sliders = [9, 9, 9, "Random"]; +MODULES.maps.preferGardens = !getPageSetting("PreferMetal"); +MODULES.maps.SpireFarm199Maps = !0; +MODULES.maps.shouldFarmCell = 59; +MODULES.maps.SkipNumUnboughtPrestiges = 2; +MODULES.maps.UnearnedPrestigesRequired = 2; + +var doVoids = !1; +var needToVoid = !1; +var needPrestige = !1; +var skippedPrestige = !1; +var scryerStuck = !1; +var shouldDoMaps = !1; var mapTimeEstimate = 0; var lastMapWeWereIn = null; -var preSpireFarming = false; -var spireMapBonusFarming = false; +var preSpireFarming = !1; +var spireMapBonusFarming = !1; var spireTime = 0; -var doMaxMapBonus = false; -var vanillaMapatZone = false; +var doMaxMapBonus = !1; +var vanillaMapatZone = !1; +var farmingWonder = !1; +var additionalCritMulti = 2 < getPlayerCritChance() ? 25 : 5; + +function updateAutoMapsStatus(get) { + + var status; + var minSp = getPageSetting('MinutestoFarmBeforeSpire'); + + //Fail Safes + if (getPageSetting('AutoMaps') == 0) status = 'Off'; + else if (challengeActive("Mapology") && game.challenges.Mapology.credits < 1) status = 'Out of Map Credits'; + + //Raiding + else if (game.global.mapsActive && getCurrentMapObject().level > game.global.world && getCurrentMapObject().location != "Void" && getCurrentMapObject().location != "Bionic") status = 'Prestige Raiding'; + else if (game.global.mapsActive && getCurrentMapObject().level > game.global.world && getCurrentMapObject().location == "Bionic") status = 'BW Raiding'; + + //Spire + else if (preSpireFarming) { + var secs = Math.floor(60 - (spireTime * 60) % 60).toFixed(0); + var mins = Math.floor(minSp - spireTime).toFixed(0); + var hours = ((minSp - spireTime) / 60).toFixed(2); + var spiretimeStr = (minSp - spireTime >= 60) ? + (hours + 'h') : (mins + 'm:' + (secs >= 10 ? secs : ('0' + secs)) + 's'); + status = 'Farming for Spire ' + spiretimeStr + ' left'; + } else if (spireMapBonusFarming) status = 'Getting Spire Map Bonus'; + else if (getPageSetting('SkipSpires') == 1 && ((game.global.challengeActive != 'Daily' && isActiveSpireAT()) || (game.global.challengeActive == 'Daily' && disActiveSpireAT()))) status = 'Skipping Spire'; + else if (doMaxMapBonus) status = 'Max Map Bonus After Zone'; + else if (!game.global.mapsUnlocked) status = ' '; + else if (needPrestige && !doVoids) status = 'Prestige'; + else if (doVoids) { + var stackedMaps = Fluffy.isRewardActive('void') ? countStackedVoidMaps() : 0; + status = 'Void Maps: ' + game.global.totalVoidMaps + ((stackedMaps) ? " (" + stackedMaps + " stacked)" : "") + ' remaining'; + } else if (shouldFarm && !doVoids) status = 'Farming: ' + calcHDratio().toFixed(4) + 'x'; + else if (!enoughHealth && !enoughDamage) status = 'Want Health & Damage'; + else if (!enoughDamage) status = 'Want ' + calcHDratio().toFixed(4) + 'x  more damage'; + else if (!enoughHealth) status = 'Want more health'; + else if (farmingWonder) status = 'Experiencing Wonder'; + else if (enoughHealth && enoughDamage) status = 'Advancing'; + + if (skippedPrestige) + status += '
Prestige Skipped'; + + //hider he/hr% status + var getPercent = (game.stats.heliumHour.value() / (game.global.totalHeliumEarned - (game.global.heliumLeftover + game.resources.helium.owned))) * 100; + var lifetime = (game.resources.helium.owned / (game.global.totalHeliumEarned - game.resources.helium.owned)) * 100; + var hiderStatus = 'He/hr: ' + getPercent.toFixed(3) + '%
   He: ' + lifetime.toFixed(3) + '%'; + + if (get) { + return [status, getPercent, lifetime]; + } else { + document.getElementById('autoMapStatus').innerHTML = status; + document.getElementById('hiderStatus').innerHTML = hiderStatus; + } +} + +MODULES["maps"].advSpecialMapMod_numZones = 3; +var advExtraMapLevels = 0; + +function testMapSpecialModController() { + var a = []; + if (Object.keys(mapSpecialModifierConfig).forEach(function(o) { + var p = mapSpecialModifierConfig[o]; + game.global.highestLevelCleared + 1 >= p.unlocksAt && a.push(p.abv.toLowerCase()); + }), !(1 > a.length)) { + var c = document.getElementById("advSpecialSelect"); + if (c) { + if (59 <= game.global.highestLevelCleared) { + if (needPrestige && a.includes("p")) { + c.value = "p"; + } else if (shouldFarm || !enoughHealth || preSpireFarming) { + c.value = a.includes("lmc") ? "lmc" : a.includes("hc") ? "hc" : a.includes("smc") ? "smc" : "lc"; + } else c.value = "fa"; + for (var d = updateMapCost(!0), e = game.resources.fragments.owned, f = 100 * (d / e); 0 < c.selectedIndex && d > e;) { + c.selectedIndex -= 1; + "0" != c.value && console.log("Could not afford " + mapSpecialModifierConfig[c.value].name); + } + var d = updateMapCost(!0), + e = game.resources.fragments.owned; + "0" != c.value && debug("Set the map special modifier to: " + mapSpecialModifierConfig[c.value].name + ". Cost: " + (100 * (d / e)).toFixed(2) + "% of your fragments."); + } + var g = getSpecialModifierSetting(), + h = 109 <= game.global.highestLevelCleared, + i = checkPerfectChecked(), + j = document.getElementById("advPerfectCheckbox"), + k = getPageSetting("AdvMapSpecialModifier") ? getExtraMapLevels() : 0, + l = 209 <= game.global.highestLevelCleared; + if (l) { + var m = document.getElementById("advExtraMapLevelselect"); + if (!m) + return; + var n = document.getElementById("mapLevelInput").value; + for (m.selectedIndex = n == game.global.world ? MODULES.maps.advSpecialMapMod_numZones : 0; 0 < m.selectedIndex && updateMapCost(!0) > game.resources.fragments.owned;) + m.selectedIndex -= 1; + } + } + } +} -//AutoMap - function originally created by Belaith (in 1971) -//anything/everything to do with maps. function autoMap() { - var customVars = MODULES["maps"]; - //allow script to handle abandoning - // if(game.options.menu.alwaysAbandon.enabled == 1) toggleSetting('alwaysAbandon'); - //if we are prestige mapping, force equip first mode - var prestige = autoTrimpSettings.Prestige.selected; - if(prestige != "Off" && game.options.menu.mapLoot.enabled != 1) toggleSetting('mapLoot'); - //Control in-map right-side-buttons for people who can't control themselves. If you wish to use these buttons manually, turn off autoMaps temporarily. - if(game.options.menu.repeatUntil.enabled == 2) toggleSetting('repeatUntil'); - if(game.options.menu.exitTo.enabled != 0) toggleSetting('exitTo'); - if(game.options.menu.repeatVoids.enabled != 0) toggleSetting('repeatVoids'); - //exit and do nothing if we are prior to zone 6 (maps haven't been unlocked): - if (!game.global.mapsUnlocked || !(baseDamage > 0)) { //if we have no damage, why bother running anything? (this fixes weird bugs) - enoughDamage = true; enoughHealth = true; shouldFarm = false; - updateAutoMapsStatus(); //refresh the UI status (10x per second) + + //Failsafes + if (!game.global.mapsUnlocked || calcOurDmg("avg", false, true) <= 0) { + enoughDamage = true; + enoughHealth = true; + shouldFarm = false; + updateAutoMapsStatus(); return; } - //if we are in mapology and we have no credits, exit - if (game.global.challengeActive == "Mapology" && game.challenges.Mapology.credits < 1) { + if (challengeActive("Mapology") && game.challenges.Mapology.credits < 1) { updateAutoMapsStatus(); return; } + + //WS + var mapenoughdamagecutoff = getPageSetting("mapcuntoff"); + if (getEmpowerment() == 'Wind' && game.global.challengeActive != "Daily" && !game.global.runningChallengeSquared && getPageSetting("AutoStance") == 3 && getPageSetting("WindStackingMin") > 0 && game.global.world >= getPageSetting("WindStackingMin") && getPageSetting("windcutoffmap") > 0) + mapenoughdamagecutoff = getPageSetting("windcutoffmap"); + if (getEmpowerment() == 'Wind' && game.global.challengeActive == "Daily" && !game.global.runningChallengeSquared && (getPageSetting("AutoStance") == 3 || getPageSetting("use3daily") == true) && getPageSetting("dWindStackingMin") > 0 && game.global.world >= getPageSetting("dWindStackingMin") && getPageSetting("dwindcutoffmap") > 0) + mapenoughdamagecutoff = getPageSetting("dwindcutoffmap"); + if (getPageSetting("mapc2hd") > 0 && game.global.challengeActive == "Mapology") + mapenoughdamagecutoff = getPageSetting("mapc2hd"); + + //Vars + var customVars = MODULES["maps"]; + var prestige = autoTrimpSettings.Prestige.selected; + if (prestige != "Off" && game.options.menu.mapLoot.enabled != 1) toggleSetting('mapLoot'); + if (game.global.repeatMap == true && !game.global.mapsActive && !game.global.preMapsActive) repeatClicked(); + if ((game.options.menu.repeatUntil.enabled == 1 || game.options.menu.repeatUntil.enabled == 2 || game.options.menu.repeatUntil.enabled == 3) && !game.global.mapsActive && !game.global.preMapsActive) toggleSetting('repeatUntil'); + if (game.options.menu.exitTo.enabled != 0) toggleSetting('exitTo'); + if (game.options.menu.repeatVoids.enabled != 0) toggleSetting('repeatVoids'); var challSQ = game.global.runningChallengeSquared; - //advanced "Extra Zones" dropdown var extraMapLevels = getPageSetting('AdvMapSpecialModifier') ? getExtraMapLevels() : 0; - //FIND VOID MAPS LEVEL: - var voidMapLevelSetting = getPageSetting('VoidMaps'); - //decimal void maps are possible, using string function to avoid false float precision (0.29999999992). javascript can compare ints to strings anyway. - var voidMapLevelSettingZone = (voidMapLevelSetting+"").split(".")[0]; - var voidMapLevelSettingMap = (voidMapLevelSetting+"").split(".")[1]; - if (voidMapLevelSettingMap === undefined || (game.global.challengeActive == 'Lead' && !challSQ)) - voidMapLevelSettingMap = 93; - if (voidMapLevelSettingMap.length == 1) voidMapLevelSettingMap += "0"; //entering 187.70 becomes 187.7, this will bring it back to 187.70 - var voidsuntil = getPageSetting('RunNewVoidsUntil'); - needToVoid = voidMapLevelSetting > 0 && game.global.totalVoidMaps > 0 && game.global.lastClearedCell + 1 >= voidMapLevelSettingMap && - (game.global.world == voidMapLevelSettingZone || - (game.global.world >= voidMapLevelSettingZone && getPageSetting('RunNewVoids') && (voidsuntil == -1 || game.global.world <= voidsuntil))); - if(game.global.totalVoidMaps == 0 || !needToVoid) + + //Void Vars + var voidMapLevelSetting = 0; + var voidMapLevelSettingCell; + var voidMapLevelPlus = 0; + if (game.global.challengeActive != "Daily") { + voidMapLevelSettingCell = ((getPageSetting('voidscell') > 0) ? getPageSetting('voidscell') : 70); + } + if (game.global.challengeActive == "Daily") { + voidMapLevelSettingCell = ((getPageSetting('dvoidscell') > 0) ? getPageSetting('dvoidscell') : 70); + } + if (game.global.challengeActive != "Daily" && getPageSetting('VoidMaps') > 0) { + voidMapLevelSetting = getPageSetting('VoidMaps'); + } + if (game.global.challengeActive == "Daily" && getPageSetting('DailyVoidMod') >= 1) { + voidMapLevelSetting = getPageSetting('DailyVoidMod'); + } + if (getPageSetting('RunNewVoidsUntilNew') != 0 && game.global.challengeActive != "Daily") { + voidMapLevelPlus = getPageSetting('RunNewVoidsUntilNew'); + } + if (getPageSetting('dRunNewVoidsUntilNew') != 0 && game.global.challengeActive == "Daily") { + voidMapLevelPlus = getPageSetting('dRunNewVoidsUntilNew'); + } + + needToVoid = (voidMapLevelSetting > 0 && game.global.totalVoidMaps > 0 && game.global.lastClearedCell + 1 >= voidMapLevelSettingCell && + ( + (game.global.world == voidMapLevelSetting) || + (voidMapLevelPlus < 0 && game.global.world >= voidMapLevelSetting && + (game.global.universe == 1 && + ( + (getPageSetting('runnewvoidspoison') == false && game.global.challengeActive != "Daily") || + (getPageSetting('drunnewvoidspoison') == false && game.global.challengeActive == "Daily") + ) || + ( + (getPageSetting('runnewvoidspoison') == true && getEmpowerment() == 'Poison' && game.global.challengeActive != "Daily") || + (getPageSetting('drunnewvoidspoison') == true && getEmpowerment() == 'Poison' && game.global.challengeActive == "Daily") + ) + ) || + (voidMapLevelPlus > 0 && game.global.world >= voidMapLevelSetting && game.global.world <= (voidMapLevelSetting + voidMapLevelPlus) && + (game.global.universe == 1 && + ( + (getPageSetting('runnewvoidspoison') == false && game.global.challengeActive != "Daily") || + (getPageSetting('drunnewvoidspoison') == false && game.global.challengeActive == "Daily") + ) || + ( + (getPageSetting('runnewvoidspoison') == true && getEmpowerment() == 'Poison' && game.global.challengeActive != "Daily") || + (getPageSetting('drunnewvoidspoison') == true && getEmpowerment() == 'Poison' && game.global.challengeActive == "Daily") + ) + ) + ) + ) + ) + ); + + var voidArrayDoneS = []; + if (game.global.challengeActive != "Daily" && getPageSetting('onlystackedvoids') == true) { + for (var mapz in game.global.mapsOwnedArray) { + var theMapz = game.global.mapsOwnedArray[mapz]; + if (theMapz.location == 'Void' && theMapz.stacked > 0) { + voidArrayDoneS.push(theMapz); + } + } + } + + if ( + (game.global.totalVoidMaps <= 0) || + (!needToVoid) || + (getPageSetting('novmsc2') == true && game.global.runningChallengeSquared) || + (game.global.challengeActive != "Daily" && game.global.totalVoidMaps > 0 && getPageSetting('onlystackedvoids') == true && voidArrayDoneS.length < 1) + ) { doVoids = false; - // if force prestige, check if we are behind any first - if ((getPageSetting('ForcePresZ') >= 0) && ((game.global.world+extraMapLevels) >= getPageSetting('ForcePresZ'))) { - const prestigeList = ['Supershield','Dagadder','Megamace','Polierarm','Axeidic','Greatersword','Harmbalest','Bootboost','Hellishmet','Pantastic','Smoldershoulder','Bestplate','GambesOP']; - needPrestige = prestigeList.some(pres => game.mapUnlocks[pres].last <= (game.global.world+extraMapLevels) - 5); + } + + //Prestige + if ((getPageSetting('ForcePresZ') >= 0) && ((game.global.world + extraMapLevels) >= getPageSetting('ForcePresZ'))) { + const prestigeList = ['Supershield', 'Dagadder', 'Megamace', 'Polierarm', 'Axeidic', 'Greatersword', 'Harmbalest', 'Bootboost', 'Hellishmet', 'Pantastic', 'Smoldershoulder', 'Bestplate', 'GambesOP']; + needPrestige = (offlineProgress.countMapItems(game.global.world) !== 0); } else - //calculate if we are behind on unlocking prestiges - needPrestige = prestige != "Off" && game.mapUnlocks[prestige] && game.mapUnlocks[prestige].last <= (game.global.world+extraMapLevels) - 5 && game.global.challengeActive != "Frugal"; - //dont need prestige if we are caught up, and have (2) unbought prestiges: + needPrestige = prestige != "Off" && game.mapUnlocks[prestige] && game.mapUnlocks[prestige].last <= (game.global.world + extraMapLevels) - 5 && game.global.challengeActive != "Frugal"; + skippedPrestige = false; - if (needPrestige && getPageSetting('PrestigeSkipMode')) { - var prestigeList = ['Dagadder','Megamace','Polierarm','Axeidic','Greatersword','Harmbalest','Bootboost','Hellishmet','Pantastic','Smoldershoulder','Bestplate','GambesOP']; + if (needPrestige && (getPageSetting('PrestigeSkip1_2') == 1 || getPageSetting('PrestigeSkip1_2') == 2)) { + var prestigeList = ['Dagadder', 'Megamace', 'Polierarm', 'Axeidic', 'Greatersword', 'Harmbalest', 'Bootboost', 'Hellishmet', 'Pantastic', 'Smoldershoulder', 'Bestplate', 'GambesOP']; var numUnbought = 0; for (var i in prestigeList) { var p = prestigeList[i]; @@ -111,260 +254,141 @@ function autoMap() { skippedPrestige = true; } } - // Don't need prestige if there aren't many weapon prestiges left - if ((needPrestige || skippedPrestige) && getPageSetting('PrestigeSkip2')) { - const prestigeList = ['Dagadder','Megamace','Polierarm','Axeidic','Greatersword','Harmbalest']; - const numLeft = prestigeList.filter(pres => game.mapUnlocks[pres].last <= (game.global.world+extraMapLevels) - 5); + + if ((needPrestige || skippedPrestige) && (getPageSetting('PrestigeSkip1_2') == 1 || getPageSetting('PrestigeSkip1_2') == 3)) { + const prestigeList = ['Dagadder', 'Megamace', 'Polierarm', 'Axeidic', 'Greatersword', 'Harmbalest']; + const numLeft = prestigeList.filter(prestige => game.mapUnlocks[prestige].last <= (game.global.world + extraMapLevels) - 5); const shouldSkip = numLeft <= customVars.UnearnedPrestigesRequired; - if (shouldSkip != skippedPrestige) { // not both conditions are met / is met but not already skipped: unskip it / do skip it - needPrestige = !needPrestige; - skippedPrestige = !skippedPrestige; - } - } - -//START CALCULATING DAMAGES: - var AutoStance = getPageSetting('AutoStance'); - //calculate crits (baseDamage was calced in function autoStance) this is a weighted average of nonCrit + Crit. (somewhere in the middle) - ourBaseDamage = (baseDamage * (1-getPlayerCritChance()) + (baseDamage * getPlayerCritChance() * getPlayerCritDamageMult())); - //calculate with map bonus - var mapbonusmulti = 1 + (0.20*game.global.mapBonus); - //(autostance2 has mapbonusmulti built in) - ourBaseDamage2 = ourBaseDamage; //keep a version without mapbonus - ourBaseDamage *= mapbonusmulti; - - //get average enemyhealth and damage for the next zone, cell 50, snimp type and multiply it by a max range fluctuation of 1.2 - var enemyDamage; - var enemyHealth; - if (AutoStance<=1) { - enemyDamage = getEnemyMaxAttack(game.global.world + 1, 50, 'Snimp', 1.2); - enemyDamage = calcDailyAttackMod(enemyDamage); //daily mods: badStrength,badMapStrength,bloodthirst - } else { - enemyDamage = calcBadGuyDmg(null,getEnemyMaxAttack(game.global.world + 1, 50, 'Snimp', 1.0),true,true); //(enemy,attack,daily,maxormin,[disableFlucts]) - } - enemyHealth = getEnemyMaxHealth(game.global.world + 1,50); - if(game.global.challengeActive == "Toxicity") { - enemyHealth *= 2; - } - //Corruption Zone Proportionality Farming Calculator: - var corrupt = game.global.world >= mutations.Corruption.start(true); - if (getPageSetting('CorruptionCalc') && corrupt) { - var cptnum = getCorruptedCellsNum(); //count corrupted cells - var cpthlth = getCorruptScale("health"); //get corrupted health mod - var cptpct = cptnum / 100; //percentage of zone which is corrupted. - var hlthprop = cptpct * cpthlth; //Proportion of cells corrupted * health of a corrupted cell - if (hlthprop >= 1) //dont allow sub-1 numbers to make the number less - enemyHealth *= hlthprop; - var cptatk = getCorruptScale("attack"); //get corrupted attack mod - var atkprop = cptpct * cptatk; //Proportion of cells corrupted * attack of a corrupted cell - if (atkprop >= 1) - enemyDamage *= atkprop; - //console.log("enemy dmg:" + enemyDamage + " enemy hp:" + enemyHealth + " base dmg: " + ourBaseDamage); - } - // enter farming if it takes over 4 hits in D stance (16) (and exit if under.) - if(!getPageSetting('DisableFarm')) { - shouldFarm = enemyHealth > (ourBaseDamage * customVars.farmingCutoff); - if(game.options.menu.repeatUntil.enabled == 1) toggleSetting('repeatUntil'); //turn repeat forever on if farming is on. - } - - //Lead specific farming calcuation section: - if((game.global.challengeActive == 'Lead' && !challSQ)) { - ourBaseDamage /= mapbonusmulti; - if (AutoStance<=1) - enemyDamage *= (1 + (game.challenges.Lead.stacks * 0.04)); - enemyHealth *= (1 + (game.challenges.Lead.stacks * 0.04)); - //if the zone is odd: (skip the +2 calc for the last level. - if (game.global.world % 2 == 1 && game.global.world != 179){ - //calculate for the next level in advance (since we only farm on odd, and evens are very tough) - if (AutoStance <= 1) { - enemyDamage = getEnemyMaxAttack(game.global.world + 1, 99, 'Snimp', 1.2); - enemyDamage = calcDailyAttackMod(enemyDamage); //daily mods: badStrength,badMapStrength,bloodthirst - } else { - enemyDamage = calcBadGuyDmg(null, getEnemyMaxAttack(game.global.world + 1, 99, 'Snimp', 1.0), true, true); //(enemy,attack,daily,maxormin,[disableFlucts]) - } - enemyDamage *= (1 + (100 * 0.04)); - ourBaseDamage /= 1.5; //subtract the odd-zone bonus. - } - if (game.global.world == 179) { - ourBaseDamage *= mapbonusmulti; - } - //let people disable this if they want. - if(!getPageSetting('DisableFarm')) { - shouldFarm = enemyHealth > (ourBaseDamage * customVars.LeadfarmingCutoff); + if (shouldSkip != skippedPrestige) { + needPrestige = !needPrestige; + skippedPrestige = !skippedPrestige; } } - //Enough Health and Damage calculations: - var pierceMod = (game.global.brokenPlanet && !game.global.mapsActive) ? getPierceAmt() : 0; - const FORMATION_MOD_1 = game.upgrades.Dominance.done ? 2 : 1; - //asks if we can survive x number of hits in either D stance or X stance. - enoughHealth = (baseHealth/FORMATION_MOD_1 > customVars.numHitsSurvived * (enemyDamage - baseBlock/FORMATION_MOD_1 > 0 ? enemyDamage - baseBlock/FORMATION_MOD_1 : enemyDamage * pierceMod)); - enoughDamage = (ourBaseDamage * customVars.enoughDamageCutoff > enemyHealth); - - //remove this in the meantime until it works for everyone. -/* if (!wantToScry) { - //enough health if we can survive 8 hits in D stance (health/2 and block/2) - enoughHealth = (baseHealth/2 > 8 * (enemyDamage - baseBlock/2 > 0 ? enemyDamage - baseBlock/2 : enemyDamage * pierceMod)); - //enough damage if we can one-shot the enemy in D (ourBaseDamage*4) - enoughDamage = (ourBaseDamage * 4) > enemyHealth; - scryerStuck = false; - } else { - //enough health if we can pass all the tests in autostance2 under the best of the worst conditions. - //enough damage if we can one-shot the enemy in S (ourBaseDamage/2) - var result = autoStanceCheck(true); - enoughHealth = result[0]; - enoughDamage = result[1]; - scryerStuck = !enoughHealth; - } */ - //Health:Damage ratio: (status) - HDratio = enemyHealth / ourBaseDamage; - updateAutoMapsStatus(); //refresh the UI status (10x per second) + //Calc + var ourBaseDamage = calcOurDmg("avg", false, true); + var enemyDamage = calcBadGuyDmg(null, getEnemyMaxAttack(game.global.world + 1, 50, 'Snimp', 1.0), true, true); + var enemyHealth = calcEnemyHealth(); + if (getPageSetting('DisableFarm') > 0) { + shouldFarm = (calcHDratio() >= getPageSetting('DisableFarm')); + if (game.options.menu.repeatUntil.enabled == 1 && shouldFarm) + toggleSetting('repeatUntil'); + } + if (game.global.spireActive) { + enemyDamage = calcSpire(99, game.global.gridArray[99].name, 'attack'); + } + highDamageShield(); + if (getPageSetting('loomswap') > 0 && game.global.challengeActive != "Daily" && game.global.ShieldEquipped.name != getPageSetting('highdmg')) + ourBaseDamage *= trimpAA; + if (getPageSetting('dloomswap') > 0 && game.global.challengeActive == "Daily" && game.global.ShieldEquipped.name != getPageSetting('dhighdmg')) + ourBaseDamage *= trimpAA; + var mapbonusmulti = 1 + (0.20 * game.global.mapBonus); + var ourBaseDamage2 = ourBaseDamage; + ourBaseDamage2 /= mapbonusmulti; + var pierceMod = (game.global.brokenPlanet) ? getPierceAmt() : 0; + const FORMATION_MOD_1 = game.upgrades.Dominance.done ? 2 : 1; + enoughHealth = (calcOurHealth() / FORMATION_MOD_1 > customVars.numHitsSurvived * (enemyDamage - calcOurBlock() / FORMATION_MOD_1 > 0 ? enemyDamage - calcOurBlock() / FORMATION_MOD_1 : enemyDamage * pierceMod)); + enoughDamage = (ourBaseDamage * mapenoughdamagecutoff > enemyHealth); + updateAutoMapsStatus(); -//BEGIN AUTOMAPS DECISIONS: - //variables for doing maps + //Farming var selectedMap = "world"; var shouldFarmLowerZone = false; shouldDoMaps = false; - //prevents map-screen from flickering on and off during startup when base damage is 0. - if (ourBaseDamage > 0){ - shouldDoMaps = !enoughDamage || shouldFarm || scryerStuck; + if (ourBaseDamage > 0) { + shouldDoMaps = (!enoughDamage || shouldFarm || scryerStuck); } - //Check our graph history and - Estimate = The zone should take around this long in milliseconds. - mapTimeEstimate = mapTimeEstimater(); - var shouldDoHealthMaps = false; - //if we are at max map bonus (10), and we don't need to farm, don't do maps - if (game.global.mapBonus >= customVars.maxMapBonus && !shouldFarm) + if (game.global.mapBonus >= getPageSetting('MaxMapBonuslimit') && !shouldFarm) shouldDoMaps = false; - else if (game.global.mapBonus >= customVars.maxMapBonus && shouldFarm) + else if (game.global.mapBonus >= getPageSetting('MaxMapBonuslimit') && shouldFarm) shouldFarmLowerZone = getPageSetting('LowerFarmingZone'); - //do (1) map if we dont have enough health - else if (game.global.mapBonus < customVars.wantHealthMapBonus && !enoughHealth && !shouldDoMaps && !needPrestige) { + else if (game.global.mapBonus < getPageSetting('MaxMapBonushealth') && !enoughHealth && !shouldDoMaps && !needPrestige) { shouldDoMaps = true; shouldDoHealthMaps = true; } - - //FarmWhenNomStacks7 var restartVoidMap = false; - if(game.global.challengeActive == 'Nom' && getPageSetting('FarmWhenNomStacks7')) { - //Get maxMapBonus (10) if we go above (7) stacks on Improbability (boss) - if (game.global.gridArray[99].nomStacks > customVars.NomFarmStacksCutoff[0]){ - if (game.global.mapBonus != customVars.maxMapBonus) + if (challengeActive("Nom") && getPageSetting('FarmWhenNomStacks7')) { + if (game.global.gridArray[99].nomStacks > customVars.NomFarmStacksCutoff[0]) { + if (game.global.mapBonus != getPageSetting('MaxMapBonuslimit')) shouldDoMaps = true; } - //Go into maps on (30) stacks on Improbability (boss), farm until we fall under (10) H:D ratio - if (game.global.gridArray[99].nomStacks == customVars.NomFarmStacksCutoff[1]){ - shouldFarm = (HDratio > customVars.NomfarmingCutoff); + if (game.global.gridArray[99].nomStacks == customVars.NomFarmStacksCutoff[1]) { + shouldFarm = (calcHDratio() > customVars.NomfarmingCutoff); shouldDoMaps = true; } - //If we ever hit (100) nomstacks in the world, farm. - if(!game.global.mapsActive && game.global.gridArray[game.global.lastClearedCell + 1].nomStacks >= customVars.NomFarmStacksCutoff[2]) { - shouldFarm = (HDratio > customVars.NomfarmingCutoff); + if (!game.global.mapsActive && game.global.gridArray[game.global.lastClearedCell + 1].nomStacks >= customVars.NomFarmStacksCutoff[2]) { + shouldFarm = (calcHDratio() > customVars.NomfarmingCutoff); shouldDoMaps = true; } - //If we ever hit (100) nomstacks in a map (likely a voidmap), farm, (exit the voidmap and prevent void from running, until situation is clear) - if(game.global.mapsActive && game.global.mapGridArray[game.global.lastClearedMapCell + 1].nomStacks >= customVars.NomFarmStacksCutoff[2]) { - shouldFarm = (HDratio > customVars.NomfarmingCutoff); + if (game.global.mapsActive && game.global.mapGridArray[game.global.lastClearedMapCell + 1].nomStacks >= customVars.NomFarmStacksCutoff[2]) { + shouldFarm = (calcHDratio() > customVars.NomfarmingCutoff); shouldDoMaps = true; restartVoidMap = true; } } - //Disable Farm mode if we have nothing left to farm for (prevent infinite farming) + //Prestige if (shouldFarm && !needPrestige) { - //check if we have cap to 10 equip on, and we are capped for all attack weapons var capped = areWeAttackLevelCapped(); - //check if we have any additional prestiges available to unlock: var prestigeitemsleft; if (game.global.mapsActive) { prestigeitemsleft = addSpecials(true, true, getCurrentMapObject()); - } - else if (lastMapWeWereIn) { + } else if (lastMapWeWereIn) { prestigeitemsleft = addSpecials(true, true, lastMapWeWereIn); } - //check if we have unbought+available prestiges - var prestigeList = ['Dagadder','Megamace','Polierarm','Axeidic','Greatersword','Harmbalest']; + const prestigeList = ['Dagadder', 'Megamace', 'Polierarm', 'Axeidic', 'Greatersword', 'Harmbalest']; var numUnbought = 0; - for (var i=0,len=prestigeList.length; i < len; i++) { + for (var i = 0, len = prestigeList.length; i < len; i++) { var p = prestigeList[i]; if (game.upgrades[p].allowed - game.upgrades[p].done > 0) numUnbought++; } - //Disable farm mode, only do up to mapbonus. if (capped && prestigeitemsleft == 0 && numUnbought == 0) { shouldFarm = false; - if (game.global.mapBonus >= customVars.maxMapBonus && !shouldFarm) + if (game.global.mapBonus >= getPageSetting('MaxMapBonuslimit') && !shouldFarm) shouldDoMaps = false; } } - //stack tox stacks if we are doing max tox, or if we need to clear our void maps - if(game.global.challengeActive == 'Toxicity' && game.global.lastClearedCell > 93 && game.challenges.Toxicity.stacks < 1500 && ((getPageSetting('MaxTox') && game.global.world > 59) || needToVoid)) { - shouldDoMaps = true; - //we will get at least 85 toxstacks from the 1st voidmap (unless we have overkill) -// if (!game.portal.Overkill.locked && game.stats.cellsOverkilled.value) - - stackingTox = !(needToVoid && game.challenges.Toxicity.stacks > 1415); - //force abandon army - if(!game.global.mapsActive && !game.global.preMapsActive) { - mapsClicked(); - mapsClicked(); - } - } - else stackingTox = false; - - //during 'watch' challenge, run maps on these levels: - var watchmaps = customVars.watchChallengeMaps; - var shouldDoWatchMaps = false; - if (game.global.challengeActive == 'Watch' && watchmaps.indexOf(game.global.world) > -1 && game.global.mapBonus < 1){ - shouldDoMaps = true; - shouldDoWatchMaps = true; - } - //Farm X Minutes Before Spire: + //Spire var shouldDoSpireMaps = false; - preSpireFarming = (isActiveSpireAT()) && (spireTime = (new Date().getTime() - game.global.zoneStarted) / 1000 / 60) < getPageSetting('MinutestoFarmBeforeSpire'); - spireMapBonusFarming = getPageSetting('MaxStacksForSpire') && isActiveSpireAT() && game.global.mapBonus < customVars.maxMapBonus; + preSpireFarming = (isActiveSpireAT() || disActiveSpireAT()) && (spireTime = (new Date().getTime() - game.global.zoneStarted) / 1000 / 60) < getPageSetting('MinutestoFarmBeforeSpire'); + spireMapBonusFarming = getPageSetting('MaxStacksForSpire') && (isActiveSpireAT() || disActiveSpireAT()) && game.global.mapBonus < 10; if (preSpireFarming || spireMapBonusFarming) { shouldDoMaps = true; shouldDoSpireMaps = true; } - //Run a single map to get nurseries when 1. it's still locked, - // 2. blacksmithery is purchased, - // but not when 3A. home detector is purchased, or 3B. we don't need nurseries - if (game.buildings.Nursery.locked && game.talents.blacksmith.purchased && !(game.talents.housing.purchased || - (getPageSetting('PreSpireNurseries') < 0 ? - !(getPageSetting('MaxNursery') && game.global.world >= getPageSetting('NoNurseriesUntil')) : - !getPageSetting('PreSpireNurseries'))) && game.global.world >= customVars.NurseryMapLevel) { - shouldDoMaps = true; - shouldDoWatchMaps = true; //TODO coding: this is overloaded - not ideal. - } - //MaxMapBonusAfterZone (idea from awnv) + + //Map Bonus var maxMapBonusZ = getPageSetting('MaxMapBonusAfterZone'); - doMaxMapBonus = (maxMapBonusZ >= 0 && game.global.mapBonus < customVars.maxMapBonusAfterZ && game.global.world >= maxMapBonusZ); + doMaxMapBonus = (maxMapBonusZ >= 0 && game.global.mapBonus < getPageSetting("MaxMapBonuslimit") && game.global.world >= maxMapBonusZ); if (doMaxMapBonus) shouldDoMaps = true; - //Allow automaps to work with in-game Map at Zone option: - vanillaMapatZone = (game.options.menu.mapAtZone.enabled && game.options.menu.mapAtZone.setZone == game.global.world && !isActiveSpireAT()); - if (vanillaMapatZone) - shouldDoMaps = true; + //Maps + vanillaMapatZone = (game.options.menu.mapAtZone.enabled && game.global.canMapAtZone && !isActiveSpireAT() && !disActiveSpireAT()); + if (vanillaMapatZone) { + for (var x = 0; x < game.options.menu.mapAtZone.setZone.length; x++) { + if (game.global.world == game.options.menu.mapAtZone.setZone[x].world) + shouldDoMaps = true; + } + } - //Dynamic Siphonology section (when necessary) - //Lower Farming Zone = Lowers the zone used during Farming mode. Starts 10 zones below current and Finds the minimum map level you can successfully one-shot var siphlvl = shouldFarmLowerZone ? game.global.world - 10 : game.global.world - game.portal.Siphonology.level; var maxlvl = game.talents.mapLoot.purchased ? game.global.world - 1 : game.global.world; - maxlvl += extraMapLevels; // extraMapLevels : advanced slider - if (getPageSetting('DynamicSiphonology') || shouldFarmLowerZone){ + maxlvl += extraMapLevels; + if (getPageSetting('DynamicSiphonology') || shouldFarmLowerZone) { for (siphlvl; siphlvl < maxlvl; siphlvl++) { - //check HP vs damage and find how many siphonology levels we need. - var maphp = getEnemyMaxHealth(siphlvl) * 1.1; // 1.1 mod is for all maps (taken out of the function) - var cpthlth = getCorruptScale("health")/2; //get corrupted health mod + var maphp = getEnemyMaxHealth(siphlvl) * 1.1; + var cpthlth = getCorruptScale("health") / 2; if (mutations.Magma.active()) maphp *= cpthlth; - var mapdmg = ourBaseDamage2 * (game.unlocks.imps.Titimp ? 2 : 1); // *2 for titimp. (ourBaseDamage2 has no mapbonus in it) - if (game.upgrades.Dominance.done && !getPageSetting('ScryerUseinMaps2')) - mapdmg*=4; //dominance stance and not-scryer stance in maps. - if (mapdmg < maphp){ + var mapdmg = ourBaseDamage2; + if (game.upgrades.Dominance.done) + mapdmg *= 4; + if (mapdmg < maphp) { break; } } @@ -374,238 +398,259 @@ function autoMap() { for (var map in game.global.mapsOwnedArray) { if (!game.global.mapsOwnedArray[map].noRecycle) { obj[map] = game.global.mapsOwnedArray[map].level; - //Get matching map for our siphonology level - if(game.global.mapsOwnedArray[map].level == siphlvl) + if (game.global.mapsOwnedArray[map].level == siphlvl) siphonMap = map; } } - //Organize a list of the sorted map's levels and their index in the mapOwnedarray var keysSorted = Object.keys(obj).sort(function(a, b) { return obj[b] - obj[a]; }); - //if there are no non-unique maps, there will be nothing in keysSorted, so set to create a map var highestMap; - if (keysSorted[0]) + var lowestMap; + if (keysSorted[0]) { highestMap = keysSorted[0]; - else + lowestMap = keysSorted[keysSorted.length - 1]; + } else selectedMap = "create"; - //Look through all the maps we have and figure out, find and Run Uniques if we need to - var runUniques = (getPageSetting('AutoMaps')==1); + //Uniques + var runUniques = (getPageSetting('AutoMaps') > 0); + var AMUwall = (getPageSetting('AutoMaps') == 2 && getPageSetting('AMUwall') == true); + var AMUblock = (getPageSetting('AutoMaps') == 2 && getPageSetting('AMUblock') == true); + var AMUanger = (getPageSetting('AutoMaps') == 2 && getPageSetting('AMUanger') == true); + var AMUtrimple = (getPageSetting('AutoMaps') == 2 && getPageSetting('AMUtrimple') == true); + var AMUprison = (getPageSetting('AutoMaps') == 2 && getPageSetting('AMUprison') == true); + var AMUbw = (getPageSetting('AutoMaps') == 2 && getPageSetting('AMUbw') == true); + var AMUstar = (getPageSetting('AutoMaps') == 2 && getPageSetting('AMUstar') == true); + if (runUniques) { - for (var map in game.global.mapsOwnedArray) { - var theMap = game.global.mapsOwnedArray[map]; - if (theMap.noRecycle) { - if (theMap.name == 'The Wall' && game.upgrades.Bounty.allowed == 0 && !game.talents.bounty.purchased) { - var theMapDifficulty = Math.ceil(theMap.difficulty / 2); - if(game.global.world < 15 + theMapDifficulty) continue; - selectedMap = theMap.id; - break; - } - if (theMap.name == 'Dimension of Anger' && document.getElementById("portalBtn").style.display == "none" && !game.talents.portal.purchased) { - var theMapDifficulty = Math.ceil(theMap.difficulty / 2); - if(game.global.world < 20 + theMapDifficulty) continue; - selectedMap = theMap.id; - break; - } - var dont = game.global.runningChallengeSquared; - if(theMap.name == 'The Block' && !game.upgrades.Shieldblock.allowed && ((game.global.challengeActive == "Scientist" || game.global.challengeActive == "Trimp") && !dont || getPageSetting('BuyShieldblock'))) { - var theMapDifficulty = Math.ceil(theMap.difficulty / 2); - if(game.global.world < 11 + theMapDifficulty) continue; - selectedMap = theMap.id; - break; - } - var treasure = getPageSetting('TrimpleZ'); - if (theMap.name == 'Trimple Of Doom' && (!dont && (game.global.challengeActive == "Meditate" || game.global.challengeActive == "Trapper") && game.mapUnlocks.AncientTreasure.canRunOnce && game.global.world >= treasure)) { - var theMapDifficulty = Math.ceil(theMap.difficulty / 2); - if ((game.global.world < 33 + theMapDifficulty) || treasure > -33 && treasure < 33) continue; - selectedMap = theMap.id; - if (treasure < 0) // need to reset - setPageSetting('TrimpleZ', 0); - break; - } - if (!dont) { - //run the prison only if we are 'cleared' to run level 80 + 1 level per 200% difficulty. Could do more accurate calc if needed - if(theMap.name == 'The Prison' && (game.global.challengeActive == "Electricity" || game.global.challengeActive == "Mapocalypse")) { - var theMapDifficulty = Math.ceil(theMap.difficulty / 2); - if(game.global.world < 80 + theMapDifficulty) continue; - selectedMap = theMap.id; - break; - } - if(theMap.name == 'Bionic Wonderland' && game.global.challengeActive == "Crushed" ) { - var theMapDifficulty = Math.ceil(theMap.difficulty / 2); - if(game.global.world < 125 + theMapDifficulty) continue; - selectedMap = theMap.id; - break; - } - } - //Bionic Before Spire - mandates preReq of UniqueMaps. run Bionics before spire to farm. - if (getPageSetting('RunBionicBeforeSpire') && (game.global.world == 200) && theMap.name.includes('Bionic Wonderland')){ - //this is how to check if a bionic is green or not. - var bionicnumber = 1 + ((theMap.level - 125) / 15); - //if numbers match, map is green, so run it. (do the pre-requisite bionics one at a time in order) - if (bionicnumber == game.global.bionicOwned && bionicnumber < 6){ - selectedMap = theMap.id; - break; - } - if (shouldDoSpireMaps && theMap.name == 'Bionic Wonderland VI'){ - selectedMap = theMap.id; - break; - } - } //TODO Spire II+?? - //other unique maps here - } - } - } - -//VOIDMAPS: - //Only proceed if we needToVoid right now. + for (var map in game.global.mapsOwnedArray) { + var theMap = game.global.mapsOwnedArray[map]; + if (theMap.noRecycle) { + if (theMap.name == 'The Wall' && game.upgrades.Bounty.allowed == 0 && !game.talents.bounty.purchased) { + var theMapDifficulty = Math.ceil(theMap.difficulty / 2); + if (game.global.world < 15 + theMapDifficulty) continue; + selectedMap = theMap.id; + break; + } else if (theMap.name == 'The Wall' && AMUwall) { + var theMapDifficulty = Math.ceil(theMap.difficulty / 2); + if (game.global.world < 15 + theMapDifficulty) continue; + selectedMap = theMap.id; + break; + } + if (theMap.name == 'Dimension of Anger' && document.getElementById("portalBtn").style.display == "none" && !game.talents.portal.purchased) { + var theMapDifficulty = Math.ceil(theMap.difficulty / 2); + if (game.global.world < 20 + theMapDifficulty) continue; + selectedMap = theMap.id; + break; + } else if (theMap.name == 'Dimension of Anger' && AMUanger) { + var theMapDifficulty = Math.ceil(theMap.difficulty / 2); + if (game.global.world < 20 + theMapDifficulty) continue; + selectedMap = theMap.id; + break; + } + var runningC2 = game.global.runningChallengeSquared; + if (theMap.name == 'The Block' && !game.upgrades.Shieldblock.allowed && ((game.global.challengeActive == "Scientist" || game.global.challengeActive == "Trimp") && !runningC2 || getPageSetting('BuyShieldblock'))) { + var theMapDifficulty = Math.ceil(theMap.difficulty / 2); + if (game.global.world < 11 + theMapDifficulty) continue; + selectedMap = theMap.id; + break; + } else if (theMap.name == 'The Block' && AMUblock) { + var theMapDifficulty = Math.ceil(theMap.difficulty / 2); + if (game.global.world < 11 + theMapDifficulty) continue; + selectedMap = theMap.id; + break; + } + var treasure = getPageSetting('TrimpleZ'); + if (theMap.name == 'Trimple Of Doom' && (!runningC2 && game.mapUnlocks.AncientTreasure.canRunOnce && game.global.world >= treasure)) { + var theMapDifficulty = Math.ceil(theMap.difficulty / 2); + if ((game.global.world < 33 + theMapDifficulty) || treasure > -33 && treasure < 33) continue; + selectedMap = theMap.id; + if (treasure < 0) + setPageSetting('TrimpleZ', 0); + break; + } else if (theMap.name == 'Trimple Of Doom' && AMUtrimple) { + var theMapDifficulty = Math.ceil(theMap.difficulty / 2); + if (game.global.world < 33 + theMapDifficulty) continue; + selectedMap = theMap.id; + break; + } + if (!runningC2) { + if (theMap.name == 'The Prison' && (challengeActive("Electricity") || game.global.challengeActive == "Mapocalypse")) { + var theMapDifficulty = Math.ceil(theMap.difficulty / 2); + if (game.global.world < 80 + theMapDifficulty) continue; + selectedMap = theMap.id; + break; + } else if (theMap.name == 'The Prison' && AMUprison) { + var theMapDifficulty = Math.ceil(theMap.difficulty / 2); + if (game.global.world < 80 + theMapDifficulty) continue; + selectedMap = theMap.id; + break; + } + if (theMap.name == 'Bionic Wonderland' && game.global.challengeActive == "Crushed") { + var theMapDifficulty = Math.ceil(theMap.difficulty / 2); + if (game.global.world < 125 + theMapDifficulty) continue; + selectedMap = theMap.id; + break; + } else if (theMap.name == 'Bionic Wonderland' && AMUbw) { + var theMapDifficulty = Math.ceil(theMap.difficulty / 2); + if (game.global.world < 125 + theMapDifficulty) continue; + selectedMap = theMap.id; + break; + } + } + if (theMap.name == 'Imploding Star' && AMUstar) { + var theMapDifficulty = Math.ceil(theMap.difficulty / 2); + if (game.global.world < 170 + theMapDifficulty) continue; + selectedMap = theMap.id; + break; + } + } + } + } + + //Voids + if (getPageSetting('novmsc2') == true && game.global.runningChallengeSquared) { + needToVoid = false; + } + if (needToVoid) { - //voidArray: make an array with all our voidmaps, so we can sort them by real-world difficulty level var voidArray = []; - //values are easiest to hardest. (hardest has the highest value) - var prefixlist = {'Deadly':10, 'Heinous':11, 'Poisonous':20, 'Destructive':30}; + var prefixlist = { + 'Deadly': 10, + 'Heinous': 11, + 'Poisonous': 20, + 'Destructive': 30 + }; var prefixkeys = Object.keys(prefixlist); - var suffixlist = {'Descent':7.077, 'Void':8.822, 'Nightmare':9.436, 'Pit':10.6}; + var suffixlist = { + 'Descent': 7.077, + 'Void': 8.822, + 'Nightmare': 9.436, + 'Pit': 10.6 + }; var suffixkeys = Object.keys(suffixlist); - for (var map in game.global.mapsOwnedArray) { - var theMap = game.global.mapsOwnedArray[map]; - if(theMap.location == 'Void') { - for (var pre in prefixkeys) { - if (theMap.name.includes(prefixkeys[pre])) - theMap.sortByDiff = 1 * prefixlist[prefixkeys[pre]]; + + if (game.global.challengeActive != "Daily" && getPageSetting('onlystackedvoids') == true) { + for (var map in game.global.mapsOwnedArray) { + var theMap = game.global.mapsOwnedArray[map]; + if (theMap.location == 'Void' && theMap.stacked > 0) { + for (var pre in prefixkeys) { + if (theMap.name.includes(prefixkeys[pre])) + theMap.sortByDiff = 1 * prefixlist[prefixkeys[pre]]; + } + for (var suf in suffixkeys) { + if (theMap.name.includes(suffixkeys[suf])) + theMap.sortByDiff += 1 * suffixlist[suffixkeys[suf]]; + } + voidArray.push(theMap); } - for (var suf in suffixkeys) { - if (theMap.name.includes(suffixkeys[suf])) - theMap.sortByDiff += 1 * suffixlist[suffixkeys[suf]]; + } + } else { + for (var map in game.global.mapsOwnedArray) { + var theMap = game.global.mapsOwnedArray[map]; + if (theMap.location == 'Void') { + for (var pre in prefixkeys) { + if (theMap.name.includes(prefixkeys[pre])) + theMap.sortByDiff = 1 * prefixlist[prefixkeys[pre]]; + } + for (var suf in suffixkeys) { + if (theMap.name.includes(suffixkeys[suf])) + theMap.sortByDiff += 1 * suffixlist[suffixkeys[suf]]; + } + voidArray.push(theMap); } - voidArray.push(theMap); } } - //sort the array (harder/highvalue last): + var voidArraySorted = voidArray.sort(function(a, b) { return a.sortByDiff - b.sortByDiff; }); for (var map in voidArraySorted) { var theMap = voidArraySorted[map]; - //if we are on toxicity, don't clear until we will have max stacks at the last cell. - if(game.global.challengeActive == 'Toxicity' && game.challenges.Toxicity.stacks < (1500 - theMap.size)) break; doVoids = true; - //check to make sure we won't get 1-shot in nostance by boss + if (getPageSetting('novmsc2') == true && game.global.runningChallengeSquared) { + doVoids = false; + } var eAttack = getEnemyMaxAttack(game.global.world, theMap.size, 'Voidsnimp', theMap.difficulty); if (game.global.world >= 181 || (game.global.challengeActive == "Corrupted" && game.global.world >= 60)) eAttack *= (getCorruptScale("attack") / 2).toFixed(1); - //TODO: Account for magmated voidmaps. (not /2) - //TODO: Account for daily. - var ourHealth = baseHealth; - if(game.global.challengeActive == 'Balance') { - var stacks = game.challenges.Balance.balanceStacks ? (game.challenges.Balance.balanceStacks > theMap.size) ? theMap.size : game.challenges.Balance.balanceStacks : false; + if (challengeActive("Balance")) { eAttack *= 2; - if(stacks) { - for (i = 0; i < stacks; i++ ) { - ourHealth *= 1.01; - } - } - } - if(game.global.challengeActive == 'Toxicity') eAttack *= 5; - //break to prevent finishing map to finish a challenge? - //continue to check for doable map? - var diff = parseInt(getPageSetting('VoidCheck')) > 0 ? parseInt(getPageSetting('VoidCheck')) : 2; - var ourBlock = getBattleStats("block", true); //use block tooltip (after death block) instead of current army block. - if(ourHealth/diff < eAttack - ourBlock) { - shouldFarm = true; - voidCheckPercent = Math.round((ourHealth/diff)/(eAttack-ourBlock)*100); - abandonVoidMap(); //exit/restart if below <95% health, we have ForceAbandon on, and its not due to randomly losing anti stacks - break; } - else { - voidCheckPercent = 0; - if(getPageSetting('DisableFarm')) - shouldFarm = shouldFarm || false; + if (challengeActive("Toxicity")) { + eAttack *= 5; } - //only go into the voidmap if we need to. + if (getPageSetting('DisableFarm') <= 0) + shouldFarm = shouldFarm || false; if (!restartVoidMap) selectedMap = theMap.id; - //Restart the voidmap if we hit (100) nomstacks on the final boss - if(game.global.mapsActive && getCurrentMapObject().location == "Void" && game.global.challengeActive == "Nom" && getPageSetting('FarmWhenNomStacks7')) { - if(game.global.mapGridArray[theMap.size-1].nomStacks >= customVars.NomFarmStacksCutoff[2]) { + if (game.global.mapsActive && getCurrentMapObject().location == "Void" && challengeActive("Nom") && getPageSetting('FarmWhenNomStacks7')) { + if (game.global.mapGridArray[theMap.size - 1].nomStacks >= customVars.NomFarmStacksCutoff[2]) { mapsClicked(true); } } break; } } -//MAPS CREATION pt1: - //map if we don't have health/dmg or we need to clear void maps or if we are prestige mapping, and our set item has a new prestige available + + //Skip Spires + if (!preSpireFarming && getPageSetting('SkipSpires') == 1 && ((game.global.challengeActive != 'Daily' && isActiveSpireAT()) || (game.global.challengeActive == 'Daily' && disActiveSpireAT()))) { + enoughDamage = true; + enoughHealth = true; + shouldFarm = false; + shouldDoMaps = false; + } + + //Automaps if (shouldDoMaps || doVoids || needPrestige) { - //selectedMap = world here if we haven't set it to create yet, meaning we found appropriate high level map, or siphon map if (selectedMap == "world") { - //if preSpireFarming x minutes is true, switch over from wood maps to metal maps. if (preSpireFarming) { var spiremaplvl = (game.talents.mapLoot.purchased && MODULES["maps"].SpireFarm199Maps) ? game.global.world - 1 : game.global.world; - if (game.global.mapsOwnedArray[highestMap].level >= spiremaplvl && game.global.mapsOwnedArray[highestMap].location == ((customVars.preferGardens && game.global.decayDone) ? 'Plentiful' : 'Mountain')) - selectedMap = game.global.mapsOwnedArray[highestMap].id; - else - selectedMap = "create"; - //if needPrestige, TRY to find current level map as the highest level map we own. + selectedMap = "create"; + for (i = 0; i < keysSorted.length; i++) { + if (game.global.mapsOwnedArray[keysSorted[i]].level >= spiremaplvl && + game.global.mapsOwnedArray[keysSorted[i]].location == ((customVars.preferGardens && game.global.decayDone) ? 'Plentiful' : 'Mountain')) { + selectedMap = game.global.mapsOwnedArray[keysSorted[i]].id; + break; + } + } } else if (needPrestige || (extraMapLevels > 0)) { - if ((game.global.world + extraMapLevels) == game.global.mapsOwnedArray[highestMap].level) + if ((game.global.world + extraMapLevels) <= game.global.mapsOwnedArray[highestMap].level) selectedMap = game.global.mapsOwnedArray[highestMap].id; else selectedMap = "create"; - //if shouldFarm is true, use a siphonology adjusted map, as long as we aren't trying to prestige } else if (siphonMap != -1) selectedMap = game.global.mapsOwnedArray[siphonMap].id; - //if we dont' have an appropriate max level map, or a siphon map, we need to make one else selectedMap = "create"; } - //if selectedMap != world, it already has a map ID and will be run below } -//LEAD EVEN ZONE EXIT - //don't map on even worlds if on Lead Challenge, except if person is dumb and wants to void on even - if((game.global.challengeActive == 'Lead' && !challSQ) && !doVoids && (game.global.world % 2 == 0 || game.global.lastClearedCell < customVars.shouldFarmCell)) { - if(game.global.preMapsActive) + if ((challengeActive("Lead") && !challSQ) && !doVoids && (game.global.world % 2 == 0 || game.global.lastClearedCell < customVars.shouldFarmCell)) { + if (game.global.preMapsActive) mapsClicked(); - return; //exit + return; } -//REPEAT BUTTON: - //Repeat Button Management (inside a map): + if (!game.global.preMapsActive && game.global.mapsActive) { - //Set the repeatBionics flag (farm bionics before spire), for the repeat button management code. - var repeatBionics = getPageSetting('RunBionicBeforeSpire') && game.global.bionicOwned >= 6; - //if we are doing the right map, and it's not a norecycle (unique) map, and we aren't going to hit max map bonus - //or repeatbionics is true and there are still prestige items available to get - var doDefaultMapBonus = game.global.mapBonus < customVars.maxMapBonus-1; - if (selectedMap == game.global.currentMapId && (!getCurrentMapObject().noRecycle && (doDefaultMapBonus || vanillaMapatZone || doMaxMapBonus || shouldFarm || stackingTox || needPrestige || shouldDoSpireMaps) || repeatBionics)) { + var doDefaultMapBonus = game.global.mapBonus < getPageSetting('MaxMapBonuslimit') - 1; + if (selectedMap == game.global.currentMapId && (!getCurrentMapObject().noRecycle && (doDefaultMapBonus || vanillaMapatZone || doMaxMapBonus || shouldFarm || needPrestige || shouldDoSpireMaps))) { var targetPrestige = autoTrimpSettings.Prestige.selected; - //make sure repeat map is on if (!game.global.repeatMap) { repeatClicked(); } - //if we aren't here for dmg/hp, and we see the prestige we are after on the last cell of this map, and it's the last one available, turn off repeat to avoid an extra map cycle - if (!shouldDoMaps && (game.global.mapGridArray[game.global.mapGridArray.length - 1].special == targetPrestige && game.mapUnlocks[targetPrestige].last >= (game.global.world+extraMapLevels - 9 ))) { + if (!shouldDoMaps && (game.global.mapGridArray[game.global.mapGridArray.length - 1].special == targetPrestige && game.mapUnlocks[targetPrestige].last >= (game.global.world + extraMapLevels - 9))) { repeatClicked(); } - //avoid another map cycle due to having the amount of tox stacks we need. - if (stackingTox && (game.challenges.Toxicity.stacks + game.global.mapGridArray.length - (game.global.lastClearedMapCell + 1) >= 1500)){ - repeatClicked(); - } - //turn off repeat maps if we doing Watch maps. - if (shouldDoWatchMaps) - repeatClicked(); - //turn repeat off on the last WantHealth map. - if (shouldDoHealthMaps && game.global.mapBonus >= customVars.wantHealthMapBonus - 1) { + if (shouldDoHealthMaps && game.global.mapBonus >= getPageSetting('MaxMapBonushealth') - 1) { repeatClicked(); shouldDoHealthMaps = false; } - //turn repeat off on the last maxMapBonusAfterZ map. - if (doMaxMapBonus && game.global.mapBonus >= customVars.maxMapBonusAfterZ - 1) { + if (doMaxMapBonus && game.global.mapBonus >= getPageSetting('MaxMapBonuslimit') - 1) { repeatClicked(); doMaxMapBonus = false; } } else { - //otherwise, make sure repeat map is off if (game.global.repeatMap) { repeatClicked(); } @@ -613,148 +658,119 @@ function autoMap() { mapsClicked(true); } } -//FORCE EXIT WORLD->MAPS - //clicks the maps button, once or twice (inside the world): } else if (!game.global.preMapsActive && !game.global.mapsActive) { if (selectedMap != "world") { - //if we should not be in the world, and the button is not already clicked, click map button once (and wait patiently until death) - if (!game.global.switchToMaps){ + if (!game.global.switchToMaps) { mapsClicked(); } - //Get Impatient/Abandon if: (need prestige / _NEED_ to do void maps / on lead in odd world.) AND (a new army is ready, OR _need_ to void map OR lead farming and we're almost done with the zone) (handle shouldDoWatchMaps elsewhere below) - if ((!getPageSetting('PowerSaving') || (getPageSetting('PowerSaving') == 2) && doVoids) && game.global.switchToMaps && !shouldDoWatchMaps && + if ((!getPageSetting('PowerSaving') || (getPageSetting('PowerSaving') == 2) && doVoids) && game.global.switchToMaps && (needPrestige || doVoids || - ((game.global.challengeActive == 'Lead' && !challSQ) && game.global.world % 2 == 1) || - (!enoughDamage && enoughHealth && game.global.lastClearedCell < 9) || - (shouldFarm && game.global.lastClearedCell >= customVars.shouldFarmCell) || - (scryerStuck)) - && - ( - (game.resources.trimps.realMax() <= game.resources.trimps.owned + 1) - || ((game.global.challengeActive == 'Lead' && !challSQ) && game.global.lastClearedCell > 93) - || (doVoids && game.global.lastClearedCell > 93) - ) - ){ - //output stuck message + ((challengeActive("Lead") && !challSQ) && game.global.world % 2 == 1) || + (!enoughDamage && enoughHealth && game.global.lastClearedCell < 9) || + (shouldFarm && game.global.lastClearedCell >= customVars.shouldFarmCell) || + (scryerStuck)) && + ( + (game.resources.trimps.realMax() <= game.resources.trimps.owned + 1) || + ((challengeActive("Lead") && !challSQ) && game.global.lastClearedCell > 93) || + (doVoids && game.global.lastClearedCell > 70) + ) + ) { if (scryerStuck) { - debug("Got perma-stuck on cell " + (game.global.lastClearedCell+2) + " during scryer stance. Are your scryer settings correct? Entering map to farm to fix it."); + debug("Got perma-stuck on cell " + (game.global.lastClearedCell + 2) + " during scryer stance. Are your scryer settings correct? Entering map to farm to fix it."); } mapsClicked(); } } - //forcibly run watch maps (or click to restart voidmap?) - if (shouldDoWatchMaps) { - mapsClicked(); - } -//MAPS CREATION pt2: } else if (game.global.preMapsActive) { + var minFragmentsNeeded = Math.floor((((game.global.world / 150) * (Math.pow(1.14, game.global.world - 1))) * game.global.world * 2) * Math.pow((1.03 + (game.global.world / 50000)), game.global.world)) * 2; if (selectedMap == "world") { - mapsClicked(); //go back - } - else if (selectedMap == "create") { + mapsClicked(); + } else if (selectedMap == "create") { + if (game.global.selectedMapPreset > 1) selectAdvMapsPreset(1); var $mapLevelInput = document.getElementById("mapLevelInput"); $mapLevelInput.value = needPrestige ? game.global.world : siphlvl; - //choose spire level 199 or 200 if (preSpireFarming && MODULES["maps"].SpireFarm199Maps) $mapLevelInput.value = game.talents.mapLoot.purchased ? game.global.world - 1 : game.global.world; - var decrement; //['size','diff','loot'] - var tier; //taken from MODULES vars at the top of this file. - //instead of normal map locations, use Plentiful (Gardens) if the Decay challenge has been completed. (for +25% better loot) - var useGardens = (customVars.preferGardens && game.global.decayDone); + var decrement; + var tier; if (game.global.world >= customVars.MapTierZone[0]) { - //Zone 72+ (old: 9/9/9 Metal): tier = customVars.MapTier0Sliders; decrement = []; } else if (game.global.world >= customVars.MapTierZone[1]) { - //Zone 47-72 (old: 9/9/4 Metal): tier = customVars.MapTier1Sliders; decrement = ['loot']; } else if (game.global.world >= customVars.MapTierZone[2]) { - //Zone 16-47 (old: 9/9/0 Random): tier = customVars.MapTier2Sliders; decrement = ['loot']; } else { - //Zone 6-16 (old: 9/0/0 Random): tier = customVars.MapTier3Sliders; - decrement = ['diff','loot']; + decrement = ['diff', 'loot']; } - //NEW: start all maps off on 9/9/9 sliders and decrement from there. sizeAdvMapsRange.value = tier[0]; adjustMap('size', tier[0]); difficultyAdvMapsRange.value = tier[1]; adjustMap('difficulty', tier[1]); lootAdvMapsRange.value = tier[2]; adjustMap('loot', tier[2]); - biomeAdvMapsSelect.value = useGardens ? "Plentiful" : tier[3]; - //recalculate cost. + biomeAdvMapsSelect.value = autoTrimpSettings.mapselection.selected == "Gardens" ? "Plentiful" : autoTrimpSettings.mapselection.selected; updateMapCost(); - //if we are "Farming" for resources, make sure it's Plentiful OR metal (and always aim for lowest difficulty) - if(shouldFarm || !enoughDamage || !enoughHealth || game.global.challengeActive == 'Metal') { - biomeAdvMapsSelect.value = useGardens ? "Plentiful" : "Mountain"; + if (shouldFarm || challengeActive("Metal")) { + biomeAdvMapsSelect.value = game.global.decayDone ? "Plentiful" : "Mountain"; updateMapCost(); } - //set up various priorities for various situations if (updateMapCost(true) > game.resources.fragments.owned) { if (needPrestige && !enoughDamage) decrement.push('diff'); if (shouldFarm) decrement.push('size'); } - - //Decrement 1 - use priorities first: - //if we STILL cant afford the map, lower the loot slider (less loot) while (decrement.indexOf('loot') > -1 && lootAdvMapsRange.value > 0 && updateMapCost(true) > game.resources.fragments.owned) { lootAdvMapsRange.value -= 1; } - //default: if we can't afford the map: - //Put a priority on small size, and increase the difficulty? for high Helium that just wants prestige = yes. - //Really just trying to prevent prestige mapping from getting stuck while (decrement.indexOf('diff') > -1 && difficultyAdvMapsRange.value > 0 && updateMapCost(true) > game.resources.fragments.owned) { difficultyAdvMapsRange.value -= 1; } - //if we still cant afford the map, lower the size slider (make it larger) (doesn't matter much for farming.) while (decrement.indexOf('size') > -1 && sizeAdvMapsRange.value > 0 && updateMapCost(true) > game.resources.fragments.owned) { sizeAdvMapsRange.value -= 1; } - //Decrement 2 - if its still too expensive: - //if we STILL cant afford the map, lower the loot slider (less loot) while (lootAdvMapsRange.value > 0 && updateMapCost(true) > game.resources.fragments.owned) { lootAdvMapsRange.value -= 1; } - //default: if we can't afford the map: - //Put a priority on small size, and increase the difficulty? for high Helium that just wants prestige = yes. - //Really just trying to prevent prestige mapping from getting stuck while (difficultyAdvMapsRange.value > 0 && updateMapCost(true) > game.resources.fragments.owned) { difficultyAdvMapsRange.value -= 1; } - //if we still cant afford the map, lower the size slider (make it larger) (doesn't matter much for farming.) while (sizeAdvMapsRange.value > 0 && updateMapCost(true) > game.resources.fragments.owned) { sizeAdvMapsRange.value -= 1; } - - //run the Advanced Special Modifier script, bring if (getPageSetting('AdvMapSpecialModifier')) testMapSpecialModController(); - - //if we can't afford the map we designed, pick our highest existing map - //TODO Debug Output the mods we made. var maplvlpicked = parseInt($mapLevelInput.value) + (getPageSetting('AdvMapSpecialModifier') ? getExtraMapLevels() : 0); if (updateMapCost(true) > game.resources.fragments.owned) { - selectMap(game.global.mapsOwnedArray[highestMap].id); - debug("Can't afford the map we designed, #" + maplvlpicked , "maps", '*crying2'); - debug("...selected our highest map instead # " + game.global.mapsOwnedArray[highestMap].id + " Level: " + game.global.mapsOwnedArray[highestMap].level, "maps", '*happy2'); - runMap(); - lastMapWeWereIn = getCurrentMapObject(); - //if we can afford it, buy it and run it: + if (game.jobs.Explorer.owned > 0 || game.unlocks.imps.Flutimp == true) { + selectMap(game.global.mapsOwnedArray[highestMap].id); + debug("Can't afford the map we designed, #" + maplvlpicked, "maps", '*crying2'); + debug("...selected our highest map instead # " + game.global.mapsOwnedArray[highestMap].id + " Level: " + game.global.mapsOwnedArray[highestMap].level, "maps", '*happy2'); + runMap(); + lastMapWeWereIn = getCurrentMapObject(); + } else { + selectedMap == "world"; + } } else { debug("Buying a Map, level: #" + maplvlpicked, "maps", 'th-large'); var result = buyMap(); - if(result == -2){ + if (result == -2) { debug("Too many maps, recycling now: ", "maps", 'th-large'); recycleBelow(true); debug("Retrying, Buying a Map, level: #" + maplvlpicked, "maps", 'th-large'); - buyMap(); + result = buyMap(); + if (result == -2) { + recycleMap(lowestMap); + result = buyMap(); + if (result == -2) + debug("AutoMaps unable to recycle to buy map!"); + else + debug("Retrying map buy after recycling lowest level map"); + } } } - //if we already have a map picked, run it } else { selectMap(selectedMap); var themapobj = game.global.mapsOwnedArray[getMapIndex(selectedMap)]; @@ -765,141 +781,795 @@ function autoMap() { lastMapWeWereIn = getCurrentMapObject(); } } + + // Experience Challenge + if (game.global.challengeActive == "Experience" && getPageSetting('farmWonders')) { + var wondersFromZ = getPageSetting('maxExpZone'); + var wondersAmount = getPageSetting('wondersAmount'); + var wondersFloorZ = wondersFromZ - ((getPageSetting('wondersAmount') - 1) * 5); + var finishOnBw = (() => { + var pageSetting = getPageSetting('finishExpOnBw'); + pageSetting = pageSetting < 125 ? 125 : pageSetting; + pageSetting = pageSetting != -1 ? (Math.floor((pageSetting - 125) / 15) * 15) + 125 : -1; + return pageSetting; + })(); + var bionics = game.global.mapsOwnedArray + .filter((map) => map.location == "Bionic") + .sort((a, b) => b.level - a.level) + if (game.global.world >= game.challenges.Experience.nextWonder && + wondersAmount > game.challenges.Experience.wonders && + game.global.world >= wondersFloorZ) { + farmingWonder = true; + if (!game.global.mapsActive && game.global.mapsOwnedArray.filter(function(map) { + return map.level == game.global.world && map.location != 'Bionic'; + }).length >= 1) { + var mapID = game.global.mapsOwnedArray.find(function(map) { + return map.level == game.global.world && map.location != 'Bionic'; + }).id; + selectedMap = mapID; + selectMap(mapID); + runMap(); + } else if (!game.global.mapsActive) { + selectedMap = "create" + maplvlpicked = game.global.world + debug("Buying a Map, level: #" + maplvlpicked, "maps", 'th-large'); + mapsClicked(true) + var result = buyMap(); + if (result == -2) { + debug("Too many maps, recycling now: ", "maps", 'th-large'); + recycleBelow(true); + debug("Retrying, Buying a Map, level: #" + maplvlpicked, "maps", 'th-large'); + result = buyMap(); + if (result == -2) { + recycleMap(lowestMap); + result = buyMap(); + if (result == -2) + debug("AutoMaps unable to recycle to buy map!"); + else + debug("Retrying map buy after recycling lowest level map"); + } + } + } + } else if (game.global.world > 600 && !game.global.mapsActive && game.global.world != 700 && + wondersFromZ != -1 && game.global.world >= wondersFromZ && finishOnBw != -1) { + // Finish challenge with target BW. If for some reason we've raided past it, pick the lowest BW available. + // If we somehow did not raid for it, pick the highest available which will climb if necessary to 605. + // If at 700, clear the zone to complete instead. + farmingWonder = true; + var finishBw = bionics.find(map => map.level == finishOnBw); + if (finishBw) { + selectMap(finishBw.id); + } else { + if (bionics.every((map) => map.level > finishOnBw)) { + selectMap(bionics[bionics.length - 1].id); + } else { + selectMap(bionics[0].id); + } + } + runMap(); + } else { + farmingWonder = false; + selectedMap = "world"; + } + } } -//update the UI with stuff from automaps. -function updateAutoMapsStatus(get) { - //automaps status +//Radon +MODULES.maps.RMapTierZone = [72, 47, 16]; +MODULES.maps.RMapTier0Sliders = [9, 9, 9, "Mountain"]; +MODULES.maps.RMapTier1Sliders = [9, 9, 9, "Depths"]; +MODULES.maps.RMapTier2Sliders = [9, 9, 9, "Random"]; +MODULES.maps.RMapTier3Sliders = [9, 9, 9, "Random"]; +MODULES.maps.RshouldFarmCell = 59; +MODULES.maps.RSkipNumUnboughtPrestiges = 2; +MODULES.maps.RUnearnedPrestigesRequired = 2; + +function RupdateAutoMapsStatus(get) { + var status; - var minSp = getPageSetting('MinutestoFarmBeforeSpire'); - if(getPageSetting('AutoMaps') == 0) status = 'Off'; - else if (game.global.challengeActive == "Mapology" && game.challenges.Mapology.credits < 1) status = 'Out of Map Credits'; - else if (preSpireFarming) { - var secs = Math.floor(60 - (spireTime*60)%60).toFixed(0) - var mins = Math.floor(minSp - spireTime).toFixed(0); - var hours = minSp - (spireTime / 60).toFixed(2); - var spiretimeStr = (spireTime>=60) ? - (hours + 'h') : (mins + 'm:' + (secs>=10 ? secs : ('0'+secs)) + 's'); - status = 'Farming for Spire ' + spiretimeStr + ' left'; - } - else if (spireMapBonusFarming) status = 'Getting Spire Map Bonus'; - else if (doMaxMapBonus) status = 'Max Map Bonus After Zone'; - else if (!game.global.mapsUnlocked) status = ' '; - else if (needPrestige && !doVoids) status = 'Prestige'; - else if (doVoids && voidCheckPercent == 0) status = 'Void Maps: ' + game.global.totalVoidMaps + ' remaining'; - else if (stackingTox) status = 'Getting Tox Stacks'; - else if (needToVoid && !doVoids && game.global.totalVoidMaps > 0) status = 'Prepping for Voids'; - else if (doVoids && voidCheckPercent > 0) status = 'Farming to do Voids: ' + voidCheckPercent + '%'; - else if (shouldFarm && !doVoids) status = 'Farming: ' + HDratio.toFixed(4) + 'x'; - else if (scryerStuck) status = 'Scryer Got Stuck, Farming'; - else if (!enoughHealth && !enoughDamage) status = 'Want Health & Damage'; - else if (!enoughDamage) status = 'Want ' + HDratio.toFixed(4) + 'x  more damage'; - else if (!enoughHealth) status = 'Want more health'; - else if (enoughHealth && enoughDamage) status = 'Advancing'; - if (skippedPrestige) // Show skipping prestiges - status += '
Prestige Skipped'; + //Fail Safes + if (getPageSetting('RAutoMaps') == 0) status = 'Off'; + else if (!game.global.mapsUnlocked) status = 'Maps Locked'; - //hider he/hr% status - var getPercent = (game.stats.heliumHour.value() / (game.global.totalHeliumEarned - (game.global.heliumLeftover + game.resources.helium.owned)))*100; - var lifetime = (game.resources.helium.owned / (game.global.totalHeliumEarned-game.resources.helium.owned))*100; - var hiderStatus = 'He/hr: ' + getPercent.toFixed(3) + '%
   He: ' + lifetime.toFixed(3) +'%'; + //Status + else if (Rshouldcastle && game.global.totalVoidMaps <= 0) status = 'Frozen Castle'; + else if (contractVoid) status = 'Contract'; + else if (Rshouldshipfarm) status = 'Ship Farming'; + else if (Rshouldequipfarm) status = 'Equip Farming to ' + equipfarmdynamicHD().toFixed(2) + " and " + estimateEquipsForZone()[2] + " Equality"; + else if (Rshouldstormfarm) status = 'Storm Farming to ' + stormdynamicHD().toFixed(2); + else if (Rshouldinsanityfarm) status = 'Insanity Farming'; + else if (Rshouldalchfarm) status = 'Alchemy Farming'; + else if (Rshouldhypofarm) status = 'Hypo Farming'; + else if (Rshouldmayhem == 1) status = 'Mayhem Attack'; + else if (Rshouldmayhem == 2) status = 'Mayhem Health'; + else if (Rshouldpanda) status = 'Pandemonium'; + else if (Rshoulddesofarm) status = 'Deso Farming to ' + desodynamicHD().toFixed(2); + else if (Rshoulddopraid) status = 'Praiding'; + else if (Rdshoulddopraid) status = 'Daily Praiding'; + else if (Rshoulddoquest) status = 'Questing'; + else if (Rshouldtimefarm) status = 'Time Farming'; + else if (Rdshouldtimefarm) status = 'Daily Time Farming'; + else if (Rshouldsmithyfarm) status = 'Smithy Farming'; + else if (Rshouldtributefarm) status = 'Tribute Farming'; + else if (Rshoulddobogs) status = 'Black Bogs'; + else if (RdoMaxMapBonus) status = 'Max Map Bonus After Zone'; + else if (RvanillaMAZ) status = 'Vanilla MAZing'; + else if (!game.global.mapsUnlocked) status = ' '; + else if (RneedPrestige && !RdoVoids) status = 'Prestige'; + else if (RdoVoids) { + var stackedMaps = Fluffy.isRewardActive('void') ? countStackedVoidMaps() : 0; + status = 'Void Maps: ' + game.global.totalVoidMaps + ((stackedMaps) ? " (" + stackedMaps + " stacked)" : "") + ' remaining'; + } else if (RshouldFarm && !RdoVoids) status = 'Farming: ' + RcalcHDratio().toFixed(4) + 'x'; + else if (!RenoughHealth && !RenoughDamage) status = 'Want Health & Damage'; + else if (!RenoughDamage) status = 'Want ' + RcalcHDratio().toFixed(4) + 'x  more damage'; + else if (!RenoughHealth) status = 'Want more health'; + else if (RenoughHealth && RenoughDamage) status = 'Advancing'; + + var getPercent = (game.stats.heliumHour.value() / (game.global.totalRadonEarned - (game.global.radonLeftover + game.resources.radon.owned))) * 100; + var lifetime = (game.resources.radon.owned / (game.global.totalRadonEarned - game.resources.radon.owned)) * 100; + var hiderStatus = 'Rn/hr: ' + getPercent.toFixed(3) + '%
   Rn: ' + lifetime.toFixed(3) + '%'; if (get) { - return [status,getPercent,lifetime]; + return [status, getPercent, lifetime]; } else { document.getElementById('autoMapStatus').innerHTML = status; document.getElementById('hiderStatus').innerHTML = hiderStatus; } } +//RAutoMaps -//New Code for Map Special Mods dropdown. (only the first dropdown for now) -// -//PLAN: -//1. lmc when you can afford it, or cycle down the list sequentially until one can be afforded. -//2. prestigious when you need prestiges, -//NEW IDEA: -//+lmc when you need more lvls in your eq -//+perfect sliders when you can afford it -// another valid idea is burn out all your frags on perfect nearthe end i guess -//Automaps: Map Special Modifier Selector Decider Magical Action Taker -//TODO: a priority list? Which is more important, perfect slide, LMC or the +x value? +function RautoMap() { -MODULES["maps"].advSpecialMapMod_numZones = 3; //The default amount of +x zones you try to skip and work backwards from there. (if its too hard you will fail the map there is no dmg check only cost yet) -var advExtraMapLevels = 0; -function testMapSpecialModController() { - //var mapSpecialMods = ["Fast Attacks", "Large Cache", "Small Savory Cache", "Small Wooden Cache", "Small Metal Cache", "Prestigious", "Huge Cache", "Large Savory Cache", "Large Wooden Cache", "Large Metal Cache"]; - var mapSpecialMods=[]; - Object.keys(mapSpecialModifierConfig).forEach(function(key){ - var elem = mapSpecialModifierConfig[key]; - if ((game.global.highestLevelCleared + 1) >= elem.unlocksAt) - mapSpecialMods.push(elem.name); - }); - if (mapSpecialMods.length < 1) - return; //nothing to do. - //try to use the highest one we have. - var maxIndex = mapSpecialMods.length; - var $advSpecialMod = document.getElementById('advSpecialSelect'); - if (!$advSpecialMod) + //Failsafes + if (!game.global.mapsUnlocked || RcalcOurDmg("avg", false, true) <= 0) { + RenoughDamage = true; + RenoughHealth = true; + RshouldFarm = false; + RupdateAutoMapsStatus(); return; - if (game.global.highestLevelCleared >= 59) { - if (needPrestige) - maxIndex=6; - //Set the special mod to some max. - $advSpecialMod.selectedIndex = maxIndex; - if ($advSpecialMod.selectedIndex == 0) - return; - //Check Hyperspeed 2 or Fast Attacks - if (!needPrestige && game.talents.hyperspeed2.purchased && (game.global.world > Math.floor((game.global.highestLevelCleared + 1) * 0.5))) - $advSpecialMod.selectedIndex=1; - else if (needPrestige) - $advSpecialMod.selectedIndex=0; - if (game.global.mapExtraBonus != "fa" && $advSpecialMod.selectedIndex==1) ; - //map frag cost is stored in: document.getElementById("mapCostFragmentCost").innerHTML - var mc = updateMapCost(true); - var my = game.resources.fragments.owned; - var pct = mc/my*100; - while ($advSpecialMod.selectedIndex > 0 && mc > my) { - $advSpecialMod.selectedIndex -= 1; - } - var mc = updateMapCost(true); - var my = game.resources.fragments.owned; - var pct = mc/my*100; - if ($advSpecialMod.value != "0") //if its 0 it fails { - console.log("Set the map special modifier to: " + mapSpecialModifierConfig[$advSpecialMod.value].name + ". Cost: " + pct.toFixed(2) + "% of your fragments."); - } - //TODO: - var specialMod = getSpecialModifierSetting(); //either 0 or the abbreviation/property of mapSpecialModifierConfig - var perfectAllowed = (game.global.highestLevelCleared >= 109); //levels are 109 and 209 for Perfect sliders and Extra Levels - var perfectChecked = checkPerfectChecked(); //Perfect Checkboxes - var $advPerfect = document.getElementById('advPerfectCheckbox'); - var extraMapLevels = getPageSetting('AdvMapSpecialModifier') ? getExtraMapLevels() : 0; //Extra Levels - - //Set the extra level to max ( 3 ) - var extraAllowed = (game.global.highestLevelCleared >= 209); - if (extraAllowed) { - var $advExtraLevel = document.getElementById('advExtraMapLevelselect'); - if (!$advExtraLevel) - return; - var maplvlpicked = document.getElementById("mapLevelInput").value; - if (maplvlpicked == game.global.world) //then the +x zones dropdown is open. - $advExtraLevel.selectedIndex=MODULES["maps"].advSpecialMapMod_numZones; - else - $advExtraLevel.selectedIndex = 0; - while ($advExtraLevel.selectedIndex > 0 && (updateMapCost(true) > game.resources.fragments.owned)) { - $advExtraLevel.selectedIndex -= 1; + } + + //Calc + var ourBaseDamage = RcalcOurDmg("avg", false, true); + var ourBaseHealth = RcalcOurHealth(); + var enemyDamage = RcalcBadGuyDmg(null, RgetEnemyMaxAttack(game.global.world, 50, 'Snimp', 1.0)); + var mapenoughdamagecutoff = getPageSetting("Rmapcuntoff"); + + if (getPageSetting('RDisableFarm') > 0) { + RshouldFarm = (RcalcHDratio() >= getPageSetting('RDisableFarm')); + if (game.options.menu.repeatUntil.enabled == 1 && RshouldFarm) + toggleSetting('repeatUntil'); + } + var hitsSurvived = 10; + if (getPageSetting("Rhitssurvived") > 0) hitsSurvived = getPageSetting("Rhitssurvived"); + RenoughHealth = (ourBaseHealth > (hitsSurvived * enemyDamage)); + RenoughDamage = (RcalcHDratio() <= mapenoughdamagecutoff); + + RupdateAutoMapsStatus(); + + //Map Options + var customVars = MODULES["maps"]; + if (game.global.repeatMap == true && !game.global.mapsActive && !game.global.preMapsActive) repeatClicked(); + if ((game.options.menu.repeatUntil.enabled == 1 || game.options.menu.repeatUntil.enabled == 2 || game.options.menu.repeatUntil.enabled == 3) && !game.global.mapsActive && !game.global.preMapsActive) toggleSetting('repeatUntil'); + if (game.options.menu.exitTo.enabled != 0) toggleSetting('exitTo'); + if (game.options.menu.repeatVoids.enabled != 0) toggleSetting('repeatVoids'); + + //Void Vars + var voidMapLevelSetting = 0; + var voidMapLevelSettingCell = ((getPageSetting('Rvoidscell') > 0) ? getPageSetting('Rvoidscell') : 70); + var voidMapLevelPlus = 0; + if (game.global.challengeActive != "Daily" && getPageSetting('RVoidMaps') > 0) { + voidMapLevelSetting = getPageSetting('RVoidMaps'); + } + if (game.global.challengeActive == "Daily" && getPageSetting('RDailyVoidMod') >= 1) { + voidMapLevelSetting = getPageSetting('RDailyVoidMod'); + } + if (getPageSetting('RRunNewVoidsUntilNew') != 0 && game.global.challengeActive != "Daily") { + voidMapLevelPlus = getPageSetting('RRunNewVoidsUntilNew'); + } + if (getPageSetting('RdRunNewVoidsUntilNew') != 0 && game.global.challengeActive == "Daily") { + voidMapLevelPlus = getPageSetting('RdRunNewVoidsUntilNew'); + } + + RneedToVoid = (voidMapLevelSetting > 0 && game.global.totalVoidMaps > 0 && game.global.lastClearedCell + 1 >= voidMapLevelSettingCell && + ( + (game.global.world == voidMapLevelSetting) || + (voidMapLevelPlus < 0 && game.global.world >= voidMapLevelSetting) || + (voidMapLevelPlus > 0 && game.global.world >= voidMapLevelSetting && game.global.world <= (voidMapLevelSetting + voidMapLevelPlus)) + ) + ); + + var voidArrayDoneS = []; + if (game.global.challengeActive != "Daily" && getPageSetting('Ronlystackedvoids') == true) { + for (var mapz in game.global.mapsOwnedArray) { + var theMapz = game.global.mapsOwnedArray[mapz]; + if (theMapz.location == 'Void' && theMapz.stacked > 0) { + voidArrayDoneS.push(theMapz); + } } } -} -function mapTimeEstimater() { - //Check our graph history and - Estimate = The zone should take around this long in milliseconds. - var thiszone = lookUpZoneData(game.global.world); - var lastzone = lookUpZoneData(game.global.world-1); - if (thiszone && lastzone) - mapTimeEstimate = thiszone.currentTime - lastzone.currentTime; - else - mapTimeEstimate = 0; - return mapTimeEstimate; + if ( + (game.global.totalVoidMaps <= 0) || + (!RneedToVoid) || + (getPageSetting('Rnovmsc2') == true && game.global.runningChallengeSquared) || + (game.global.challengeActive != "Daily" && game.global.totalVoidMaps > 0 && getPageSetting('Ronlystackedvoids') == true && voidArrayDoneS.length < 1) + ) { + RdoVoids = false; + } + + //Contract + if (autoBattle.activeContract != '') { + if (getPageSetting('RABsolve') == true && contractVoid) { + RneedToVoid = true; + RdoVoids = true; + } + } + + //Quest + var Rquestfarming = false; + Rshoulddoquest = false; + Rquestfarming = (game.global.world > 5 && game.global.challengeActive == "Quest" && questcheck() > 0); + + if (Rquestfarming) { + if (questcheck() == 3) Rshoulddoquest = 3; + else if (questcheck() == 4 && RcalcHDratio() > 0.95 && (((new Date().getTime() - game.global.zoneStarted) / 1000 / 60) < 121)) Rshoulddoquest = 4; + else if (questcheck() == 6) Rshoulddoquest = 6; + else if (questcheck() == 7 && !canAffordBuilding('Smithy')) Rshoulddoquest = 7; + else if (questcheck() == 10 || questcheck() == 20) Rshoulddoquest = 10; + else if (questcheck() == 11 || questcheck() == 21) Rshoulddoquest = 11; + else if (questcheck() == 12 || questcheck() == 22) Rshoulddoquest = 12; + else if (questcheck() == 13 || questcheck() == 23) Rshoulddoquest = 13; + else if (questcheck() == 14 || questcheck() == 24) Rshoulddoquest = 14; + } + + //Quest Shield + if (game.global.world < 6 && (Rquestshieldzone != 0 || Rquestequalityscale != false)) { + Rquestshieldzone = 0; + Rquestequalityscale = false; + } + if (Rquestfarming && questcheck() == 5 && ((game.global.soldierEnergyShieldMax / enemyDamage) < RcalcHDratio()) && game.portal.Equality.scalingActive && !game.global.mapsActive) { + toggleEqualityScale(); + Rquestshieldzone = game.global.world; + Rquestequalityscale = true; + } + if (game.global.world > 5 && game.global.challengeActive == "Quest" && Rquestshieldzone > 0 && !game.portal.Equality.scalingActive && game.global.world > Rquestshieldzone && Rquestequalityscale) { + toggleEqualityScale(); + Rquestequalityscale = false; + } + + //### Map Modules found in mapfunctions.js + + //Farming + var selectedMap = "world"; + + RshouldDoMaps = false; + Rshouldfragfarm = false; + Rshouldtimefarm = false; + Rdshouldtimefarm = false; + Rshouldsmithyfarm = false; + Rshouldtributefarm = false; + Rshoulddobogs = false; + Rshoulddopraid = false; + Rdshoulddopraid = false; + Rshouldinsanityfarm = false; + Rshouldalchfarm = false; + Rshouldhypofarm = false; + Rhyposhouldwood = true; + Rshouldstormfarm = false; + Rshoulddesofarm = false; + Rshouldequipfarm = false; + Rshouldshipfarm = false; + contractVoid = false; + Rshouldmayhem = 0; + Rshouldpanda = false; + RvanillaMAZ = false; + + if (ourBaseDamage > 0) { + RshouldDoMaps = (!RenoughDamage || RshouldFarm); + } + var shouldDoHealthMaps = false; + if (game.global.mapBonus >= getPageSetting('RMaxMapBonuslimit') && !RshouldFarm) + RshouldDoMaps = false; + else if (game.global.mapBonus < getPageSetting('RMaxMapBonushealth') && !RenoughHealth && !RshouldDoMaps) { + RshouldDoMaps = true; + shouldDoHealthMaps = true; + } + var restartVoidMap = false; + + //Map Bonus + var maxMapBonusZ = getPageSetting('RMaxMapBonusAfterZone'); + RdoMaxMapBonus = (maxMapBonusZ >= 0 && game.global.mapBonus < getPageSetting("RMaxMapBonuslimit") && game.global.world >= maxMapBonusZ); + if (RdoMaxMapBonus) { + RshouldDoMaps = true; + } + + //MAZ + if (game.options.menu.mapAtZone.enabled && game.global.canMapAtZone) { + var nextCell = game.global.lastClearedCell; + if (nextCell == -1) nextCell = 1; + else nextCell += 2; + var totalPortals = getTotalPortals(); + let setZone = game.options.menu.mapAtZone.getSetZone(); + for (var x = 0; x < setZone.length; x++) { + if (!setZone[x].on) continue; + if (game.global.world < setZone[x].world || game.global.world > setZone[x].through) continue; + if (game.global.preMapsActive && setZone[x].done == totalPortals + "_" + game.global.world + "_" + nextCell) continue; + if (setZone[x].times === -1 && game.global.world !== setZone[x].world) continue; + if (setZone[x].times > 0 && (game.global.world - setZone[x].world) % setZone[x].times !== 0) continue; + if (setZone[x].cell === game.global.lastClearedCell + 2) { + RvanillaMAZ = true; + if (setZone[x].until == 6) game.global.mapCounterGoal = 25; + if (setZone[x].until == 7) game.global.mapCounterGoal = 50; + if (setZone[x].until == 8) game.global.mapCounterGoal = 100; + if (setZone[x].until == 9) game.global.mapCounterGoal = setZone[x].rx; + break; + } + } + + //Toggle void repeat on if it's disabled. + if (RvanillaMAZ) { + if (game.options.menu.repeatVoids.enabled != 1) toggleSetting('repeatVoids'); + return RupdateAutoMapsStatus(); + } + } + + //Time Farm + if (getPageSetting('Rtimefarm') || (game.global.challengeActive == 'Daily' && getPageSetting('Rdtimefarm') == 2)) { + RtimeFarm(true, false, false, false, false); + } + + //dTime Farm + if (game.global.challengeActive == 'Daily' && getPageSetting('Rdtimefarm') == 1) { + RtimeFarm(true, false, false, false, true); + } + + //Smithy Farm + if (getPageSetting('Rsmithyfarm')) { + RsmithyFarm(false); + } + + //Tribute Farm + if (getPageSetting('Rtributefarm')) { + RtributeFarm(true, false, false, false); + } + + //Bogs + if (game.global.world > 5 && (game.global.challengeActive == "Quagmire" && getPageSetting('Rblackbog') == true && getPageSetting('Rblackbogzone')[0] > 0 && getPageSetting('Rblackbogamount')[0] > 0)) { + Rbogs(); + } + + //Praid + var Rdopraid = false; + Rdopraid = (game.global.world > 5 && (((getPageSetting('RAMPraid') == true) || (game.global.challengeActive == "Daily" && getPageSetting('RdAMPraid') == 2)) && getPageSetting('RAMPraidzone')[0] > 0 && getPageSetting('RAMPraidraid')[0] > 0)); + if (game.global.challengeActive == 'Daily' && getPageSetting('RdAMPraid') != 2) { + Rdopraid = false; + } + if (Rdopraid) { + RPraid(false); + } + if (!Rshoulddopraid && (RAMPrepMap1 != undefined || RAMPrepMap2 != undefined || RAMPrepMap3 != undefined || RAMPrepMap4 != undefined || RAMPrepMap5 != undefined)) { + RAMPreset(false); + } + + //dPraid + var Rddopraid = false; + Rddopraid = (game.global.challengeActive == "Daily" && game.global.world > 5 && (getPageSetting('RdAMPraid') == 1 && getPageSetting('RdAMPraidzone')[0] > 0 && getPageSetting('RdAMPraidraid')[0] > 0)); + if (Rddopraid) { + RPraid(true); + } + if (!Rdshoulddopraid && (RdAMPrepMap1 != undefined || RdAMPrepMap2 != undefined || RdAMPrepMap3 != undefined || RdAMPrepMap4 != undefined || RdAMPrepMap5 != undefined)) { + RAMPreset(true); + } + + //Mayhem + if (game.global.challengeActive == "Mayhem") { + var Rdomayhem = false; + Rdomayhem = (game.global.world > 5 && game.global.challengeActive == "Mayhem" && getPageSetting('Rmayhemon') == true && (getPageSetting('Rmayhemhealth') == true || getPageSetting('Rmayhemattack') == true)); + if (Rdomayhem) { + Rmayhem(); + } + } + + //Panda + if (game.global.challengeActive == "Pandemonium") { + var Rdopanda = false; + Rdopanda = (game.global.world >= getPageSetting('Rpandazone') && game.global.challengeActive == "Pandemonium" && getPageSetting('Rpandaon') == true); + if (Rdopanda && game.challenges.Pandemonium.pandemonium > 0 && getPageSetting('Rpandamaps') == true) { + Rshouldpanda = true; + } + } + + //Insanity + if (game.global.challengeActive == "Insanity") { + var insanityfarmzone = getPageSetting('Rinsanityfarmzone'); + var insanitystacksfarmindex = insanityfarmzone.indexOf(game.global.world); + var insanityfarmcell = ((getPageSetting('Rinsanityfarmcell') != 0) ? getPageSetting('Rinsanityfarmcell')[insanitystacksfarmindex] : 1); + Rinsanityfarm = (getPageSetting('Rinsanityon') == true && ((insanityfarmcell <= 1) || (insanityfarmcell > 1 && (game.global.lastClearedCell + 1) >= insanityfarmcell)) && game.global.world > 5 && (game.global.challengeActive == "Insanity" && getPageSetting('Rinsanityfarmzone')[0] > 0 && getPageSetting('Rinsanityfarmstack')[0] > 0)); + if (Rinsanityfarm) { + Rinsanity(true, false, false); + } + Rinsanity(false, false, true); + } + + //Storm + if (game.global.challengeActive == "Storm") { + Rstormfarm = (getPageSetting('Rstormon') == true && game.global.world > 5 && (game.global.challengeActive == "Storm" && getPageSetting('Rstormzone') > 0 && getPageSetting('RstormHD') > 0 && getPageSetting('Rstormmult') > 0)); + if (Rstormfarm) { + Rstorm(true); + } + } + + //Desolation + if (game.global.challengeActive == "Desolation") { + Rdesofarm = (getPageSetting('Rdesoon') == true && game.global.world > 5 && (game.global.challengeActive == "Desolation" && getPageSetting('Rdesozone') > 0 && getPageSetting('RdesoHD') > 0 && getPageSetting('Rdesomult') > 0)); + if (Rdesofarm) { + Rdeso(true); + } + } + + //Ship + if (game.jobs.Worshipper.locked == 0) { + var shipfarmcell = ((getPageSetting('Rshipfarmcell') > 0) ? getPageSetting('Rshipfarmcell') : 1); + Rshipfarm = (game.jobs.Worshipper.locked == 0 && getPageSetting('Rshipfarmon') == true && ((shipfarmcell <= 1) || (shipfarmcell > 1 && (game.global.lastClearedCell + 1) >= shipfarmcell)) && game.global.world > 5 && (getPageSetting('Rshipfarmzone')[0] > 0 && getPageSetting('Rshipfarmamount')[0] > 0)); + if (Rshipfarm) { + Rship(true, false, false); + } + Rship(false, false, true); + } + //Alch + if (game.global.challengeActive == "Alchemy") { + var alchfarmzone = getPageSetting('Ralchfarmzone'); + var alchstacksfarmindex = alchfarmzone.indexOf(game.global.world); + var alchfarmcell = ((getPageSetting('Ralchfarmcell') != 0) ? getPageSetting('Ralchfarmcell')[alchstacksfarmindex] : 1); + Ralchfarm = (getPageSetting('Ralchon') == true && ((alchfarmcell <= 1) || (alchfarmcell > 1 && (game.global.lastClearedCell + 1) >= alchfarmcell)) && game.global.world > 5 && (game.global.challengeActive == "Alchemy" && getPageSetting('Ralchfarmzone')[0] > 0 && getPageSetting('Ralchfarmstack').length > 0)); + if (Ralchfarm) { + Ralch(true, false, false); + } + Ralch(false, false, true); + } + + //Hypo + Rshouldcastle = false; + if (game.global.challengeActive == "Hypothermia") { + if (game.global.world >= getPageSetting('Rhypocastle')) { + Rshouldcastle = true; + } + var hypofarmzone = getPageSetting('Rhypofarmzone'); + var hypoamountfarmindex = hypofarmzone.indexOf(game.global.world); + var hypofarmcell = ((getPageSetting('Rhypofarmcell') != 0) ? getPageSetting('Rhypofarmcell')[hypoamountfarmindex] : 1); + Rhypofarm = (getPageSetting('Rhypoon') == true && ((hypofarmcell <= 1) || (hypofarmcell > 1 && (game.global.lastClearedCell + 1) >= hypofarmcell)) && game.global.world > 5 && (game.global.challengeActive == "Hypothermia" && getPageSetting('Rhypofarmzone')[0] > 0 && getPageSetting('Rhypofarmstack').length > 0)); + if (Rhypofarm) { + Rhypo(true, false, false); + } + Rhypo(false, false, true); + } + + //Equip Farming + Requipfarm = (getPageSetting('Requipfarmon') == true && game.global.world > 5 && (getPageSetting('Requipfarmzone') > 0 && getPageSetting('RequipfarmHD') > 0 && getPageSetting('Requipfarmmult') > 0)); + if (Requipfarm) { + var equipfarmzone = getPageSetting('Requipfarmzone'); + var metal = game.resources.metal.owned + var metalneeded = estimateEquipsForZone()[0]; + + if (game.global.world >= equipfarmzone && metal < metalneeded) { + Rshouldequipfarm = true; + } + } + + //### Map selection section + + //Map Selection + var obj = {}; + for (var map in game.global.mapsOwnedArray) { + if (!game.global.mapsOwnedArray[map].noRecycle) { + obj[map] = game.global.mapsOwnedArray[map].level; + } + } + var keysSorted = Object.keys(obj).sort(function(a, b) { + return obj[b] - obj[a]; + }); + var highestMap; + var lowestMap; + if (keysSorted[0]) { + highestMap = keysSorted[0]; + lowestMap = keysSorted[keysSorted.length - 1]; + } else + selectedMap = "create"; + + //### Specific maps that take priority over everything else that can be found in mapfunctions.js + + //Uniques + var runUniques = (getPageSetting('RAutoMaps') == 1); + if (runUniques || Rshoulddobogs || Rshouldcastle) { + for (var map in game.global.mapsOwnedArray) { + var theMap = game.global.mapsOwnedArray[map]; + if (Rshoulddobogs && theMap.name == 'The Black Bog') { + selectedMap = theMap.id; + break; + } else if (runUniques && theMap.noRecycle) { + if (theMap.name == 'Big Wall' && !game.upgrades.Bounty.allowed && !game.upgrades.Bounty.done && game.global.highestRadonLevelCleared < 40) { + if (game.global.world < 8 && RcalcHDratio() > 4) continue; + selectedMap = theMap.id; + break; + } + if (theMap.name == 'Dimension of Rage' && document.getElementById("portalBtn").style.display == "none" && game.upgrades.Rage.done == 1) { + if (game.global.challenge != "Unlucky" && (game.global.world < 16 || RcalcHDratio() < 2)) continue; + selectedMap = theMap.id; + break; + } + if (getPageSetting('Rprispalace') == true && theMap.name == 'Prismatic Palace' && game.mapUnlocks.Prismalicious.canRunOnce) { + if (game.global.world < 21 || RcalcHDratio() > 25) continue; + selectedMap = theMap.id; + break; + } + var meltingpoint = [10000, 10000]; + if (getPageSetting('Rmeltpoint')[0] > 0 && getPageSetting('Rmeltpoint')[1] >= 0) meltingpoint = getPageSetting('Rmeltpoint'); + if (theMap.name == 'Melting Point' && ((game.global.challengeActive == "Trappapalooza" && game.global.world >= meltingpoint[0] && ((game.global.lastClearedCell + 1) >= meltingpoint[1])) || (game.global.challengeActive == "Melt" && game.global.world >= meltingpoint[0] && ((game.global.lastClearedCell + 1) >= meltingpoint[1])) || (getPageSetting('Rmeltsmithy') > 0 && getPageSetting('Rmeltsmithy') <= game.buildings.Smithy.owned && game.mapUnlocks.SmithFree.canRunOnce))) { + if (game.global.world < 50 || (game.global.world == 50 && game.global.lastClearedCell < 55)) continue; + selectedMap = theMap.id; + break; + } + if (game.global.challengeActive == "Hypothermia" && getPageSetting('Rhypocastle') > 0 && theMap.name == 'Frozen Castle' && game.global.world >= getPageSetting('Rhypocastle')) { + if (getPageSetting('Rhypovoids') == true && game.global.totalVoidMaps <= 0) { + selectedMap = theMap.id; + break; + } + if (getPageSetting('Rhypovoids') == false) { + selectedMap = theMap.id; + break; + } + } + if (game.global.challengeActive != "Hypothermia" && getPageSetting('Rfrozencastle') != -1 && theMap.name == 'Frozen Castle' && game.global.world >= getPageSetting('Rfrozencastle')[0] && ((game.global.lastClearedCell + 1) >= getPageSetting('Rfrozencastle')[1])) { + selectedMap = theMap.id; + break; + } + } + } + } + + //Voids + if (RneedToVoid) { + var voidArray = []; + var prefixlist = { + 'Deadly': 10, + 'Heinous': 11, + 'Poisonous': 20, + 'Destructive': 30 + }; + var prefixkeys = Object.keys(prefixlist); + var suffixlist = { + 'Descent': 7.077, + 'Void': 8.822, + 'Nightmare': 9.436, + 'Pit': 10.6 + }; + var suffixkeys = Object.keys(suffixlist); + + for (var map in game.global.mapsOwnedArray) { + var theMap = game.global.mapsOwnedArray[map]; + if (theMap.location == 'Void') { + for (var pre in prefixkeys) { + if (theMap.name.includes(prefixkeys[pre])) + theMap.sortByDiff = 1 * prefixlist[prefixkeys[pre]]; + } + for (var suf in suffixkeys) { + if (theMap.name.includes(suffixkeys[suf])) + theMap.sortByDiff += 1 * suffixlist[suffixkeys[suf]]; + } + voidArray.push(theMap); + } + } + + var voidArraySorted = voidArray.sort(function(a, b) { + return a.sortByDiff - b.sortByDiff; + }); + for (var map in voidArraySorted) { + var theMap = voidArraySorted[map]; + RdoVoids = true; + if (getPageSetting('RDisableFarm') <= 0) + RshouldFarm = RshouldFarm || false; + if (!restartVoidMap) + selectedMap = theMap.id; + break; + } + } + + //### Automaps automatic part + + //Raiding - split off from the rest to make it easier + if (Rshoulddopraid) { + if (selectedMap == "world") { + selectedMap = "createp"; + } + } + + if (Rdshoulddopraid) { + if (selectedMap == "world") { + selectedMap = "dcreatep"; + } + } + + //Everything else - mostly stuff from mapfunctions.js but also some important bits like voids or general farming + if (!Rshoulddopraid && !Rdshoulddopraid) selectedMap = RselectMap(selectedMap); + + //### Getting to Map Creation and Repeat. + + //Repeat + if (!game.global.preMapsActive && game.global.mapsActive) { + RmapRepeat(selectedMap, shouldDoHealthMaps, restartVoidMap); + } + + //Quest - no maps + if (Rshoulddoquest == 6) selectedMap = "world"; + + //Maps please + else if (!game.global.preMapsActive && !game.global.mapsActive) { + if (selectedMap != "world" && !game.global.switchToMaps) { + mapsClicked(); + } + } + + //### Creating Map Section + + else if (game.global.preMapsActive) { + + //Back to world + if (selectedMap == "world") { + mapsClicked(); + } + + //Praiding + else if (selectedMap == "createp") { + RAMP(); + } else if (selectedMap == "dcreatep") { + dRAMP(); + } + + //Everything else + else if (selectedMap == "create") { + if (game.global.selectedMapPreset > 1) selectAdvMapsPreset(1); + document.getElementById("mapLevelInput").value = game.global.world; + var decrement; + var tier; + if (game.global.world >= customVars.RMapTierZone[0]) { + tier = customVars.RMapTier0Sliders; + decrement = []; + } else if (game.global.world >= customVars.RMapTierZone[1]) { + tier = customVars.RMapTier1Sliders; + decrement = ['loot']; + } else if (game.global.world >= customVars.RMapTierZone[2]) { + tier = customVars.RMapTier2Sliders; + decrement = ['loot']; + } else { + tier = customVars.RMapTier3Sliders; + decrement = ['diff', 'loot']; + } + sizeAdvMapsRange.value = tier[0]; + adjustMap('size', tier[0]); + difficultyAdvMapsRange.value = tier[1]; + adjustMap('difficulty', tier[1]); + lootAdvMapsRange.value = tier[2]; + adjustMap('loot', tier[2]); + biomeAdvMapsSelect.value = autoTrimpSettings.Rmapselection.selected == "Gardens" ? "Plentiful" : autoTrimpSettings.Rmapselection.selected; + updateMapCost(); + if (RshouldFarm || game.global.challengeActive == 'Transmute') { + biomeAdvMapsSelect.value = "Plentiful"; + updateMapCost(); + } + if (Rshould(false, true) == "frag") { + RfragMap(); + } + if (Rshould(false, true) == "insanity") { + RinsanityMap(); + } + if (Rshould(false, true) == "alch") { + RalchMap(); + } + if (Rshould(false, true) == "hypo") { + RhypoMap(); + } + if (Rshould(false, true) == "ship") { + RshipMap(); + } + if (Rshould(false, true) == "time") { + RtimeFarmMap(false); + } + if (Rshould(false, true) == "dtime") { + RtimeFarmMap(true); + } + if (Rshould(false, true) == "smithy") { + RsmithyFarmMap(); + } + if (Rshould(false, true) == "tribute") { + RtributeFarmMap(); + } + if (Rshoulddoquest) { + RquestMap(Rshoulddoquest); + } + if (Rshouldmayhem > 0 && getPageSetting('Rmayhemmap') == 2 && !Rshouldtimefarm && !Rdshouldtimefarm) { + RlevelMap("mayhem"); + } + if (Rshouldpanda && getPageSetting('Rpandamaps') == true && !Rshouldtimefarm && !Rdshouldtimefarm) { + RlevelMap("panda"); + } + if (Rshoulddesofarm && !Rshouldtimefarm && !Rdshouldtimefarm) { + RlevelMap("deso"); + } + if (Rshouldequipfarm) { + RlevelMap("equip"); + } + + //Are things too expensive + if (updateMapCost(true) > game.resources.fragments.owned) { + if (!RenoughDamage) decrement.push('diff'); + if (RshouldFarm) decrement.push('size'); + } + while (decrement.indexOf('loot') > -1 && lootAdvMapsRange.value > 0 && updateMapCost(true) > game.resources.fragments.owned) { + lootAdvMapsRange.value -= 1; + } + while (decrement.indexOf('diff') > -1 && difficultyAdvMapsRange.value > 0 && updateMapCost(true) > game.resources.fragments.owned) { + difficultyAdvMapsRange.value -= 1; + } + while (decrement.indexOf('size') > -1 && sizeAdvMapsRange.value > 0 && updateMapCost(true) > game.resources.fragments.owned) { + sizeAdvMapsRange.value -= 1; + } + while (lootAdvMapsRange.value > 0 && updateMapCost(true) > game.resources.fragments.owned) { + lootAdvMapsRange.value -= 1; + } + while (difficultyAdvMapsRange.value > 0 && updateMapCost(true) > game.resources.fragments.owned) { + difficultyAdvMapsRange.value -= 1; + } + while (sizeAdvMapsRange.value > 0 && updateMapCost(true) > game.resources.fragments.owned) { + sizeAdvMapsRange.value -= 1; + } + + //Looks like things are too expensive + var maplvlpicked = parseInt(document.getElementById("mapLevelInput").value); + if (updateMapCost(true) > game.resources.fragments.owned) { + selectMap(game.global.mapsOwnedArray[highestMap].id); + debug("Can't afford the map we designed, #" + maplvlpicked, "maps", '*crying2'); + debug("...selected our highest map instead # " + game.global.mapsOwnedArray[highestMap].id + " Level: " + game.global.mapsOwnedArray[highestMap].level, "maps", '*happy2'); + runMap(); + RlastMapWeWereIn = getCurrentMapObject(); + } + + //You can afford things + else { + debug("Buying a Map, level: #" + maplvlpicked, "maps", 'th-large'); + var result = buyMap(); + if (result == -2) { + debug("Too many maps, recycling now: ", "maps", 'th-large'); + recycleBelow(true); + debug("Retrying, Buying a Map, level: #" + maplvlpicked, "maps", 'th-large'); + result = buyMap(); + if (result == -2) { + recycleMap(lowestMap); + result = buyMap(); + if (result == -2) + debug("AutoMaps unable to recycle to buy map!"); + else + debug("Retrying map buy after recycling lowest level map"); + } + } + } + + //We created the map, selectedMap is the map we want + } else { + selectMap(selectedMap); + var themapobj = game.global.mapsOwnedArray[getMapIndex(selectedMap)]; + var levelText; + if (themapobj.level > 0) { + levelText = " Level: " + themapobj.level; + } else { + levelText = " Level: " + game.global.world; + } + var voidorLevelText = themapobj.location == "Void" ? " Void: " : levelText; + debug("Running selected " + selectedMap + voidorLevelText + " Name: " + themapobj.name, "maps", 'th-large'); + runMap(); + RlastMapWeWereIn = getCurrentMapObject(); + } + } } diff --git a/modules/nature.js b/modules/nature.js new file mode 100644 index 000000000..d45b76fa4 --- /dev/null +++ b/modules/nature.js @@ -0,0 +1,191 @@ +function autoNatureTokens() { + var changed = false; + var thresh = 0; + if (getPageSetting('tokenthresh') > 0) { + thresh = getPageSetting('tokenthresh'); + } + for (var nature in game.empowerments) { + var empowerment = game.empowerments[nature]; + var setting = getPageSetting('Auto' + nature); + if (!setting || setting == 'Off') continue; + + if (setting == 'Empowerment') { + var cost = getNextNatureCost(nature); + if (empowerment.tokens < cost+thresh || empowerment.tokens < thresh) + continue; + empowerment.tokens -= cost; + empowerment.level++; + changed = true; + debug('Upgraded Empowerment of ' + nature, 'nature'); + } + else if (setting == 'Transfer') { + if (empowerment.retainLevel >= 80+thresh || empowerment.tokens < thresh) + continue; + var cost = getNextNatureCost(nature, true); + if (empowerment.tokens < cost) continue; + empowerment.tokens -= cost; + empowerment.retainLevel++; + changed = true; + debug('Upgraded ' + nature + ' transfer rate', 'nature'); + } + else if (setting == 'Convert to Both') { + if (empowerment.tokens < 20+thresh || empowerment.tokens < thresh) continue; + for (var targetNature in game.empowerments) { + if (targetNature == nature) continue; + empowerment.tokens -= 10; + var convertRate = (game.talents.nature.purchased) ? ((game.talents.nature2.purchased) ? 8 : 6) : 5; + game.empowerments[targetNature].tokens += convertRate; + changed = true; + debug('Converted ' + nature + ' tokens to ' + targetNature, 'nature'); + } + } + else { + if (empowerment.tokens < 10+thresh || empowerment.tokens < thresh) + continue; + var match = setting.match(/Convert to (\w+)/); + var targetNature = match ? match[1] : null; + if (!targetNature || targetNature === nature || !game.empowerments[targetNature]) continue; + empowerment.tokens -= 10; + var convertRate = (game.talents.nature.purchased) ? ((game.talents.nature2.purchased) ? 8 : 6) : 5; + game.empowerments[targetNature].tokens += convertRate; + changed = true; + debug('Converted ' + nature + ' tokens to ' + targetNature, 'nature'); + } + } + if (changed) + updateNatureInfoSpans(); +} + +function purchaseEnlight(nature) { + if (game.global.uberNature == false && game.empowerments[nature].nextUberCost <= game.empowerments[nature].tokens) { + naturePurchase('uberEmpower', nature); + } +} + +function autoEnlight() { + var nature = "None", dnature = "None", cnature = "None"; + var fillernature = [], poison, poisondiff, wind, winddiff, ice, icediff, dailynature = [], dpoison, dpoisondiff, dwind, dwinddiff, dice, dicediff, c2nature = [], cpoison, cpoisondiff, cwind, cwinddiff, cice, cicediff; + + //FILLER + if (game.global.challengeActive != "Daily" && !game.global.runningChallengeSquared) { + if (getPageSetting('pfillerenlightthresh') >= 0) { + poison = (game.empowerments.Poison.nextUberCost <= getPageSetting('pfillerenlightthresh') && game.empowerments.Poison.nextUberCost <= game.empowerments.Poison.tokens); + if (poison) { + poisondiff = (getPageSetting('pfillerenlightthresh') - game.empowerments.Poison.nextUberCost); + } + else poisondiff = -999999; + } + else poisondiff = -999999; + + if (getPageSetting('wfillerenlightthresh') >= 0) { + wind = (game.empowerments.Wind.nextUberCost <= getPageSetting('wfillerenlightthresh') && game.empowerments.Wind.nextUberCost <= game.empowerments.Wind.tokens); + if (wind) { + winddiff = (getPageSetting('wfillerenlightthresh') - game.empowerments.Wind.nextUberCost); + } + else winddiff = -999999; + } + else winddiff = -999999; + + if (getPageSetting('ifillerenlightthresh') >= 0) { + ice = (game.empowerments.Ice.nextUberCost <= getPageSetting('ifillerenlightthresh') && game.empowerments.Ice.nextUberCost <= game.empowerments.Ice.tokens); + if (ice) { + icediff = (getPageSetting('ifillerenlightthresh') - game.empowerments.Ice.nextUberCost); + } + else icediff = -999999; + } + else icediff = -999999; + + fillernature = [{nature:'Poison', cost:poisondiff}, {nature:'Wind', cost:winddiff}, {nature:'Ice', cost:icediff}].sort(function(a, b) {return a.cost > b.cost ? -1 : a.cost < b.cost ? 1 : 0;}); + + if (fillernature[0].cost > 0) { + nature = fillernature[0].nature; + } + else { nature = "None"; } + + if (fillernature.length > 0 && game.global.challengeActive != "Daily" && !game.global.runningChallengeSquared && nature != "None") { + purchaseEnlight(nature); + } + } + + //DAILY + if (game.global.challengeActive == "Daily") { + if (getPageSetting('pdailyenlightthresh') >= 0) { + dpoison = (game.empowerments.Poison.nextUberCost <= getPageSetting('pdailyenlightthresh') && game.empowerments.Poison.nextUberCost <= game.empowerments.Poison.tokens); + if (dpoison) { + dpoisondiff = (getPageSetting('pdailyenlightthresh') - game.empowerments.Poison.nextUberCost); + } + else dpoisondiff = -999999; + } + else dpoisondiff = -999999; + + if (getPageSetting('wdailyenlightthresh') >= 0) { + dwind = (game.empowerments.Wind.nextUberCost <= getPageSetting('wdailyenlightthresh') && game.empowerments.Wind.nextUberCost <= game.empowerments.Wind.tokens); + if (dwind) { + dwinddiff = (getPageSetting('wdailyenlightthresh') - game.empowerments.Wind.nextUberCost); + } + else dwinddiff = -999999; + } + else dwinddiff = -999999; + + if (getPageSetting('idailyenlightthresh') >= 0) { + dice = (game.empowerments.Ice.nextUberCost <= getPageSetting('idailyenlightthresh') && game.empowerments.Ice.nextUberCost <= game.empowerments.Ice.tokens); + if (dice) { + dicediff = (getPageSetting('idailyenlightthresh') - game.empowerments.Ice.nextUberCost); + } + else dicediff = -999999; + } + else dicediff = -999999; + + dailynature = [{nature:'Poison', cost:dpoisondiff}, {nature:'Wind', cost:dwinddiff}, {nature:'Ice', cost:dicediff}].sort(function(a, b) {return a.cost > b.cost ? -1 : a.cost < b.cost ? 1 : 0;}); + + if (dailynature[0].cost > 0) { + dnature = dailynature[0].nature; + } + else { dnature = "None"; } + + if (dailynature.length > 0 && game.global.challengeActive == "Daily" && dnature != "None") { + purchaseEnlight(dnature); + } + } + + //C2 + if (game.global.runningChallengeSquared) { + if (getPageSetting('pc2enlightthresh') >= 0) { + cpoison = (game.empowerments.Poison.nextUberCost <= getPageSetting('pc2enlightthresh') && game.empowerments.Poison.nextUberCost <= game.empowerments.Poison.tokens); + if (cpoison) { + cpoisondiff = (getPageSetting('pc2enlightthresh') - game.empowerments.Poison.nextUberCost); + } + else cpoisondiff = -999999; + } + else cpoisondiff = -999999; + + if (getPageSetting('wc2enlightthresh') >= 0) { + cwind = (game.empowerments.Wind.nextUberCost <= getPageSetting('wc2enlightthresh') && game.empowerments.Wind.nextUberCost <= game.empowerments.Wind.tokens); + if (cwind) { + cwinddiff = (getPageSetting('wc2enlightthresh') - game.empowerments.Wind.nextUberCost); + } + else cwinddiff = -999999; + } + else cwinddiff = -999999; + + if (getPageSetting('ic2enlightthresh') >= 0) { + cice = (game.empowerments.Ice.nextUberCost <= getPageSetting('ic2enlightthresh') && game.empowerments.Ice.nextUberCost <= game.empowerments.Ice.tokens); + if (cice) { + cicediff = (getPageSetting('ic2enlightthresh') - game.empowerments.Ice.nextUberCost); + } + else cicediff = -999999; + } + else cicediff = -999999; + + c2nature = [{nature:'Poison', cost:cpoisondiff}, {nature:'Wind', cost:cwinddiff}, {nature:'Ice', cost:cicediff}].sort(function(a, b) {return a.cost > b.cost ? -1 : a.cost < b.cost ? 1 : 0;}); + + if (c2nature[0].cost > 0) { + cnature = c2nature[0].nature; + } + else { cnature = "None"; } + + if (c2nature.length > 0 && game.global.runningChallengeSquared && cnature != "None") { + purchaseEnlight(cnature); + } + } +} diff --git a/modules/other.js b/modules/other.js index 64bc59541..25b746c3f 100644 --- a/modules/other.js +++ b/modules/other.js @@ -1,134 +1,2354 @@ MODULES["other"] = {}; -MODULES["other"].enableRoboTrimpSpam = true; //set this to false to stop Spam of "Activated Robotrimp MagnetoShriek Ability" +MODULES["other"].enableRoboTrimpSpam = true; +var prestraid = !1, + dprestraid = !1, + failpraid = !1, + dfailpraid = !1, + bwraided = !1, + dbwraided = !1, + failbwraid = !1, + dfailbwraid = !1, + perked = !1, + prestraidon = !1, + dprestraidon = !1, + mapbought = !1, + dmapbought = !1, + bwraidon = !1, + dbwraidon = !1, + presteps = null, + minMaxMapCost, fMap, pMap, shouldFarmFrags = !1, + praidDone = !1; +function armydeath() { + if (game.global.mapsActive) return !1; + var e = game.global.lastClearedCell + 1, + l = game.global.gridArray[e].attack * dailyModifiers.empower.getMult(game.global.dailyChallenge.empower.strength, game.global.dailyChallenge.empower.stacks), + a = game.global.soldierHealth + game.global.soldierEnergyShield; + "Ice" == getEmpowerment() && (l *= game.empowerments.Ice.getCombatModifier()); + var g = game.global.soldierCurrentBlock; + return 3 == game.global.formation ? g /= 4 : "0" != game.global.formation && (g *= 2), g > game.global.gridArray[e].attack ? l *= getPierceAmt() : l -= g * (1 - getPierceAmt()), "Daily" == game.global.challengeActive && void 0 !== game.global.dailyChallenge.crits && (l *= dailyModifiers.crits.getMult(game.global.dailyChallenge.crits.strength)), void 0 !== game.global.dailyChallenge.bogged && (a -= game.global.soldierHealthMax * dailyModifiers.bogged.getMult(game.global.dailyChallenge.bogged.strength)), void 0 !== game.global.dailyChallenge.plague && (a -= game.global.soldierHealthMax * dailyModifiers.plague.getMult(game.global.dailyChallenge.plague.strength, game.global.dailyChallenge.plague.stacks)), challengeActive("Electricity") && (a -= game.global.soldierHealth -= game.global.soldierHealthMax * (.1 * game.challenges.Electricity.stacks)), "corruptCrit" == game.global.gridArray[e].corrupted ? l *= 5 : "healthyCrit" == game.global.gridArray[e].corrupted ? l *= 7 : "corruptBleed" == game.global.gridArray[e].corrupted ? a *= .8 : "healthyBleed" == game.global.gridArray[e].corrupted && (a *= .7), (a -= l) <= 1e3 +} -//Activate Robo Trimp (will activate on the first zone after liquification) function autoRoboTrimp() { - //exit if the cooldown is active, or we havent unlocked robotrimp. - if (game.global.roboTrimpCooldown > 0 || !game.global.roboTrimpLevel) return; - var robotrimpzone = parseInt(getPageSetting('AutoRoboTrimp')); - //exit if we have the setting set to 0 - if (robotrimpzone == 0) return; - //activate the button when we are above the cutoff zone, and we are out of cooldown (and the button is inactive) - if (game.global.world >= robotrimpzone && !game.global.useShriek){ - magnetoShriek(); - if (MODULES["other"].enableRoboTrimpSpam) - debug("Activated Robotrimp MagnetoShriek Ability @ z" + game.global.world, "graphs", '*podcast'); + if (!(0 < game.global.roboTrimpCooldown) && game.global.roboTrimpLevel) { + var a = parseInt(getPageSetting("AutoRoboTrimp")); + 0 == a || game.global.world >= a && (game.global.world - a) % 5 == 0 && !checkIfLiquidZone() && !game.global.useShriek && (magnetoShriek(), MODULES.other.enableRoboTrimpSpam && debug("Activated Robotrimp MagnetoShriek Ability @ z" + game.global.world, "graphs", "*podcast")) } } -//Version 3.6 Golden Upgrades - //setting param : get the numerical value of the selected index of the dropdown box +function isBelowThreshold(a) { + return a != game.global.world +} + +function buyWeps() { + if (!((getPageSetting('BuyWeaponsNew') == 1) || (getPageSetting('BuyWeaponsNew') == 3))) return; + preBuy(), game.global.buyAmt = getPageSetting('gearamounttobuy'), game.equipment.Dagger.level < getPageSetting('CapEquip2') && canAffordBuilding('Dagger', null, null, !0) && buyEquipment('Dagger', !0, !0), game.equipment.Mace.level < getPageSetting('CapEquip2') && canAffordBuilding('Mace', null, null, !0) && buyEquipment('Mace', !0, !0), game.equipment.Polearm.level < getPageSetting('CapEquip2') && canAffordBuilding('Polearm', null, null, !0) && buyEquipment('Polearm', !0, !0), game.equipment.Battleaxe.level < getPageSetting('CapEquip2') && canAffordBuilding('Battleaxe', null, null, !0) && buyEquipment('Battleaxe', !0, !0), game.equipment.Greatsword.level < getPageSetting('CapEquip2') && canAffordBuilding('Greatsword', null, null, !0) && buyEquipment('Greatsword', !0, !0), !game.equipment.Arbalest.locked && game.equipment.Arbalest.level < getPageSetting('CapEquip2') && canAffordBuilding('Arbalest', null, null, !0) && buyEquipment('Arbalest', !0, !0), postBuy() +} + +function buyArms() { + if (!((getPageSetting('BuyArmorNew') == 1) || (getPageSetting('BuyArmorNew') == 3))) return; + preBuy(), game.global.buyAmt = 10, game.equipment.Shield.level < getPageSetting('CapEquiparm') && canAffordBuilding('Shield', null, null, !0) && buyEquipment('Shield', !0, !0), game.equipment.Boots.level < getPageSetting('CapEquiparm') && canAffordBuilding('Boots', null, null, !0) && buyEquipment('Boots', !0, !0), game.equipment.Helmet.level < getPageSetting('CapEquiparm') && canAffordBuilding('Helmet', null, null, !0) && buyEquipment('Helmet', !0, !0), game.equipment.Pants.level < getPageSetting('CapEquiparm') && canAffordBuilding('Pants', null, null, !0) && buyEquipment('Pants', !0, !0), game.equipment.Shoulderguards.level < getPageSetting('CapEquiparm') && canAffordBuilding('Shoulderguards', null, null, !0) && buyEquipment('Shoulderguards', !0, !0), game.equipment.Breastplate.level < getPageSetting('CapEquiparm') && canAffordBuilding('Breastplate', null, null, !0) && buyEquipment('Breastplate', !0, !0), !game.equipment.Gambeson.locked && game.equipment.Gambeson.level < getPageSetting('CapEquiparm') && canAffordBuilding('Gambeson', null, null, !0) && buyEquipment('Gambeson', !0, !0), postBuy() +} + +function isActiveSpireAT() { + return game.global.challengeActive != 'Daily' && game.global.spireActive && game.global.world >= getPageSetting('IgnoreSpiresUntil') +} + +function disActiveSpireAT() { + return game.global.challengeActive == 'Daily' && game.global.spireActive && game.global.world >= getPageSetting('dIgnoreSpiresUntil') +} + +function exitSpireCell() { + isActiveSpireAT() && game.global.lastClearedCell >= getPageSetting('ExitSpireCell') - 1 && endSpire() +} + +function dailyexitSpireCell() { + disActiveSpireAT() && game.global.lastClearedCell >= getPageSetting('dExitSpireCell') - 1 && endSpire() +} + +function plusPres() { + document.getElementById("biomeAdvMapsSelect").value = "Random", document.getElementById("advExtraLevelSelect").value = plusMapToRun(game.global.world), document.getElementById("advSpecialSelect").value = "p", document.getElementById("lootAdvMapsRange").value = 0, document.getElementById("difficultyAdvMapsRange").value = 9, document.getElementById("sizeAdvMapsRange").value = 9, document.getElementById("advPerfectCheckbox").checked = !1, document.getElementById("mapLevelInput").value = game.global.world, updateMapCost() +} + +function plusMapToRun(a) { + return 9 == a % 10 ? 6 : 5 > a % 10 ? 5 - a % 10 : 11 - a % 10 +} + +function findLastBionic() { + for (var a = game.global.mapsOwnedArray.length - 1; 0 <= a; a--) + if ("Bionic" === game.global.mapsOwnedArray[a].location) return game.global.mapsOwnedArray[a] +} + +function helptrimpsnotdie() { + if (!game.global.preMapsActive && !game.global.fighting) buyArms(); +} + +function usedaily3() { + !0 != getPageSetting('use3daily') || 'Daily' != game.global.challengeActive || daily3 || (daily3 = !0), !1 == getPageSetting('use3daily') && 'Daily' != game.global.challengeActive && daily3 && (daily3 = !1), !0 == getPageSetting('use3daily') && 'Daily' != game.global.challengeActive && daily3 && (daily3 = !1) +} + +function buyshitspire() { + !0 == getPageSetting('spireshitbuy') && game.global.spireActive && game.global.world >= getPageSetting('IgnoreSpiresUntil') && (buyWeps(), buyArms()) +} + +//Helium + function autoGoldenUpgradesAT(setting) { var num = getAvailableGoldenUpgrades(); - if (num == 0) return; //if we have nothing to buy, exit. - //Challenge^2 cant Get/Buy Helium, so adapt - do Derskagg mod. - var challSQ = game.global.runningChallengeSquared; - //Default: True = Always get 60% void by skipping the 12% upgrade then buying 14%/16% - var goldStrat = getPageSetting('goldStrat'); - //Try to achieve 60% Void - if (setting == "Void" && goldStrat == "Max then Helium") { - var nextVoidAmt = game.goldenUpgrades.Void.nextAmt().toFixed(2); - if (nextVoidAmt == 0.12) //skip the 6th void upgrade - setting = "Helium"; - if (challSQ) //always buy battle during max then helium mode. - setting = "Battle"; - } - //buy one upgrade per loop. - var success = buyGoldenUpgrade(setting); - - var doDerskaggChallSQ = false; - if (setting == ("Helium" || "Void") && challSQ) - {doDerskaggChallSQ = true; setting = (challSQ) ? "Battle" : "Helium"} - // DZUGAVILI MOD - SMART VOID GUs - // Assumption: buyGoldenUpgrades is not an asynchronous operation and resolves completely in function execution. - // Assumption: "Locking" game option is not set or does not prevent buying Golden Void - var noBat = getPageSetting('goldNoBattle'); //true = no battle = buy helium - //In 'Alternating' mode : instead of alternating between buying Helium and Battle, with this on it will only buy Helium. - if (!success && setting == "Void" || doDerskaggChallSQ) { - num = getAvailableGoldenUpgrades(); //recheck availables. + var setting2; + if (num == 0) return; + if (setting == "Helium") + setting2 = "Helium"; + if ((!game.global.dailyChallenge.seed && !game.global.runningChallengeSquared && autoTrimpSettings.AutoGoldenUpgrades.selected == "Helium" && getPageSetting('radonbattle') > 0 && game.goldenUpgrades.Helium.purchasedAt.length >= getPageSetting('radonbattle')) || (game.global.dailyChallenge.seed && autoTrimpSettings.dAutoGoldenUpgrades.selected == "Helium" && getPageSetting('dradonbattle') > 0 && game.goldenUpgrades.Helium.purchasedAt.length >= getPageSetting('dradonbattle'))) + setting2 = "Battle"; + if (setting == "Battle") + setting2 = "Battle"; + if ((!game.global.dailyChallenge.seed && !game.global.runningChallengeSquared && autoTrimpSettings.AutoGoldenUpgrades.selected == "Battle" && getPageSetting('battleradon') > 0 && game.goldenUpgrades.Battle.purchasedAt.length >= getPageSetting('battleradon')) || (game.global.dailyChallenge.seed && autoTrimpSettings.dAutoGoldenUpgrades.selected == "Battle" && getPageSetting('dbattleradon') > 0 && game.goldenUpgrades.Battle.purchasedAt.length >= getPageSetting('dbattleradon'))) + setting2 = "Helium"; + if (setting == "Void" || setting == "Void + Battle") + setting2 = "Void"; + var success = buyGoldenUpgrade(setting2); + if (!success && setting2 == "Void") { + num = getAvailableGoldenUpgrades(); if (num == 0) return; - // DerSkagg Mod - Instead of Voids, For every Helium upgrade buy X-1 battle upgrades to maintain speed runs - if (goldStrat == "Alternating") { - var goldAlternating = getPageSetting('goldAlternating'); - setting = (game.global.goldenUpgrades%goldAlternating == 0 || noBat) ? "Helium" : "Battle"; - } else if (goldStrat == "Zone") { - var goldZone = getPageSetting('goldZone'); - setting = (game.global.world <= goldZone || noBat) ? "Helium" : "Battle"; - } else if (goldStrat == "Max then Helium") { - setting = (challSQ) ? "Battle" : "Helium"; - } else - setting = (challSQ) ? "Battle" : "Helium"; - buyGoldenUpgrade(setting); - } - // END OF DerSkagg & DZUGAVILI MOD -//} catch(err) { debug("Error in autoGoldenUpgrades: " + err.message, "general"); } -} - -//auto spend nature tokens -function autoNatureTokens() { - var changed = false; - for (var nature in game.empowerments) { - var empowerment = game.empowerments[nature]; - var setting = getPageSetting('Auto' + nature); - if (!setting || setting == 'Off') continue; - - //buy/convert once per nature per loop - if (setting == 'Empowerment') { - var cost = getNextNatureCost(nature); - if (empowerment.tokens < cost) - continue; - empowerment.tokens -= cost; - empowerment.level++; - changed = true; - debug('Upgraded Empowerment of ' + nature, 'nature'); - } - else if (setting == 'Transfer') { - if (empowerment.retainLevel >= 80) - continue; - var cost = getNextNatureCost(nature, true); - if (empowerment.tokens < cost) continue; - empowerment.tokens -= cost; - empowerment.retainLevel++; - changed = true; - debug('Upgraded ' + nature + ' transfer rate', 'nature'); - } - else if (setting == 'Convert to Both') { - if (empowerment.tokens < 20) continue; - for (var targetNature in game.empowerments) { - if (targetNature == nature) continue; - empowerment.tokens -= 10; - var convertRate = (game.talents.nature.purchased) ? ((game.talents.nature2.purchased) ? 8 : 6) : 5; - game.empowerments[targetNature].tokens += convertRate; - changed = true; - debug('Converted ' + nature + ' tokens to ' + targetNature, 'nature'); - } - } - else { - if (empowerment.tokens < 10) - continue; - var match = setting.match(/Convert to (\w+)/); - var targetNature = match ? match[1] : null; - //sanity check - if (!targetNature || targetNature === nature || !game.empowerments[targetNature]) continue; - empowerment.tokens -= 10; - var convertRate = (game.talents.nature.purchased) ? ((game.talents.nature2.purchased) ? 8 : 6) : 5; - game.empowerments[targetNature].tokens += convertRate; - changed = true; - debug('Converted ' + nature + ' tokens to ' + targetNature, 'nature'); - } - } - if (changed) - updateNatureInfoSpans(); -} - -//Check if currently in a Spire past IgnoreSpiresUntil -function isActiveSpireAT() { - return game.global.spireActive && game.global.world >= getPageSetting('IgnoreSpiresUntil'); + if ((autoTrimpSettings.AutoGoldenUpgrades.selected == "Void" && !game.global.dailyChallenge.seed && !game.global.runningChallengeSquared) || (autoTrimpSettings.dAutoGoldenUpgrades.selected == "Void" && game.global.dailyChallenge.seed)) + setting2 = "Helium"; + if (((autoTrimpSettings.AutoGoldenUpgrades.selected == "Void" && getPageSetting('voidheliumbattle') > 0 && game.global.world >= getPageSetting('voidheliumbattle')) || (autoTrimpSettings.dAutoGoldenUpgrades.selected == "Void" && getPageSetting('dvoidheliumbattle') > 0 && game.global.world >= getPageSetting('dvoidheliumbattle'))) || ((autoTrimpSettings.AutoGoldenUpgrades.selected == "Void + Battle" && !game.global.dailyChallenge.seed && !game.global.runningChallengeSquared) || (autoTrimpSettings.dAutoGoldenUpgrades.selected == "Void + Battle" && game.global.dailyChallenge.seed) || (autoTrimpSettings.cAutoGoldenUpgrades.selected == "Void + Battle" && game.global.runningChallengeSquared))) + setting2 = "Battle"; + buyGoldenUpgrade(setting2); + } } -//Exits the Spire after completing the specified cell. -function exitSpireCell() { - if(isActiveSpireAT() && game.global.lastClearedCell >= getPageSetting('ExitSpireCell')-1) - endSpire(); +//Praiding + +function plusMapToRun1() { + var map = 1; + if (game.global.world % 10 == 5) + map = 6; + if (game.global.world % 10 == 6) + map = 5; + if (game.global.world % 10 == 7) + map = 4; + if (game.global.world % 10 == 8) + map = 3; + if (game.global.world % 10 == 9) + map = 2; + return map; +} + +function plusMapToRun2() { + var map = 2; + if (game.global.world % 10 == 4) + map = 7; + if (game.global.world % 10 == 5) + map = 7; + if (game.global.world % 10 == 6) + map = 6; + if (game.global.world % 10 == 7) + map = 5; + if (game.global.world % 10 == 8) + map = 4; + if (game.global.world % 10 == 9) + map = 3; + return map; +} + +function plusMapToRun3() { + var map = 3; + if (game.global.world % 10 == 3) + map = 8; + if (game.global.world % 10 == 4) + map = 8; + if (game.global.world % 10 == 5) + map = 8; + if (game.global.world % 10 == 6) + map = 7; + if (game.global.world % 10 == 7) + map = 6; + if (game.global.world % 10 == 8) + map = 5; + if (game.global.world % 10 == 9) + map = 4; + return map; +} + +function plusMapToRun4() { + var map = 4; + if (game.global.world % 10 == 2) + map = 9; + if (game.global.world % 10 == 3) + map = 9; + if (game.global.world % 10 == 4) + map = 9; + if (game.global.world % 10 == 5) + map = 9; + if (game.global.world % 10 == 6) + map = 8; + if (game.global.world % 10 == 7) + map = 7; + if (game.global.world % 10 == 8) + map = 6; + if (game.global.world % 10 == 9) + map = 5; + return map; +} + +function plusMapToRun5() { + var map = 5; + if (game.global.world % 10 == 1) + map = 10; + if (game.global.world % 10 == 2) + map = 10; + if (game.global.world % 10 == 3) + map = 10; + if (game.global.world % 10 == 4) + map = 10; + if (game.global.world % 10 == 5) + map = 10; + if (game.global.world % 10 == 6) + map = 9; + if (game.global.world % 10 == 7) + map = 8; + if (game.global.world % 10 == 8) + map = 7; + if (game.global.world % 10 == 9) + map = 6; + return map; +} + +function plusPres1() { + document.getElementById("biomeAdvMapsSelect").value = "Depths"; + document.getElementById("advExtraLevelSelect").value = plusMapToRun1(); + document.getElementById("advSpecialSelect").value = "p"; + document.getElementById("lootAdvMapsRange").value = 0; + document.getElementById("difficultyAdvMapsRange").value = 9; + document.getElementById("sizeAdvMapsRange").value = 9; + document.getElementById("advPerfectCheckbox").checked = true; + document.getElementById("mapLevelInput").value = game.global.world; + updateMapCost(); + + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("biomeAdvMapsSelect").value = "Random"; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("advPerfectCheckbox").checked = false; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 8; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 8; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 7; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 7; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 6; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 6; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 5; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 5; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 4; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 4; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 3; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 3; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 2; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 2; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 1; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 1; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 0; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 0; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("advSpecialSelect").value = "fa"; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("advSpecialSelect").value = "0"; + updateMapCost(); + } +} + +function plusPres2() { + document.getElementById("biomeAdvMapsSelect").value = "Depths"; + document.getElementById("advExtraLevelSelect").value = plusMapToRun2(); + document.getElementById("advSpecialSelect").value = "p"; + document.getElementById("lootAdvMapsRange").value = 0; + document.getElementById("difficultyAdvMapsRange").value = 9; + document.getElementById("sizeAdvMapsRange").value = 9; + document.getElementById("advPerfectCheckbox").checked = true; + document.getElementById("mapLevelInput").value = game.global.world; + updateMapCost(); + + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("biomeAdvMapsSelect").value = "Random"; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("advPerfectCheckbox").checked = false; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 8; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 8; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 7; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 7; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 6; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 6; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 5; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 5; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 4; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 4; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 3; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 3; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 2; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 2; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 1; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 1; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 0; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 0; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("advSpecialSelect").value = "fa"; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("advSpecialSelect").value = "0"; + updateMapCost(); + } +} + +function plusPres3() { + document.getElementById("biomeAdvMapsSelect").value = "Depths"; + document.getElementById("advExtraLevelSelect").value = plusMapToRun3(); + document.getElementById("advSpecialSelect").value = "p"; + document.getElementById("lootAdvMapsRange").value = 0; + document.getElementById("difficultyAdvMapsRange").value = 9; + document.getElementById("sizeAdvMapsRange").value = 9; + document.getElementById("advPerfectCheckbox").checked = true; + document.getElementById("mapLevelInput").value = game.global.world; + updateMapCost(); + + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("biomeAdvMapsSelect").value = "Random"; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("advPerfectCheckbox").checked = false; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 8; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 8; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 7; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 7; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 6; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 6; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 5; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 5; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 4; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 4; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 3; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 3; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 2; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 2; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 1; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 1; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 0; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 0; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("advSpecialSelect").value = "fa"; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("advSpecialSelect").value = "0"; + updateMapCost(); + } +} + +function plusPres4() { + document.getElementById("biomeAdvMapsSelect").value = "Depths"; + document.getElementById("advExtraLevelSelect").value = plusMapToRun4(); + document.getElementById("advSpecialSelect").value = "p"; + document.getElementById("lootAdvMapsRange").value = 0; + document.getElementById("difficultyAdvMapsRange").value = 9; + document.getElementById("sizeAdvMapsRange").value = 9; + document.getElementById("advPerfectCheckbox").checked = true; + document.getElementById("mapLevelInput").value = game.global.world; + updateMapCost(); + + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("biomeAdvMapsSelect").value = "Random"; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("advPerfectCheckbox").checked = false; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 8; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 8; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 7; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 7; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 6; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 6; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 5; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 5; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 4; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 4; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 3; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 3; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 2; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 2; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 1; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 1; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 0; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 0; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("advSpecialSelect").value = "fa"; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("advSpecialSelect").value = "0"; + updateMapCost(); + } +} + +function plusPres5() { + document.getElementById("biomeAdvMapsSelect").value = "Depths"; + document.getElementById("advExtraLevelSelect").value = plusMapToRun5(); + document.getElementById("advSpecialSelect").value = "p"; + document.getElementById("lootAdvMapsRange").value = 0; + document.getElementById("difficultyAdvMapsRange").value = 9; + document.getElementById("sizeAdvMapsRange").value = 9; + document.getElementById("advPerfectCheckbox").checked = true; + document.getElementById("mapLevelInput").value = game.global.world; + updateMapCost(); + + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("biomeAdvMapsSelect").value = "Random"; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("advPerfectCheckbox").checked = false; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 8; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 8; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 7; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 7; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 6; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 6; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 5; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 5; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 4; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 4; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 3; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 3; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 2; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 2; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 1; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 1; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("difficultyAdvMapsRange").value = 0; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("sizeAdvMapsRange").value = 0; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("advSpecialSelect").value = "fa"; + updateMapCost(); + } + if (updateMapCost(true) > game.resources.fragments.owned) { + document.getElementById("advSpecialSelect").value = "0"; + updateMapCost(); + } +} + +function pcheck1() { + + var HD; + var P; + var I; + + if (game.global.challengeActive != "Daily") { + HD = getPageSetting('PraidingHD'); + P = (getPageSetting('PraidingP') > 0 ? getPageSetting('PraidingP') : 0); + I = (getPageSetting('PraidingI') > 0 ? getPageSetting('PraidingI') : 0); + } + if (game.global.challengeActive == "Daily") { + HD = getPageSetting('dPraidingHD'); + P = (getPageSetting('dPraidingP') > 0 ? getPageSetting('dPraidingP') : 0); + I = (getPageSetting('dPraidingI') > 0 ? getPageSetting('dPraidingI') : 0); + } + + var go = false; + + if (HD <= 0) { + go = true; + } else if (HD > 0) { + go = (HD >= calcHDratio(game.global.world + plusMapToRun1())); + } + if (P > 0 && getEmpowerment() == "Poison") { + go = (P >= plusMapToRun1()); + } + if (I > 0 && getEmpowerment() == "Ice") { + go = (I >= plusMapToRun1()); + } + return go; +} + +function pcheck2() { + + var HD; + var P; + var I; + + if (game.global.challengeActive != "Daily") { + HD = getPageSetting('PraidingHD'); + P = (getPageSetting('PraidingP') > 0 ? getPageSetting('PraidingP') : 0); + I = (getPageSetting('PraidingI') > 0 ? getPageSetting('PraidingI') : 0); + } + if (game.global.challengeActive == "Daily") { + HD = getPageSetting('dPraidingHD'); + P = (getPageSetting('dPraidingP') > 0 ? getPageSetting('dPraidingP') : 0); + I = (getPageSetting('dPraidingI') > 0 ? getPageSetting('dPraidingI') : 0); + } + + var go = false; + + if (HD <= 0) { + go = true; + } else if (HD > 0) { + go = (HD >= calcHDratio(game.global.world + plusMapToRun2())); + } + if (P > 0 && getEmpowerment() == "Poison") { + go = (P >= plusMapToRun2()); + } + if (I > 0 && getEmpowerment() == "Ice") { + go = (I >= plusMapToRun2()); + } + return go; +} + +function pcheck3() { + + var HD; + var P; + var I; + + if (game.global.challengeActive != "Daily") { + HD = getPageSetting('PraidingHD'); + P = (getPageSetting('PraidingP') > 0 ? getPageSetting('PraidingP') : 0); + I = (getPageSetting('PraidingI') > 0 ? getPageSetting('PraidingI') : 0); + } + if (game.global.challengeActive == "Daily") { + HD = getPageSetting('dPraidingHD'); + P = (getPageSetting('dPraidingP') > 0 ? getPageSetting('dPraidingP') : 0); + I = (getPageSetting('dPraidingI') > 0 ? getPageSetting('dPraidingI') : 0); + } + + var go = false; + + if (HD <= 0) { + go = true; + } else if (HD > 0) { + go = (HD >= calcHDratio(game.global.world + plusMapToRun3())); + } + if (P > 0 && getEmpowerment() == "Poison") { + go = (P >= plusMapToRun3()); + } + if (I > 0 && getEmpowerment() == "Ice") { + go = (I >= plusMapToRun3()); + } + return go; +} + +function pcheck4() { + + var HD; + var P; + var I; + + if (game.global.challengeActive != "Daily") { + HD = getPageSetting('PraidingHD'); + P = (getPageSetting('PraidingP') > 0 ? getPageSetting('PraidingP') : 0); + I = (getPageSetting('PraidingI') > 0 ? getPageSetting('PraidingI') : 0); + } + if (game.global.challengeActive == "Daily") { + HD = getPageSetting('dPraidingHD'); + P = (getPageSetting('dPraidingP') > 0 ? getPageSetting('dPraidingP') : 0); + I = (getPageSetting('dPraidingI') > 0 ? getPageSetting('dPraidingI') : 0); + } + + var go = false; + + if (HD <= 0) { + go = true; + } else if (HD > 0) { + go = (HD >= calcHDratio(game.global.world + plusMapToRun4())); + } + if (P > 0 && getEmpowerment() == "Poison") { + go = (P >= plusMapToRun4()); + } + if (I > 0 && getEmpowerment() == "Ice") { + go = (I >= plusMapToRun4()); + } + return go; +} + +function pcheck5() { + + var HD; + var P; + var I; + + if (game.global.challengeActive != "Daily") { + HD = getPageSetting('PraidingHD'); + P = (getPageSetting('PraidingP') > 0 ? getPageSetting('PraidingP') : 0); + I = (getPageSetting('PraidingI') > 0 ? getPageSetting('PraidingI') : 0); + } + if (game.global.challengeActive == "Daily") { + HD = getPageSetting('dPraidingHD'); + P = (getPageSetting('dPraidingP') > 0 ? getPageSetting('dPraidingP') : 0); + I = (getPageSetting('dPraidingI') > 0 ? getPageSetting('dPraidingI') : 0); + } + + var go = false; + + if (HD <= 0) { + go = true; + } else if (HD > 0) { + go = (HD >= calcHDratio(game.global.world + plusMapToRun5())); + } + if (P > 0 && getEmpowerment() == "Poison") { + go = (P >= plusMapToRun5()); + } + if (I > 0 && getEmpowerment() == "Ice") { + go = (I >= plusMapToRun5()); + } + return go; +} + +function pcheckmap1() { + var go = false; + if (game.global.world % 10 == 0 && plusMapToRun1() == 1) { + go = true; + } + if (game.global.world % 10 == 1 && (plusMapToRun1() == 1 || plusMapToRun1() == 10)) { + go = true; + } + if (game.global.world % 10 == 2 && (plusMapToRun1() == 1 || plusMapToRun1() >= 9)) { + go = true; + } + if (game.global.world % 10 == 3 && (plusMapToRun1() == 1 || plusMapToRun1() >= 8)) { + go = true; + } + if (game.global.world % 10 == 4 && (plusMapToRun1() == 1 || plusMapToRun1() >= 7)) { + go = true; + } + if (game.global.world % 10 == 5 && plusMapToRun1() >= 6) { + go = true; + } + if (game.global.world % 10 == 6 && plusMapToRun1() >= 5) { + go = true; + } + if (game.global.world % 10 == 7 && plusMapToRun1() >= 4) { + go = true; + } + if (game.global.world % 10 == 8 && plusMapToRun1() >= 3) { + go = true; + } + if (game.global.world % 10 == 9 && plusMapToRun1() >= 2) { + go = true; + } + return go; +} + +function pcheckmap2() { + var go = false; + if (game.global.world % 10 == 0 && plusMapToRun2() == 2) { + go = true; + } + if (game.global.world % 10 == 1 && (plusMapToRun2() == 2 || plusMapToRun2() == 10)) { + go = true; + } + if (game.global.world % 10 == 2 && (plusMapToRun2() == 2 || plusMapToRun2() >= 9)) { + go = true; + } + if (game.global.world % 10 == 3 && (plusMapToRun2() == 2 || plusMapToRun2() >= 8)) { + go = true; + } + if (game.global.world % 10 == 4 && plusMapToRun2() >= 7) { + go = true; + } + if (game.global.world % 10 == 5 && plusMapToRun2() >= 6) { + go = true; + } + if (game.global.world % 10 == 6 && plusMapToRun2() >= 6) { + go = true; + } + if (game.global.world % 10 == 7 && plusMapToRun2() >= 5) { + go = true; + } + if (game.global.world % 10 == 8 && plusMapToRun2() >= 4) { + go = true; + } + if (game.global.world % 10 == 9 && plusMapToRun2() >= 3) { + go = true; + } + return go; +} + +function pcheckmap3() { + var go = false; + if (game.global.world % 10 == 0 && plusMapToRun3() == 3) { + go = true; + } + if (game.global.world % 10 == 1 && (plusMapToRun3() == 3 || plusMapToRun3() == 10)) { + go = true; + } + if (game.global.world % 10 == 2 && (plusMapToRun3() == 3 || plusMapToRun3() >= 9)) { + go = true; + } + if (game.global.world % 10 == 3 && plusMapToRun3() >= 8) { + go = true; + } + if (game.global.world % 10 == 4 && plusMapToRun3() >= 8) { + go = true; + } + if (game.global.world % 10 == 5 && plusMapToRun3() >= 8) { + go = true; + } + if (game.global.world % 10 == 6 && plusMapToRun3() >= 7) { + go = true; + } + if (game.global.world % 10 == 7 && plusMapToRun3() >= 6) { + go = true; + } + if (game.global.world % 10 == 8 && plusMapToRun3() >= 5) { + go = true; + } + if (game.global.world % 10 == 9 && plusMapToRun3() >= 4) { + go = true; + } + return go; +} + +function pcheckmap4() { + var go = false; + if (game.global.world % 10 == 0 && plusMapToRun4() == 4) { + go = true; + } + if (game.global.world % 10 == 1 && (plusMapToRun4() == 4 || plusMapToRun4() == 10)) { + go = true; + } + if (game.global.world % 10 == 2 && plusMapToRun4() >= 9) { + go = true; + } + if (game.global.world % 10 == 3 && plusMapToRun4() >= 8) { + go = true; + } + if (game.global.world % 10 == 4 && plusMapToRun4() >= 7) { + go = true; + } + if (game.global.world % 10 == 5 && plusMapToRun4() >= 6) { + go = true; + } + if (game.global.world % 10 == 6 && plusMapToRun4() >= 5) { + go = true; + } + if (game.global.world % 10 == 7 && plusMapToRun4() >= 4) { + go = true; + } + if (game.global.world % 10 == 8 && plusMapToRun4() >= 3) { + go = true; + } + if (game.global.world % 10 == 9 && plusMapToRun4() >= 2) { + go = true; + } + return go; +} + +function pcheckmap5() { + var go = false; + if (game.global.world % 10 == 0 && plusMapToRun5() == 5) { + go = true; + } + if (game.global.world % 10 == 1 && (plusMapToRun5() == 4 || plusMapToRun5() == 10)) { + go = true; + } + if (game.global.world % 10 == 2 && (plusMapToRun5() == 3 || plusMapToRun5() >= 9)) { + go = true; + } + if (game.global.world % 10 == 3 && (plusMapToRun5() == 2 || plusMapToRun5() >= 8)) { + go = true; + } + if (game.global.world % 10 == 4 && (plusMapToRun5() == 1 || plusMapToRun5() >= 7)) { + go = true; + } + if (game.global.world % 10 == 5 && plusMapToRun5() >= 6) { + go = true; + } + if (game.global.world % 10 == 6 && plusMapToRun5() >= 5) { + go = true; + } + if (game.global.world % 10 == 7 && plusMapToRun5() >= 4) { + go = true; + } + if (game.global.world % 10 == 8 && plusMapToRun5() >= 3) { + go = true; + } + if (game.global.world % 10 == 9 && plusMapToRun5() >= 2) { + go = true; + } + return go; +} + +var pMap1 = undefined; +var pMap2 = undefined; +var pMap3 = undefined; +var pMap4 = undefined; +var pMap5 = undefined; +var repMap1 = undefined; +var repMap2 = undefined; +var repMap3 = undefined; +var repMap4 = undefined; +var repMap5 = undefined; +var mapbought1 = false; +var mapbought2 = false; +var mapbought3 = false; +var mapbought4 = false; +var mapbought5 = false; + +function Praiding() { + var cell; + cell = ((getPageSetting('Praidingcell') > 0) ? getPageSetting('Praidingcell') : 0); + if (getPageSetting('Praidingzone').length) { + if (getPageSetting('Praidingzone').includes(game.global.world) && ((cell <= 1) || (cell > 1 && (game.global.lastClearedCell + 1) >= cell)) && !prestraid && !failpraid) { + prestraidon = true; + if (getPageSetting('AutoMaps') == 1 && !prestraid && !failpraid) { + autoTrimpSettings["AutoMaps"].value = 0; + } + if (!game.global.preMapsActive && !game.global.mapsActive && !prestraid) { + mapsClicked(); + if (!game.global.preMapsActive) { + mapsClicked(); + } + debug("Beginning Prestige Raiding..."); + } + if (game.options.menu.repeatUntil.enabled != 2 && !prestraid) { + game.options.menu.repeatUntil.enabled = 2; + } + if (game.global.preMapsActive && !game.global.mapsActive && !prestraid) { + debug("Map Loop"); + if (pcheckmap5() == true && pcheck5() == true && pMap5 == undefined && !mapbought5 && game.global.preMapsActive && !prestraid) { + debug("Check complete for 5th map"); + plusPres5(); + if ((updateMapCost(true) <= game.resources.fragments.owned)) { + buyMap(); + mapbought5 = true; + if (mapbought5) { + pMap5 = game.global.mapsOwnedArray[game.global.mapsOwnedArray.length - 1].id; + debug("5th map bought"); + } + } + } + if (pcheckmap4() == true && pcheck4() == true && pMap4 == undefined && !mapbought4 && game.global.preMapsActive && !prestraid) { + debug("Check complete for 4th map"); + plusPres4(); + if ((updateMapCost(true) <= game.resources.fragments.owned)) { + buyMap(); + mapbought4 = true; + if (mapbought4) { + pMap4 = game.global.mapsOwnedArray[game.global.mapsOwnedArray.length - 1].id; + debug("4th map bought"); + } + } + } + if (pcheckmap3() == true && pcheck3() == true && pMap3 == undefined && !mapbought3 && game.global.preMapsActive && !prestraid) { + debug("Check complete for 3rd map"); + plusPres3(); + if ((updateMapCost(true) <= game.resources.fragments.owned)) { + buyMap(); + mapbought3 = true; + if (mapbought3) { + pMap3 = game.global.mapsOwnedArray[game.global.mapsOwnedArray.length - 1].id; + debug("3rd map bought"); + } + } + } + if (pcheckmap2() == true && pcheck2() == true && pMap2 == undefined && !mapbought2 && game.global.preMapsActive && !prestraid) { + debug("Check complete for 2nd map"); + plusPres2(); + if ((updateMapCost(true) <= game.resources.fragments.owned)) { + buyMap(); + mapbought2 = true; + if (mapbought2) { + pMap2 = game.global.mapsOwnedArray[game.global.mapsOwnedArray.length - 1].id; + debug("2nd map bought"); + } + } + } + if (pcheckmap1() == true && pcheck1() == true && pMap1 == undefined && !mapbought1 && game.global.preMapsActive && !prestraid) { + debug("Check complete for 1st map"); + plusPres1(); + if ((updateMapCost(true) <= game.resources.fragments.owned)) { + buyMap(); + mapbought1 = true; + if (mapbought1) { + pMap1 = game.global.mapsOwnedArray[game.global.mapsOwnedArray.length - 1].id; + debug("1st map bought"); + } + } + } + if (!mapbought1 && !mapbought2 && !mapbought3 && !mapbought4 && !mapbought5) { + if (getPageSetting('AutoMaps') == 0 && !prestraid) { + autoTrimpSettings["AutoMaps"].value = 1; + game.options.menu.repeatUntil.enabled = 0; + prestraidon = false; + failpraid = true; + praidDone = true; + pMap1 = undefined; + pMap2 = undefined; + pMap3 = undefined; + pMap4 = undefined; + pMap5 = undefined; + debug("Failed to Prestige Raid. Looks like you can't afford to or you are too weak or you have limited yourself in a P/I zone. "); + } + return; + } + } + if (game.global.preMapsActive && !game.global.mapsActive && mapbought1 && pMap1 != undefined && !prestraid) { + debug("running map 1"); + selectMap(pMap1); + runMap(); + repMap1 = pMap1; + pMap1 = undefined; + } + if (game.global.preMapsActive && !game.global.mapsActive && mapbought2 && pMap2 != undefined && !prestraid) { + debug("running map 2"); + selectMap(pMap2); + runMap(); + repMap2 = pMap2; + pMap2 = undefined; + } + if (game.global.preMapsActive && !game.global.mapsActive && mapbought3 && pMap3 != undefined && !prestraid) { + debug("running map 3"); + selectMap(pMap3); + runMap(); + repMap3 = pMap3; + pMap3 = undefined; + } + if (game.global.preMapsActive && !game.global.mapsActive && mapbought4 && pMap4 != undefined && !prestraid) { + debug("running map 4"); + selectMap(pMap4); + runMap(); + repMap4 = pMap4; + pMap4 = undefined; + } + if (game.global.preMapsActive && !game.global.mapsActive && mapbought5 && pMap5 != undefined && !prestraid) { + debug("running map 5"); + selectMap(pMap5); + runMap(); + repMap5 = pMap5; + pMap5 = undefined; + } + if (!prestraid && !game.global.repeatMap) { + repeatClicked(); + } + } + } + if (game.global.preMapsActive && (mapbought1 || mapbought2 || mapbought3 || mapbought4 || mapbought5) && pMap1 == undefined && pMap2 == undefined && pMap3 == undefined && pMap4 == undefined && pMap5 == undefined && !prestraid && !failpraid) { + prestraid = true; + failpraid = false; + mapbought1 = false; + mapbought2 = false; + mapbought3 = false; + mapbought4 = false; + mapbought5 = false; + } + if (getPageSetting('AutoMaps') == 0 && game.global.preMapsActive && prestraid && !failpraid && prestraidon) { + praidDone = true; + prestraidon = false; + if (repMap1 != undefined) { + recycleMap(getMapIndex(repMap1)); + repMap1 = undefined; + } + if (repMap2 != undefined) { + recycleMap(getMapIndex(repMap2)); + repMap2 = undefined; + } + if (repMap3 != undefined) { + recycleMap(getMapIndex(repMap3)); + repMap3 = undefined; + } + if (repMap4 != undefined) { + recycleMap(getMapIndex(repMap4)); + repMap4 = undefined; + } + if (repMap5 != undefined) { + recycleMap(getMapIndex(repMap5)); + repMap5 = undefined; + } + autoTrimpSettings["AutoMaps"].value = 1; + game.options.menu.repeatUntil.enabled = 0; + pMap1 = undefined; + pMap2 = undefined; + pMap3 = undefined; + pMap4 = undefined; + pMap5 = undefined; + debug("Prestige raiding successful!"); + debug("Turning AutoMaps back on"); + } + if (getPageSetting('Praidingzone').every(isBelowThreshold)) { + prestraid = false; + failpraid = false; + prestraidon = false; + mapbought1 = false; + mapbought2 = false; + mapbought3 = false; + mapbought4 = false; + mapbought5 = false; + pMap1 = undefined; + pMap2 = undefined; + pMap3 = undefined; + pMap4 = undefined; + pMap5 = undefined; + repMap1 = undefined; + repMap2 = undefined; + repMap3 = undefined; + repMap4 = undefined; + repMap5 = undefined; + praidDone = false; + } +} + +function PraidHarder() { + var maxPlusZones; + var mapModifiers = ["p", "fa", "0"]; + var farmFragments; + var praidBeforeFarm; + var pRaidIndex; + var maxPraidZSetting; + var cell; + + // Determine whether to use daily or normal run settings + if (game.global.challengeActive == "Daily") { + praidSetting = 'dPraidingzone'; + maxPraidZSetting = 'dMaxPraidZone'; + farmFragments = getPageSetting('dPraidFarmFragsZ').includes(game.global.world); + praidBeforeFarm = getPageSetting('dPraidBeforeFarmZ').includes(game.global.world); + cell = ((getPageSetting('dPraidingcell') > 0) ? getPageSetting('dPraidingcell') : 0); + } else { + praidSetting = 'Praidingzone'; + maxPraidZSetting = 'MaxPraidZone'; + farmFragments = getPageSetting('PraidFarmFragsZ').includes(game.global.world); + praidBeforeFarm = getPageSetting('PraidBeforeFarmZ').includes(game.global.world); + cell = ((getPageSetting('Praidingcell') > 0) ? getPageSetting('Praidingcell') : 0); + } + + pRaidIndex = getPageSetting(praidSetting).indexOf(game.global.world); + if (pRaidIndex == -1 || typeof(getPageSetting(maxPraidZSetting)[pRaidIndex]) === "undefined") maxPlusZones = plusMapToRun(game.global.world); + else maxPlusZones = getPageSetting(maxPraidZSetting)[pRaidIndex] - game.global.world; + + // Check we have a valid number for maxPlusZones + maxPlusZones = maxPlusZones > 10 ? 10 : (maxPlusZones < 0 ? 10 : maxPlusZones); + + // Work out the max number of +map zones it's worth farming for prestige. + if ((game.global.world + maxPlusZones) % 10 > 5) + maxPlusZones = Math.max(maxPlusZones + (5 - (game.global.world + maxPlusZones) % 10), 0); + else if ((game.global.world + maxPlusZones) % 10 == 0) + maxPlusZones = Math.min(5, maxPlusZones); + + // If we have any Praiding zones defined... + if (getPageSetting(praidSetting).length) { + if (getPageSetting(praidSetting).includes(game.global.world) && ((game.global.lastClearedCell + 1) >= cell) && !prestraid && !failpraid && !shouldFarmFrags) { + debug('Beginning Praiding'); + // Initialise shouldFarmFrags to false + shouldFarmFrags = false; + // Mark that we are prestige raiding and turn off automaps to stop it interfering + prestraidon = true; + autoTrimpSettings["AutoMaps"].value = 0; + // Get into the preMaps screen + if (!game.global.preMapsActive && !game.global.mapsActive) { + mapsClicked(); + if (!game.global.preMapsActive) { + mapsClicked(); + } + } + // Set repeat for items + game.options.menu.repeatUntil.enabled = 2; + toggleSetting("repeatUntil", null, false, true); + // if we can farm for fragments, work out the minimum number we need to get all available prestiges + if (farmFragments) { + plusPres(); + document.getElementById('advExtraLevelSelect').value = maxPlusZones; + document.getElementById('sizeAdvMapsRange').value = 0; + document.getElementById('difficultyAdvMapsRange').value = 0; + document.getElementById('advSpecialSelect').value = "0"; + minMaxMapCost = updateMapCost(true); + // If we are not Praiding before farming, and cannot afford a max plus map, set flags for farming + if (!praidBeforeFarm && game.resources.fragments.owned < minMaxMapCost) { + prestraid = true; + failpraid = false; + shouldFarmFrags = true; + } + } + // Set map settings to the best map for Praiding (even if we can't afford it) + plusPres(); + document.getElementById('advExtraLevelSelect').value = maxPlusZones; + // Iterate down through plusMaps setting until we find one we can afford + for (var curPlusZones = maxPlusZones; curPlusZones >= 0; curPlusZones--) { + // If the current targeted zone has no prestiges, decrement the number of plusZones and continue + if ((game.global.world + curPlusZones) % 10 == 0 || (game.global.world + curPlusZones) % 10 > 5) continue; + // Otherwise check to see if we can afford a map at the current plusZones setting + document.getElementById('advExtraLevelSelect').value = curPlusZones; + // If we find a map we can afford, break out of the loop + if (relaxMapReqs(mapModifiers)) break; + // conserve fragments if going to farm after by selecting only maps with no special modifier + else if (farmFragments) mapModifiers = ["0"]; + } + // If the map is not at the highest level with prestiges possible, set shouldFarmFrags to true + if (maxPlusZones > curPlusZones) shouldFarmFrags = true; + + // If we found a suitable map... + if (curPlusZones >= 0 && (praidBeforeFarm || shouldFarmFrags == false)) { + // ...buy it + buyMap(); + pMap = game.global.mapsOwnedArray[game.global.mapsOwnedArray.length - 1].id; + selectMap(pMap); + // Set flags to avoid rerunning this step + prestraid = true; + // prestraidon = false; + failpraid = false; + // Set repeat on and run the map + game.global.repeatMap = true; + runMap(); + repeatClicked(true); + } + // If we can't afford a map, and can't farm fragments, fail and turn automaps back on + else if (!farmFragments) { + failpraid = true; + prestraidon = false; + praidDone = true; + debug("Failed to prestige raid. Looks like you can't afford to."); + } else { + debug("Turning AutoMaps back on"); + autoTrimpSettings['AutoMaps'].value = 1; + game.options.menu.repeatUntil.enabled = 0; + } + return; + } + } + if (farmFragments && shouldFarmFrags && game.global.preMapsActive && prestraid && !fMap) { + if (pMap) recycleMap(getMapIndex(pMap)); + pMap = null; + // Choose a fragment farming map + document.getElementById("biomeAdvMapsSelect").value = "Depths"; + document.getElementById('advExtraLevelSelect').value = 0; + document.getElementById('advSpecialSelect').value = "fa"; + document.getElementById("lootAdvMapsRange").value = 9; + document.getElementById("difficultyAdvMapsRange").value = 9; + document.getElementById("sizeAdvMapsRange").value = 9; + document.getElementById('advPerfectCheckbox').checked = true; + document.getElementById("mapLevelInput").value = game.global.world - 1; + game.options.menu.repeatUntil.enabled = 0; + toggleSetting("repeatUntil", null, false, true); + if (updateMapCost(true) <= game.resources.fragments.owned) { + debug("Buying perfect sliders fragment farming map"); + buyMap(); + fMap = game.global.mapsOwnedArray[game.global.mapsOwnedArray.length - 1].id; + selectMap(fMap); + game.global.repeatMap = true; + runMap(); + repeatClicked(true); + } else { + document.getElementById('advPerfectCheckbox').checked = false; + if (updateMapCost(true) <= game.resources.fragments.owned) { + debug("Buying imperfect sliders fragment farming map"); + buyMap(); + fMap = game.global.mapsOwnedArray[game.global.mapsOwnedArray.length - 1].id; + selectMap(fMap); + game.global.repeatMap = true; + runMap(); + repeatClicked(true); + } + // if we can't buy a map, wait until the next main loop iteration and try again + else debug("Can't afford fragment farming map yet"); + } + } + + if ((game.global.mapsActive || game.global.preMapsActive) && minMaxMapCost <= game.resources.fragments.owned && shouldFarmFrags) { + game.global.repeatMap = false; + repeatClicked(true); + if (game.global.preMapsActive) { + minMaxMapCost = null; + shouldFarmFrags = false; + prestraid = false; + failpraid = false; + } + } + if (game.global.preMapsActive && prestraid && !failpraid && !shouldFarmFrags && prestraidon) { + prestraidon = false; + praidDone = true; + debug("Prestige raiding successful! - recycling Praid map"); + if (pMap) recycleMap(getMapIndex(pMap)); + if (fMap) recycleMap(getMapIndex(fMap)); + pMap = null; + fMap = null; + debug("Turning AutoMaps back on"); + game.options.menu.repeatUntil.enabled = 0; + autoTrimpSettings['AutoMaps'].value = 1; + } + + if (!getPageSetting(praidSetting).includes(game.global.world)) { + prestraid = false; + failpraid = false; + prestraidon = false; + shouldFarmFrags = false; + praidDone = false; + } +} + +function relaxMapReqs(mapModifiers) { + for (var j = 0; j < mapModifiers.length; j++) { + document.getElementById('sizeAdvMapsRange').value = 9; + document.getElementById('advSpecialSelect').value = mapModifiers[j]; + for (var i = 9; i >= 0; i--) { + document.getElementById('difficultyAdvMapsRange').value = i; + if (updateMapCost(true) <= game.resources.fragments.owned) return true; + } + for (i = 9; i >= 0; i--) { + document.getElementById('sizeAdvMapsRange').value = i; + if (updateMapCost(true) <= game.resources.fragments.owned) return true; + } + } + return false; +} + +function BWraiding() { + var bwraidZ; + var bwraidSetting; + var bwraidMax; + var isBWRaidZ; + var targetBW; + var bwIndex; + var cell; + + if (game.global.challengeActive == "Daily") { + bwraidZ = 'dBWraidingz'; + bwraidSetting = 'Dailybwraid'; + bwraidMax = 'dBWraidingmax'; + cell = ((getPageSetting('dbwraidcell') > 0) ? getPageSetting('dbwraidcell') : 1); + } else { + bwraidZ = 'BWraidingz'; + bwraidSetting = 'BWraid'; + bwraidMax = 'BWraidingmax'; + cell = ((getPageSetting('bwraidcell') > 0) ? getPageSetting('bwraidcell') : 1); + } + + isBWRaidZ = getPageSetting(bwraidZ).includes(game.global.world) && ((game.global.lastClearedCell + 1) >= cell); + bwIndex = getPageSetting(bwraidZ).indexOf(game.global.world); + if (bwIndex == -1 || typeof(getPageSetting(bwraidMax)[bwIndex]) === "undefined") targetBW = -1; + else targetBW = getPageSetting(bwraidMax)[bwIndex]; + + if (isBWRaidZ && !bwraided && !failbwraid && getPageSetting(bwraidSetting)) { + if (getPageSetting('AutoMaps') == 1 && !bwraided && !failbwraid) { + autoTrimpSettings["AutoMaps"].value = 0; + } + + game.options.menu.climbBw.enabled = 0; + + while (!game.global.preMapsActive && !bwraidon) mapsClicked(); + + if (game.options.menu.repeatUntil.enabled != 2 && !bwraided && !failbwraid) { + game.options.menu.repeatUntil.enabled = 2; + } + + if (game.global.preMapsActive && !bwraided && !failbwraid && findLastBionic()) { + selectMap(findLastBionic().id); + failbwraid = false; + debug("Beginning BW Raiding..."); + } else if (game.global.preMapsActive && !bwraided && !failbwraid) { + if (getPageSetting('AutoMaps') == 0 && isBWRaidZ && !bwraided) { + autoTrimpSettings["AutoMaps"].value = 1; + failbwraid = true; + debug("Failed to BW raid. Looks like you don't have a BW to raid..."); + } + } + + if (findLastBionic().level <= targetBW && !bwraided && !failbwraid && game.global.preMapsActive) { + runMap(); + bwraidon = true; + } + + if (!game.global.repeatMap && !bwraided && !failbwraid && game.global.mapsActive) { + repeatClicked(); + } + + if (findLastBionic().level > targetBW && !bwraided && !failbwraid) { + bwraided = true; + failbwraid = false; + bwraidon = false; + debug("...Successfully BW raided!"); + } + } + + if (getPageSetting('AutoMaps') == 0 && game.global.preMapsActive && bwraided && !failbwraid) { + autoTrimpSettings["AutoMaps"].value = 1; + debug("Turning AutoMaps back on"); + } + + if (!isBWRaidZ) { + bwraided = false; + failbwraid = false; + bwraidon = false; + } +} + +var dpMap1 = undefined; +var dpMap2 = undefined; +var dpMap3 = undefined; +var dpMap4 = undefined; +var dpMap5 = undefined; +var drepMap1 = undefined; +var drepMap2 = undefined; +var drepMap3 = undefined; +var drepMap4 = undefined; +var drepMap5 = undefined; +var dmapbought1 = false; +var dmapbought2 = false; +var dmapbought3 = false; +var dmapbought4 = false; +var dmapbought5 = false; +var dpraidDone = false; + +function dailyPraiding() { + var cell; + cell = ((getPageSetting('dPraidingcell') > 0) ? getPageSetting('dPraidingcell') : 0); + if (getPageSetting('dPraidingzone').length) { + if (getPageSetting('dPraidingzone').includes(game.global.world) && ((cell <= 1) || (cell > 1 && (game.global.lastClearedCell + 1) >= cell)) && !dprestraid && !dfailpraid) { + dprestraidon = true; + if (getPageSetting('AutoMaps') == 1 && !dprestraid && !dfailpraid) { + autoTrimpSettings["AutoMaps"].value = 0; + } + if (!game.global.preMapsActive && !game.global.mapsActive && !dprestraid) { + mapsClicked(); + if (!game.global.preMapsActive) { + mapsClicked(); + } + debug("Beginning Prestige Raiding..."); + } + if (game.options.menu.repeatUntil.enabled != 2 && !dprestraid) { + game.options.menu.repeatUntil.enabled = 2; + } + if (game.global.preMapsActive && !game.global.mapsActive && !dprestraid) { + debug("Map Loop"); + if (pcheckmap5() == true && pcheck5() == true && dpMap5 == undefined && !dmapbought5 && game.global.preMapsActive && !dprestraid) { + debug("Check complete for 5th map"); + plusPres5(); + if ((updateMapCost(true) <= game.resources.fragments.owned)) { + buyMap(); + dmapbought5 = true; + if (dmapbought5) { + dpMap5 = game.global.mapsOwnedArray[game.global.mapsOwnedArray.length - 1].id; + debug("5th map bought"); + } + } + } + if (pcheckmap4() == true && pcheck4() == true && dpMap4 == undefined && !dmapbought4 && game.global.preMapsActive && !dprestraid) { + debug("Check complete for 4th map"); + plusPres4(); + if ((updateMapCost(true) <= game.resources.fragments.owned)) { + buyMap(); + dmapbought4 = true; + if (dmapbought4) { + dpMap4 = game.global.mapsOwnedArray[game.global.mapsOwnedArray.length - 1].id; + debug("4th map bought"); + } + } + } + if (pcheckmap3() == true && pcheck3() == true && dpMap3 == undefined && !dmapbought3 && game.global.preMapsActive && !dprestraid) { + debug("Check complete for 3rd map"); + plusPres3(); + if ((updateMapCost(true) <= game.resources.fragments.owned)) { + buyMap(); + dmapbought3 = true; + if (dmapbought3) { + dpMap3 = game.global.mapsOwnedArray[game.global.mapsOwnedArray.length - 1].id; + debug("3rd map bought"); + } + } + } + if (pcheckmap2() == true && pcheck2() == true && dpMap2 == undefined && !dmapbought2 && game.global.preMapsActive && !dprestraid) { + debug("Check complete for 2nd map"); + plusPres2(); + if ((updateMapCost(true) <= game.resources.fragments.owned)) { + buyMap(); + dmapbought2 = true; + if (dmapbought2) { + dpMap2 = game.global.mapsOwnedArray[game.global.mapsOwnedArray.length - 1].id; + debug("2nd map bought"); + } + } + } + if (pcheckmap1() == true && pcheck1() == true && dpMap1 == undefined && !dmapbought1 && game.global.preMapsActive && !dprestraid) { + debug("Check complete for 1st map"); + plusPres1(); + if ((updateMapCost(true) <= game.resources.fragments.owned)) { + buyMap(); + dmapbought1 = true; + if (dmapbought1) { + dpMap1 = game.global.mapsOwnedArray[game.global.mapsOwnedArray.length - 1].id; + debug("1st map bought"); + } + } + } + if (!dmapbought1 && !dmapbought2 && !dmapbought3 && !dmapbought4 && !dmapbought5) { + if (getPageSetting('AutoMaps') == 0 && !dprestraid) { + autoTrimpSettings["AutoMaps"].value = 1; + game.options.menu.repeatUntil.enabled = 0; + dprestraidon = false; + dfailpraid = true; + dpraidDone = true; + dpMap1 = undefined; + dpMap2 = undefined; + dpMap3 = undefined; + dpMap4 = undefined; + dpMap5 = undefined; + debug("Failed to Prestige Raid. Looks like you can't afford to or you are too weak or you have limited yourself in a P/I zone. "); + } + return; + } + } + if (game.global.preMapsActive && !game.global.mapsActive && dmapbought1 && dpMap1 != undefined && !dprestraid) { + debug("running map 1"); + selectMap(dpMap1); + runMap(); + drepMap1 = dpMap1; + dpMap1 = undefined; + } + if (game.global.preMapsActive && !game.global.mapsActive && dmapbought2 && dpMap2 != undefined && !dprestraid) { + debug("running map 2"); + selectMap(dpMap2); + runMap(); + drepMap2 = dpMap2; + dpMap2 = undefined; + } + if (game.global.preMapsActive && !game.global.mapsActive && dmapbought3 && dpMap3 != undefined && !dprestraid) { + debug("running map 3"); + selectMap(dpMap3); + runMap(); + drepMap3 = dpMap3; + dpMap3 = undefined; + } + if (game.global.preMapsActive && !game.global.mapsActive && dmapbought4 && dpMap4 != undefined && !dprestraid) { + debug("running map 4"); + selectMap(dpMap4); + runMap(); + drepMap4 = dpMap4; + dpMap4 = undefined; + } + if (game.global.preMapsActive && !game.global.mapsActive && dmapbought5 && dpMap5 != undefined && !dprestraid) { + debug("running map 5"); + selectMap(dpMap5); + runMap(); + drepMap5 = dpMap5; + dpMap5 = undefined; + } + if (!dprestraid && !game.global.repeatMap) { + repeatClicked(); + } + } + } + if (game.global.preMapsActive && (dmapbought1 || dmapbought2 || dmapbought3 || dmapbought4 || dmapbought5) && pMap1 == undefined && dpMap2 == undefined && dpMap3 == undefined && dpMap4 == undefined && dpMap5 == undefined && !dprestraid && !dfailpraid) { + dprestraid = true; + dfailpraid = false; + dmapbought1 = false; + dmapbought2 = false; + dmapbought3 = false; + dmapbought4 = false; + dmapbought5 = false; + } + if (getPageSetting('AutoMaps') == 0 && game.global.preMapsActive && dprestraid && !dfailpraid && dprestraidon) { + dpraidDone = true; + dprestraidon = false; + if (drepMap1 != undefined) { + recycleMap(getMapIndex(drepMap1)); + drepMap1 = undefined; + } + if (drepMap2 != undefined) { + recycleMap(getMapIndex(drepMap2)); + drepMap2 = undefined; + } + if (drepMap3 != undefined) { + recycleMap(getMapIndex(drepMap3)); + drepMap3 = undefined; + } + if (drepMap4 != undefined) { + recycleMap(getMapIndex(drepMap4)); + drepMap4 = undefined; + } + if (drepMap5 != undefined) { + recycleMap(getMapIndex(drepMap5)); + drepMap5 = undefined; + } + autoTrimpSettings["AutoMaps"].value = 1; + game.options.menu.repeatUntil.enabled = 0; + pMap1 = undefined; + dpMap2 = undefined; + dpMap3 = undefined; + dpMap4 = undefined; + dpMap5 = undefined; + debug("Prestige raiding successful!"); + debug("Turning AutoMaps back on"); + } + if (getPageSetting('dPraidingzone').every(isBelowThreshold)) { + dprestraid = false; + dfailpraid = false; + dprestraidon = false; + dmapbought1 = false; + dmapbought2 = false; + dmapbought3 = false; + dmapbought4 = false; + dmapbought5 = false; + pMap1 = undefined; + dpMap2 = undefined; + dpMap3 = undefined; + dpMap4 = undefined; + dpMap5 = undefined; + repMap1 = undefined; + repMap2 = undefined; + repMap3 = undefined; + repMap4 = undefined; + repMap5 = undefined; + dpraidDone = false; + } +} + +function dailyBWraiding() { + var cell; + cell = ((getPageSetting('dbwraidcell') > 0) ? getPageSetting('dbwraidcell') : 1); + if (!dprestraidon && game.global.world == getPageSetting('dBWraidingz') && ((game.global.lastClearedCell + 1) >= cell) && !dbwraided && !dfailbwraid && getPageSetting('Dailybwraid')) { + if (getPageSetting('AutoMaps') == 1 && !dbwraided && !dfailbwraid) { + autoTrimpSettings["AutoMaps"].value = 0; + } + if (!game.global.preMapsActive && !game.global.mapsActive && !dbwraided && !dfailbwraid) { + mapsClicked(); + if (!game.global.preMapsActive) { + mapsClicked(); + } + } + if (game.options.menu.repeatUntil.enabled != 2 && !dbwraided && !dfailbwraid) { + game.options.menu.repeatUntil.enabled = 2; + } + + game.options.menu.climbBw.enabled = 0; + + if (game.global.preMapsActive && !dbwraided && !dfailbwraid) { + selectMap(findLastBionic().id); + dfailbwraid = false; + debug("Beginning Daily BW Raiding..."); + } else if (game.global.preMapsActive && !dbwraided && !dfailbwraid) { + if (getPageSetting('AutoMaps') == 0 && game.global.world == getPageSetting('dBWraidingz') && !dbwraided) { + autoTrimpSettings["AutoMaps"].value = 1; + dfailbwraid = true; + debug("Failed to Daily BW raid. Looks like you don't have a BW to raid..."); + } + } + if (findLastBionic().level <= getPageSetting('dBWraidingmax') && !dbwraided && !dfailbwraid && game.global.preMapsActive) { + runMap(); + dbwraidon = true; + } + if (!game.global.repeatMap && !dbwraided && !dfailbwraid && game.global.mapsActive) { + repeatClicked(); + } + if (findLastBionic().level > getPageSetting('dBWraidingmax') && !dbwraided && !dfailbwraid) { + dbwraided = true; + dfailbwraid = false; + dbwraidon = false; + debug("...Successfully Daily BW raided!"); + } + if (getPageSetting('AutoMaps') == 0 && game.global.preMapsActive && game.global.world == getPageSetting('dBWraidingz') && dbwraided && !dfailbwraid) { + autoTrimpSettings["AutoMaps"].value = 1; + debug("Turning AutoMaps back on"); + } + } + if (getPageSetting('AutoMaps') == 0 && game.global.preMapsActive && dbwraided && !dfailbwraid) { + autoTrimpSettings["AutoMaps"].value = 1; + debug("Turning AutoMaps back on"); + } + if (dbwraided && !dfailbwraid && game.global.world !== getPageSetting('dBWraidingz')) { + dbwraided = false; + dfailbwraid = false; + dbwraidon = false; + } +} + +function trimpcide() { + if (game.portal.Anticipation.level > 0) { + var antistacklimit = (game.talents.patience.purchased) ? 45 : 30; + if (game.global.fighting && ((game.jobs.Amalgamator.owned > 0) ? Math.floor((new Date().getTime() - game.global.lastSoldierSentAt) / 1000) : Math.floor(game.global.lastBreedTime / 1000)) >= antistacklimit && (game.global.antiStacks < antistacklimit || antistacklimit == 0 && game.global.antiStacks >= 1) && !game.global.spireActive) + forceAbandonTrimps(); + if (game.global.fighting && ((game.jobs.Amalgamator.owned > 0) ? Math.floor((new Date().getTime() - game.global.lastSoldierSentAt) / 1000) : Math.floor(game.global.lastBreedTime / 1000)) >= antistacklimit && game.global.antiStacks < antistacklimit && game.global.mapsActive) { + if (getCurrentMapObject().location == "Void") { + abandonVoidMap(); + } + } + } +} + +function avoidempower() { + if (armydeath()) { + if (typeof game.global.dailyChallenge.bogged === 'undefined' && typeof game.global.dailyChallenge.plague === 'undefined') { + mapsClicked(true); + return; + } + } +} + +var spirebreeding = false; + +function ATspirebreed() { + if (!spirebreeding && getPageSetting('SpireBreedTimer') > 0 && getPageSetting('IgnoreSpiresUntil') <= game.global.world && game.global.spireActive) + var prespiretimer = game.global.GeneticistassistSetting; + if (getPageSetting('SpireBreedTimer') > 0 && getPageSetting('IgnoreSpiresUntil') <= game.global.world && game.global.spireActive && game.global.GeneticistassistSetting != getPageSetting('SpireBreedTimer')) { + spirebreeding = true; + if (game.global.GeneticistassistSetting != getPageSetting('SpireBreedTimer')) + game.global.GeneticistassistSetting = getPageSetting('SpireBreedTimer'); + } + if (getPageSetting('SpireBreedTimer') > 0 && getPageSetting('IgnoreSpiresUntil') <= game.global.world && !game.global.spireActive && game.global.GeneticistassistSetting == getPageSetting('SpireBreedTimer')) { + spirebreeding = false; + if (game.global.GeneticistassistSetting == getPageSetting('SpireBreedTimer')) { + game.global.GeneticistassistSetting = prespiretimer; + toggleGeneticistassist(); + toggleGeneticistassist(); + toggleGeneticistassist(); + toggleGeneticistassist(); + } + } +} + +function fightalways() { + if (game.global.gridArray.length === 0 || game.global.preMapsActive || !game.upgrades.Battle.done || game.global.fighting || (game.global.spireActive && game.global.world >= getPageSetting('IgnoreSpiresUntil'))) + return; + if (!game.global.fighting) + fightManual(); +} + +function armormagic() { + var armormagicworld = Math.floor((game.global.highestLevelCleared + 1) * 0.8); + if (((getPageSetting('carmormagic') == 1 || getPageSetting('darmormagic') == 1) && game.global.world >= armormagicworld && (game.global.soldierHealth <= game.global.soldierHealthMax * 0.4)) || ((getPageSetting('carmormagic') == 2 || getPageSetting('darmormagic') == 2) && calcHDratio() >= MODULES["maps"].enoughDamageCutoff && (game.global.soldierHealth <= game.global.soldierHealthMax * 0.4)) || ((getPageSetting('carmormagic') == 3 || getPageSetting('darmormagic') == 3) && (game.global.soldierHealth <= game.global.soldierHealthMax * 0.4))) + buyArms(); +} + +trapIndexs = ["", "Fire", "Frost", "Poison", "Lightning", "Strength", "Condenser", "Knowledge"]; + +function tdStringCode2() { + var thestring = document.getElementById('importBox').value.replace(/\s/g, ''); + var s = new String(thestring); + var index = s.indexOf("+", 0); + s = s.slice(0, index); + var length = s.length; + + var saveLayout = []; + for (var i = 0; i < length; i++) { + saveLayout.push(trapIndexs[s.charAt(i)]); + } + playerSpire['savedLayout' + -1] = saveLayout; + + if ((playerSpire.runestones + playerSpire.getCurrentLayoutPrice()) < playerSpire.getSavedLayoutPrice(-1)) return false; + playerSpire.resetTraps(); + for (var x = 0; x < saveLayout.length; x++) { + if (!saveLayout[x]) continue; + playerSpire.buildTrap(x, saveLayout[x]); + } +} + +var oldPlayerSpireDrawInfo = playerSpire.drawInfo; +playerSpire.drawInfo = function(arguments) { + var ret = oldPlayerSpireDrawInfo.apply(this, arguments); + var elem = document.getElementById('spireTrapsWindow'); + if (!elem) return arguments; + var importBtn = "
Import
"; + elem.innerHTML = importBtn + elem.innerHTML; + return arguments; +} + +//Radon +function RbuyWeps() { + if (!((getPageSetting('RBuyWeaponsNew') == 1) || (getPageSetting('RBuyWeaponsNew') == 3))) return; + preBuy(), game.global.buyAmt = getPageSetting('Rgearamounttobuy'), game.equipment.Dagger.level < getPageSetting('RCapEquip2') && canAffordBuilding('Dagger', null, null, !0) && buyEquipment('Dagger', !0, !0), game.equipment.Mace.level < getPageSetting('RCapEquip2') && canAffordBuilding('Mace', null, null, !0) && buyEquipment('Mace', !0, !0), game.equipment.Polearm.level < getPageSetting('RCapEquip2') && canAffordBuilding('Polearm', null, null, !0) && buyEquipment('Polearm', !0, !0), game.equipment.Battleaxe.level < getPageSetting('RCapEquip2') && canAffordBuilding('Battleaxe', null, null, !0) && buyEquipment('Battleaxe', !0, !0), game.equipment.Greatsword.level < getPageSetting('RCapEquip2') && canAffordBuilding('Greatsword', null, null, !0) && buyEquipment('Greatsword', !0, !0), !game.equipment.Arbalest.locked && game.equipment.Arbalest.level < getPageSetting('RCapEquip2') && canAffordBuilding('Arbalest', null, null, !0) && buyEquipment('Arbalest', !0, !0), postBuy() +} + +function RbuyArms() { + if (!((getPageSetting('RBuyArmorNew') == 1) || (getPageSetting('RBuyArmorNew') == 3))) return; + preBuy(), game.global.buyAmt = 10, game.equipment.Shield.level < getPageSetting('RCapEquiparm') && canAffordBuilding('Shield', null, null, !0) && buyEquipment('Shield', !0, !0), game.equipment.Boots.level < getPageSetting('RCapEquiparm') && canAffordBuilding('Boots', null, null, !0) && buyEquipment('Boots', !0, !0), game.equipment.Helmet.level < getPageSetting('RCapEquiparm') && canAffordBuilding('Helmet', null, null, !0) && buyEquipment('Helmet', !0, !0), game.equipment.Pants.level < getPageSetting('RCapEquiparm') && canAffordBuilding('Pants', null, null, !0) && buyEquipment('Pants', !0, !0), game.equipment.Shoulderguards.level < getPageSetting('RCapEquiparm') && canAffordBuilding('Shoulderguards', null, null, !0) && buyEquipment('Shoulderguards', !0, !0), game.equipment.Breastplate.level < getPageSetting('RCapEquiparm') && canAffordBuilding('Breastplate', null, null, !0) && buyEquipment('Breastplate', !0, !0), !game.equipment.Gambeson.locked && game.equipment.Gambeson.level < getPageSetting('RCapEquiparm') && canAffordBuilding('Gambeson', null, null, !0) && buyEquipment('Gambeson', !0, !0), postBuy() +} + +function Rhelptrimpsnotdie() { + if (!game.global.preMapsActive && !game.global.fighting) RbuyArms(); +} + +var Rprestraid = !1, + Rdprestraid = !1, + Rfailpraid = !1, + Rdfailpraid = !1, + Rbwraided = !1, + Rdbwraided = !1, + Rfailbwraid = !1, + Rdfailbwraid = !1, + Rprestraidon = !1, + Rdprestraidon = !1, + Rmapbought = !1, + Rdmapbought = !1, + Rbwraidon = !1, + Rdbwraidon = !1, + Rpresteps = null, + RminMaxMapCost, RfMap, RpMap, RshouldFarmFrags = !1, + RpraidDone = !1; + +function Rfightalways() { + if (game.global.gridArray.length === 0 || game.global.preMapsActive || !game.upgrades.Battle.done || game.global.fighting) + return; + if (!game.global.fighting) + fightManual(); +} + +function Rarmormagic() { + var armormagicworld = Math.floor((game.global.highestLevelCleared + 1) * 0.8); + if (((getPageSetting('Rcarmormagic') == 1 || getPageSetting('Rdarmormagic') == 1) && game.global.world >= armormagicworld && (game.global.soldierHealth <= game.global.soldierHealthMax * 0.4)) || ((getPageSetting('Rcarmormagic') == 2 || getPageSetting('Rdarmormagic') == 2) && RcalcHDratio() >= MODULES["maps"].RenoughDamageCutoff && (game.global.soldierHealth <= game.global.soldierHealthMax * 0.4)) || ((getPageSetting('Rcarmormagic') == 3 || getPageSetting('Rdarmormagic') == 3) && (game.global.soldierHealth <= game.global.soldierHealthMax * 0.4))) + RbuyArms(); +} + +function questcheck() { + if (game.global.world < game.challenges.Quest.getQuestStartZone()) { + return 0; + } + //x5 resource + if (game.challenges.Quest.getQuestDescription() == "Quintuple (x5) your food" && game.challenges.Quest.getQuestProgress() != "Quest Complete!" && game.challenges.Quest.getQuestProgress() != "Failed!") + return 10; + else if (game.challenges.Quest.getQuestDescription() == "Quintuple (x5) your wood" && game.challenges.Quest.getQuestProgress() != "Quest Complete!" && game.challenges.Quest.getQuestProgress() != "Failed!") + return 11; + else if (game.challenges.Quest.getQuestDescription() == "Quintuple (x5) your metal" && game.challenges.Quest.getQuestProgress() != "Quest Complete!" && game.challenges.Quest.getQuestProgress() != "Failed!") + return 12; + else if (game.challenges.Quest.getQuestDescription() == "Quintuple (x5) your gems" && game.challenges.Quest.getQuestProgress() != "Quest Complete!" && game.challenges.Quest.getQuestProgress() != "Failed!") + return 13; + else if (game.challenges.Quest.getQuestDescription() == "Quintuple (x5) your science" && game.challenges.Quest.getQuestProgress() != "Quest Complete!" && game.challenges.Quest.getQuestProgress() != "Failed!") + return 14; + //x2 resource + else if (game.challenges.Quest.getQuestDescription() == "Double your food" && game.challenges.Quest.getQuestProgress() != "Quest Complete!" && game.challenges.Quest.getQuestProgress() != "Failed!") + return 20; + else if (game.challenges.Quest.getQuestDescription() == "Double your wood" && game.challenges.Quest.getQuestProgress() != "Quest Complete!" && game.challenges.Quest.getQuestProgress() != "Failed!") + return 21; + else if (game.challenges.Quest.getQuestDescription() == "Double your metal" && game.challenges.Quest.getQuestProgress() != "Quest Complete!" && game.challenges.Quest.getQuestProgress() != "Failed!") + return 22; + else if (game.challenges.Quest.getQuestDescription() == "Double your gems" && game.challenges.Quest.getQuestProgress() != "Quest Complete!" && game.challenges.Quest.getQuestProgress() != "Failed!") + return 23; + else if (game.challenges.Quest.getQuestDescription() == "Double your science" && game.challenges.Quest.getQuestProgress() != "Quest Complete!" && game.challenges.Quest.getQuestProgress() != "Failed!") + return 24; + //Everything else + else if (game.challenges.Quest.getQuestDescription() == "Complete 5 Maps at Zone level" && game.challenges.Quest.getQuestProgress() != "Quest Complete!" && game.challenges.Quest.getQuestProgress() != "Failed!") + return 3; + else if (game.challenges.Quest.getQuestDescription() == "One-shot 5 world enemies" && game.challenges.Quest.getQuestProgress() != "Quest Complete!" && game.challenges.Quest.getQuestProgress() != "Failed!") + return 4; + else if (game.challenges.Quest.getQuestDescription() == "Don't let your shield break before Cell 100" && game.challenges.Quest.getQuestProgress() != "Quest Complete!" && game.challenges.Quest.getQuestProgress() != "Failed!") + return 5; + else if (game.challenges.Quest.getQuestDescription() == "Don't run a map before Cell 100" && game.challenges.Quest.getQuestProgress() != "Quest Complete!" && game.challenges.Quest.getQuestProgress() != "Failed!") + return 6; + else if (game.challenges.Quest.getQuestDescription() == "Buy a Smithy" && game.challenges.Quest.getQuestProgress() != "Quest Complete!" && game.challenges.Quest.getQuestProgress() != "Failed!") + return 7; + else + return 0; +} + +function Rgetequipcost(equip, resource, amt) { + var cost = Math.ceil(getBuildingItemPrice(game.equipment[equip], resource, true, amt) * (Math.pow(amt - game.portal.Artisanistry.modifier, game.portal.Artisanistry.radLevel))); + return cost; +} + +//smithylogic('Shield', 'wood', true) +function smithylogic(name, resource, equip) { + + var go = true; + + //Checks + + if (getPageSetting('Rsmithylogic') == false || getPageSetting('Rsmithynumber') <= 0 || getPageSetting('Rsmithypercent') <= 0 || getPageSetting('Rsmithyseconds') <= 0) { + return go; + } + if (getPageSetting('Rsmithynumber') > 0 && getPageSetting('Rsmithynumber') >= game.buildings.Smithy.owned) { + return go; + } + if (name == undefined) { + return go; + } + + //Vars + + var amt = (getPageSetting('Rgearamounttobuy') > 0) ? getPageSetting('Rgearamounttobuy') : 1; + var percent = (getPageSetting('Rsmithypercent') / 100); + var seconds = getPageSetting('Rsmithyseconds'); + var resourcesecwood = getPsString("wood", true); + var resourcesecmetal = getPsString("metal", true); + var resourcesecgems = getPsString("gems", true); + var smithywood = getBuildingItemPrice(game.buildings.Smithy, "wood", false, 1); + var smithymetal = getBuildingItemPrice(game.buildings.Smithy, "metal", false, 1); + var smithygems = getBuildingItemPrice(game.buildings.Smithy, "gems", false, 1); + var smithypercentwood = smithywood * percent; + var smithypercentmetal = smithymetal * percent; + var smithypercentgems = smithygems * percent; + var smithyclosewood = ((smithywood / resourcesecwood) <= seconds); + var smithyclosemetal = ((smithymetal / resourcesecmetal) <= seconds); + var smithyclosegems = ((smithygems / resourcesecgems) <= seconds); + + var itemwood = null; + var itemmetal = null; + var itemgems = null; + + if (!equip) { + if (name == "Hut") { + itemwood = getBuildingItemPrice(game.buildings[name], "wood", false, amt); + } else if (name == "House") { + itemwood = getBuildingItemPrice(game.buildings[name], "wood", false, amt); + itemmetal = getBuildingItemPrice(game.buildings[name], "metal", false, amt); + } else if (name == "Mansion") { + itemwood = getBuildingItemPrice(game.buildings[name], "wood", false, amt); + itemmetal = getBuildingItemPrice(game.buildings[name], "metal", false, amt); + itemgems = getBuildingItemPrice(game.buildings[name], "gems", false, amt); + } else if (name == "Hotel") { + itemwood = getBuildingItemPrice(game.buildings[name], "wood", false, amt); + itemmetal = getBuildingItemPrice(game.buildings[name], "metal", false, amt); + itemgems = getBuildingItemPrice(game.buildings[name], "gems", false, amt); + } else if (name == "Resort") { + itemwood = getBuildingItemPrice(game.buildings[name], "wood", false, amt); + itemmetal = getBuildingItemPrice(game.buildings[name], "metal", false, amt); + itemgems = getBuildingItemPrice(game.buildings[name], "gems", false, amt); + } else if (name == "Gateway") { + itemmetal = getBuildingItemPrice(game.buildings[name], "metal", false, amt); + itemgems = getBuildingItemPrice(game.buildings[name], "gems", false, amt); + } else if (name == "Collector") { + itemgems = getBuildingItemPrice(game.buildings[name], "gems", false, amt); + } + } else if (equip && name == "Shield") { + itemwood = Rgetequipcost("Shield", "wood", amt); + } else if (equip && name != "Shield") { + itemmetal = Rgetequipcost(name, resource, amt); + } + + if (itemwood == null && itemmetal == null && itemgems == null) { + return go; + } + if (!smithyclosewood && !smithyclosemetal && !smithyclosegems) { + return go; + } else if (smithyclosewood && itemwood > smithypercentwood && (name == "Shield" || name == "Hut" || name == "House" || name == "Mansion" || name == "Hotel" || name == "Resort")) { + go = false; + return go; + } else if (smithyclosemetal && itemmetal > smithypercentmetal && ((equip && name != "Shield") || name == "House" || name == "Mansion" || name == "Hotel" || name == "Resort" || name == "Gateway")) { + go = false; + return go; + } else if (smithyclosegems && itemgems > smithypercentgems && (name == "Mansion" || name == "Hotel" || name == "Resort" || name == "Gateway" || name == "Collector")) { + go = false; + return go; + } else if (smithyclosewood && itemwood <= smithypercentwood && (name == "Shield" || name == "Hut" || name == "House" || name == "Mansion" || name == "Hotel" || name == "Resort")) { + go = true; + return go; + } else if (smithyclosemetal && itemmetal <= smithypercentmetal && ((equip && name != "Shield") || name == "House" || name == "Mansion" || name == "Hotel" || name == "Resort" || name == "Gateway")) { + go = true; + return go; + } else if (smithyclosegems && itemgems <= smithypercentgems && (name == "Mansion" || name == "Hotel" || name == "Resort" || name == "Gateway" || name == "Collector")) { + go = true; + return go; + } +} + +function archstring() { + if (getPageSetting('Rarchon') == false) return; + if (getPageSetting('Rarchstring1') != "undefined" && getPageSetting('Rarchstring2') != "undefined" && getPageSetting('Rarchstring3') != "undefined") { + var string1 = getPageSetting('Rarchstring1'), + string2 = getPageSetting('Rarchstring2'), + string3 = getPageSetting('Rarchstring3'); + var string1z = string1.split(',')[0], + string2z = string2.split(',')[0]; + var string1split = string1.split(',').slice(1).toString(), + string2split = string2.split(',').slice(1).toString(); + if (game.global.world <= string1z && game.global.archString != string1split) { + game.global.archString = string1split; + } + if (game.global.world > string1z && game.global.world <= string2z && game.global.archString != string2split) { + game.global.archString = string2split; + } + if (game.global.world > string2z && game.global.archString != string3) { + game.global.archString = string3; + } + } +} + +var fastimps = [ + "Snimp", + "Kittimp", + "Gorillimp", + "Squimp", + "Shrimp", + "Chickimp", + "Frimp", + "Slagimp", + "Lavimp", + "Kangarimp", + "Entimp", + "Fusimp", + "Carbimp", + "Shadimp", + "Voidsnimp", + "Prismimp", + "Sweltimp", + "Indianimp", + "Improbability", + "Neutrimp", + "Cthulimp", + "Omnipotrimp", + "Mutimp", + "Hulking_Mutimp", + "Liquimp", + "Poseidimp", + "Darknimp", + "Horrimp", + "Arachnimp", + "Beetlimp", + "Mantimp", + "Butterflimp", + "Frosnimp", + "Turkimp", + "Ubersmith" +]; + +function Rmanageequality() { + + if (!(game.global.challengeActive == "Exterminate" && getPageSetting('Rexterminateon') == true && getPageSetting('Rexterminateeq') == true && !game.global.mapsActive)) { + if ( + (game.global.challengeActive == "Glass") || + (fastimps.includes(getCurrentEnemy().name)) || + (game.global.mapsActive && getCurrentMapObject().location == "Void" && game.global.voidBuff == 'doubleAttack') || + (!game.global.mapsActive && game.global.gridArray[game.global.lastClearedCell+1].u2Mutation.length > 0) || + (game.global.mapsActive && game.global.challengeActive == "Desolation") + ) { + if (!game.portal.Equality.scalingActive) { + game.portal.Equality.scalingActive = true; + manageEqualityStacks(); + updateEqualityScaling(); + } + } else { + if (game.portal.Equality.scalingActive) { + game.portal.Equality.scalingActive = false; + game.portal.Equality.disabledStackCount = "0"; + manageEqualityStacks(); + updateEqualityScaling(); + } + } + } else if (game.global.challengeActive == "Exterminate" && getPageSetting('Rexterminateon') == true && getPageSetting('Rexterminateeq') == true && !game.global.mapsActive) { + if ((getCurrentEnemy().name == "Arachnimp" || getCurrentEnemy().name == "Beetlimp" || getCurrentEnemy().name == "Mantimp" || getCurrentEnemy().name == "Butterflimp") && !game.challenges.Exterminate.experienced) { + if (!game.portal.Equality.scalingActive) { + game.portal.Equality.scalingActive = true; + manageEqualityStacks(); + updateEqualityScaling(); + } + } else if ((getCurrentEnemy().name == "Arachnimp" || getCurrentEnemy().name == "Beetlimp" || getCurrentEnemy().name == "Mantimp" || getCurrentEnemy().name == "Butterflimp") && game.challenges.Exterminate.experienced) { + if (game.portal.Equality.scalingActive) { + game.portal.Equality.scalingActive = false; + game.portal.Equality.disabledStackCount = "0"; + manageEqualityStacks(); + updateEqualityScaling(); + } + } + } +} + +function autoshrine() { + var universe; + var mode = game.global.challengeActive == "Daily" ? "Daily" : "Standard"; + + switch (game.global.universe) { + case 1: + universe = "Helium"; + break; + case 2: + universe = "Radon"; + break; + } + + var shrineSettings = { + Helium: { + Standard: { + core: "Hshrine", + zone: "Hshrinezone", + amount: "Hshrineamount", + cell: "Hshrinecell", + charge: "Hshrinecharge", + }, + Daily: { + core: "Hdshrine", + zone: "Hdshrinezone", + amount: "Hdshrineamount", + cell: "Hdshrinecell", + charge: "Hshrinecharge", + }, + }, + Radon: { + Standard: { + core: "Rshrine", + zone: "Rshrinezone", + amount: "Rshrineamount", + cell: "Rshrinecell", + charge: "Rshrinecharge", + }, + Daily: { + core: "Rdshrine", + zone: "Rdshrinezone", + amount: "Rdshrineamount", + cell: "Rdshrinecell", + charge: "Rshrinecharge", + }, + }, + }; + + if (getPageSetting(shrineSettings[universe][mode].core) && game.permaBoneBonuses.boosts.charges > 0) { + var shrinezone = getPageSetting(shrineSettings[universe][mode].zone); + if (shrinezone.includes(game.global.world)) { + var shrineamount = getPageSetting(shrineSettings[universe][mode].amount); + var shrineindex = shrinezone.indexOf(game.global.world); + var shrinecell = getPageSetting(shrineSettings[universe][mode].cell)[shrineindex]; + var shrinezones = shrineamount[shrineindex]; + + shrinezones = shrinezones - autoTrimpSettings[shrineSettings[universe][mode].charge].value; + + if (game.global.lastClearedCell + 2 >= shrinecell && shrinezones > 0) { + game.permaBoneBonuses.boosts.consume(); + autoTrimpSettings[shrineSettings[universe][mode].charge].value += 1; + } + } + } +} + +var old_nextWorld = nextWorld; +nextWorld = function() { + var retVal = old_nextWorld(...arguments); + autoTrimpSettings.Hshrinecharge.value = 0; + autoTrimpSettings.Rshrinecharge.value = 0; + return retVal; +} + +function autoBoneChargeWhenMax() { + // Uses bone charges when they are at max charges automatically. + + // If "Daily Only" was chosen and we're not on a daily challenge, exit. + if ( + getPageSetting("AutoBoneChargeMax") === 2 && + !(game.global.challengeActive == "Daily") + ) { + return; + } + + // If the option is enabled but no zone is specified, set a default value to + // the highest zone cleared - 10% or 60 (broken planet equipment discount) + // if the HZC value would be less than 60. Otherwise use the user value. + const autoBoneChargeEnabled = + getPageSetting("AutoBoneChargeMax") > 0 ? true : false; + const autoBoneChargeZoneSet = + getPageSetting("AutoBoneChargeMaxStartZone") > 0 ? true : false; + const highestZoneCleared = game.global.highestLevelCleared; + const percentOfHZC = Math.round((10 / 100) * highestZoneCleared); + const optimalChargeZone = + highestZoneCleared - percentOfHZC > 60 + ? highestZoneCleared - percentOfHZC + : 60; + const chargeZone = !autoBoneChargeZoneSet + ? optimalChargeZone + : autoTrimpSettings.AutoBoneChargeMaxStartZone.value; + const boneChargesAvailable = game.permaBoneBonuses.boosts.charges; + const currentZone = game.global.world; + + // If we have more than 10 bone charges and our current world zone is + // greater than or equal to the charge zone set; use a bone charge. + if (boneChargesAvailable === 10 && currentZone >= chargeZone) { + game.permaBoneBonuses.boosts.consume(); + debug("Max bone charges reached! Used a bone charge.", "general", "*bolt"); + } +} + +function Rarmydeath() { + if (game.global.mapsActive) return false; + var cell = game.global.lastClearedCell + 1; + var attack = game.global.gridArray[cell].attack * dailyModifiers.empower.getMult(game.global.dailyChallenge.empower.strength, game.global.dailyChallenge.empower.stacks) * Math.pow(game.portal.Equality.modifier, game.portal.Equality.scalingCount); + var health = game.global.soldierHealth + game.global.soldierEnergyShield; + var healthmax = game.global.soldierHealthMax * (Fluffy.isRewardActive('shieldlayer') ? 1 + (getEnergyShieldMult() * (1 + Fluffy.isRewardActive('shieldlayer'))) : 1 + getEnergyShieldMult()); + + if (attack >= healthmax && game.portal.Equality.getActiveLevels() < game.portal.Equality.radLevel) return false; + else if (attack >= health) return true; + else return false; +} + +function Ravoidempower() { + if (Rarmydeath()) { + if (typeof game.global.dailyChallenge.bogged === 'undefined' && typeof game.global.dailyChallenge.plague === 'undefined') { + mapsClicked(true); + return; + } + } } diff --git a/modules/performance.js b/modules/performance.js index 79661e2de..1508ca9c1 100644 --- a/modules/performance.js +++ b/modules/performance.js @@ -141,9 +141,15 @@ M["performance"].UpdateAFKOverlay = function UpdateAFKOverlay() { - M["performance"].AFKOverlayZone.innerText = 'Current Zone: ' + game.global.world; - M["performance"].AFKOverlayHelium.innerText = 'Current Helium: ' + prettify(Math.floor(game.resources.helium.owned)); - M["performance"].AFKOverlayStatus.innerHTML = 'Current Status: ' + updateAutoMapsStatus(true)[0]; + M["performance"].AFKOverlayZone.innerText = 'Zone: ' + game.global.world + (game.global.mapsActive ? " (Map: " + ((getCurrentMapObject().level - game.global.world) >= 0 ? "+" : "") + (getCurrentMapObject().level - game.global.world) + " " + (getCurrentMapObject().bonus !== undefined ? getCurrentMapObject().bonus : "") + ")" : "") + if (game.global.universe == 1) { + M["performance"].AFKOverlayHelium.innerText = 'Current Helium: ' + prettify(Math.floor(game.resources.helium.owned)); + M["performance"].AFKOverlayStatus.innerHTML = 'Current Status: ' + updateAutoMapsStatus(true)[0]; + } + if (game.global.universe == 2) { + M["performance"].AFKOverlayHelium.innerText = 'Current Radon: ' + prettify(Math.floor(game.resources.radon.owned)); + M["performance"].AFKOverlayStatus.innerHTML = 'Current Status: ' + RupdateAutoMapsStatus(true)[0]; + } } })(MODULES, window); diff --git a/modules/perks.js b/modules/perks.js index 835bb38b8..fd3f3898f 100644 --- a/modules/perks.js +++ b/modules/perks.js @@ -1,71 +1,43 @@ -// ==UserScript== -// @name AutoPerks -// @namespace http://tampermonkey.net/ -// @version 1.1.2-4-2-2018+genBTC -// @description Trimps Automatic Perk Calculator -// @author zxv, genBTC -// @include *trimps.github.io* -// @include *kongregate.com/games/GreenSatellite/trimps -// @grant none -// ==/UserScript== - -//Create blank AutoPerks object var AutoPerks = {}; MODULES["perks"] = {}; -MODULES["perks"].showDetails = true; //show which individual perks are spent; -MODULES["perks"].useAlgo2 = false; //use algorithm 2 instead. +MODULES["perks"].showDetails = true; -//Import the FastPriorityQueue.js general Library (not AT specific, but needed for perk queue) var head = document.getElementsByTagName('head')[0]; var queuescript = document.createElement('script'); queuescript.type = 'text/javascript'; -//This does not need to be changed to your own repo. Its a 3rd party file. -queuescript.src = 'https://genbtc.github.io/AutoTrimps/FastPriorityQueue.js'; +queuescript.src = 'https://Zorn192.github.io/AutoTrimps/FastPriorityQueue.js'; head.appendChild(queuescript); - -//-------------------------------------- -//Ratio Presets - Perk proportions: -// (in perk order): [looting,toughness,power,motivation,pheromones,artisanistry,carpentry,resilience,coordinated,resourceful,overkill,cunning,curious]; -var preset_ZXV = [20, 0.5, 1, 1.5, 0.5, 1.5, 8, 1, 25, 2, 3, 1, 1]; -var preset_ZXVnew = [50, 0.75, 1, 3, 0.75, 3, 10, 1.5, 60, 2, 5, 1, 1]; -var preset_ZXV3 = [100, 1, 3, 3, 1, 3, 40, 2, 100, 1, 3, 1, 1]; -var preset_TruthEarly = [30, 4, 4, 4, 4, 2, 24, 8, 60, 2, 3, 1, 1]; -var preset_TruthLate = [120, 4, 4, 4, 4, 2, 24, 8, 60, 2, 3, 1, 1]; -var preset_nsheetz = [42, 1.75, 5, 4, 1.5, 5, 29, 3.5, 100, 1, 5, 1, 1]; -var preset_nsheetzNew= [160, 1.5, 5, 2.5, 1.5, 3.5, 18, 3, 100, 1, 10, 1, 1]; -var preset_HiderHehr = [90, 4, 12, 10, 1, 8, 8, 1, 20, 0.1, 3, 1, 1]; -var preset_HiderBalance = [75, 4, 8, 4, 1, 4, 24, 1, 75, 0.5, 3, 1, 1]; -var preset_HiderMore = [20, 4, 10, 12, 1, 8, 8, 1, 40, 0.1, 0.5, 1, 1]; -var preset_genBTC = [100, 8, 8, 4, 4, 5, 18, 8, 14, 1, 1, 1, 1]; -var preset_genBTC2 = [96, 19, 15.4, 8, 8, 7, 14, 19, 11, 1, 1, 1, 1]; -var preset_Zek450 = [300, 1, 30, 2, 4, 2, 9, 8, 17, 0.1, 1, 320, 1]; -var preset_Zek4502 = [350, 1, 40, 2, 3, 2, 5, 8, 2, 0.1, 1, 300, 20]; //Will update again in few days, this seems to be more optimal for more helium for now -var preset_Zek4503 = [450, 0.9, 48, 3.35, 1, 2.8, 7.8, 1.95, 4, 0.04, 1, 120, 175]; //Final change till perky(?) integration -//gather these into an array of objects. this is one important object. -var presetList = [preset_ZXV,preset_ZXVnew,preset_ZXV3,preset_TruthEarly,preset_TruthLate,preset_nsheetz,preset_nsheetzNew,preset_HiderHehr,preset_HiderBalance,preset_HiderMore,preset_genBTC,preset_genBTC2,preset_Zek450,preset_Zek4502,preset_Zek4503]; -//Specific ratios labeled above must be given the matching ID below. -//Ratio preset dropdown list -var presetListHtml = "\ -\ -\ -\ -\ -\ -\ -\ -\ -\ -\ -\ -\ -\ -\ -"; -//Custom Creation for all perk customRatio boxes in Trimps Perk Window +if (game.global.universe == 1) { +//[looting,toughness,power,motivation,pheromones,artisanistry,carpentry,resilience,coordinated,resourceful,overkill,cunning,curious,classy] +var preset_space = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; +var preset_Zek059 = [7, 0.6, 3, 0.8, 0.3, 3, 25, 0.6, 0, 0, 0, 0, 0, 0]; +var preset_Zek100 = [9.8, 1.8, 3.2, 2.6, 0.7, 2.9, 25, 1.8, 0, 0, 0, 0, 0, 0]; +var preset_Zek180 = [13, 1.3, 4, 2.6, 0.7, 2.9, 25, 1.3, 37, 0.05, 1, 0, 0, 0]; +var preset_Zek229 = [11.2, 0.58, 2.37, 1.464, 0.3, 2.02, 12.2, 0.58, 39, 0.22, 2.2, 0, 0, 0]; +var preset_Zek299 = [16.8, 3, 1.9, 1.1, 1.2, 1, 17.1, 3, 105, 0.06, 0.8, 0, 0]; +var preset_Zek399 = [135, 6.1, 18.5, 6.5, 2.5, 6, 17, 6.1, 28, 0.08, 1, 0, 0]; +var preset_Zek449 = [245, 5.85, 29, 1.95, 2.8, 6, 6.1, 5.85, 18, 0.05, 1, 57, 0, 0]; +var preset_Zek450 = [450, 0.9, 48, 3.35, 1, 2.8, 7.8, 1.95, 10, 0.03, 1, 120, 175, 0]; +var preset_Zek500 = [600, 2.4, 60, 2, 1, 2.5, 8, 2.4, 8, 0.02, 1, 145, 180, 130]; +var preset_Zek550 = [700, 2.8, 70, 1.4, 1, 2.2, 7.5, 2.8, 8, 0.003, 1, 50, 80, 45]; +var presetList = [preset_Zek059,preset_Zek100,preset_Zek180,preset_Zek229,preset_Zek299,preset_Zek399,preset_Zek449,preset_Zek450,preset_Zek500,preset_Zek550,preset_space]; +var presetListHtml = "\ +\ +\ +\ +\ +\ +\ +\ +\ +\ +\ +\ +"; AutoPerks.createInput = function(perkname,div) { var perk1input = document.createElement("Input"); perk1input.id = perkname + 'Ratio'; - var oldstyle = 'text-align: center; width: 60px;'; + var oldstyle = 'text-align: center; width: calc(100vw/36); font-size: 1.0vw; '; if(game.options.menu.darkTheme.enabled != 2) perk1input.setAttribute("style", oldstyle + " color: black;"); else perk1input.setAttribute('style', oldstyle); perk1input.setAttribute('class', 'perkRatios'); @@ -73,25 +45,26 @@ AutoPerks.createInput = function(perkname,div) { var perk1label = document.createElement("Label"); perk1label.id = perkname + 'Label'; perk1label.innerHTML = perkname; - perk1label.setAttribute('style', 'margin-right: 1vw; width: 120px; color: white;'); - //add to the div. + perk1label.setAttribute('style', 'margin-right: 0.7vw; width: calc(100vw/18); color: white; font-size: 0.9vw; font-weight: lighter; margin-left: 0.3vw; '); div.appendChild(perk1input); div.appendChild(perk1label); } -//-------------------------------------- -//BEGIN AUTOPERKS GUI CODE:>>>>>>>>>>>>>> -//-------------------------------------- AutoPerks.GUI = {}; AutoPerks.removeGUI = function() { Object.keys(AutoPerks.GUI).forEach(function(key) { var $elem = AutoPerks.GUI[key]; - $elem.parentNode.removeChild($elem); - delete AutoPerks.GUI[key]; + if (!$elem) { + console.log("error in: "+key); + return; + } + if ($elem.parentNode) { + $elem.parentNode.removeChild($elem); + delete $elem; + } }); } AutoPerks.displayGUI = function() { let apGUI = AutoPerks.GUI; - //Create Allocator button and add it to Trimps Perk Window var $buttonbar = document.getElementById("portalBtnContainer"); apGUI.$allocatorBtn1 = document.createElement("DIV"); apGUI.$allocatorBtn1.id = 'allocatorBtn1'; @@ -105,68 +78,62 @@ AutoPerks.displayGUI = function() { //Line 1 of the UI apGUI.$ratiosLine1 = document.createElement("DIV"); apGUI.$ratiosLine1.setAttribute('style', 'display: inline-block; text-align: left; width: 100%'); - var listratiosLine1 = ["Overkill","Resourceful","Coordinated","Resilience","Carpentry","Artisanistry"]; + var listratiosLine1 = ["Overkill","Resourceful","Coordinated","Resilience","Carpentry","Pheromones","Motivation"]; for (var i in listratiosLine1) AutoPerks.createInput(listratiosLine1[i],apGUI.$ratiosLine1); apGUI.$customRatios.appendChild(apGUI.$ratiosLine1); //Line 2 of the UI apGUI.$ratiosLine2 = document.createElement("DIV"); apGUI.$ratiosLine2.setAttribute('style', 'display: inline-block; text-align: left; width: 100%'); - var listratiosLine2 = ["Pheromones","Motivation","Power","Looting","Cunning","Curious"]; + var listratiosLine2 = ["Power","Looting","Artisanistry","Cunning","Curious","Classy"]; for (var i in listratiosLine2) AutoPerks.createInput(listratiosLine2[i],apGUI.$ratiosLine2); //Create dump perk dropdown apGUI.$dumpperklabel = document.createElement("Label"); apGUI.$dumpperklabel.id = 'DumpPerk Label'; apGUI.$dumpperklabel.innerHTML = "Dump Perk:"; - apGUI.$dumpperklabel.setAttribute('style', 'margin-right: 1vw; color: white;'); + apGUI.$dumpperklabel.setAttribute('style', 'margin-right: 1vw; color: white; font-size: 0.9vw;'); apGUI.$dumpperk = document.createElement("select"); apGUI.$dumpperk.id = 'dumpPerk'; apGUI.$dumpperk.setAttribute('onchange', 'AutoPerks.saveDumpPerk()'); - var oldstyle = 'text-align: center; width: 120px;'; + var oldstyle = 'text-align: center; width: 8vw; font-size: 0.8vw; font-weight: lighter; '; if(game.options.menu.darkTheme.enabled != 2) apGUI.$dumpperk.setAttribute("style", oldstyle + " color: black;"); else apGUI.$dumpperk.setAttribute('style', oldstyle); //Add the dump perk dropdown to UI Line 2 apGUI.$ratiosLine2.appendChild(apGUI.$dumpperklabel); apGUI.$ratiosLine2.appendChild(apGUI.$dumpperk); - //Toggle Algorithm 2 checkbox - apGUI.$toggleAlgo2 = document.createElement("DIV"); - apGUI.$toggleAlgo2.setAttribute('style', 'display: inline-block; text-align: left; margin-left: 1vw; width: 7vw;'); - apGUI.$toggleAlgo2.innerHTML = '\ - \ - Fast Allocate!:'; - apGUI.$ratiosLine2.appendChild(apGUI.$toggleAlgo2); - //Create ratioPreset dropdown apGUI.$ratioPresetLabel = document.createElement("Label"); apGUI.$ratioPresetLabel.id = 'Ratio Preset Label'; apGUI.$ratioPresetLabel.innerHTML = "Ratio Preset:"; - apGUI.$ratioPresetLabel.setAttribute('style', 'margin-right: 1vw; color: white;'); + apGUI.$ratioPresetLabel.setAttribute('style', 'margin-right: 0.5vw; color: white; font-size: 0.9vw;'); apGUI.$ratioPreset = document.createElement("select"); apGUI.$ratioPreset.id = 'ratioPreset'; apGUI.$ratioPreset.setAttribute('onchange', 'AutoPerks.setDefaultRatios()'); - oldstyle = 'text-align: center; width: 110px;'; + oldstyle = 'text-align: center; width: 8vw; font-size: 0.8vw; font-weight: lighter; '; if(game.options.menu.darkTheme.enabled != 2) apGUI.$ratioPreset.setAttribute("style", oldstyle + " color: black;"); else apGUI.$ratioPreset.setAttribute('style', oldstyle); - //Populate ratio preset dropdown list from HTML above: apGUI.$ratioPreset.innerHTML = presetListHtml; - //load the last ratio used var loadLastPreset = localStorage.getItem('AutoperkSelectedRatioPresetID'); - apGUI.$ratioPreset.selectedIndex = (loadLastPreset != null) ? loadLastPreset : 0; // First element is zxv (default) ratio. - //Add the presets dropdown to UI Line 1 + var setID; + if (loadLastPreset != null) { + if (loadLastPreset == 15 && !localStorage.getItem('AutoperkSelectedRatioPresetName')) + loadLastPreset = 11; + if (localStorage.getItem('AutoperkSelectedRatioPresetName')=="customPreset") + loadLastPreset = 11; + setID = loadLastPreset; + } + else + setID = 0; + apGUI.$ratioPreset.selectedIndex = setID; apGUI.$ratiosLine1.appendChild(apGUI.$ratioPresetLabel); apGUI.$ratiosLine1.appendChild(apGUI.$ratioPreset); apGUI.$customRatios.appendChild(apGUI.$ratiosLine2); - //Add it all to the perk/portal screen var $portalWrapper = document.getElementById("portalWrapper") $portalWrapper.appendChild(apGUI.$customRatios); - //////////////////////////////////////// - //Main LOGIC Loop/////////////////////// - //////////////////////////////////////// - AutoPerks.initializePerks();// Init all the new vars + AutoPerks.initializePerks(); AutoPerks.populateDumpPerkList(); } -//populate dump perk dropdown list AutoPerks.populateDumpPerkList = function() { var $dumpDropdown = document.getElementById('dumpPerk'); if ($dumpDropdown == null) return; @@ -176,17 +143,17 @@ AutoPerks.populateDumpPerkList = function() { html += "" html += ""; $dumpDropdown.innerHTML = html; - //load the last dump preset used var loadLastDump = localStorage.getItem('AutoperkSelectedDumpPresetID'); if (loadLastDump != null) $dumpDropdown.selectedIndex = loadLastDump; else - $dumpDropdown.selectedIndex = $dumpDropdown.length - 2; // Second to last element is looting_II (or other) + $dumpDropdown.selectedIndex = $dumpDropdown.length - 2; } AutoPerks.saveDumpPerk = function() { - var dumpIndex = document.getElementById("dumpPerk").selectedIndex; - safeSetItems('AutoperkSelectedDumpPresetID', dumpIndex); + var $dump = document.getElementById("dumpPerk"); + safeSetItems('AutoperkSelectedDumpPresetID', $dump.selectedIndex); + safeSetItems('AutoperkSelectedDumpPresetName', $dump.value); } AutoPerks.saveCustomRatios = function() { @@ -206,42 +173,35 @@ AutoPerks.switchToCustomRatios = function() { ($rp.selectedIndex = $rp.length-1); } -//sets the ratioboxes with the default ratios embedded in the script when perks are instanciated. -// (and everytime the ratio-preset dropdown-selector is changed) -//loads custom ratio selections from localstorage if applicable AutoPerks.setDefaultRatios = function() { var $perkRatioBoxes = document.getElementsByClassName("perkRatios"); - var ratioSet = document.getElementById("ratioPreset").selectedIndex; + var $rp = document.getElementById("ratioPreset"); + if (!$rp || !$perkRatioBoxes || !$rp.selectedOptions[0]) return; + var ratioSet = $rp.selectedIndex; var currentPerk; for(var i = 0; i < $perkRatioBoxes.length; i++) { currentPerk = AutoPerks.getPerkByName($perkRatioBoxes[i].id.substring(0, $perkRatioBoxes[i].id.length - 5)); // Remove "ratio" from the id to obtain the perk name $perkRatioBoxes[i].value = currentPerk.value[ratioSet]; } - //If "Custom" dropdown is selected: - if (ratioSet == document.getElementById("ratioPreset").length-1) { - //Try to grab custom ratios from LocalStorage if they were saved. + if (ratioSet == $rp.length-1) { var tmp = JSON.parse(localStorage.getItem('AutoPerksCustomRatios')); if (tmp !== null) AutoPerks.GUI.$customRatios = tmp; else { - // If no file was found, start by setting all $perkRatioBoxes to 1. for(var i = 0; i < $perkRatioBoxes.length; i++) - $perkRatioBoxes[i].value = 1; //initialize to 1. - return; //then exit. + $perkRatioBoxes[i].value = 1; + return; } - //if we have ratios in the storage file, load them for(var i = 0; i < $perkRatioBoxes.length; i++) { - //do a quick sanity check (order) if (AutoPerks.GUI.$customRatios[i].id != $perkRatioBoxes[i].id) continue; currentPerk = AutoPerks.getPerkByName($perkRatioBoxes[i].id.substring(0, $perkRatioBoxes[i].id.length - 5)); // Remove "ratio" from the id to obtain the perk name $perkRatioBoxes[i].value = AutoPerks.GUI.$customRatios[i].value; } } - //save the last ratio used safeSetItems('AutoperkSelectedRatioPresetID', ratioSet); + safeSetItems('AutoperkSelectedRatioPresetName', $rp.selectedOptions[0].id); } -//updates the internal perk variables with values grabbed from the custom ratio input boxes that the user may have changed. AutoPerks.updatePerkRatios = function() { var $perkRatioBoxes = document.getElementsByClassName('perkRatios'); var currentPerk; @@ -255,27 +215,21 @@ AutoPerks.updatePerkRatios = function() { for(var i in tierIIPerks) tierIIPerks[i].updatedValue = tierIIPerks[i].parent.updatedValue / tierIIPerks[i].relativeIncrease; } -//END AUTOPERKS GUI CODE:>>>>>>>>>>>>>> -//get ready / initialize AutoPerks.initialise = function() { - //save custom ratios if "custom" is selected AutoPerks.saveCustomRatios(); - AutoPerks.initializePerks(); // Init all the new vars - AutoPerks.updatePerkRatios(); //grab new ratios if any + AutoPerks.initializePerks(); + AutoPerks.updatePerkRatios(); } -//Main function (green "Allocate Perks" button): AutoPerks.clickAllocate = function() { - AutoPerks.initialise(); // Reset all fixed perks to 0 and grab new ratios if any + AutoPerks.initialise(); var helium = AutoPerks.getHelium(); - // Get fixed perks var preSpentHe = 0; var fixedPerks = AutoPerks.getFixedPerks(); for (var i in fixedPerks) { - //Maintain your existing fixed perks levels. fixedPerks[i].level = game.portal[AutoPerks.capitaliseFirstLetter(fixedPerks[i].name)].level; var price = AutoPerks.calculateTotalPrice(fixedPerks[i], fixedPerks[i].level); fixedPerks[i].spent += price; @@ -284,35 +238,32 @@ AutoPerks.clickAllocate = function() { if (preSpentHe) debug("AutoPerks: Your existing fixed-perks reserve Helium: " + prettify(preSpentHe), "perks"); - //if one of these is NaN, bugs. - var remainingHelium = helium - preSpentHe; - //Check for NaN - if one of these is NaN, bugs. + var remainingHelium = 0; + if (!Number.isSafeInteger(helium)) { + remainingHelium = (helium - preSpentHe) * 0.999; + } + else { + remainingHelium = helium - preSpentHe; + } if (Number.isNaN(remainingHelium)) debug("AutoPerks: Major Error: Reading your Helium amount. " + remainingHelium, "perks"); - // determine how to spend helium - if (MODULES["perks"].useAlgo2) - var result = AutoPerks.spendHelium2(remainingHelium); + var result; + if (getPageSetting('fastallocate')==true) + result = AutoPerks.spendHelium2(remainingHelium); else - var result = AutoPerks.spendHelium(remainingHelium); + result = AutoPerks.spendHelium(remainingHelium); if (result == false) { debug("AutoPerks: Major Error: Make sure all ratios are set properly.","perks"); return; } - - // Get owned perks var perks = AutoPerks.getOwnedPerks(); - //re-arrange perk points AutoPerks.applyCalculations(perks,remainingHelium); - //Done debug("AutoPerks: Auto-Allocate Finished.","perks"); } -//NEW way: Get accurate count of helium (calcs it like the game does) AutoPerks.getHelium = function() { - //determines if we are in the portal screen or the perk screen. var respecMax = (game.global.viewingUpgrades) ? game.global.heliumLeftover : game.global.heliumLeftover + game.resources.helium.owned; - //iterates all the perks and gathers up their heliumSpent counts. for (var item in game.portal){ if (game.portal[item].locked) continue; var portUpgrade = game.portal[item]; @@ -322,13 +273,11 @@ AutoPerks.getHelium = function() { return respecMax; } -//Calculate Price -AutoPerks.calculatePrice = function(perk, level) { // Calculate price of buying *next* level +AutoPerks.calculatePrice = function(perk, level) { if(perk.fluffy) return Math.ceil(perk.base * Math.pow(10,level)); - if(perk.type == 'exponential') return Math.ceil(level/2 + perk.base * Math.pow(1.3, level)); + else if(perk.type == 'exponential') return Math.ceil(level/2 + perk.base * Math.pow(perk.exprate, level)); else if(perk.type == 'linear') return Math.ceil(perk.base + perk.increase * level); } -//Calculate Total Price AutoPerks.calculateTotalPrice = function(perk, finalLevel) { if(perk.type == 'linear' && !perk.fluffy) return AutoPerks.calculateTIIprice(perk, finalLevel); @@ -338,15 +287,12 @@ AutoPerks.calculateTotalPrice = function(perk, finalLevel) { } return totalPrice; } -//Calculate Tier 2 Total Price (Shortcut) AutoPerks.calculateTIIprice = function(perk, finalLevel) { - //based on Trimps getAdditivePrice() @ main.js line 2056 return Math.ceil((((finalLevel - 1) * finalLevel) / 2 * perk.increase) + (perk.base * finalLevel)); } -//Calculate the increase in stat. AutoPerks.calculateIncrease = function(perk, level) { var increase = 0; - var value; // Allows for custom perk ratios. + var value; if(perk.updatedValue != -1) value = perk.updatedValue; else value = perk.value; @@ -360,34 +306,35 @@ AutoPerks.spendHelium = function(helium) { debug("Beginning AutoPerks1 calculate how to spend " + prettify(helium) + " Helium... This could take a while...","perks"); if(helium < 0) { debug("AutoPerks: Major Error - Not enough helium to buy fixed perks.","perks"); - //document.getElementById("nextCoordinated").innerHTML = "Not enough helium to buy fixed perks."; - return; + return false; } if (Number.isNaN(helium)) { debug("AutoPerks: Major Error - Helium is Not a Number!","perks"); - return; + return false; } var perks = AutoPerks.getVariablePerks(); var effQueue = new FastPriorityQueue(function(a,b) { return a.efficiency > b.efficiency } ) // Queue that keeps most efficient purchase at the top - // Calculate base efficiency of all perks var mostEff, price, inc; for(var i in perks) { price = AutoPerks.calculatePrice(perks[i], 0); inc = AutoPerks.calculateIncrease(perks[i], 0); perks[i].efficiency = inc/price; - if(perks[i].efficiency <= 0) { + if(perks[i].efficiency < 0) { debug("Perk ratios must be positive values.","perks"); return false; } if(perks[i].efficiency != 0) effQueue.add(perks[i]); } + if (effQueue.size < 1) { + debug("All Perk Ratios were 0, or some other error.","perks"); + return false; + } var i=0; - //Change the way we iterate. function iterateQueue() { mostEff = effQueue.poll(); price = AutoPerks.calculatePrice(mostEff, mostEff.level); // Price of *next* purchase. @@ -396,26 +343,23 @@ AutoPerks.spendHelium = function(helium) { i++; } for (iterateQueue() ; price <= helium ; iterateQueue() ) { - if(mostEff.level < mostEff.max) { // but first, check if the perk has reached its maximum value - // Purchase the most efficient perk + if(mostEff.level < mostEff.max) { helium -= price; mostEff.level++; mostEff.spent += price; - price = AutoPerks.calculatePrice(mostEff, mostEff.level); // Price of *next* purchase. + price = AutoPerks.calculatePrice(mostEff, mostEff.level); inc = AutoPerks.calculateIncrease(mostEff, mostEff.level); mostEff.efficiency = inc / price; - effQueue.add(mostEff); // Add back into queue run again until out of helium + effQueue.add(mostEff); } } debug("AutoPerks1: Pass One Complete. Loops ran: " + i, "perks"); - //Begin selectable dump perk code var $selector = document.getElementById('dumpPerk'); if ($selector != null && $selector.value != "None") { var heb4dump = helium; var index = $selector.selectedIndex; var dumpPerk = AutoPerks.getPerkByName($selector[index].innerHTML); - //debug(AutoPerks.capitaliseFirstLetter(dumpPerk.name) + " level pre-dump: " + dumpPerk.level,"perks"); if(dumpPerk.level < dumpPerk.max) { for(price = AutoPerks.calculatePrice(dumpPerk, dumpPerk.level); price < helium && dumpPerk.level < dumpPerk.max; price = AutoPerks.calculatePrice(dumpPerk, dumpPerk.level)) { helium -= price; @@ -425,22 +369,17 @@ AutoPerks.spendHelium = function(helium) { } var dumpresults = heb4dump - helium; debug("AutoPerks1: Dump Perk " + AutoPerks.capitaliseFirstLetter(dumpPerk.name) + " level post-dump: "+ dumpPerk.level + " Helium Dumped: " + prettify(dumpresults) + " He.", "perks"); - } //end dump perk code. + } var heB4round2 = helium; - //Repeat the process for spending round 2. This spends any extra helium we have that is less than the cost of the last point of the dump-perk. while (effQueue.size > 1) { mostEff = effQueue.poll(); if (mostEff.level >= mostEff.max) continue; price = AutoPerks.calculatePrice(mostEff, mostEff.level); - // Add back into queue run again until out of helium - // but first, check if the perk has reached its maximum value if (price >= helium) continue; - // Purchase the most efficient perk helium -= price; mostEff.level++; mostEff.spent += price; - // Reduce its efficiency inc = AutoPerks.calculateIncrease(mostEff, mostEff.level); price = AutoPerks.calculatePrice(mostEff, mostEff.level); mostEff.efficiency = inc/price; @@ -454,18 +393,16 @@ AutoPerks.spendHelium2 = function(helium) { debug("Beginning AutoPerks2 calculate how to spend " + prettify(helium) + " Helium... This could take a while...","perks"); if(helium < 0) { debug("AutoPerks: Major Error - Not enough helium to buy fixed perks.","perks"); - //document.getElementById("nextCoordinated").innerHTML = "Not enough helium to buy fixed perks."; - return; + return false; } if (Number.isNaN(helium)) { debug("AutoPerks: Major Error - Helium is Not a Number!","perks"); - return; + return false; } var perks = AutoPerks.getVariablePerks(); var effQueue = new FastPriorityQueue(function(a,b) { return a.efficiency > b.efficiency } ) // Queue that keeps most efficient purchase at the top - // Calculate base efficiency of all perks for(var i in perks) { var price = AutoPerks.calculatePrice(perks[i], 0); var inc = AutoPerks.calculateIncrease(perks[i], 0); @@ -477,21 +414,23 @@ AutoPerks.spendHelium2 = function(helium) { if(perks[i].efficiency != 0) effQueue.add(perks[i]); } + if (effQueue.size < 1) { + debug("All Perk Ratios were 0, or some other error.","perks"); + return false; + } var mostEff, price, inc; var packPrice,packLevel; var i=0; - //Change the way we iterate. function iterateQueue() { mostEff = effQueue.poll(); - price = AutoPerks.calculatePrice(mostEff, mostEff.level); // Price of *next* purchase. + price = AutoPerks.calculatePrice(mostEff, mostEff.level); inc = AutoPerks.calculateIncrease(mostEff, mostEff.level); mostEff.efficiency = inc / price; i++; } for (iterateQueue() ; price <= helium ; iterateQueue() ) { - if(mostEff.level < mostEff.max) { // but first, check if the perk has reached its maximum value - // Purchase the most efficient perk + if(mostEff.level < mostEff.max) { var t2 = mostEff.name.endsWith("_II"); if (t2) { packLevel = mostEff.increase * 10; @@ -506,21 +445,19 @@ AutoPerks.spendHelium2 = function(helium) { mostEff.level++; mostEff.spent += price; } - price = AutoPerks.calculatePrice(mostEff, mostEff.level); // Price of *next* purchase. + price = AutoPerks.calculatePrice(mostEff, mostEff.level); inc = AutoPerks.calculateIncrease(mostEff, mostEff.level); mostEff.efficiency = inc / price; - effQueue.add(mostEff); // Add back into queue run again until out of helium + effQueue.add(mostEff); } } debug("AutoPerks2: Pass One Complete. Loops ran: " + i, "perks"); - //Begin selectable dump perk code var $selector = document.getElementById('dumpPerk'); if ($selector != null && $selector.value != "None") { var heb4dump = helium; var index = $selector.selectedIndex; var dumpPerk = AutoPerks.getPerkByName($selector[index].innerHTML); - //debug(AutoPerks.capitaliseFirstLetter(dumpPerk.name) + " level pre-dump: " + dumpPerk.level,"perks"); if(dumpPerk.level < dumpPerk.max) { for(price = AutoPerks.calculatePrice(dumpPerk, dumpPerk.level); price < helium && dumpPerk.level < dumpPerk.max; price = AutoPerks.calculatePrice(dumpPerk, dumpPerk.level)) { helium -= price; @@ -530,24 +467,20 @@ AutoPerks.spendHelium2 = function(helium) { } var dumpresults = heb4dump - helium; debug("AutoPerks2: Dump Perk " + AutoPerks.capitaliseFirstLetter(dumpPerk.name) + " level post-dump: "+ dumpPerk.level + " Helium Dumped: " + prettify(dumpresults) + " He.", "perks"); - } //end dump perk code. + } var heB4round2 = helium; - //Repeat the process for spending round 2. This spends any extra helium we have that is less than the cost of the last point of the dump-perk. while (effQueue.size > 1) { mostEff = effQueue.poll(); - if (mostEff.level >= mostEff.max) continue; // but first, check if the perk has reached its maximum value + if (mostEff.level >= mostEff.max) continue; price = AutoPerks.calculatePrice(mostEff, mostEff.level); if (price >= helium) continue; - // Purchase the most efficient perk helium -= price; mostEff.level++; mostEff.spent += price; - // Reduce its efficiency inc = AutoPerks.calculateIncrease(mostEff, mostEff.level); price = AutoPerks.calculatePrice(mostEff, mostEff.level); mostEff.efficiency = inc/price; - // Add back into queue run again until out of helium effQueue.add(mostEff); } var r2results = heB4round2 - helium; @@ -556,9 +489,7 @@ AutoPerks.spendHelium2 = function(helium) { -//Pushes the respec button, then the Clear All button, then assigns perk points based on what was calculated. AutoPerks.applyCalculationsRespec = function(perks,remainingHelium){ - // *Apply calculations with respec if (game.global.canRespecPerks) { respecPerks(); } @@ -569,7 +500,7 @@ AutoPerks.applyCalculationsRespec = function(perks,remainingHelium){ for(var i in perks) { var capitalized = AutoPerks.capitaliseFirstLetter(perks[i].name); game.global.buyAmt = perks[i].level; - if (getPortalUpgradePrice(capitalized) <= remainingHelium) { + if (getPortalUpgradePrice(capitalized) <= remainingHelium || perks[i].fixed) { if (MODULES["perks"].showDetails) debug("AutoPerks-Respec Buying: " + capitalized + " " + perks[i].level, "perks"); buyPortalUpgrade(capitalized); @@ -578,9 +509,8 @@ AutoPerks.applyCalculationsRespec = function(perks,remainingHelium){ debug("AutoPerks-Respec Error Couldn't Afford Asked Perk: " + capitalized + " " + perks[i].level, "perks"); } game.global.buyAmt = preBuyAmt; - numTab(1,true); //selects the 1st number of the buy-amount tab-bar (Always 1) - cancelTooltip(); //displays the last perk we bought's tooltip without this. idk why. - //activateClicked(); //click OK for them (disappears the window). + numTab(1,true); + cancelTooltip(); } else { debug("A Respec would be required and is not available. You used it already, try again next portal.","perks"); @@ -589,9 +519,7 @@ AutoPerks.applyCalculationsRespec = function(perks,remainingHelium){ } } -//Assigns perk points without respeccing if nothing is needed to be negative. AutoPerks.applyCalculations = function(perks,remainingHelium){ - // // *Apply calculations WITHOUT respec var preBuyAmt = game.global.buyAmt; var needsRespec = false; @@ -612,11 +540,10 @@ AutoPerks.applyCalculations = function(perks,remainingHelium){ } game.global.buyAmt = preBuyAmt; - numTab(1,true); //selects the 1st number of the buy-amount tab-bar (Always 1) - cancelTooltip(); //displays the last perk we bought's tooltip without this. idk why. + numTab(1,true); + cancelTooltip(); if (needsRespec){ debug("AutoPerks - A Respec is required. Trying respec...", "perks"); - //get the variable, in this order, then switch screens (or else the sequence is messed up) var whichscreen = game.global.viewingUpgrades; cancelPortal(); if (whichscreen) @@ -629,9 +556,7 @@ AutoPerks.applyCalculations = function(perks,remainingHelium){ var exportPerks = {}; for (var item in game.portal){ el = game.portal[item]; - //For smaller strings and backwards compatibility, perks not added to the object will be treated as if the perk is supposed to be level 0. if (el.locked || el.level <= 0) continue; - //Add the perk to the object with the desired level exportPerks[item] = el.level + el.levelTemp; } console.log(exportPerks); @@ -650,21 +575,18 @@ AutoPerks.getPercent = function(spentHelium, totalHelium) { frac = (frac* 100).toPrecision(2); return frac + "%"; } -AutoPerks.toggleFastAllocate = function() { - MODULES["perks"].useAlgo2 = !MODULES["perks"].useAlgo2; -} AutoPerks.FixedPerk = function(name, base, level, max, fluffy) { this.id = -1; this.name = name; this.base = base; this.type = "exponential"; + this.exprate = 1.3; this.fixed = true; this.level = level || 0; this.spent = 0; this.max = max || Number.MAX_VALUE; if (fluffy == "fluffy") { - //This affects cost calculation on "Capable" fixed perk (during line 273) this.fluffy = true; this.type = "linear"; this.increase = 10; @@ -676,15 +598,15 @@ AutoPerks.VariablePerk = function(name, base, compounding, value, baseIncrease, this.name = name; this.base = base; this.type = "exponential"; - this.exprate = 1.3; //cost is almost always the default 1.3x + this.exprate = 1.3; this.fixed = false; this.compounding = compounding; - this.updatedValue = -1; // If a custom ratio is supplied, this will be modified to hold the new value. - this.baseIncrease = baseIncrease; // The raw stat increase that the perk gives. - this.efficiency = -1; // Efficiency is defined as % increase * value / He cost + this.updatedValue = -1; + this.baseIncrease = baseIncrease; + this.efficiency = -1; this.max = max || Number.MAX_VALUE; - this.level = level || 0; // How many levels have been invested into a perk - this.spent = 0; // Total helium spent on each perk. + this.level = level || 0; + this.spent = 0; function getRatiosFromPresets() { var valueArray = []; for (var i=0; i"+RAutoPerks.capitaliseFirstLetter(dumpperks[i].name)+"" + html += ""; + $dumpDropdown.innerHTML = html; + var loadLastDump = localStorage.getItem('RAutoperkSelectedDumpPresetID'); + if (loadLastDump != null) + $dumpDropdown.selectedIndex = loadLastDump; + else + $dumpDropdown.selectedIndex = $dumpDropdown.length - 2; +}; + +RAutoPerks.saveDumpPerk = function() { + var $dump = document.getElementById("RdumpPerk"); + safeSetItems('RAutoperkSelectedDumpPresetID', $dump.selectedIndex); + safeSetItems('RAutoperkSelectedDumpPresetName', $dump.value); +}; + +RAutoPerks.saveCustomRatios = function() { + if (document.getElementById("RratioPreset").selectedIndex == document.getElementById("RratioPreset").length-1) { + var $perkRatioBoxes = document.getElementsByClassName('RperkRatios'); + var customRatios = []; + for(var i = 0; i < $perkRatioBoxes.length; i++) { + customRatios.push({'id':$perkRatioBoxes[i].id,'value':parseFloat($perkRatioBoxes[i].value)}); + } + safeSetItems('RAutoPerksCustomRatios', JSON.stringify(customRatios) ); + } +}; -//Run the GUI: -AutoPerks.displayGUI(); \ No newline at end of file +RAutoPerks.switchToCustomRatios = function() { + var $rp = document.getElementById("RratioPreset"); + if ($rp.selectedIndex != $rp.length-1) + ($rp.selectedIndex = $rp.length-1); +}; + +RAutoPerks.setDefaultRatios = function() { + var $perkRatioBoxes = document.getElementsByClassName("RperkRatios"); + var $rp = document.getElementById("RratioPreset"); + if (!$rp || !$perkRatioBoxes || !$rp.selectedOptions[0]) return; + var ratioSet = $rp.selectedIndex; + var currentPerk; + for(var i = 0; i < $perkRatioBoxes.length; i++) { + currentPerk = RAutoPerks.getPerkByName($perkRatioBoxes[i].id.substring(0, $perkRatioBoxes[i].id.length - 5)); + $perkRatioBoxes[i].value = currentPerk.value[ratioSet]; + } + if (ratioSet == $rp.length-1) { + var tmp = JSON.parse(localStorage.getItem('RAutoPerksCustomRatios')); + if (tmp !== null) + RAutoPerks.GUI.$customRatios = tmp; + else { + for(var i = 0; i < $perkRatioBoxes.length; i++) + $perkRatioBoxes[i].value = 1; + return; + } + for(var i = 0; i < $perkRatioBoxes.length; i++) { + if (RAutoPerks.GUI.$customRatios[i].id != $perkRatioBoxes[i].id) continue; + currentPerk = RAutoPerks.getPerkByName($perkRatioBoxes[i].id.substring(0, $perkRatioBoxes[i].id.length - 5)); + $perkRatioBoxes[i].value = RAutoPerks.GUI.$customRatios[i].value; + } + } + safeSetItems('RAutoperkSelectedRatioPresetID', ratioSet); + safeSetItems('RAutoperkSelectedRatioPresetName', $rp.selectedOptions[0].id); +}; + +RAutoPerks.updatePerkRatios = function() { + var $perkRatioBoxes = document.getElementsByClassName('RperkRatios'); + var currentPerk; + for(var i = 0; i < $perkRatioBoxes.length; i++) { + currentPerk = RAutoPerks.getPerkByName($perkRatioBoxes[i].id.substring(0, $perkRatioBoxes[i].id.length - 5)); + currentPerk.updatedValue = parseFloat($perkRatioBoxes[i].value); + } + var tierIIPerks = RAutoPerks.getTierIIPerks(); + for(var i in tierIIPerks) + tierIIPerks[i].updatedValue = tierIIPerks[i].parent.updatedValue / tierIIPerks[i].relativeIncrease; +}; + +RAutoPerks.updatePerkRatios = function() { + var $perkRatioBoxes = document.getElementsByClassName('RperkRatios'); + var currentPerk; + for(var i = 0; i < $perkRatioBoxes.length; i++) { + currentPerk = RAutoPerks.getPerkByName($perkRatioBoxes[i].id.substring(0, $perkRatioBoxes[i].id.length - 5)); + currentPerk.updatedValue = parseFloat($perkRatioBoxes[i].value); + } +} + +RAutoPerks.initialise = function() { + RAutoPerks.saveCustomRatios(); + RAutoPerks.initializePerks(); + RAutoPerks.updatePerkRatios(); +}; + +RAutoPerks.clickAllocate = function() { + RAutoPerks.initialise(); + + var radon = RAutoPerks.getRadon(); + + var preSpentRn = 0; + var fixedPerks = RAutoPerks.getFixedPerks(); + for (var i in fixedPerks) { + fixedPerks[i].radLevel = game.portal[RAutoPerks.capitaliseFirstLetter(fixedPerks[i].name)].radLevel; + var price = RAutoPerks.calculateTotalPrice(fixedPerks[i], fixedPerks[i].radLevel); + fixedPerks[i].spent += price; + preSpentRn += price; + } + if (preSpentRn) + debug("RAutoPerks: Your existing fixed-perks reserve Radon: " + prettify(preSpentRn), "perks"); + + var remainingRadon = 0; + if (!Number.isSafeInteger(radon)) { + remainingRadon = (radon - preSpentRn) * 0.999; + } + else { + remainingRadon = radon - preSpentRn; + } + if (Number.isNaN(remainingRadon)) + debug("RAutoPerks: Major Error: Reading your Radon amount. " + remainingRadon, "perks"); + + var result; + if (getPageSetting('fastallocate')==true) + result = RAutoPerks.spendRadon2(remainingRadon); + else + result = RAutoPerks.spendRadon(remainingRadon); + if (result == false) { + debug("RAutoPerks: Major Error: Make sure all ratios are set properly.","perks"); + return; + } + var perks = RAutoPerks.getOwnedPerks(); + RAutoPerks.applyCalculations(perks,remainingRadon); + debug("RAutoPerks: Auto-Allocate Finished.","perks"); +}; + +RAutoPerks.getRadon = function() { + var respecMax = (game.global.viewingUpgrades) ? game.global.radonLeftover : game.global.radonLeftover + game.resources.radon.owned; + for (var item in game.portal){ + if (game.portal[item].radLocked) continue; + var portUpgrade = game.portal[item]; + if (typeof portUpgrade.radLevel === 'undefined') continue; + respecMax += portUpgrade.radSpent; + } + return respecMax; +}; + +RAutoPerks.calculatePrice = function(perk, level) { + if(perk.fluffy) return Math.ceil(perk.base * Math.pow(10,level)); + else if(perk.type == 'exponential') return Math.ceil(level/2 + perk.base * Math.pow(perk.exprate, level)); + else if(perk.type == 'linear') return Math.ceil(perk.base + perk.increase * level); +}; +RAutoPerks.calculateTotalPrice = function(perk, finalLevel) { + if(perk.type == 'linear' && !perk.fluffy) + return RAutoPerks.calculateTIIprice(perk, finalLevel); + var totalPrice = 0; + for(var i = 0; i < finalLevel; i++) { + totalPrice += RAutoPerks.calculatePrice(perk, i); + } + return totalPrice; +}; +RAutoPerks.calculateTIIprice = function(perk, finalLevel) { + return Math.ceil((((finalLevel - 1) * finalLevel) / 2 * perk.increase) + (perk.base * finalLevel)); +}; +RAutoPerks.calculateIncrease = function(perk, level) { + var increase = 0; + var value; + + if(perk.updatedValue != -1) value = perk.updatedValue; + else value = perk.value; + + if(perk.compounding) increase = perk.baseIncrease; + else increase = (1 + (level + 1) * perk.baseIncrease) / ( 1 + level * perk.baseIncrease) - 1; + return increase / perk.baseIncrease * value; +}; + +RAutoPerks.spendRadon = function(radon) { + debug("Beginning RAutoPerks1 calculate how to spend " + prettify(radon) + " Radon... This could take a while...","perks"); + if(radon < 0) { + debug("RAutoPerks: Major Error - Not enough radon to buy fixed perks.","perks"); + return false; + } + if (Number.isNaN(radon)) { + debug("RAutoPerks: Major Error - Radon is Not a Number!","perks"); + return false; + } + + var perks = RAutoPerks.getVariablePerks(); + + var effQueue = new FastPriorityQueue(function(a,b) { return a.efficiency > b.efficiency } ); + + var mostEff, price, inc; + for(var i in perks) { + price = RAutoPerks.calculatePrice(perks[i], 0); + inc = RAutoPerks.calculateIncrease(perks[i], 0); + perks[i].efficiency = inc/price; + if(perks[i].efficiency < 0) { + debug("Perk ratios must be positive values.","perks"); + return false; + } + if(perks[i].efficiency != 0) + effQueue.add(perks[i]); + } + if (effQueue.size < 1) { + debug("All Perk Ratios were 0, or some other error.","perks"); + return false; + } + + var i=0; + function iterateQueue() { + mostEff = effQueue.poll(); + price = RAutoPerks.calculatePrice(mostEff, mostEff.radLevel); + inc = RAutoPerks.calculateIncrease(mostEff, mostEff.radLevel); + mostEff.efficiency = inc / price; + i++; + } + for (iterateQueue() ; price <= radon ; iterateQueue() ) { + if(mostEff.radLevel < mostEff.max) { + radon -= price; + mostEff.radLevel++; + mostEff.spent += price; + price = RAutoPerks.calculatePrice(mostEff, mostEff.radLevel); + inc = RAutoPerks.calculateIncrease(mostEff, mostEff.radLevel); + mostEff.efficiency = inc / price; + effQueue.add(mostEff); + } + } + debug("RAutoPerks1: Pass One Complete. Loops ran: " + i, "perks"); + + var $selector = document.getElementById('RdumpPerk'); + if ($selector != null && $selector.value != "None") { + var heb4dump = radon; + var index = $selector.selectedIndex; + var RdumpPerk = RAutoPerks.getPerkByName($selector[index].innerHTML); + if(RdumpPerk.radLevel < RdumpPerk.max) { + for(price = RAutoPerks.calculatePrice(RdumpPerk, RdumpPerk.radLevel); price < radon && RdumpPerk.radLevel < RdumpPerk.max; price = RAutoPerks.calculatePrice(RdumpPerk, RdumpPerk.radLevel)) { + radon -= price; + RdumpPerk.spent += price; + RdumpPerk.radLevel++; + } + } + var dumpresults = heb4dump - radon; + debug("RAutoPerks1: Dump Perk " + RAutoPerks.capitaliseFirstLetter(RdumpPerk.name) + " level post-dump: "+ RdumpPerk.radLevel + " Radon Dumped: " + prettify(dumpresults) + " Rn.", "perks"); + } + + var heB4round2 = radon; + while (effQueue.size > 1) { + mostEff = effQueue.poll(); + if (mostEff.radLevel >= mostEff.max) continue; + price = RAutoPerks.calculatePrice(mostEff, mostEff.radLevel); + if (price >= radon) continue; + radon -= price; + mostEff.radLevel++; + mostEff.spent += price; + inc = RAutoPerks.calculateIncrease(mostEff, mostEff.radLevel); + price = RAutoPerks.calculatePrice(mostEff, mostEff.radLevel); + mostEff.efficiency = inc/price; + effQueue.add(mostEff); + } + var r2results = heB4round2 - radon; + debug("RAutoPerks1: Pass two complete. Round 2 cleanup spend of : " + prettify(r2results),"perks"); +}; + +RAutoPerks.spendRadon2 = function(radon) { + debug("Beginning RAutoPerks2 calculate how to spend " + prettify(radon) + " Radon... This could take a while...","perks"); + if(radon < 0) { + debug("RAutoPerks: Major Error - Not enough radon to buy fixed perks.","perks"); + return false; + } + if (Number.isNaN(radon)) { + debug("RAutoPerks: Major Error - Radon is Not a Number!","perks"); + return false; + } + + var perks = RAutoPerks.getVariablePerks(); + + var effQueue = new FastPriorityQueue(function(a,b) { return a.efficiency > b.efficiency } ); // Queue that keeps most efficient purchase at the top + for(var i in perks) { + var price = RAutoPerks.calculatePrice(perks[i], 0); + var inc = RAutoPerks.calculateIncrease(perks[i], 0); + perks[i].efficiency = inc/price; + if(perks[i].efficiency < 0) { + debug("Perk ratios must be positive values.","perks"); + return false; + } + if(perks[i].efficiency != 0) + effQueue.add(perks[i]); + } + if (effQueue.size < 1) { + debug("All Perk Ratios were 0, or some other error.","perks"); + return false; + } + + var mostEff, price, inc; + var packPrice,packLevel; + var i=0; + function iterateQueue() { + mostEff = effQueue.poll(); + price = RAutoPerks.calculatePrice(mostEff, mostEff.radLevel); + inc = RAutoPerks.calculateIncrease(mostEff, mostEff.radLevel); + mostEff.efficiency = inc / price; + i++; + } + for (iterateQueue() ; price <= radon ; iterateQueue() ) { + if(mostEff.radLevel < mostEff.max) { + var t2 = mostEff.name.endsWith("_II"); + if (t2) { + packLevel = mostEff.increase * 10; + packPrice = RAutoPerks.calculateTotalPrice(mostEff, mostEff.radLevel + packLevel) - mostEff.spent; + } + if (t2 && packPrice <= radon) { + radon -= packPrice; + mostEff.radLevel+= packLevel; + mostEff.spent += packPrice; + } else { + radon -= price; + mostEff.radLevel++; + mostEff.spent += price; + } + price = RAutoPerks.calculatePrice(mostEff, mostEff.radLevel); + inc = RAutoPerks.calculateIncrease(mostEff, mostEff.radLevel); + mostEff.efficiency = inc / price; + effQueue.add(mostEff); + } + } + debug("RAutoPerks2: Pass One Complete. Loops ran: " + i, "perks"); + + var $selector = document.getElementById('RdumpPerk'); + if ($selector != null && $selector.value != "None") { + var heb4dump = radon; + var index = $selector.selectedIndex; + var RdumpPerk = RAutoPerks.getPerkByName($selector[index].innerHTML); + if(RdumpPerk.radLevel < RdumpPerk.max) { + for(price = RAutoPerks.calculatePrice(RdumpPerk, RdumpPerk.radLevel); price < radon && RdumpPerk.radLevel < RdumpPerk.max; price = RAutoPerks.calculatePrice(RdumpPerk, RdumpPerk.radLevel)) { + radon -= price; + RdumpPerk.spent += price; + RdumpPerk.radLevel++; + } + } + var dumpresults = heb4dump - radon; + debug("RAutoPerks2: Dump Perk " + RAutoPerks.capitaliseFirstLetter(RdumpPerk.name) + " level post-dump: "+ RdumpPerk.radLevel + " Radon Dumped: " + prettify(dumpresults) + " Rn.", "perks"); + } + + var heB4round2 = radon; + while (effQueue.size > 1) { + mostEff = effQueue.poll(); + if (mostEff.radLevel >= mostEff.max) continue; + price = RAutoPerks.calculatePrice(mostEff, mostEff.radLevel); + if (price >= radon) continue; + radon -= price; + mostEff.radLevel++; + mostEff.spent += price; + inc = RAutoPerks.calculateIncrease(mostEff, mostEff.radLevel); + price = RAutoPerks.calculatePrice(mostEff, mostEff.radLevel); + mostEff.efficiency = inc/price; + effQueue.add(mostEff); + } + var r2results = heB4round2 - radon; + debug("RAutoPerks2: Pass Two Complete. Cleanup Spent Any Leftover Radon: " + prettify(r2results) + " He.","perks"); +}; + + + +RAutoPerks.applyCalculationsRespec = function(perks,remainingRadon){ + if (game.global.canRespecPerks) { + respecPerks(); + } + if (game.global.respecActive) { + clearPerks(); + var preBuyAmt = game.global.buyAmt; + + for(var i in perks) { + var capitalized = RAutoPerks.capitaliseFirstLetter(perks[i].name); + game.global.buyAmt = perks[i].radLevel; + if (getPortalUpgradePrice(capitalized) <= remainingRadon || perks[i].fixed) { + if (MODULES["perks"].RshowDetails) + debug("RAutoPerks-Respec Buying: " + capitalized + " " + perks[i].radLevel, "perks"); + buyPortalUpgrade(capitalized); + } else + if (MODULES["perks"].RshowDetails) + debug("RAutoPerks-Respec Error Couldn't Afford Asked Perk: " + capitalized + " " + perks[i].radLevel, "perks"); + } + game.global.buyAmt = preBuyAmt; + numTab(1,true); + cancelTooltip(); + } + else { + debug("A Respec would be required and is not available. You used it already, try again next portal.","perks"); + RAutoPerks.GUI.$allocatorBtn1.setAttribute('class', 'btn inPortalBtn settingsBtn settingBtnfalse'); + tooltip("Automatic Perk Allocation Error", "customText", event, "A Respec would be required and is NOT available. You used it already, try again next portal. Press esc to close this tooltip." ); + } +}; + +RAutoPerks.applyCalculations = function(perks,remainingRadon){ + + var preBuyAmt = game.global.buyAmt; + var needsRespec = false; + for(var i in perks) { + var capitalized = RAutoPerks.capitaliseFirstLetter(perks[i].name); + game.global.buyAmt = perks[i].radLevel - game.portal[capitalized].radLevel - game.portal[capitalized].levelTemp; + if (game.global.buyAmt < 0) { + needsRespec = true; + if (MODULES["perks"].RshowDetails) + debug("RAutoPerks RESPEC Required for: " + capitalized + " " + game.global.buyAmt, "perks"); + //break; + } + else if (game.global.buyAmt > 0) { + if (MODULES["perks"].RshowDetails) + debug("RAutoPerks-NoRespec Adding: " + capitalized + " " + game.global.buyAmt, "perks"); + buyPortalUpgrade(capitalized); + } + } + + game.global.buyAmt = preBuyAmt; + numTab(1,true); + cancelTooltip(); + if (needsRespec){ + debug("RAutoPerks - A Respec is required. Trying respec...", "perks"); + var whichscreen = game.global.viewingUpgrades; + cancelPortal(); + if (whichscreen) + viewPortalUpgrades(); + else + portalClicked(); + RAutoPerks.applyCalculationsRespec(perks,remainingRadon); + // + if (MODULES["perks"].RshowDetails) { + var exportPerks = {}; + for (var item in game.portal){ + el = game.portal[item]; + if (el.radLocked || el.radLevel <= 0) continue; + exportPerks[item] = el.radLevel + el.levelTemp; + } + console.log(exportPerks); + } + } +}; + +RAutoPerks.lowercaseFirst = function(str) { + return str.substr(0, 1).toLowerCase() + str.substr(1); +}; +RAutoPerks.capitaliseFirstLetter = function(str) { + return str.charAt(0).toUpperCase() + str.slice(1); +}; +RAutoPerks.getPercent = function(spentRadon, totalRadon) { + var frac = spentRadon / totalRadon; + frac = (frac* 100).toPrecision(2); + return frac + "%"; +}; + +RAutoPerks.FixedPerk = function(name, base, level, max, fluffy) { + this.id = -1; + this.name = name; + this.base = base; + this.type = "exponential"; + this.exprate = 1.3; + this.fixed = true; + this.radLevel = level || 0; + this.spent = 0; + this.max = max || Number.MAX_VALUE; + if (fluffy == "fluffy") { + this.fluffy = true; + this.type = "linear"; + this.increase = 10; + } +}; + +RAutoPerks.VariablePerk = function(name, base, compounding, value, baseIncrease, max, level) { + this.id = -1; + this.name = name; + this.base = base; + this.type = "exponential"; + this.exprate = 1.3; + this.fixed = false; + this.compounding = compounding; + this.updatedValue = -1; + this.baseIncrease = baseIncrease; + this.efficiency = -1; + this.max = max || Number.MAX_VALUE; + this.radLevel = level || 0; + this.spent = 0; + function getRatiosFromPresets() { + var valueArray = []; + for (var i=0; i Altizar -> Zeker0 -> genBTC -// @match https://trimps.github.io/* -// @include *trimps.github.io* -// @include *kongregate.com/games/GreenSatellite/trimps -// @grant GM_xmlhttpRequest -// ==/UserScript== - -//Create blank AutoPerks object -MODULES["perks"] = {}; -var AutoPerks = {}; - -var AutoPerks = { - data: { - he_left: 0, - zone: 60, - targetzone: 60, - perks: null, - weight: { - helium: 0, - attack: 0, - health: 0, - xp: 0, - trimps: 0 - }, - fluffy: { - xp: 0, - prestige: 0 - }, - mod: { - storage: 0.125, - soldiers: 0, - dg: 0, - tent_city: false, - whip: false, - magn: false, - taunt: false, - ven: false, - chronojest: 0, - prod: 0, - loot: 0, - breed_timer: 0 - } - }, - preset: "z450", - fixed: "", - Perk: /** @class */ (function () { - function Perk(base_cost, increment, cap, free, scaling) { - if (scaling === void 0) { - scaling = 30; - } - this.base_cost = base_cost; - this.increment = increment; - this.cap = cap; - this.free = free; - this.scaling = scaling; - this.locked = true; - this.level = 0; - this.pack = 1; - this.must = 0; - this.spent = 0; - } - // Compute the current cost of a perk, based on its current level. - Perk.prototype.cost = function () { - return this.increment - ? this.pack * - (this.base_cost + - this.increment * (this.level + (this.pack - 1) / 2)) - : Math.ceil(this.level / 2 + this.base_cost * AutoPerky.mult(this, this.scaling)); - }; - return Perk; - })(), - unlocks: "", - notation: 2, - perks: null, - presets: { - early: ["5", "4", "3"], - broken: ["7", "3", "1"], - mid: ["16", "5", "1"], - corruption: ["25", "7", "1"], - magma: ["35", "4", "3"], - z280: ["42", "6", "1"], - z400: ["88", "10", "1"], - z450: ["500", "50", "1"], - spire: ["0", "1", "1"], - nerfed: ["0", "4", "3"], - tent: ["5", "4", "3"], - scientist: ["0", "1", "3"], - carp: ["0", "0", "0"], - trapper: ["0", "7", "1"], - coord: ["0", "40", "1"], - trimp: ["0", "99", "1"], - metal: ["0", "7", "1"], - c2: ["0", "7", "1"], - custom: ["1", "1", "1"] - }, - notations: [ - [], - ( - "KMBTQaQiSxSpOcNoDcUdDdTdQadQidSxdSpdOdNdVUvDvTvQavQivSxvSpvOvNvTgUtgDtgTtgQatg" + - "QitgSxtgSptgOtgNtgQaaUqaDqaTqaQaqaQiqaSxqaSpqaOqaNqaQiaUqiDqiTqiQaqiQiqiSxqiSpqi" + - "OqiNqiSxaUsxDsxTsxQasxQisxSxsxSpsxOsxNsxSpaUspDspTspQaspQispSxspSpspOspNspOgUog" + - "DogTogQaogQiogSxogSpogOogNogNaUnDnTnQanQinSxnSpnOnNnCtUc" - ).split(/(?=[A-Z])/), - [], - ( - "a b c d e f g h i j k l m n o p q r s t u v w x y z" + - " aa ab ac ad ae af ag ah ai aj ak al am an ao ap aq ar as at au av aw ax ay az" + - " ba bb bc bd be bf bg bh bi bj bk bl bm bn bo bp bq br bs bt bu bv bw bx by bz" + - " ca cb cc cd ce cf cg ch ci cj ck cl cm cn co cp cq cr cs ct cu cv cw cx" - ).split(" "), - "KMBTQaQiSxSpOcNoDcUdDdTdQadQidSxdSpdOdNdVUvDvTvQavQivSxvSpvOvNvTg".split( - /(?=[A-Z])/ - ) - ], - add: function (perk, x) { - return 1 + perk.level * x / 100; - }, - mult: function (perk, x) { - return Math.pow(1 + x / 100, perk.level); - }, - mastery: function (name) { - if (!game.talents[name]) { - throw "unknown mastery: " + name; - } - return game.talents[name].purchased; - }, - parse_suffixes: function (str) { - str = str.replace(/\*.*|[^--9+a-z]/gi, ""); - var suffixes = AutoPerky.notations[AutoPerky.notation === "3" ? 3 : 1]; - for (var i = suffixes.length; i > 0; --i) { - str = str.replace(new RegExp(suffixes[i - 1] + "$", "i"), "E" + 3 * i); - } - return +str; - }, - parse_perks: function (fixed, unlocks) { - var perks = { - Looting_II: new AutoPerky.Perk(100e3, 10e3, Infinity, 1e4), - Carpentry_II: new AutoPerky.Perk(100e3, 10e3, Infinity, 1e4), - Motivation_II: new AutoPerky.Perk(50e3, 1e3, Infinity, 1e4), - Power_II: new AutoPerky.Perk(20e3, 500, Infinity, 1e4), - Toughness_II: new AutoPerky.Perk(20e3, 500, Infinity, 1e4), - Capable: new AutoPerky.Perk(1e8, 0, 10, 1e4, 900), - Cunning: new AutoPerky.Perk(1e11, 0, Infinity, 1e4), - Curious: new AutoPerky.Perk(1e14, 0, Infinity, 1e4), - Overkill: new AutoPerky.Perk(1e6, 0, 30, 1e4), - Resourceful: new AutoPerky.Perk(50e3, 0, Infinity, 1e6), - Coordinated: new AutoPerky.Perk(150e3, 0, Infinity, 1e4), - Siphonology: new AutoPerky.Perk(100e3, 0, 3, 1e4), - Anticipation: new AutoPerky.Perk(1000, 0, 10, 1e4), - Resilience: new AutoPerky.Perk(100, 0, Infinity, 1e4), - Meditation: new AutoPerky.Perk(75, 0, 7, 1e4), - Relentlessness: new AutoPerky.Perk(75, 0, 10, 1e4), - Carpentry: new AutoPerky.Perk(25, 0, Infinity, 1e4), - Artisanistry: new AutoPerky.Perk(15, 0, Infinity, 1e4), - Range: new AutoPerky.Perk(1, 0, 10, 1e4), - Agility: new AutoPerky.Perk(4, 0, 20, 1e4), - Bait: new AutoPerky.Perk(4, 0, Infinity, 1e7), - Trumps: new AutoPerky.Perk(3, 0, Infinity, 1e8), - Pheromones: new AutoPerky.Perk(3, 0, Infinity, 1e6), - Packrat: new AutoPerky.Perk(3, 0, Infinity, 1e7), - Motivation: new AutoPerky.Perk(2, 0, Infinity, 1e4), - Power: new AutoPerky.Perk(1, 0, Infinity, 1e4), - Toughness: new AutoPerky.Perk(1, 0, Infinity, 1e4), - Looting: new AutoPerky.Perk(1, 0, Infinity, 1e4) - }; - if (!unlocks.match(/>/)) { - unlocks = unlocks.replace(/(?=,|$)/g, ">0"); - } - var list = (unlocks + "," + fixed).split(/,/).filter(x => x); - for (var key in list) { - var item = list[key]; - var m = (m = item.match(/(\S+) *([<=>])=?(.*)/)); - if (!m) { - throw "Enter a list of perk levels, such as “power=42, toughness=51”."; - } - var tier2 = m[1].match(/2$|II$/); - var name = m[1].replace(/[ _]?(2|II)/i, "").replace(/^OK/i, "O").replace(/^Looty/i, "L"); - var regex = new RegExp(`^${name}[a-z]*${tier2 ? "_II" : ""}$`, "i"); - var matches = Object.keys(perks).filter(p => p.match(regex)); - if (matches.length > 1) { - throw `Ambiguous perk abbreviation: ${m[1]}.`; - } - if (matches.length < 1) { - throw `Unknown perk: ${m[1]}.`; - } - let level = m[3]; - if (!isFinite(level)) { - throw `Invalid number: ${m[3]}.`; - } - perks[matches[0]].locked = false; - if (m[2] != ">") { - perks[matches[0]].cap = parseInt(level); - } - if (m[2] != "<") { - perks[matches[0]].must = parseInt(level); - } - } - return perks; - }, - select_preset: function (name, manually) { - if (manually === void 0) { - manually = true; - } - this.data.weight = { - helium: parseInt(this.presets[name][0]), - attack: parseInt(this.presets[name][1]), - health: parseInt(this.presets[name][2]), - xp: Math.floor((+this.presets[name][0] + +this.presets[name][1] + +this.presets[name][2]) / 5), - trimps: 0 - }; - }, - read_data: function () { - this.data.zone = this.data.targetzone; - this.unlocks = Object.keys(game.portal).filter(function (perk) { - return !game.portal[perk].locked; - }).join(","); - this.data.perks = this.parse_perks(this.fixed, this.unlocks); - var preset = this.preset; - this.select_preset(preset); - if (preset == "trapper" && (!game || game.global.challengeActive != "Trapper")) { - throw "This preset requires a save currently running Trapper². Start a new run using “Trapper² (initial)”, export, and try again."; - } - this.update_dg(); - //extra settings - var zone = this.data.targetzone; - var helium = game.global.viewingUpgrades ? game.global.heliumLeftover : game.global.heliumLeftover + game.resources.helium.owned; - for (var perk in game.portal) { - helium += game.portal[perk].heliumSpent; - } - var unlocks = Object.keys(game.portal).filter(function (perk) { - return !game.portal[perk].locked; - }); - if (!game.global.canRespecPerks) { - unlocks = unlocks.map(function (perk) { - return perk + ">" + game.portal[perk].level; - }); - } - // Income - var tt = this.mastery("turkimp4") ? 1 : this.mastery("turkimp3") ? 0.6 : this.mastery("turkimp2") ? 0.4 : this.mastery("turkimp") ? 0.3 : 0.25; - var prod = 1 + tt; - var loot = 1 + 0.333 * tt; - var spires = Math.min(Math.floor((zone - 101) / 100), game.global.spiresCompleted); - loot *= zone < 100 ? 0.7 : 1 + (this.mastery("stillRowing") ? 0.3 : 0.2) * spires; - var chronojest = 27 * game.unlocks.imps.Jestimp + 15 * game.unlocks.imps.Chronoimp; - var cache = zone < 60 ? 0 : zone < 85 ? 7 : zone < 160 ? 10 : zone < 185 ? 14 : 20; - chronojest += (this.mastery("mapLoot2") ? 5 : 4) * cache; - for (var _i = 0, _a = game.global.StaffEquipped.mods || []; _i < _a.length; _i++) { - var mod = _a[_i]; - if (mod[0] === "MinerSpeed") { - prod *= 1 + 0.01 * mod[1]; - } else if (mod[0] === "metalDrop") { - loot *= 1 + 0.01 * mod[1]; - } - } - this.data.he_left = helium + (game.global.canRespecPerks ? 0 : game.resources.helium.owned); - this.data.fluffy = { - xp: game ? game.global.fluffyExp : 0, - prestige: game ? game.global.fluffyPrestige : 0 - }; - this.data.mod = { - storage: 0.125, - soldiers: 0, - dg: preset == "nerfed" ? 0 : this.data.mod.dg, - tent_city: preset == "tent", - whip: game.unlocks.imps.Whipimp, - magn: game.unlocks.imps.Magnimp, - taunt: game.unlocks.imps.Tauntimp, - ven: game.unlocks.imps.Venimp, - chronojest: chronojest, - prod: prod, - loot: loot, - breed_timer: 45 - }; - if (preset == "nerfed") { - this.data.he_left = 1e8; - this.data.zone = 200; - this.data.mod.dg = 0; - } - if (preset == "trapper") { - this.data.mod.soldiers = game.resources.trimps.owned; - this.data.mod.prod = 0; - this.data.perks.Pheromones.cap = 0; - this.data.perks.Anticipation.cap = 0; - } - if (preset == "spire") { - this.data.mod.prod = this.data.mod.loot = 0; - this.data.perks.Overkill.cap = 0; - this.data.zone = game.global.world; - } - if (preset == "carp") { - this.data.mod.prod = this.data.mod.loot = 0; - this.data.weight.trimps = 1e6; - } - if (preset == "metal") { - this.data.mod.prod = 0; - } - if (preset == "trimp") { - this.data.mod.soldiers = 1; - } - if (preset == "nerfed") { - this.data.perks.Overkill.cap = 1; - } - if (preset == "scientist") { - this.data.perks.Coordinated.cap = 0; - } - }, - update_dg: function () { - var max_zone = this.data.targetzone / 2 + 115; - var eff = 500e6 + 50e6 * game.generatorUpgrades.Efficiency.upgrades; - var capa = 3 + 0.4 * game.generatorUpgrades.Capacity.upgrades; - var max_fuel = game.permanentGeneratorUpgrades.Storage.owned ? capa * 1.5 : capa; - var supply = 230 + 2 * game.generatorUpgrades.Supply.upgrades; - var overclock = game.generatorUpgrades.Overclocker.upgrades; - overclock = overclock && 1 - 0.5 * Math.pow(0.99, overclock - 1); - var burn = game.permanentGeneratorUpgrades.Slowburn.owned ? 0.4 : 0.5; - var cells = this.mastery("magmaFlow") ? 18 : 16; - var accel = this.mastery("quickGen") ? 1.03 : 1.02; - var hs2 = this.mastery("hyperspeed2") ? (game.global.highestLevelCleared + 1) / 2 : 0; - var bs = 0.5 * this.mastery("blacksmith") + 0.25 * this.mastery("blacksmith2") + 0.15 * this.mastery("blacksmith3"); - bs *= game.global.highestLevelCleared + 1; - var housing = 0; - var fuel = 0; - var time = 0; - function tick(mult) { - housing += mult * eff * Math.sqrt(Math.min(capa, fuel)); - fuel -= burn; - } - for (var zone = 230; zone <= max_zone; ++zone) { - fuel += cells * (0.01 * Math.min(zone, supply) - 2.1); - var tick_time = Math.ceil(60 / Math.pow(accel, Math.floor((zone - 230) / 3))); - time += zone > bs ? 28 : zone > hs2 ? 20 : 15; - while (time >= tick_time) { - time -= tick_time; - tick(1); - } - while (fuel > max_fuel) { - tick(overclock); - } - housing *= 1.009; - } - while (fuel >= burn) { - tick(1); - } - this.data.mod.dg = housing; - }, - optimize: function (data) { - var he_left = data.he_left, - zone = data.zone, - fluffy = data.fluffy, - perks = data.perks, - weight = data.weight, - mod = data.mod; - var Looting_II = perks.Looting_II, - Carpentry_II = perks.Carpentry_II, - Motivation_II = perks.Motivation_II, - Power_II = perks.Power_II, - Toughness_II = perks.Toughness_II, - Capable = perks.Capable, - Cunning = perks.Cunning, - Curious = perks.Curious, - Overkill = perks.Overkill, - Resourceful = perks.Resourceful, - Coordinated = perks.Coordinated, - Siphonology = perks.Siphonology, - Anticipation = perks.Anticipation, - Resilience = perks.Resilience, - Meditation = perks.Meditation, - Relentlessness = perks.Relentlessness, - Carpentry = perks.Carpentry, - Artisanistry = perks.Artisanistry, - Range = perks.Range, - Agility = perks.Agility, - Bait = perks.Bait, - Trumps = perks.Trumps, - Pheromones = perks.Pheromones, - Packrat = perks.Packrat, - Motivation = perks.Motivation, - Power = perks.Power, - Toughness = perks.Toughness, - Looting = perks.Looting; - for (var name in perks) { - if (name.endsWith("_II")) { - perks[name].pack = Math.pow(10, Math.max(0, Math.floor(Math.log(he_left) / Math.log(100) - 4.2))); - } - } - for (var _i = 0, _a = ["whip", "magn", "taunt", "ven"]; _i < _a.length; _i++) { - var name = _a[_i]; - mod[name] = Math.pow(1.003, zone * 99 * 0.03 * mod[name]); - } - var books = Math.pow(1.25, zone) * Math.pow(zone > 100 ? 1.28 : 1.2, Math.max(zone - 59, 0)); - var gigas = Math.max(0, Math.min(zone - 60, zone / 2 - 25, zone / 3 - 12, zone / 5, zone / 10 + 17, 39)); - var base_housing = Math.pow(1.25, Math.min(zone / 2, 30) + gigas); - var mystic = zone >= 25 ? Math.floor(Math.min(zone / 5, 9 + zone / 25, 15)) : 0; - var tacular = (20 + zone - zone % 5) / 100; - var base_income = 600 * mod.whip * books; - var base_helium = Math.pow(zone - 19, 2); - var max_tiers = zone / 5 + +((zone - 1) % 10 < 5); - var exponents = { - cost: Math.pow(1.069, 0.85 * (zone < 60 ? 57 : 53)), - attack: Math.pow(1.19, 13), - health: Math.pow(1.19, 14), - block: Math.pow(1.19, 10) - }; - var equip_cost = { - attack: 211 * (weight.attack + weight.health) / weight.attack, - health: 248 * (weight.attack + weight.health) / weight.health, - block: 5 * (weight.attack + weight.health) / weight.health - }; - // Number of ticks it takes to one-shot an enemy. - function ticks() { - return 1 + +(Agility.level < 3) + Math.ceil(10 * AutoPerky.mult(Agility, -5)); - } - var moti = function () { - return AutoPerky.add(Motivation, 5) * AutoPerky.add(Motivation_II, 1); - }; - var looting = function () { - return AutoPerky.add(Looting, 5) * AutoPerky.add(Looting_II, 0.25); - }; - function income(ignore_prod) { - var storage = mod.storage * AutoPerky.mult(Resourceful, -5) / AutoPerky.add(Packrat, 20); - var loot = looting() * mod.magn / ticks(); - var prod = ignore_prod ? 0 : moti() * AutoPerky.add(Meditation, 1) * mod.prod; - var chronojest = mod.chronojest * 0.1 * prod * loot; - return (base_income * (prod + loot * mod.loot + chronojest) * (1 - storage)); - } - // Max population - var trimps = mod.tent_city - ? function () { - var carp = AutoPerky.mult(Carpentry, 10) * AutoPerky.add(Carpentry_II, 0.25); - var territory = AutoPerky.add(Trumps, 20); - return 10 * (mod.taunt + territory * (mod.taunt - 1) * 111) * carp; - } - : function () { - var carp = AutoPerky.mult(Carpentry, 10) * AutoPerky.add(Carpentry_II, 0.25); - var bonus = 3 + Math.max(Math.log(income() / base_income * carp / AutoPerky.mult(Resourceful, -5)), 0); - var territory = AutoPerky.add(Trumps, 20) * zone; - return (10 * (base_housing * bonus + territory) * carp * mod.taunt + mod.dg * carp); - }; - function equip(stat) { - var cost = equip_cost[stat] * AutoPerky.mult(Artisanistry, -5); - var levels = 1.136; - var tiers = Math.log(1 + income() * trimps() / cost) / Math.log(exponents.cost); - if (tiers > max_tiers + 0.45) { - levels = Math.log(1 + Math.pow(exponents.cost, tiers - max_tiers) * 0.2) / Math.log(1.2); - tiers = max_tiers; - } - return levels * Math.pow(exponents[stat], tiers); - } - // Number of buildings of a given kind that can be built with the current income. - // cost: base cost of the buildings - // exp: cost increase for each new level of the building - function building(cost, exp) { - cost *= 4 * AutoPerky.mult(Resourceful, -5); - return Math.log(1 + income(true) * trimps() * (exp - 1) / cost) / Math.log(exp); - } - // Number of zones spent in the Magma - function magma() { - return Math.max(zone - 229, 0); - } - // function mancers() { - // let tributes = building(10000, 1.05); - // let mancers = Math.log(loot * Math.pow(1.05, tributes) / 1e62) / Math.log(1.01); - // return magma() ? 1 + 0.6 * (1 - Math.pow(0.9999, mancers)) : 1; - // } - // Breed speed - function breed() { - var nurseries = building(2e6, 1.06) / (1 + 0.1 * Math.min(magma(), 20)); - var potency = 0.0085 * (zone >= 60 ? 0.1 : 1) * Math.pow(1.1, Math.floor(zone / 5)); - return potency * Math.pow(1.01, nurseries) * AutoPerky.add(Pheromones, 10) * mod.ven; - } - var group_size = []; - for (var coord = 0; coord <= Math.log(1 + he_left / 500e3) / Math.log(1.3); ++coord) { - var ratio = 1 + 0.25 * Math.pow(0.98, coord); - var result = 1; - for (var i = 0; i < 100; ++i) { - result = Math.ceil(result * ratio); - } - group_size[coord] = result / Math.pow(ratio, 100); - } - // Theoretical fighting group size (actual size is lower because of Coordinated) - function soldiers() { - var ratio = 1 + 0.25 * AutoPerky.mult(Coordinated, -2); - var pop = (mod.soldiers || trimps()) / 3; - if (mod.soldiers > 1) - pop += 36000 * AutoPerky.add(Bait, 100); - var coords = Math.log(pop / group_size[Coordinated.level]) / Math.log(ratio); - var available = zone - 1 + (magma() ? 100 : 0); - return group_size[0] * Math.pow(1.25, Math.min(coords, available)); - } - // Total attack - function attack() { - var attack = (0.15 + equip("attack")) * Math.pow(0.8, magma()); - attack *= AutoPerky.add(Power, 5) * AutoPerky.add(Power_II, 1); - attack *= AutoPerky.add(Relentlessness, 5 * AutoPerky.add(Relentlessness, 30)); - attack *= Math.pow(1 + Siphonology.level, 0.1) * AutoPerky.add(Range, 1); - attack *= AutoPerky.add(Anticipation, 6); - return soldiers() * attack; - } - // Total survivability (accounts for health and block) - function health() { - var health = (0.6 + equip("health")) * Math.pow(0.8, magma()); - health *= AutoPerky.add(Toughness, 5) * AutoPerky.add(Toughness_II, 1) * AutoPerky.mult(Resilience, 10); - // block - var gyms = building(400, 1.185); - var trainers = (gyms * Math.log(1.185) - Math.log(1 + gyms)) / Math.log(1.1) + 25 - mystic; - var block = 0.04 * gyms * Math.pow(1 + mystic / 100, gyms) * (1 + tacular * trainers); - // target number of attacks to survive - var attacks = 60; - if (zone < 70) { - // number of ticks needed to repopulate an army - var timer = - Math.log(1 + soldiers() * breed() / AutoPerky.add(Bait, 100)) / Math.log(1 + breed()); - attacks = timer / ticks(); - } else { - var ratio = 1 + 0.25 * AutoPerky.mult(Coordinated, -2); - var available = zone - 1 + (magma() ? 100 : 0); - var required = group_size[Coordinated.level] * Math.pow(ratio, available); - var fighting = Math.min(required / trimps(), 1 / 3); - var target_speed = fighting > 1e-9 ? (Math.pow(0.5 / (0.5 - fighting), 0.1 / mod.breed_timer) - 1) * 10 : fighting / mod.breed_timer; - var geneticists = Math.log(breed() / target_speed) / -Math.log(0.98); - health *= Math.pow(1.01, geneticists); - } - health /= attacks; - if (zone < 60) { - block += equip("block"); - } else { - block = Math.min(block, 4 * health); - } - return soldiers() * (block + health); - } - // XP earned by Fluffy over the run - fluffy.base = 0; - for (var z = 301; z < zone; ++z) { - fluffy.base += 50 * Math.pow(1.015, z - 300); - } - function xp() { - var total = fluffy.base * AutoPerky.add(Cunning, 25) * AutoPerky.add(Curious, 60); - var cap = Capable.level == 10 ? Infinity : 1000 * Math.pow(5, fluffy.prestige) * (AutoPerky.mult(Capable, 300) - 1) / 3; - return Math.max(1, Math.min(total, cap - fluffy.xp) + Math.min(total * 7, cap - fluffy.xp)); - } - var agility = function () { - return 1 / AutoPerky.mult(Agility, -5); - }; - var helium = function () { - return base_helium * looting() + 45; - }; - var overkill = function () { - return Math.max(0.2, Overkill.level); - }; - var stats = { - agility: agility, - helium: helium, - xp: xp, - attack: attack, - health: health, - overkill: overkill, - trimps: trimps - }; - function score() { - var result = 0; - for (var i in weight) { - if (!weight[i]) { - continue; - } - var stat = stats[i](); - if (!isFinite(stat)) { - throw Error(i + " is " + stat); - } - result += weight[i] * Math.log(stat); - } - return result; - } - function best_perk() { - var best; - var max = 0; - var baseline = score(); - for (var name in perks) { - var perk = perks[name]; - if (perk.locked || perk.level >= perk.cap || perk.cost() > he_left) { - continue; - } - perk.level += perk.pack; - var gain = score() - baseline; - perk.level -= perk.pack; - var efficiency = gain / perk.cost(); - if (efficiency >= max) { - max = efficiency; - best = perk; - } - } - return best; - } - mod.loot *= 20.8; // TODO: check that this is correct - weight.agility = (weight.helium + weight.attack) / 2; - weight.overkill = 0.25 * weight.attack * (2 - Math.pow(0.9, weight.helium / weight.attack)); - //Disable Bait if we are above z110 - if (zone > 110 && mod.soldiers <= 1 && Bait.must == 0) { - Bait.cap = 0; - } - if (!Capable.must) { - Capable.must = Math.ceil(Math.log(0.003 * fluffy.xp / Math.pow(5, fluffy.prestige) + 1) / Math.log(4)); - } - // Dirty fix - Capable.must = Math.min(Capable.must, 10, Math.floor(Math.log(he_left) / Math.log(10) - 7.5)); - for (var name in perks) { - var perk = perks[name]; - while (perk.level < perk.must) { - var cost = perk.cost(); - he_left -= cost; - perk.level += perk.pack; - perk.spent += cost; - } - } - if (he_left < 0) { - throw game && game.global.canRespecPerks ? "You don’t have enough Helium to afford your Fixed Perks." : "You don’t have a respec available."; - } - // Main loop - for (var best = void 0; (best = best_perk()); ) { - var spent = 0; - while (best.level < best.cap && (best.level < best.must || spent < he_left / best.free)) { - he_left -= best.cost(); - spent += best.cost(); - best.level += best.pack; - if (best.level == 1000 * best.pack) { - best.pack *= 10; - } - } - best.spent += spent; - } - for (var perk in perks) { - //console.log(perk, "=", perks[perk].level, "=", perks[perk].must); - } - return [he_left, perks]; - }, - init: function () { - var ratio = JSON.parse(localStorage.getItem("AutoperkCustomRatio")); - if (ratio !== null && ratio !== undefined && ratio.length === 3) { - this.presets["custom"] = ratio; - } - this.buildButtons(); - }, - run: function () { - this.inputs = this.read_data(); - this.optimize(this.data); - }, - clickAllocate: function () { - AutoPerky.run(); - this.applyCalculations(this.data.perks); - }, - applyCalculations: function (perks) { - var preBuyAmt = game.global.buyAmt; - if (game.global.canRespecPerks) { - respecPerks(); - } - if (game.global.respecActive) { - clearPerks(); - for (var i in perks) { - if (!game.portal[i].locked) { - game.global.buyAmt = perks[i].level; - buyPortalUpgrade(i); - } - } - } - game.global.buyAmt = preBuyAmt; - numTab(1, true); //selects the 1st number of the buy-amount tab-bar (Always 1) - cancelTooltip(); //displays the last perk we bought's tooltip without this. idk why. - }, - createInput: function (perkname, div) { - var perk1input = document.createElement("Input"); - perk1input.id = perkname + "Ratio"; - var oldstyle = "text-align: center; width: 60px;"; - if (game.options.menu.darkTheme.enabled != 2) { - perk1input.setAttribute("style", oldstyle + " color: black;"); - } else { - perk1input.setAttribute("style", oldstyle); - } - perk1input.setAttribute("class", "perkRatios"); - var perk1label = document.createElement("Label"); - perk1label.id = perkname + "Label"; - perk1label.innerHTML = perkname; - perk1label.setAttribute("style", "margin-right: 1vw; width: 120px; color: white;"); - //add to the div. - perk1input.setAttribute("onchange", "AutoPerky.saveRatios()"); - div.appendChild(perk1input); - div.appendChild(perk1label); - }, - saveRatios: function () { - if (this.preset === "custom") { - this.presets[this.preset][0] = parseInt(document.getElementById("HeliumRatio").value); - this.presets[this.preset][1] = parseInt(document.getElementById("AttackRatio").value); - this.presets[this.preset][2] = parseInt(document.getElementById("HealthRatio").value); - safeSetItems("AutoperkCustomRatio", JSON.stringify(this.presets[this.preset])); - } - if (this.fixed != document.getElementById("FixedRatio").value) { - this.fixed = document.getElementById("FixedRatio").value; - safeSetItems("AutoperkFixedPerks", this.fixed); - } - var loadZone = parseInt(document.getElementById("TargetRatio").value); - if (loadZone > 0) { - this.data.targetzone = loadZone; - safeSetItems("AutoperkTargetZone", this.data.targetzone); - } - }, - setDefaultRatios: function () { - if (this.preset !== document.getElementById("ratioPreset").value) { - var ratioSet = document.getElementById("ratioPreset").selectedIndex; - if (Number.isInteger(ratioSet)) { - safeSetItems("AutoperkSelectedRatioPresetID", ratioSet); - } - this.preset = document.getElementById("ratioPreset").value; - } - document.getElementById("HeliumRatio").value = this.presets[this.preset][0]; - document.getElementById("AttackRatio").value = this.presets[this.preset][1]; - document.getElementById("HealthRatio").value = this.presets[this.preset][2]; - if (this.preset === "custom") { - document.getElementById("HeliumRatio").disabled = false; - document.getElementById("AttackRatio").disabled = false; - document.getElementById("HealthRatio").disabled = false; - } else { - document.getElementById("HeliumRatio").disabled = true; - document.getElementById("AttackRatio").disabled = true; - document.getElementById("HealthRatio").disabled = true; - } - document.getElementById("FixedRatio").value = this.fixed; - document.getElementById("TargetRatio").value = this.data.targetzone; - }, - buildButtons: function () { - var buttonbar = document.getElementById("portalBtnContainer"); - var customRatios = document.createElement("DIV"); - customRatios.id = 'customRatios'; - this.createInput("Helium", customRatios); - this.createInput("Attack", customRatios); - this.createInput("Health", customRatios); - this.createInput("Target", customRatios); - this.createInput("Fixed", customRatios); - var loadFixed = localStorage.getItem("AutoperkFixedPerks"); - if (loadFixed !== null) { - this.fixed = loadFixed; - } - var loadZone = parseInt(localStorage.getItem("AutoperkTargetZone")); - if (loadZone > 0) { - this.data.targetzone = loadZone; - } else { - this.data.targetzone = - game.stats.highestVoidMap.valueTotal || game.global.highestLevelCleared; - } - //Create Allocator button and add it to Trimps Perk Window - var allocatorBtn1 = document.createElement("DIV"); - allocatorBtn1.id = "allocatorBTN1"; - allocatorBtn1.setAttribute("class", "btn inPortalBtn settingsBtn settingBtntrue"); - allocatorBtn1.setAttribute("onclick", "AutoPerky.clickAllocate();"); - allocatorBtn1.textContent = "Allocate Perks"; - buttonbar.appendChild(allocatorBtn1); - buttonbar.setAttribute("style", "margin-bottom: 0.8vw;"); - - var ratioPreset = document.createElement("select"); - ratioPreset.id = "ratioPreset"; - var oldstyle = "text-align: center; width: 110px;"; - if (game.options.menu.darkTheme.enabled != 2) - ratioPreset.setAttribute("style", oldstyle + " color: black;"); - else - ratioPreset.setAttribute("style", oldstyle); - //Populate dump perk dropdown list : - // var AutoPerky.presetList = [preset_ZXV,preset_ZXVnew,preset_ZXV3,preset_TruthEarly,preset_TruthLate,preset_nsheetz,preset_nsheetzNew,preset_HiderHehr,preset_HiderBalance,preset_HiderMore,preset_genBTC,preset_genBTC2]; - var html = ""; - for (var key in this.presets) { - html += '"; - } - //Specific ratios labeled above are configured down in the bottom of this file.Lines 543-556 - ratioPreset.innerHTML = html; - //load the last ratio used - var loadLastPreset = localStorage.getItem("AutoperkSelectedRatioPresetID"); - if (loadLastPreset != null) - ratioPreset.selectedIndex = loadLastPreset; // First element is zxv (default) ratio. - else - ratioPreset.selectedIndex = 0; - ratioPreset.setAttribute("onchange", "AutoPerky.setDefaultRatios()"); - //Add the presets dropdown to UI Line 1 - customRatios.appendChild(ratioPreset); - document.getElementById("portalWrapper").appendChild(customRatios); - document.getElementById("FixedRatio").style["width"] = "480px"; - this.setDefaultRatios(); - } -}; - -AutoPerky.init(); \ No newline at end of file diff --git a/modules/portal.js b/modules/portal.js index dfa883f8d..23a4f3dbc 100644 --- a/modules/portal.js +++ b/modules/portal.js @@ -1,79 +1,51 @@ MODULES["portal"] = {}; -//These can be changed (in the console) if you know what you're doing: -MODULES["portal"].timeout = 10000; //time to delay before autoportaling in milliseconds -MODULES["portal"].bufferExceedFactor = 5; //amount for: allows portaling midzone if we exceed (5x) the buffer +MODULES["portal"].timeout = 5000; +MODULES["portal"].bufferExceedFactor = 5; +var portalzone = getPageSetting('CustomAutoPortal'); +var zonePostpone = 0; -///////////////////////////////////////////////////// -//Portal Related Code)/////////////////////////////// -///////////////////////////////////////////////////// -//var lastHeliumZone = 0; //zone where the He/hr portal conditions were first met -var zonePostpone = 0; //additional postponement of the zone above. - -//Decide When to Portal function autoPortal() { - if(!game.global.portalActive) return; - var autoFinishDaily = (game.global.challengeActive == "Daily" && getPageSetting('AutoFinishDaily')); - var autoFinishDailyZone = getPageSetting('AutoFinishDailyZone'); - if (!autoFinishDaily) - autoFinishDailyZone = 0; //dont use stale disabled values + if (!game.global.portalActive) return; switch (autoTrimpSettings.AutoPortal.selected) { - //portal if we have lower He/hr than the previous zone (or buffer) case "Helium Per Hour": var OKtoPortal = false; - if (!game.global.challengeActive || autoFinishDaily) { + if (!game.global.runningChallengeSquared) { var minZone = getPageSetting('HeHrDontPortalBefore'); - minZone += autoFinishDailyZone; - game.stats.bestHeliumHourThisRun.evaluate(); //normally, evaluate() is only called once per second, but the script runs at 10x a second. + game.stats.bestHeliumHourThisRun.evaluate(); var bestHeHr = game.stats.bestHeliumHourThisRun.storedValue; var bestHeHrZone = game.stats.bestHeliumHourThisRun.atZone; var myHeliumHr = game.stats.heliumHour.value(); var heliumHrBuffer = Math.abs(getPageSetting('HeliumHrBuffer')); - //Multiply the buffer by (5) if we are in the middle of a zone (allows portaling midzone if we exceed (5x) the buffer) if (!aWholeNewWorld) heliumHrBuffer *= MODULES["portal"].bufferExceedFactor; - var bufferExceeded = myHeliumHr < bestHeHr * (1-(heliumHrBuffer/100)); + var bufferExceeded = myHeliumHr < bestHeHr * (1 - (heliumHrBuffer / 100)); if (bufferExceeded && game.global.world >= minZone) { OKtoPortal = true; if (aWholeNewWorld) - zonePostpone = 0; //reset the zonePostPone if we see a new zone + zonePostpone = 0; } - //make sure people with 0 buffer only portal on aWholeNewWorld (not midzone) if (heliumHrBuffer == 0 && !aWholeNewWorld) OKtoPortal = false; - //Postpone Portal (and Actually Portal) code: if (OKtoPortal && zonePostpone == 0) { - zonePostpone+=1; - //lastHeliumZone = game.global.world; - debug("My HeliumHr was: " + myHeliumHr + " & the Best HeliumHr was: " + bestHeHr + " at zone: " + bestHeHrZone, "portal"); + zonePostpone += 1; + debug("My HeliumHr was: " + myHeliumHr + " & the Best HeliumHr was: " + bestHeHr + " at zone: " + bestHeHrZone, "portal"); cancelTooltip(); - tooltip('confirm', null, 'update', 'Auto Portaling NOW!

Hit Delay Portal to WAIT 1 more zone.', 'zonePostpone+=1', 'NOTICE: Auto-Portaling in 10 seconds....','Delay Portal'); - //set up 2 things to happen after the timeout. close the tooltip: - setTimeout(cancelTooltip,MODULES["portal"].timeout); - //and check if we hit the confirm to postpone, and if not, portal. - setTimeout(function(){ + tooltip('confirm', null, 'update', 'Auto Portaling NOW!

Hit Delay Portal to WAIT 1 more zone.', 'zonePostpone+=1', 'NOTICE: Auto-Portaling in 5 seconds....', 'Delay Portal'); + setTimeout(cancelTooltip, MODULES["portal"].timeout); + setTimeout(function() { if (zonePostpone >= 2) - return; //do nothing if we postponed. - if (autoFinishDaily){ - abandonDaily(); - document.getElementById('finishDailyBtnContainer').style.display = 'none'; - } - // + return; if (autoTrimpSettings.HeliumHourChallenge.selected != 'None') doPortal(autoTrimpSettings.HeliumHourChallenge.selected); else doPortal(); - },MODULES["portal"].timeout+100); + }, MODULES["portal"].timeout + 100); } } break; case "Custom": - if ((game.global.world > getPageSetting('CustomAutoPortal')+autoFinishDailyZone) && - (!game.global.challengeActive || autoFinishDaily)) { - if (autoFinishDaily) { - abandonDaily(); - document.getElementById('finishDailyBtnContainer').style.display = 'none'; - } - // + var portalzone = getPageSetting('CustomAutoPortal'); + if (game.global.world > portalzone) { if (autoTrimpSettings.HeliumHourChallenge.selected != 'None') doPortal(autoTrimpSettings.HeliumHourChallenge.selected); else @@ -92,7 +64,9 @@ function autoPortal() { case "Watch": case "Lead": case "Corrupted": - if(!game.global.challengeActive) { + case "Domination": + case "Experience": + if (!game.global.challengeActive) { doPortal(autoTrimpSettings.AutoPortal.selected); } break; @@ -101,92 +75,488 @@ function autoPortal() { } } -//Actually Portal. +function dailyAutoPortal() { + if (!game.global.portalActive) return; + if (getPageSetting('AutoPortalDaily') == 1) { + var OKtoPortal = false; + if (!game.global.runningChallengeSquared) { + var minZone = getPageSetting('dHeHrDontPortalBefore'); + game.stats.bestHeliumHourThisRun.evaluate(); + var bestHeHr = game.stats.bestHeliumHourThisRun.storedValue; + var bestHeHrZone = game.stats.bestHeliumHourThisRun.atZone; + var myHeliumHr = game.stats.heliumHour.value(); + var heliumHrBuffer = Math.abs(getPageSetting('dHeliumHrBuffer')); + if (!aWholeNewWorld) { + heliumHrBuffer *= MODULES["portal"].bufferExceedFactor; + var bufferExceeded = myHeliumHr < bestHeHr * (1 - (heliumHrBuffer / 100)); + if (bufferExceeded && game.global.world >= minZone) { + OKtoPortal = true; + if (aWholeNewWorld) + zonePostpone = 0; + } + if (heliumHrBuffer == 0 && !aWholeNewWorld) + OKtoPortal = false; + if (OKtoPortal && zonePostpone == 0) { + zonePostpone += 1; + debug("My HeliumHr was: " + myHeliumHr + " & the Best HeliumHr was: " + bestHeHr + " at zone: " + bestHeHrZone, "portal"); + cancelTooltip(); + tooltip('confirm', null, 'update', 'Auto Portaling NOW!

Hit Delay Portal to WAIT 1 more zone.', 'zonePostpone+=1', 'NOTICE: Auto-Portaling in 5 seconds....', 'Delay Portal'); + setTimeout(cancelTooltip, MODULES["portal"].timeout); + setTimeout(function() { + if (zonePostpone >= 2) + return; + if (OKtoPortal) { + abandonDaily(); + document.getElementById('finishDailyBtnContainer').style.display = 'none'; + } + if (autoTrimpSettings.dHeliumHourChallenge.selected != 'None' && getPageSetting('u1daily') == false) + doPortal(autoTrimpSettings.dHeliumHourChallenge.selected); + else if (autoTrimpSettings.RdHeliumHourChallenge.selected != 'None' && getPageSetting('u1daily') == true) + doPortal(autoTrimpSettings.RdHeliumHourChallenge.selected); + else + doPortal(); + }, MODULES["portal"].timeout + 100); + } + } + } + } + if (getPageSetting('AutoPortalDaily') == 2) { + var portalzone = getPageSetting('dCustomAutoPortal'); + if (game.global.world > portalzone) { + abandonDaily(); + document.getElementById('finishDailyBtnContainer').style.display = 'none'; + if (autoTrimpSettings.dHeliumHourChallenge.selected != 'None' && getPageSetting('u1daily') == false) + doPortal(autoTrimpSettings.dHeliumHourChallenge.selected); + else if (autoTrimpSettings.RdHeliumHourChallenge.selected != 'None' && getPageSetting('u1daily') == true) + doPortal(autoTrimpSettings.RdHeliumHourChallenge.selected); + else + doPortal(); + } + } +} + +function c2runnerportal() { + if (game.global.world > getPageSetting('c2runnerportal')) { + if (game.global.runningChallengeSquared) + abandonChallenge(); + if (autoTrimpSettings.HeliumHourChallenge.selected != 'None') + doPortal(autoTrimpSettings.HeliumHourChallenge.selected); + else + doPortal(); + } +} + +function c2runner() { + +if (!game.global.portalActive) return; + if (getPageSetting('c2runnerstart') == true && getPageSetting('c2runnerportal') > 0 && getPageSetting('c2runnerpercent') > 0) { + if (game.global.highestLevelCleared > 34 && (100*(game.c2.Size/(game.global.highestLevelCleared+1))) < getPageSetting('c2runnerpercent')) { + challengeSquaredMode = true; + selectChallenge("Size"); + debug("C2 Runner: Running C2 Challenge Size"); + } + else if (game.global.highestLevelCleared > 129 && (100*(game.c2.Slow/(game.global.highestLevelCleared+1))) < getPageSetting('c2runnerpercent')) { + challengeSquaredMode = true; + selectChallenge("Slow"); + debug("C2 Runner: Running C2 Challenge Slow"); + } + else if (game.global.highestLevelCleared > 179 && (100*(game.c2.Watch/(game.global.highestLevelCleared+1))) < getPageSetting('c2runnerpercent')) { + challengeSquaredMode = true; + selectChallenge("Watch"); + debug("C2 Runner: Running C2 Challenge Watch"); + } + else if ((100*(game.c2.Discipline/(game.global.highestLevelCleared+1))) < getPageSetting('c2runnerpercent')) { + challengeSquaredMode = true; + selectChallenge("Discipline"); + debug("C2 Runner: Running C2 Challenge Discipline"); + } + else if (game.global.highestLevelCleared > 39 && (100*(game.c2.Balance/(game.global.highestLevelCleared+1))) < getPageSetting('c2runnerpercent')) { + challengeSquaredMode = true; + selectChallenge("Balance"); + debug("C2 Runner: Running C2 Challenge Balance"); + } + else if (game.global.highestLevelCleared > 44 && (100*(game.c2.Meditate/(game.global.highestLevelCleared+1))) < getPageSetting('c2runnerpercent')) { + challengeSquaredMode = true; + selectChallenge("Meditate"); + debug("C2 Runner: Running C2 Challenge Meditate"); + } + else if (game.global.highestLevelCleared > 24 && (100*(game.c2.Metal/(game.global.highestLevelCleared+1))) < getPageSetting('c2runnerpercent')) { + challengeSquaredMode = true; + selectChallenge("Metal"); + debug("C2 Runner: Running C2 Challenge Metal"); + } + else if (game.global.highestLevelCleared > 179 && (100*(game.c2.Lead/(game.global.highestLevelCleared+1))) < getPageSetting('c2runnerpercent')) { + challengeSquaredMode = true; + selectChallenge("Lead"); + debug("C2 Runner: Running C2 Challenge Lead"); + } + else if (game.global.highestLevelCleared > 144 && (100*(game.c2.Nom/(game.global.highestLevelCleared+1))) < getPageSetting('c2runnerpercent')) { + challengeSquaredMode = true; + selectChallenge("Nom"); + debug("C2 Runner: Running C2 Challenge Nom"); + } + else if ((100*(game.c2.Electricity/(game.global.highestLevelCleared+1))) < getPageSetting('c2runnerpercent')) { + challengeSquaredMode = true; + selectChallenge("Electricity"); + debug("C2 Runner: Running C2 Challenge Electricity"); + } + else if (game.global.highestLevelCleared > 164 && (100*(game.c2.Toxicity/(game.global.highestLevelCleared+1))) < getPageSetting('c2runnerpercent')) { + challengeSquaredMode = true; + selectChallenge("Toxicity"); + debug("C2 Runner: Running C2 Challenge Toxicity"); + } + } +} + function doPortal(challenge) { + var c2done = true; if(!game.global.portalActive) return; - if (getPageSetting('AutoMagmiteSpender2')==1) autoMagmiteSpender(); - // From mainLoop - if (getPageSetting('AutoHeirlooms2')) autoHeirlooms2(); //"Auto Heirlooms 2" (heirlooms.js) - else if (getPageSetting('AutoHeirlooms')) autoHeirlooms();//"Auto Heirlooms" (") - if (getPageSetting('AutoUpgradeHeirlooms') && !heirloomsShown) autoNull(); //"Auto Upgrade Heirlooms" (heirlooms.js) - //Go into portal screen + if (getPageSetting('spendmagmite')==1) { + autoMagmiteSpender(); + } + if (getPageSetting('autoheirlooms') == true && getPageSetting('typetokeep') != 'None' && getPageSetting('raretokeep') != 'None') { + autoheirlooms3(); + } + if (game.global.ShieldEquipped.name != getPageSetting('highdmg') || game.global.ShieldEquipped.name != getPageSetting('dhighdmg')) { + if (highdmgshield() != undefined) { + selectHeirloom(game.global.heirloomsCarried.indexOf(loom), "heirloomsCarried", true); + equipHeirloom(); + } + } + /*if (getPageSetting('autonu') == true && getPageSetting('heirloomnu') != undefined) { + spendNu(); spendNu(); spendNu(); spendNu(); spendNu(); spendNu(); + }*/ + if (getPageSetting('AutoAllocatePerks')==2) { + viewPortalUpgrades(); + numTab(6, true) + buyPortalUpgrade('Looting_II'); + activateClicked(); + cancelPortal(); + debug('First Stage: Bought Max Looting II'); + } portalClicked(); - //AutoPerks: do this first, because it reflashes the screen. - if (getPageSetting('AutoAllocatePerks') && (typeof MODULES["perks"] !== 'undefined' || typeof AutoPerks !== 'undefined')) + if (!portalWindowOpen) { + portalClicked(); + } + if (portalWindowOpen && getPageSetting('AutoAllocatePerks')==1 && (typeof MODULES["perks"] !== 'undefined' || typeof AutoPerks !== 'undefined')) { AutoPerks.clickAllocate(); - //Auto Start Daily: - if (getPageSetting('AutoStartDaily')) { + } + if (portalWindowOpen && getPageSetting('c2runnerstart')==true && getPageSetting('c2runnerportal') > 0 && getPageSetting('c2runnerpercent') > 0) { + c2runner(); + if (challengeSquaredMode == true) { + c2done = false; + } + else debug("C2 Runner: All C2s above Threshold!"); + } + if (portalWindowOpen && getPageSetting('AutoStartDaily') == true && c2done) { + if (getPageSetting('u2daily') == true && portalUniverse == 1) { + swapPortalUniverse(); + } selectChallenge('Daily'); checkCompleteDailies(); - - var lastUndone = -7; // Note: Most previous challenge == -6 + var lastUndone = -7; while (++lastUndone <= 0) { var done = (game.global.recentDailies.indexOf(getDailyTimeString(lastUndone)) != -1); if (!done) break; } - - if (lastUndone == 1) { // None + if (lastUndone == 1) { debug("All available Dailies already completed.", "portal"); - //Fallback to w/e Regular challenge we picked. Or none (unselect) + if ((getPageSetting('u1daily') == true && portalUniverse == 1 && challenge == autoTrimpSettings.RdHeliumHourChallenge.selected) || (getPageSetting('u2daily') == true && portalUniverse == 2)) { + swapPortalUniverse(); + } selectChallenge(challenge || 0); } else { getDailyChallenge(lastUndone); debug("Portaling into Daily for: " + getDailyTimeString(lastUndone, true) + " now!", "portal"); } } - //Regular Challenge: - else if(challenge) { + else if(portalWindowOpen && challenge && c2done) { + if (getPageSetting('u1daily') == true && portalUniverse == 1 && challenge == autoTrimpSettings.RdHeliumHourChallenge.selected) { + swapPortalUniverse(); + } selectChallenge(challenge); } - //Push He Data: - pushData(); - //Actually Portal. - activateClicked(); + if (portalWindowOpen && getPageSetting('AutoAllocatePerks')==2 && !game.portal.Looting_II.locked) { + numTab(6, true) + buyPortalUpgrade('Looting_II'); + debug('Second Stage: Bought Max Looting II'); + } activatePortal(); lastHeliumZone = 0; zonePostpone = 0; } -// Finish Challenge2 (UNI mod) -function finishChallengeSquared() { - // some checks done before reaching this: - // getPageSetting('FinishC2')>0 && game.global.runningChallengeSquared - var zone = getPageSetting('FinishC2'); - if (game.global.world >= zone) { - abandonChallenge(); - debug("Finished challenge2 because we are on zone " + game.global.world, "other", 'oil'); - } -} +function finishChallengeSquared(){var a=getPageSetting("FinishC2");game.global.world>=a&&(abandonChallenge(),debug("Finished challenge2 because we are on zone "+game.global.world,"other","oil"))} +function findOutCurrentPortalLevel(){var a=-1,b=!1,d=getPageSetting("AutoPortal");switch(d){case"Off":break;case"Custom":"Daily"!=game.global.challengeActive&&(a=getPageSetting("CustomAutoPortal")+1),"Daily"==game.global.challengeActive&&(a=getPageSetting("Dailyportal")+1),b=!("Lead"!=getPageSetting("HeliumHourChallenge"));break;default:var e={Balance:41,Decay:56,Electricity:82,Crushed:126,Nom:146,Toxicity:166,Lead:181,Watch:181,Corrupted:191}[d];e&&(a=e);}return{level:a,lead:b}} + +//Radon -//helper for returning the proper level we should be auto-portaling at. -function findOutCurrentPortalLevel() { - var portalLevel = -1; - var leadCheck = false; - var portalLevelName = - { - "Balance" : 41, - "Decay" : 56, - "Electricity" : 82, - "Crushed" : 126, - "Nom" : 146, - "Toxicity" : 166, - "Lead" : 181, - "Watch" : 181, - "Corrupted" : 191 - }; - var AP = getPageSetting("AutoPortal"); - switch (AP) { - case "Off": +MODULES["portal"].Rtimeout = 5000; +MODULES["portal"].RbufferExceedFactor = 5; +var Rportalzone = getPageSetting('RCustomAutoPortal'); +var RzonePostpone = 0; + +function RautoPortal() { + if (!game.global.portalActive) return; + switch (autoTrimpSettings.RAutoPortal.selected) { + case "Radon Per Hour": + var OKtoPortal = false; + if (!game.global.runningChallengeSquared) { + var minZone = getPageSetting('RnHrDontPortalBefore'); + game.stats.bestHeliumHourThisRun.evaluate(); + var bestHeHr = game.stats.bestHeliumHourThisRun.storedValue; + var bestHeHrZone = game.stats.bestHeliumHourThisRun.atZone; + var myHeliumHr = game.stats.heliumHour.value(); + var heliumHrBuffer = Math.abs(getPageSetting('RadonHrBuffer')); + if (!aWholeNewWorld) + heliumHrBuffer *= MODULES["portal"].RbufferExceedFactor; + var bufferExceeded = myHeliumHr < bestHeHr * (1 - (heliumHrBuffer / 100)); + if (bufferExceeded && game.global.world >= minZone) { + OKtoPortal = true; + if (aWholeNewWorld) + zonePostpone = 0; + } + if (heliumHrBuffer == 0 && !aWholeNewWorld) + OKtoPortal = false; + if (OKtoPortal && zonePostpone == 0) { + RresetVars(); + zonePostpone += 1; + debug("My RadonHr was: " + myHeliumHr + " & the Best RadonHr was: " + bestHeHr + " at zone: " + bestHeHrZone, "portal"); + cancelTooltip(); + tooltip('confirm', null, 'update', 'Auto Portaling NOW!

Hit Delay Portal to WAIT 1 more zone.', 'zonePostpone+=1', 'NOTICE: Auto-Portaling in 5 seconds....', 'Delay Portal'); + setTimeout(cancelTooltip, MODULES["portal"].Rtimeout); + setTimeout(function() { + if (zonePostpone >= 2) + return; + if (autoTrimpSettings.RadonHourChallenge.selected != 'None') + RdoPortal(autoTrimpSettings.RadonHourChallenge.selected); + else + RdoPortal(); + }, MODULES["portal"].Rtimeout + 100); + } + } break; case "Custom": - portalLevel = getPageSetting('CustomAutoPortal') + 1; - leadCheck = getPageSetting('HeliumHourChallenge') == "Lead" ? true : false; + var portalzone = getPageSetting('RCustomAutoPortal'); + if (game.global.world > portalzone) { + if (autoTrimpSettings.RadonHourChallenge.selected != 'None') + RdoPortal(autoTrimpSettings.RadonHourChallenge.selected); + else + RdoPortal(); + } + break; + case "Melt": + case "Bublé": + case "Quagmire": + case "Archaeology": + case "Insanity": + case "Nurture": + case "Alchemy": + case "Hypothermia": + if (!game.global.challengeActive) { + RdoPortal(autoTrimpSettings.RAutoPortal.selected); + } break; default: - var result = portalLevelName[AP]; - if (result) - portalLevel = result; break; } - return {level:portalLevel, lead:leadCheck}; +} + +function RdailyAutoPortal() { + if (!game.global.portalActive) return; + if (getPageSetting('RAutoPortalDaily') == 1) { + var OKtoPortal = false; + if (!game.global.runningChallengeSquared) { + var minZone = getPageSetting('RdHeHrDontPortalBefore'); + game.stats.bestHeliumHourThisRun.evaluate(); + var bestHeHr = game.stats.bestHeliumHourThisRun.storedValue; + var bestHeHrZone = game.stats.bestHeliumHourThisRun.atZone; + var myHeliumHr = game.stats.heliumHour.value(); + var heliumHrBuffer = Math.abs(getPageSetting('RdHeliumHrBuffer')); + if (!aWholeNewWorld) { + heliumHrBuffer *= MODULES["portal"].bufferExceedFactor; + var bufferExceeded = myHeliumHr < bestHeHr * (1 - (heliumHrBuffer / 100)); + if (bufferExceeded && game.global.world >= minZone) { + OKtoPortal = true; + if (aWholeNewWorld) + zonePostpone = 0; + } + if (heliumHrBuffer == 0 && !aWholeNewWorld) + OKtoPortal = false; + if (OKtoPortal && zonePostpone == 0) { + RresetVars(); + zonePostpone += 1; + debug("My RadonHr was: " + myHeliumHr + " & the Best RadonHr was: " + bestHeHr + " at zone: " + bestHeHrZone, "portal"); + cancelTooltip(); + tooltip('confirm', null, 'update', 'Auto Portaling NOW!

Hit Delay Portal to WAIT 1 more zone.', 'zonePostpone+=1', 'NOTICE: Auto-Portaling in 5 seconds....', 'Delay Portal'); + setTimeout(cancelTooltip, MODULES["portal"].Rtimeout); + setTimeout(function() { + if (zonePostpone >= 2) + return; + if (OKtoPortal) { + abandonDaily(); + document.getElementById('finishDailyBtnContainer').style.display = 'none'; + } + if (autoTrimpSettings.RdHeliumHourChallenge.selected != 'None' && getPageSetting('u2daily') == false) + RdoPortal(autoTrimpSettings.RdHeliumHourChallenge.selected); + else if (autoTrimpSettings.dHeliumHourChallenge.selected != 'None' && getPageSetting('u2daily') == true) + RdoPortal(autoTrimpSettings.dHeliumHourChallenge.selected); + else + RdoPortal(); + }, MODULES["portal"].timeout + 100); + } + } + } + } + if (getPageSetting('RAutoPortalDaily') == 2) { + var portalzone = getPageSetting('RdCustomAutoPortal'); + if (game.global.world > portalzone) { + abandonDaily(); + document.getElementById('finishDailyBtnContainer').style.display = 'none'; + if (autoTrimpSettings.RdHeliumHourChallenge.selected != 'None' && getPageSetting('u2daily') == false) + RdoPortal(autoTrimpSettings.RdHeliumHourChallenge.selected); + else if (autoTrimpSettings.dHeliumHourChallenge.selected != 'None' && getPageSetting('u2daily') == true) + RdoPortal(autoTrimpSettings.dHeliumHourChallenge.selected); + else + RdoPortal(); + } + } +} + +function RdoPortal(challenge) { + if(!game.global.portalActive) return; + if (getPageSetting('autoheirlooms') == true && getPageSetting('typetokeep') != 'None' && getPageSetting('raretokeep') != 'None') { + autoheirlooms3(); + } + if (game.global.ShieldEquipped.name != getPageSetting('highdmg') || game.global.ShieldEquipped.name != getPageSetting('dhighdmg')) { + if (highdmgshield() != undefined) { + selectHeirloom(game.global.heirloomsCarried.indexOf(loom), "heirloomsCarried", true); + equipHeirloom(); + } + } + /*if (getPageSetting('autonu') == true && getPageSetting('heirloomnu') != undefined) { + spendNu(); spendNu(); spendNu(); spendNu(); spendNu(); spendNu(); + }*/ + if (getPageSetting('RAutoAllocatePerks')==2) { + viewPortalUpgrades(); + numTab(6, true) + if (getPageSetting('Rdumpgreed') == true) { + buyPortalUpgrade('Greed'); + debug('First Stage: Bought Max Greed'); + } + else { + buyPortalUpgrade('Looting'); + debug('First Stage: Bought Max Looting'); + } + activateClicked(); + cancelPortal(); + } + portalClicked(); + if (!portalWindowOpen) { + portalClicked(); + } + if (portalWindowOpen && getPageSetting('RAutoAllocatePerks')==1 && (typeof MODULES["perks"] !== 'undefined' || typeof AutoPerks !== 'undefined')) { + RAutoPerks.clickAllocate(); + } + if (portalWindowOpen && getPageSetting('RAutoStartDaily') == true) { + if (getPageSetting('u1daily') == true && portalUniverse == 2) { + swapPortalUniverse(); + } + selectChallenge('Daily'); + checkCompleteDailies(); + var lastUndone = -7; + while (++lastUndone <= 0) { + var done = (game.global.recentDailies.indexOf(getDailyTimeString(lastUndone)) != -1); + if (!done) + break; + } + if (lastUndone == 1) { + debug("All available Dailies already completed.", "portal"); + if ((getPageSetting('u2daily') == true && portalUniverse == 2 && challenge == autoTrimpSettings.dHeliumHourChallenge.selected) || (getPageSetting('u1daily') == true && portalUniverse == 1)) { + swapPortalUniverse(); + } + selectChallenge(challenge || 0); + } else { + getDailyChallenge(lastUndone); + debug("Portaling into Daily for: " + getDailyTimeString(lastUndone, true) + " now!", "portal"); + } + } + else if(portalWindowOpen && challenge) { + if (getPageSetting('u2daily') == true && portalUniverse == 2 && challenge == autoTrimpSettings.dHeliumHourChallenge.selected) { + swapPortalUniverse(); + } + selectChallenge(challenge); + } + if (portalWindowOpen && getPageSetting('RAutoAllocatePerks')==2) { + numTab(6, true) + if (getPageSetting('Rdumpgreed') == true) { + buyPortalUpgrade('Greed'); + debug('Second Stage: Bought Max Greed'); + } + else { + buyPortalUpgrade('Looting'); + debug('Second Stage: Bought Max Looting'); + } + + } + RresetVars(); + activatePortal(); + lastRadonZone = 0; RzonePostpone = 0; + RresetVars(); +} + +function isNextU1DailyWind() { + var currWindCost = game.empowerments.Wind.nextUberCost; + var windCostChange = Math.max(currWindCost*.33,50); + var nextWindCost = currWindCost - (windCostChange < 100 ? windCostChange : 100); + + var currPoisonCost = game.empowerments.Poison.nextUberCost; + var poisonCostChange = Math.max(currPoisonCost*.33,50); + var nextPoisonCost = currPoisonCost - (poisonCostChange < 100 ? poisonCostChange : 100); + + var currIceCost = game.empowerments.Ice.nextUberCost; + var iceCostChange = Math.max(currIceCost*.33,50); + var nextIceCost = currIceCost - (iceCostChange < 100 ? iceCostChange : 100); + + var dnature = "None"; + var dailynature = [], dpoison, dpoisondiff, dwind, dwinddiff, dice, dicediff; + + if (getPageSetting('pdailyenlightthresh') >= 0) { + dpoison = (nextPoisonCost <= getPageSetting('pdailyenlightthresh') && nextPoisonCost <= game.empowerments.Poison.tokens); + if (dpoison) { + dpoisondiff = (getPageSetting('pdailyenlightthresh') - nextPoisonCost); + } + else dpoisondiff = -999999; + } + else dpoisondiff = -999999; + + if (getPageSetting('wdailyenlightthresh') >= 0) { + dwind = (nextWindCost <= getPageSetting('wdailyenlightthresh') && nextWindCost <= game.empowerments.Wind.tokens); + if (dwind) { + dwinddiff = (getPageSetting('wdailyenlightthresh') - nextWindCost); + } + else dwinddiff = -999999; + } + else dwinddiff = -999999; + + if (getPageSetting('idailyenlightthresh') >= 0) { + dice = (nextIceCost <= getPageSetting('idailyenlightthresh') && nextIceCost <= game.empowerments.Ice.tokens); + if (dice) { + dicediff = (getPageSetting('idailyenlightthresh') - nextIceCost); + } + else dicediff = -999999; + } + else dicediff = -999999; + + dailynature = [{nature:'Poison', cost:dpoisondiff}, {nature:'Wind', cost:dwinddiff}, {nature:'Ice', cost:dicediff}].sort(function(a, b) {return a.cost > b.cost ? -1 : a.cost < b.cost ? 1 : 0;}); + + if (dailynature[0].cost > 0) { + dnature = dailynature[0].nature; + } + else { dnature = "None"; } + + if(dnature=="Wind") + return true; + else + return false; } diff --git a/modules/query.js b/modules/query.js index fa209216a..20466d111 100644 --- a/modules/query.js +++ b/modules/query.js @@ -1,174 +1,78 @@ -//MODULES["query"] = {}; - -function getPerSecBeforeManual(job) { - var perSec = 0; - var increase = game.jobs[job].increase; - if (increase == "custom") return 0; - if (game.jobs[job].owned > 0){ - perSec = (game.jobs[job].owned * game.jobs[job].modifier); - if (game.portal.Motivation.level > 0) perSec += (perSec * game.portal.Motivation.level * game.portal.Motivation.modifier); - if (game.portal.Motivation_II.level > 0) perSec *= (1 + (game.portal.Motivation_II.level * game.portal.Motivation_II.modifier)); - if (game.portal.Meditation.level > 0) perSec *= (1 + (game.portal.Meditation.getBonusPercent() * 0.01)).toFixed(2); - if (game.jobs.Magmamancer.owned > 0 && increase == "metal") perSec *= game.jobs.Magmamancer.getBonusPercent(); - if (game.global.challengeActive == "Meditate") perSec *= 1.25; - else if (game.global.challengeActive == "Size") perSec *= 1.5; - if (game.global.challengeActive == "Toxicity"){ - var toxMult = (game.challenges.Toxicity.lootMult * game.challenges.Toxicity.stacks) / 100; - perSec *= (1 + toxMult); - } - if (game.global.challengeActive == "Balance"){ - perSec *= game.challenges.Balance.getGatherMult(); - } - if (game.global.challengeActive == "Decay"){ - perSec *= 10; - perSec *= Math.pow(0.995, game.challenges.Decay.stacks); - } - if (game.global.challengeActive == "Daily"){ - if (typeof game.global.dailyChallenge.dedication !== 'undefined') - perSec *= dailyModifiers.dedication.getMult(game.global.dailyChallenge.dedication.strength); - if (typeof game.global.dailyChallenge.famine !== 'undefined' && increase != "fragments" && increase != "science") - perSec *= dailyModifiers.famine.getMult(game.global.dailyChallenge.famine.strength); - } - if (game.global.challengeActive == "Watch") perSec /= 2; - if (game.global.challengeActive == "Lead" && ((game.global.world % 2) == 1)) perSec*= 2; - perSec = calcHeirloomBonus("Staff", job + "Speed", perSec); - } - return perSec; -} - -function checkJobPercentageCost(what, toBuy) { - var costItem = "food"; - var job = game.jobs[what]; - var cost = job.cost[costItem]; - var price = 0; - if (!toBuy) toBuy = game.global.buyAmt; - if (typeof cost[1] !== 'undefined') - price = Math.floor((cost[0] * Math.pow(cost[1], job.owned)) * ((Math.pow(cost[1], toBuy) - 1) / (cost[1] - 1))); - else - price = cost * toBuy; - var percent; - if (game.resources[costItem].owned < price){ - var thisPs = getPsString(costItem, true); - if (thisPs > 0) - percent = calculateTimeToMax(null, thisPs, (price - game.resources[costItem].owned)); - //console.log("time"); - return [false,percent]; - } - else - percent = (game.resources[costItem].owned > 0) ? ((price / game.resources[costItem].owned) * 100).toFixed(1) : 0; - //console.log("percent"); - return [true,percent]; -} - -function getScienceCostToUpgrade(upgrade) { - var upgradeObj = game.upgrades[upgrade]; - if (upgradeObj.cost.resources.science !== undefined ? upgradeObj.cost.resources.science[0] !== undefined : false) { - return Math.floor(upgradeObj.cost.resources.science[0] * Math.pow(upgradeObj.cost.resources.science[1], (upgradeObj.done))); - } else if (upgradeObj.cost.resources.science !== undefined && upgradeObj.cost.resources.science[0] == undefined){ - return upgradeObj.cost.resources.science; - } else { - return 0; - } -} - - -function getEnemyMaxAttack(world, level, name, diff, corrupt) { - var amt = 0; - var adjWorld = ((world - 1) * 100) + level; - amt += 50 * Math.sqrt(world) * Math.pow(3.27, world / 2); - amt -= 10; - if (world == 1){ - amt *= 0.35; - amt = (amt * 0.20) + ((amt * 0.75) * (level / 100)); - } - else if (world == 2){ - amt *= 0.5; - amt = (amt * 0.32) + ((amt * 0.68) * (level / 100)); - } - else if (world < 60) - amt = (amt * 0.375) + ((amt * 0.7) * (level / 100)); - else{ - amt = (amt * 0.4) + ((amt * 0.9) * (level / 100)); - amt *= Math.pow(1.15, world - 59); - } - if (world < 60) amt *= 0.85; - //if (world > 6 && game.global.mapsActive) amt *= 1.1; - if (diff) { - amt *= diff; - } - if (!corrupt) - amt *= game.badGuys[name].attack; - else { - amt *= getCorruptScale("attack"); - } - return Math.floor(amt); -} - -function getEnemyMaxHealth(world, level, corrupt) { - if (!level) - level = 30; - var amt = 0; - amt += 130 * Math.sqrt(world) * Math.pow(3.265, world / 2); - amt -= 110; - if (world == 1 || world == 2 && level < 10) { - amt *= 0.6; - amt = (amt * 0.25) + ((amt * 0.72) * (level / 100)); - } - else if (world < 60) - amt = (amt * 0.4) + ((amt * 0.4) * (level / 110)); - else { - amt = (amt * 0.5) + ((amt * 0.8) * (level / 100)); - amt *= Math.pow(1.1, world - 59); - } - if (world < 60) amt *= 0.75; - //if (world > 5 && game.global.mapsActive) amt *= 1.1; - if (!corrupt) - amt *= game.badGuys["Grimp"].health; - else - amt *= getCorruptScale("health"); - return Math.floor(amt); -} - -function getCurrentEnemy(current) { - if (!current) - current = 1; - var enemy; - if (!game.global.mapsActive && !game.global.preMapsActive) { - if (typeof game.global.gridArray[game.global.lastClearedCell + current] === 'undefined') { - enemy = game.global.gridArray[game.global.gridArray.length - 1]; - } else { - enemy = game.global.gridArray[game.global.lastClearedCell + current]; - } - } else if (game.global.mapsActive && !game.global.preMapsActive) { - if (typeof game.global.mapGridArray[game.global.lastClearedMapCell + current] === 'undefined') { - enemy = game.global.mapGridArray[game.global.gridArray.length - 1]; - } else { - enemy = game.global.mapGridArray[game.global.lastClearedMapCell + current]; - } - } - return enemy; +function getPerSecBeforeManual(a){var b=0,c=game.jobs[a].increase;if("custom"==c)return 0;if(0a?f=0.375*f+0.7*f*(b/100):(f=0.4*f+0.9*f*(b/100),f*=Math.pow(1.15,a-59)),60>a&&(f*=0.85),d&&(f*=d),f*=e?getCorruptScale("attack"):game.badGuys[c].attack,Math.floor(f)} +function getEnemyMaxHealth(a,b,c){b||(b=30);var d=0;return d+=130*Math.sqrt(a)*Math.pow(3.265,a/2),d-=110,1==a||2==a&&10>b?(d*=0.6,d=0.25*d+0.72*d*(b/100)):60>a?d=0.4*d+0.4*d*(b/110):(d=0.5*d+0.8*d*(b/100),d*=Math.pow(1.1,a-59)),60>a&&(d*=0.75),d*=c?getCorruptScale("health"):game.badGuys.Grimp.health,Math.floor(d)} +function getCurrentEnemy(a){a||(a=1);var b;return game.global.mapsActive||game.global.preMapsActive?game.global.mapsActive&&!game.global.preMapsActive&&('undefined'==typeof game.global.mapGridArray[game.global.lastClearedMapCell+a]?b=game.global.mapGridArray[game.global.gridArray.length-1]:b=game.global.mapGridArray[game.global.lastClearedMapCell+a]):'undefined'==typeof game.global.gridArray[game.global.lastClearedCell+a]?b=game.global.gridArray[game.global.gridArray.length-1]:b=game.global.gridArray[game.global.lastClearedCell+a],b} +function getCorruptedCellsNum(){for(var a,b=0,c=0;cgame.upgrades[a].done){if(1==game.global.world&&1e3>=game.global.totalHeliumEarned&&a.startsWith("Speed"))continue;scienceNeeded+=getScienceCostToUpgrade(a)}needGymystic&&(scienceNeeded+=getScienceCostToUpgrade("Gymystic"))} +function RsetScienceNeeded(){for(var a in RscienceNeeded=0,RupgradeList)if(a=RupgradeList[a],game.upgrades[a].allowed>game.upgrades[a].done){if(1==game.global.world&&1e3>=game.global.totalRadonEarned&&a.startsWith("Speed"))continue;RscienceNeeded+=getScienceCostToUpgrade(a)}} +function RgetEnemyMaxAttack(world, level, name) { + var amt = 0; + var attackBase = (game.global.universe == 2) ? 750 : 50; + amt += attackBase * Math.sqrt(world) * Math.pow(3.27, world / 2); + amt -= 10; + if (world == 1){ + amt *= 0.35; + amt = (amt * 0.20) + ((amt * 0.75) * (level / 100)); + } + else if (world == 2){ + amt *= 0.5; + amt = (amt * 0.32) + ((amt * 0.68) * (level / 100)); + } + else if (world < 60) + amt = (amt * 0.375) + ((amt * 0.7) * (level / 100)); + else{ + amt = (amt * 0.4) + ((amt * 0.9) * (level / 100)); + amt *= Math.pow(1.15, world - 59); + } + if (world < 60) amt *= 0.85; + if (world > 6 && game.global.mapsActive) amt *= 1.1; + amt *= game.badGuys[name].attack; + if (game.global.universe == 2){ + var part1 = (world > 40) ? 40 : world; + var part2 = (world > 60) ? 20 : world - 40; + var part3 = (world - 60); + if (part2 < 0) part2 = 0; + if (part3 < 0) part3 = 0; + amt *= Math.pow(1.5, part1); + amt *= Math.pow(1.4, part2); + amt *= Math.pow(1.32, part3); + } + return Math.floor(amt); } -function getCorruptedCellsNum() { - var enemy; - var corrupteds = 0; - for (var i = 0; i < game.global.gridArray.length - 1; i++) { - enemy = game.global.gridArray[i]; - if (enemy.mutation == "Corruption") - corrupteds++; - } - return corrupteds; -} - -function getCorruptScale(type) { - switch (type) { - case "attack": - return mutations.Corruption.statScale(3); - case "health": - return mutations.Corruption.statScale(10); - } +function RgetEnemyMaxHealth(world, level) { + if (!level) + level = 30; + var amt = 0; + var healthBase = (game.global.universe == 2) ? 10e7 : 130; + amt += healthBase * Math.sqrt(world) * Math.pow(3.265, world / 2); + amt -= 110; + if (world == 1 || world == 2 && level < 10){ + amt *= 0.6; + amt = (amt * 0.25) + ((amt * 0.72) * (level / 100)); + } + else if (world < 60) + amt = (amt * 0.4) + ((amt * 0.4) * (level / 110)); + else{ + amt = (amt * 0.5) + ((amt * 0.8) * (level / 100)); + amt *= Math.pow(1.1, world - 59); + } + if (world < 60) amt *= 0.75; + if (world > 5 && game.global.mapsActive) amt *= 1.1; + amt *= game.badGuys["Grimp"].health; + if (game.global.universe == 2){ + var part1 = (world > 60) ? 60 : world; + var part2 = (world - 60); + if (part2 < 0) part2 = 0; + amt *= Math.pow(1.4, part1); + amt *= Math.pow(1.32, part2); + } + return Math.floor(amt); } - function getPotencyMod(howManyMoreGenes) { var potencyMod = game.resources.trimps.potency; //Add potency (book) @@ -205,34 +109,8 @@ function getPotencyMod(howManyMoreGenes) { return potencyMod; } -function getBreedTime(remaining,howManyMoreGenes) { - var trimps = game.resources.trimps; - var trimpsMax = trimps.realMax(); - - var potencyMod = getPotencyMod(howManyMoreGenes); - // would be calced here without the following line in potencymod - potencyMod = (1 + (potencyMod / 10)); - var timeRemaining = log10((trimpsMax - trimps.employed) / (trimps.owned - trimps.employed)) / log10(potencyMod); - timeRemaining /= 10; - if (remaining) - return parseFloat(timeRemaining.toFixed(1)); - - var adjustedMax = (game.portal.Coordinated.level) ? game.portal.Coordinated.currentSend : trimps.maxSoldiers; - var totalTime = log10((trimpsMax - trimps.employed) / (trimpsMax - adjustedMax - trimps.employed)) / log10(potencyMod); - totalTime /= 10; - - return parseFloat(totalTime.toFixed(1)); -} - -function isBuildingInQueue(building) { - //limit to 1 building per queue - for (var b in game.global.buildingsQueue) { - if (game.global.buildingsQueue[b].includes(building)) return true; - } -} - function getArmyTime() { - var breeding = (game.resources.trimps.owned - game.resources.trimps.employed); + var breeding = (game.resources.trimps.owned - trimpsEffectivelyEmployed()); var newSquadRdy = game.resources.trimps.realMax() <= game.resources.trimps.owned + 1; var adjustedMax = (game.portal.Coordinated.level) ? game.portal.Coordinated.currentSend : game.resources.trimps.maxSoldiers; var potencyMod = getPotencyMod(); @@ -240,16 +118,3 @@ function getArmyTime() { var addTime = adjustedMax / tps; return addTime; } - -function setScienceNeeded() { - scienceNeeded = 0; - for (var upgrade in upgradeList) { - upgrade = upgradeList[upgrade]; - if (game.upgrades[upgrade].allowed > game.upgrades[upgrade].done) { //If the upgrade is available - if (game.global.world == 1 && game.global.totalHeliumEarned<=1000 && upgrade.startsWith("Speed")) continue; //skip speed upgrades on fresh game until level 2 - scienceNeeded += getScienceCostToUpgrade(upgrade); - } - } - if (needGymystic) - scienceNeeded += getScienceCostToUpgrade('Gymystic'); -} diff --git a/modules/scryer.js b/modules/scryer.js index c7a71e5db..86199a9fe 100644 --- a/modules/scryer.js +++ b/modules/scryer.js @@ -1,99 +1,157 @@ -//MODULES["scryer"] = {}; - var wantToScry = false; -//use S stance -function useScryerStance() { - var AutoStance = getPageSetting('AutoStance'); - function autostancefunction() { - if (AutoStance<=1) autoStance(); //"Auto Stance" - else if (AutoStance==2) autoStance2(); //"Auto Stance #2" - }; - //check preconditions (exit quick, if impossible to use) - var use_auto = game.global.preMapsActive || game.global.gridArray.length === 0 || game.global.highestLevelCleared < 180; - use_auto = use_auto || game.global.world <= 60; - use_auto = use_auto || game.global.mapsActive && getCurrentMapObject().location == "Void" && getPageSetting('ScryerUseinVoidMaps2') == 2; - if (use_auto) { - autostancefunction(); - wantToScry = false; - return; - } +var transitionRequired = false; + +function scryingCorruption() { + //Defines if it should be scrying vs corrupted enemies at this moment + var minZoneOK = game.global.world >= getPageSetting('ScryerMinZone'); + var maxZoneOK = game.global.world < getPageSetting('ScryerMaxZone') || getPageSetting('ScryerMaxZone') < 1; + var scryZone = minZoneOK && maxZoneOK || getPageSetting('onlyminmaxworld') >= 2; + var scryCorrupt = scryZone && getPageSetting('ScryerSkipCorrupteds2') != 0 || getPageSetting('ScryerSkipCorrupteds2') == 1; + var essenceLeft = getPageSetting('screwessence') == false || countRemainingEssenceDrops() >= 1; + var die = getPageSetting('ScryerDieZ') != -1 && game.global.world >= getPageSetting('ScryerDieZ') + return (die || scryCorrupt) && essenceLeft && getPageSetting('UseScryerStance') == true; +} - if (AutoStance<=1) - calcBaseDamageinX(); //calculate internal script variables normally processed by autostance. - else if (AutoStance==2) - calcBaseDamageinX2(); //calculate method #2 - var missingHealth = game.global.soldierHealthMax - game.global.soldierHealth; - var newSquadRdy = game.resources.trimps.realMax() <= game.resources.trimps.owned + 1; - var form = game.global.formation; - var oktoswitch = true; - var die = getPageSetting('ScryerDieToUseS'); - const willSuicide = getPageSetting('ScryerDieZ'); +function readyToSwitch(stance = "S") { + //Suicide to Scry + var essenceLeft = getPageSetting('screwessence') == false || countRemainingEssenceDrops() >= 1; + var die = getPageSetting('ScryerDieZ') != -1 && game.global.world >= getPageSetting('ScryerDieZ') && essenceLeft; + var willSuicide = getPageSetting('ScryerDieZ'); + + //Check if we are allowed to suicide in our current cell and zone if (die && willSuicide >= 0) { var [dieZ, dieC] = willSuicide.toString().split("."); if (dieC && dieC.length == 1) dieC = dieC + "0"; die = game.global.world >= dieZ && (!dieC || (game.global.lastClearedCell + 1 >= dieC)); } - if (form == 0 || form == 1) - oktoswitch = die || newSquadRdy || (missingHealth < (baseHealth / 2)); - - var useoverkill = getPageSetting('ScryerUseWhenOverkill'); - if (useoverkill && game.portal.Overkill.level == 0) - setPageSetting('ScryerUseWhenOverkill', false); - if (useoverkill && !game.global.mapsActive && isActiveSpireAT() && getPageSetting('ScryerUseinSpire2')==2) - useoverkill = false; - //Overkill button being on and being able to overkill in S will override any other setting, regardless. - if (useoverkill && game.portal.Overkill.level > 0) { - var avgDamage = (baseDamage * (1-getPlayerCritChance()) + (baseDamage * getPlayerCritChance() * getPlayerCritDamageMult())); - var Sstance = 0.5; - var ovkldmg = avgDamage * Sstance * (game.portal.Overkill.level*0.005); - //are we going to overkill in S? - var ovklHDratio = getCurrentEnemy(1).maxHealth / ovkldmg; - if (ovklHDratio < 8) { - if (oktoswitch) - setFormation(4); - return; - } + + return die || survive(stance, 2); +} + +function useScryerStance() { + var scry = 4; + var scryF = 'S'; + var x = 0; + + if (game.global.uberNature == "Wind" && getEmpowerment() != "Wind") { + scry = 5; + scryF = 'W'; + x = 5; + } + + var AutoStance = getPageSetting('AutoStance'); + function autoStanceFunctionScryer() { + if ((getPageSetting('AutoStance') == 3) || (getPageSetting('use3daily') == true && game.global.challengeActive == "Daily")) windStance(); + else if (AutoStance==1) autoStance(); + else if (AutoStance==2) autoStance2(); } -//Any of these being true will indicate scryer should not be used, and cause the function to dump back to regular autoStance(): - //check for spire - use_auto = use_auto || !game.global.mapsActive && isActiveSpireAT() && getPageSetting('ScryerUseinSpire2')!=1; - //check for voids - use_auto = use_auto || game.global.mapsActive && getCurrentMapObject().location == "Void" && !getPageSetting('ScryerUseinVoidMaps2'); - //check for maps - use_auto = use_auto || game.global.mapsActive && !getPageSetting('ScryerUseinMaps2'); - //check for bosses above voidlevel - use_auto = use_auto || getPageSetting('ScryerSkipBoss2') == 1 && game.global.world > getPageSetting('VoidMaps') && game.global.lastClearedCell == 98; - //check for bosses (all levels) - use_auto = use_auto || getPageSetting('ScryerSkipBoss2') == 2 && game.global.lastClearedCell == 98; - if (use_auto) { - autostancefunction(); //falls back to autostance when not using S. + //Never + var aboveMaxZone = getPageSetting('ScryerMaxZone') > 0 && game.global.world >= getPageSetting('ScryerMaxZone'); + var USS = getPageSetting('UseScryerStance'), MA = game.global.mapsActive, SC = getPageSetting('ScryerSkipCorrupteds2') == 0; + var never_scry = game.global.preMapsActive || game.global.gridArray.length === 0 || game.global.world <= 60 || game.global.highestLevelCleared < 180; + never_scry |= USS && MA && getPageSetting('ScryerUseinMaps2') == 0 && getCurrentMapObject().location != "Void" && getCurrentMapObject().location != "Bionic" && getCurrentMapObject().level <= game.global.world; + never_scry |= USS && MA && getPageSetting('ScryerUseinPMaps') == 0 && getCurrentMapObject().level > game.global.world && getCurrentMapObject().location != "Void" && getCurrentMapObject().location != "Bionic"; + never_scry |= USS && MA && getCurrentMapObject().location == "Void" && getPageSetting('ScryerUseinVoidMaps2') == 0; + never_scry |= USS && MA && getCurrentMapObject().location == "Bionic" && getPageSetting('ScryerUseinBW') == 0; + never_scry |= USS && !MA && (isActiveSpireAT() || disActiveSpireAT()) && getPageSetting('ScryerUseinSpire2') == 0; + never_scry |= USS && !MA && getPageSetting('ScryerSkipBoss2') == 1 && game.global.world < getPageSetting('VoidMaps') && game.global.lastClearedCell == 98; + never_scry |= USS && !MA && getPageSetting('ScryerSkipBoss2') == 0 && game.global.lastClearedCell == 98; + never_scry |= USS && !MA && (getEmpowerment() == "Poison" && (getPageSetting('ScryUseinPoison') == 0 || (getPageSetting('ScryUseinPoison') > 0 && game.global.world >= getPageSetting('ScryUseinPoison')))) || (getEmpowerment() == "Wind" && (getPageSetting('ScryUseinWind') == 0 || (getPageSetting('ScryUseinWind') > 0 && game.global.world >= getPageSetting('ScryUseinWind')))) || (getEmpowerment() == "Ice" && (getPageSetting('ScryUseinIce') == 0 || (getPageSetting('ScryUseinIce') > 0 && game.global.world >= getPageSetting('ScryUseinIce')))); + + //Check Corrupted Never + var isCorrupt = getCurrentEnemy(1) && getCurrentEnemy(1).mutation == "Corruption"; + var nextIsCorrupt = getCurrentEnemy(2) && getCurrentEnemy(2).mutation == "Corruption"; + var scryNext = !nextIsCorrupt && (transitionRequired || oneShotPower(undefined, 0, true)); + var skipOnMaxZone = getPageSetting('onlyminmaxworld') == 2 && getPageSetting('ScryerSkipCorrupteds2') != 1 && aboveMaxZone; + if (USS && !MA && (SC || skipOnMaxZone) && isCorrupt) { + transitionRequired = scryNext; + never_scry |= !scryNext; + } + else transitionRequired = false; + + //check Healthy never -- TODO + var curEnemyHealth = getCurrentEnemy(1); + var isHealthy = curEnemyHealth && curEnemyHealth.mutation == "Healthy"; + if (never_scry || getPageSetting('UseScryerStance') == true && !game.global.mapsActive && (isHealthy && getPageSetting('ScryerSkipHealthy') == 0)) { + autoStanceFunctionScryer(); wantToScry = false; return; } - //check for corrupted cells (and exit) - var iscorrupt = getCurrentEnemy(1).mutation == "Corruption"; - iscorrupt = iscorrupt || (mutations.Magma.active() && game.global.mapsActive); - iscorrupt = iscorrupt || (game.global.mapsActive && getCurrentMapObject().location == "Void" && game.global.world >= mutations.Corruption.start()); - if (iscorrupt && getPageSetting('ScryerSkipCorrupteds2')) { - autostancefunction(); + //Force + var use_scryer = getPageSetting('UseScryerStance') == true && game.global.mapsActive && getPageSetting('ScryerUseinMaps2') == 1; + use_scryer |= game.global.mapsActive && getCurrentMapObject().location == "Void" && ((getPageSetting('ScryerUseinVoidMaps2') == 1) || (getPageSetting('scryvoidmaps') == true && game.global.challengeActive != "Daily") || (getPageSetting('dscryvoidmaps')== true && game.global.challengeActive == "Daily")); + use_scryer |= game.global.mapsActive && getCurrentMapObject().location == "Bionic" && getPageSetting('ScryerUseinBW') == 1; + use_scryer |= game.global.mapsActive && getCurrentMapObject().level > game.global.world && getPageSetting('ScryerUseinPMaps') == 1 && getCurrentMapObject().location != "Bionic"; + use_scryer |= !game.global.mapsActive && getPageSetting('UseScryerStance') == true && (isActiveSpireAT() || disActiveSpireAT()) && getPageSetting('ScryerUseinSpire2') == 1; + use_scryer |= !game.global.mapsActive && getPageSetting('UseScryerStance') == true && ((getEmpowerment() == "Poison" && getPageSetting('ScryUseinPoison') > 0 && game.global.world < getPageSetting('ScryUseinPoison')) || (getEmpowerment() == "Wind" && getPageSetting('ScryUseinWind') > 0 && game.global.world < getPageSetting('ScryUseinWind')) || (getEmpowerment() == "Ice" && getPageSetting('ScryUseinIce') > 0 && game.global.world < getPageSetting('ScryUseinIce'))); + + //check Corrupted Force + if ((isCorrupt && getPageSetting('ScryerSkipCorrupteds2') == 1 && getPageSetting('UseScryerStance') == true) || (use_scryer)) { + setFormation(scry); + wantToScry = true; + return; + } + //check healthy force + if ((isHealthy && getPageSetting('ScryerSkipHealthy') == 1 && getPageSetting('UseScryerStance') == true) || (use_scryer)) { + setFormation(scry); + wantToScry = true; + return; + } + + //Calc Damage + if (AutoStance>=1) calcBaseDamageInX(); + + //Checks if Overkill is allowed + var useOverkill = getPageSetting('UseScryerStance') == true && getPageSetting('ScryerUseWhenOverkill'); + useOverkill &= !(getPageSetting('ScryerUseinSpire2') == 0 && !game.global.mapsActive && (isActiveSpireAT() || disActiveSpireAT())); + + //Overkill + if (useOverkill && getCurrentEnemy()) { + //Switches to S/W if it has enough damage to secure an overkill + var HS = oneShotPower(scryF); + var HSD = oneShotPower("D", 0, true); + var HS_next = oneShotPower(scryF, 1); + var HSD_next = oneShotPower("D", 1, true); + if (readyToSwitch() && HS > 0 && HS >= HSD && (HS > 1 || HS_next > 0 && HS_next >= HSD_next)) { + setFormation(scry); + return; + } + } + + //No Essence + if (USS && !MA && getPageSetting('screwessence') == true && countRemainingEssenceDrops() < 1) { + autoStanceFunctionScryer(); wantToScry = false; return; } - //Default. + //Default var min_zone = getPageSetting('ScryerMinZone'); var max_zone = getPageSetting('ScryerMaxZone'); - var valid_min = game.global.world >= min_zone; + var valid_min = game.global.world >= min_zone && game.global.world > 60; var valid_max = max_zone <= 0 || game.global.world < max_zone; - if (valid_min && valid_max) { - if (oktoswitch) - setFormation(4); + + if (USS && valid_min && valid_max && (!MA || getPageSetting('onlyminmaxworld') == 0) && readyToSwitch()) { + //Smooth transition to S before killing the target + if (transitionRequired) { + for (var cp=2; cp >= -2; cp--) { + if (survive("D", cp) && !oneShotPower("D", 0, true)) {setFormation( 2 ); return;} + else if (survive("XB", cp) && !oneShotPower("X", 0, true)) {setFormation( x ); return;} + else if (survive("B", cp) && !oneShotPower("B", 0, true)) {setFormation( 3 ); return;} + else if (survive("X", cp) && !oneShotPower("X", 0, true)) {setFormation( x ); return;} + else if (survive("H", cp) && !oneShotPower("H", 0, true)) {setFormation( 1 ); return;} + } + } + + //Set to scry if it won't kill us, or we are willing to die for it + setFormation(scry); wantToScry = true; - } else { - autostancefunction(); - wantToScry = false; return; } + + //No reason to Scry + autoStanceFunctionScryer(); + wantToScry = false; } diff --git a/modules/stance.js b/modules/stance.js index b157ad7e8..f5f21a5eb 100644 --- a/modules/stance.js +++ b/modules/stance.js @@ -1,574 +1,369 @@ -//MODULES["stance"] = {}; - -function calcBaseDamageinX() { - //baseDamage - baseDamage = game.global.soldierCurrentAttack * (1 + (game.global.achievementBonus / 100)) * ((game.global.antiStacks * game.portal.Anticipation.level * game.portal.Anticipation.modifier) + 1) * (1 + (game.global.roboTrimpLevel * 0.2)) * (1 + (game.global.totalSquaredReward / 100)) * (game.talents.stillRowing2.purchased ? (1 + (0.06 * game.global.spireRows)) : 1) * (game.talents.healthStrength.purchased ? (1 + (0.15 * mutations.Healthy.cellCount())) : 1) * (Fluffy.isActive() ? Fluffy.getDamageModifier() : 1) * (1 + (1 - game.empowerments.Ice.getCombatModifier())) * (game.talents.magmamancer.purchased ? game.jobs.Magmamancer.getBonusPercent() : 1); - if (game.global.challengeActive == "Daily"){ - if (typeof game.global.dailyChallenge.weakness !== 'undefined'){ - baseDamage *= dailyModifiers.weakness.getMult(game.global.dailyChallenge.weakness.strength, game.global.dailyChallenge.weakness.stacks); - } - if (typeof game.global.dailyChallenge.oddTrimpNerf !== 'undefined' && ((game.global.world % 2) == 1)){ - baseDamage *= dailyModifiers.oddTrimpNerf.getMult(game.global.dailyChallenge.oddTrimpNerf.strength); - } - if (typeof game.global.dailyChallenge.evenTrimpBuff !== 'undefined' && ((game.global.world % 2) == 0)){ - baseDamage *= dailyModifiers.evenTrimpBuff.getMult(game.global.dailyChallenge.evenTrimpBuff.strength); - } - if (typeof game.global.dailyChallenge.rampage !== 'undefined'){ - baseDamage *= dailyModifiers.rampage.getMult(game.global.dailyChallenge.rampage.strength, game.global.dailyChallenge.rampage.stacks); - } - } - //baseBlock - baseBlock = game.global.soldierCurrentBlock; - //baseHealth - baseHealth = game.global.soldierHealthMax; - - //if (game.global.soldierHealth <= 0) return; //dont calculate stances when dead, cause the "current" numbers are not updated when dead. - - //D stance - if (game.global.formation == 2) - baseDamage /= 4; - else if (game.global.formation != "0") - baseDamage *= 2; - - //B stance - if (game.global.formation == 3) - baseBlock /= 4; - else if (game.global.formation != "0") - baseBlock *= 2; - - //H stance - if (game.global.formation == 1) - baseHealth /= 4; - else if (game.global.formation != "0") - baseHealth *= 2; - //S stance is accounted for (combination of all the above's else clauses) -} +function calcBaseDamageinX(){baseDamage=calcOurDmg("avg",!1,!0),baseBlock=game.global.soldierCurrentBlock,baseHealth=game.global.soldierHealthMax} +function calcBaseDamageinX2(){baseDamage=calcOurDmg("avg",!1,!0),baseBlock=calcOurBlock(),baseHealth=calcOurHealth()} + +var baseMinDamage = 0; +var baseMaxDamage = 0; -//goes to battlecalc.js which came from Trimps "updates.js" line 1103 -function calcBaseDamageinX2() { - //baseDamage - baseDamage = calcOurDmg(game.global.soldierCurrentAttack,false); - //baseBlock - baseBlock = getBattleStats("block"); - //baseHealth - baseHealth = getBattleStats("health"); - //stances are not needed, if you do need it, call the function with (,true) +function calcBaseDamageInX() { + baseMinDamage = calcOurDmg("min", false, true); + baseMaxDamage = calcOurDmg("max", false, true); + baseDamage = calcOurDmg("avg", false, true); + baseHealth = calcOurHealth(false); + baseBlock = calcOurBlock(false); } -//Autostance - function originally created by Belaith (in 1971) -//Automatically swap formations (stances) to avoid dying -function autoStance() { - //get back to a baseline of no stance (X) - calcBaseDamageinX(); - //no need to continue + +function autoStanceNew() { if (game.global.gridArray.length === 0) return; - if (game.global.soldierHealth <= 0) return; //dont calculate stances when dead, cause the "current" numbers are not updated when dead. - if (!getPageSetting('AutoStance')) return; + if (game.global.soldierHealth <= 0) return; if (!game.upgrades.Formations.done) return; + + if (game.global.formation == 2 && game.global.soldierHealth <= game.global.soldierHealthMax * 0.25) setFormation('0'); + else if(game.global.formation == 0 && game.global.soldierHealth <= game.global.soldierHealthMax * 0.25) setFormation('1') + else if(game.global.formation == 1 && game.global.soldierHealth == game.global.soldierHealthMax) setFormation('2'); +} - //start analyzing autostance - var missingHealth = game.global.soldierHealthMax - game.global.soldierHealth; - var newSquadRdy = game.resources.trimps.realMax() <= game.resources.trimps.owned + 1; - var dHealth = baseHealth/2; - var xHealth = baseHealth; - var bHealth = baseHealth/2; - var enemy; - var corrupt = game.global.world >= mutations.Corruption.start(); - if (!game.global.mapsActive && !game.global.preMapsActive) { - enemy = getCurrentEnemy(); - var enemyFast = game.global.challengeActive == "Slow" || ((((game.badGuys[enemy.name].fast || enemy.mutation == "Corruption") && game.global.challengeActive != "Nom") && game.global.challengeActive != "Coordinate")); - var enemyHealth = enemy.health; - var enemyDamage = enemy.attack * 1.2; - enemyDamage = calcDailyAttackMod(enemyDamage); //daily mods: badStrength,badMapStrength,bloodthirst - //check for world Corruption - if (enemy && enemy.mutation == "Corruption"){ - enemyHealth *= getCorruptScale("health"); - enemyDamage *= getCorruptScale("attack"); - } - if (enemy && enemy.corrupted == 'corruptStrong') { - enemyDamage *= 2; - } - if (enemy && enemy.corrupted == 'corruptTough') { - enemyHealth *= 5; - } - if (enemy && game.global.challengeActive == "Nom" && typeof enemy.nomStacks !== 'undefined'){ - enemyDamage *= Math.pow(1.25, enemy.nomStacks); - } - if (game.global.challengeActive == 'Lead') { - enemyDamage *= (1 + (game.challenges.Lead.stacks * 0.04)); - } - if (game.global.challengeActive == 'Watch') { - enemyDamage *= 1.25; - } - var pierceMod = getPierceAmt(); - var dDamage = enemyDamage - baseBlock / 2 > enemyDamage * pierceMod ? enemyDamage - baseBlock / 2 : enemyDamage * pierceMod; - var xDamage = enemyDamage - baseBlock > enemyDamage * pierceMod ? enemyDamage - baseBlock : enemyDamage * pierceMod; - var bDamage = enemyDamage - baseBlock * 4 > enemyDamage * pierceMod ? enemyDamage - baseBlock * 4 : enemyDamage * pierceMod; - - } else if (game.global.mapsActive && !game.global.preMapsActive) { - enemy = getCurrentEnemy(); - var enemyFast = game.global.challengeActive == "Slow" || ((((game.badGuys[enemy.name].fast || enemy.mutation == "Corruption") && game.global.challengeActive != "Nom") || game.global.voidBuff == "doubleAttack") && game.global.challengeActive != "Coordinate"); - var enemyHealth = enemy.health; - var enemyDamage = enemy.attack * 1.2; - enemyDamage = calcDailyAttackMod(enemyDamage); //daily mods: badStrength,badMapStrength,bloodthirst - //check for voidmap Corruption - if (getCurrentMapObject().location == "Void" && corrupt) { - enemyDamage *= getCorruptScale("attack"); - enemyHealth *= getCorruptScale("health"); - //halve if magma is not active (like it was before) - if (!mutations.Magma.active()) { - enemyDamage /= 2; - enemyHealth /= 2; - } - } - //check for z230 magma map corruption - else if (getCurrentMapObject().location != "Void" && mutations.Magma.active()) { - enemyHealth *= (getCorruptScale("health") / 2); - enemyDamage *= (getCorruptScale("attack") / 2); - } - if (enemy && enemy.corrupted == 'corruptStrong') { - enemyDamage *= 2; - } - if (enemy && enemy.corrupted == 'corruptTough') { - enemyHealth *= 5; - } - if (enemy && game.global.challengeActive == "Nom" && typeof enemy.nomStacks !== 'undefined'){ - enemyDamage *= Math.pow(1.25, enemy.nomStacks); - } - if (game.global.challengeActive == 'Lead') { - enemyDamage *= (1 + (game.challenges.Lead.stacks * 0.04)); - } - if (game.global.challengeActive == 'Watch') { - enemyDamage *= 1.25; - } - var dDamage = enemyDamage - baseBlock / 2 > 0 ? enemyDamage - baseBlock / 2 : 0; - var dVoidCritDamage = enemyDamage*5 - baseBlock / 2 > 0 ? enemyDamage*5 - baseBlock / 2 : 0; - var xDamage = enemyDamage - baseBlock > 0 ? enemyDamage - baseBlock : 0; - var xVoidCritDamage = enemyDamage*5 - baseBlock > 0 ? enemyDamage*5 - baseBlock : 0; - var bDamage = enemyDamage - baseBlock * 4 > 0 ? enemyDamage - baseBlock * 4 : 0; +function debugStance(maxPower, ignoreArmy) { + //Returns what stance we should be using right now, or false if none grants survival + for (var critPower=2; critPower >= -2; critPower--) { + if (survive("D", critPower, ignoreArmy)) {return "D" + critPower} + else if (survive("XB", critPower, ignoreArmy)) {return "XB" + critPower} + else if (survive("B", critPower, ignoreArmy)) {return "B" + critPower} + else if (survive("X", critPower, ignoreArmy)) {return "X" + critPower} + else if (survive("H", critPower, ignoreArmy)) {return "H" + critPower} + else if (maxPower) break; } - var drainChallenge = game.global.challengeActive == 'Nom' || game.global.challengeActive == "Toxicity"; - var dailyPlague = game.global.challengeActive == 'Daily' && (typeof game.global.dailyChallenge.plague !== 'undefined'); - var dailyBogged = game.global.challengeActive == 'Daily' && (typeof game.global.dailyChallenge.bogged !== 'undefined'); - - if (game.global.challengeActive == "Electricity" || game.global.challengeActive == "Mapocalypse") { - dDamage+= dHealth * game.global.radioStacks * 0.1; - xDamage+= xHealth * game.global.radioStacks * 0.1; - bDamage+= bHealth * game.global.radioStacks * 0.1; - } else if (drainChallenge) { - dDamage += dHealth/20; - xDamage += xHealth/20; - bDamage += bHealth/20; - var drainChallengeOK = dHealth - missingHealth > dHealth/20; - } else if (dailyPlague) { - drainChallenge = true; - var hplost = dailyModifiers.plague.getMult(game.global.dailyChallenge.plague.strength, 1 + game.global.dailyChallenge.plague.stacks); - //x% of TOTAL health; - dDamage += dHealth * hplost; - xDamage += xHealth * hplost; - bDamage += bHealth * hplost; - var drainChallengeOK = dHealth - missingHealth > dHealth * hplost; - } else if (dailyBogged) { - drainChallenge = true; - // 1 + was added to the stacks to anticipate the next stack ahead of time. - var hplost = dailyModifiers.bogged.getMult(game.global.dailyChallenge.bogged.strength); - //x% of TOTAL health; - dDamage += dHealth * hplost; - xDamage += xHealth * hplost; - bDamage += bHealth * hplost; - var drainChallengeOK = dHealth - missingHealth > dHealth * hplost; - } else if (game.global.challengeActive == "Crushed") { - if(dHealth > baseBlock /2) - dDamage = enemyDamage*5 - baseBlock / 2 > 0 ? enemyDamage*5 - baseBlock / 2 : 0; - if(xHealth > baseBlock) - xDamage = enemyDamage*5 - baseBlock > 0 ? enemyDamage*5 - baseBlock : 0; - } - //^dont attach^. - if (game.global.voidBuff == "bleed" || (enemy && enemy.corrupted == 'corruptBleed')) { - dDamage += game.global.soldierHealth * 0.2; - xDamage += game.global.soldierHealth * 0.2; - bDamage += game.global.soldierHealth * 0.2; + return false; +} + +function maxOneShotPower(considerEdges) { + var power = 2; + + //No enemy to kill + if (considerEdges && !getCurrentEnemy()) return 0; + + //No overkill perk + if (game.portal.Overkill.level == 0) return 1; + + //Mastery + if (game.talents.overkill.purchased) power++; + + //Ice + if (game.global.uberNature == "Poison") power += 2; + if (getEmpowerment() == "Ice" && game.empowerments.Ice.getLevel() >= 50) power++; + if (getEmpowerment() == "Ice" && game.empowerments.Ice.getLevel() >= 100) power++; + + //No enemy to attack + if (considerEdges) for (var i=power; i > 1 && !getCurrentEnemy(i); i--); + + return power; +} + +function oneShotZone(zone, type, specificStance, maxOrMin) { + //Calculates our minimum damage + var baseDamage = calcOurDmg(maxOrMin ? "max" : "min", false, true); + var damageLeft = baseDamage + addPoison(false, (type == "world") ? zone : game.global.world); + + //Calculates how many enemies we can one shot + overkill + for (var power=1; power <= maxOneShotPower(); power++) { + //Enemy Health: A C99 Dragimp (worstCase) + damageLeft -= calcEnemyHealth(); + + //Check if we can one-shot the next enemy + if (damageLeft < 0) return power-1; + + //Calculates our minimum "left over" damage, which will be used by the Overkill + damageLeft *= 0.005 * game.portal.Overkill.level; } - baseDamage *= (game.global.titimpLeft > 0 ? 2 : 1); //consider titimp - //double attack is OK if the buff isn't double attack, or we will survive a double attack. see main.js @ 7197-7217 https://puu.sh/ssVNP/95f699a879.png (cant prevent the 2nd hit) - var isDoubleAttack = game.global.voidBuff == 'doubleAttack' || (enemy && enemy.corrupted == 'corruptDbl'); - // quality bugfix by uni @ 2.1.5.4u5 - var doubleAttackOK = true; // !isDoubleAttack || ((newSquadRdy && dHealth > dDamage * 2) || dHealth - missingHealth > dDamage * 2); - //lead attack ok if challenge isn't lead, or we are going to one shot them, or we can survive the lead damage - var leadDamage = game.challenges.Lead.stacks * 0.0003; - var leadAttackOK = game.global.challengeActive != 'Lead' || enemyHealth <= baseDamage || ((newSquadRdy && dHealth > dDamage + (dHealth * leadDamage)) || (dHealth - missingHealth > dDamage + (dHealth * leadDamage))); - //added voidcrit. - //voidcrit is OK if the buff isn't crit-buff, or we will survive a crit, or we are going to one-shot them (so they won't be able to crit) - const ignoreCrits = getPageSetting('IgnoreCrits'); // or if ignored - var isCritVoidMap = ignoreCrits == 2 ? false : (!ignoreCrits && game.global.voidBuff == 'getCrit') || (enemy && enemy.corrupted == 'corruptCrit'); - var voidCritinDok = !isCritVoidMap || (!enemyFast ? enemyHealth <= baseDamage : false) || (newSquadRdy && dHealth > dVoidCritDamage) || (dHealth - missingHealth > dVoidCritDamage); - var voidCritinXok = !isCritVoidMap || (!enemyFast ? enemyHealth <= baseDamage : false) || (newSquadRdy && xHealth > xVoidCritDamage) || (xHealth - missingHealth > xVoidCritDamage); - if (!game.global.preMapsActive && game.global.soldierHealth > 0) { - if (!enemyFast && game.upgrades.Dominance.done && enemyHealth <= baseDamage && (newSquadRdy || (dHealth - missingHealth > 0 && !drainChallenge) || (drainChallenge && drainChallengeOK))) { - setFormation(2); - //use D stance if: new army is ready&waiting / can survive void-double-attack or we can one-shot / can survive lead damage / can survive void-crit-dmg - } else if (game.upgrades.Dominance.done && ((newSquadRdy && dHealth > dDamage) || dHealth - missingHealth > dDamage) && doubleAttackOK && leadAttackOK && voidCritinDok ) { - setFormation(2); - //if CritVoidMap, switch out of D stance if we cant survive. Do various things. - } else if (isCritVoidMap && !voidCritinDok) { - //if we are already in X and the NEXT potential crit would take us past the point of being able to return to D/B, switch to B. - if (game.global.formation == "0" && game.global.soldierHealth - xVoidCritDamage < game.global.soldierHealthMax/2){ - if (game.upgrades.Barrier.done && (newSquadRdy || (missingHealth < game.global.soldierHealthMax/2)) ) - setFormation(3); - } - //else if we can totally block all crit damage in X mode, OR we can't survive-crit in D, but we can in X, switch to X. - // NOTE: during next loop, the If-block above may immediately decide it wants to switch to B. - else if (xVoidCritDamage == 0 || ((game.global.formation == 2 || game.global.formation == 4) && voidCritinXok)){ - setFormation("0"); - } - //otherwise, stuff: - else { - if (game.global.formation == "0"){ - if (game.upgrades.Barrier.done && (newSquadRdy || (missingHealth < game.global.soldierHealthMax/2)) ) - setFormation(3); - else - setFormation(1); - } - else if (game.upgrades.Barrier.done && (game.global.formation == 2 || game.global.formation == 4)) - setFormation(3); - } - } else if (game.upgrades.Formations.done && ((newSquadRdy && xHealth > xDamage) || xHealth - missingHealth > xDamage)) { - //in lead challenge, switch to H if about to die, so doesn't just die in X mode without trying - if ((game.global.challengeActive == 'Lead') && (xHealth - missingHealth < xDamage + (xHealth * leadDamage))) - setFormation(1); - else - setFormation("0"); - } else if (game.upgrades.Barrier.done && ((newSquadRdy && bHealth > bDamage) || bHealth - missingHealth > bDamage)) { - setFormation(3); //does this ever run? - } else if (game.upgrades.Formations.done) { - setFormation(1); - } else - setFormation("0"); + return power-1; +} + +function oneShotPower(specificStance, offset = 0, maxOrMin) { + //Calculates our minimum damage + var baseDamage = calcOurDmg(maxOrMin ? "max" : "min", false, true); + var damageLeft = baseDamage + addPoison(true); + + //Calculates how many enemies we can one shot + overkill + for (var power=1; power <= maxOneShotPower(); power++) { + //No enemy to overkill (usually this happens at the last cell) + if (!getCurrentEnemy(power+offset)) return power+offset-1; + + //Enemy Health: current enemy or his neighbours + if (power+offset > 1) damageLeft -= calcSpecificEnemyHealth(undefined, undefined, getCurrentEnemy(power+offset).level); + else damageLeft -= getCurrentEnemy().health; + + //Check if we can one shot the next enemy + if (damageLeft < 0) return power-1; + + //Calculates our minimum "left over" damage, which will be used by the Overkill + damageLeft *= 0.005 * game.portal.Overkill.level; } - baseDamage /= (game.global.titimpLeft > 0 ? 2 : 1); //unconsider titimp :P + + return power-1; } -function autoStance2() { - //get back to a baseline of no stance (X) - calcBaseDamageinX2(); - //no need to continue - if (game.global.gridArray.length === 0) return true; - if (game.global.soldierHealth <= 0) return; //dont calculate stances when dead, cause the "current" numbers are not updated when dead. - if (!getPageSetting('AutoStance')) return true; - if (!game.upgrades.Formations.done) return true; +function challengeDamage(maxHealth, minDamage, maxDamage, missingHealth, block, pierce, critPower = 2) { + //Pre-Init + if (!maxHealth) maxHealth = calcOurHealth(); + if (!minDamage) minDamage = calcOurDmg("min", false, true) + addPoison(true); + if (!maxDamage) maxDamage = calcOurDmg("max", false, true) + addPoison(true); + if (!missingHealth) missingHealth = game.global.soldierHealthMax - game.global.soldierHealth; + if (!pierce) pierce = (game.global.brokenPlanet && !game.global.mapsActive) ? getPierceAmt() : 0; + if (!block) block = calcOurBlock(false); - //start analyzing autostance - var missingHealth = game.global.soldierHealthMax - game.global.soldierHealth; - var newSquadRdy = game.resources.trimps.realMax() <= game.resources.trimps.owned + 1; - var dHealth = baseHealth/2; - var xHealth = baseHealth; - var bHealth = baseHealth/2; - //COMMON: - var corrupt = game.global.world >= mutations.Corruption.start(); + //Enemy var enemy = getCurrentEnemy(); - if (typeof enemy === 'undefined') return true; var enemyHealth = enemy.health; - var enemyDamage = calcBadGuyDmg(enemy,null,true,true); - //crits - var critMulti = 1; - const ignoreCrits = getPageSetting('IgnoreCrits'); - var isCrushed = false; - var isCritVoidMap = false; - var isCritDaily = false; - if (ignoreCrits == 2) { // Ignore all! - (isCrushed = (game.global.challengeActive == "Crushed") && game.global.soldierHealth > game.global.soldierCurrentBlock) - && (critMulti *= 5); - (isCritVoidMap = (!ignoreCrits && game.global.voidBuff == 'getCrit') || (enemy.corrupted == 'corruptCrit')) - && (critMulti *= 5); - (isCritDaily = (game.global.challengeActive == "Daily") && (typeof game.global.dailyChallenge.crits !== 'undefined')) - && (critMulti *= dailyModifiers.crits.getMult(game.global.dailyChallenge.crits.strength)); - enemyDamage *= critMulti; - } - //double attacks - var isDoubleAttack = game.global.voidBuff == 'doubleAttack' || (enemy.corrupted == 'corruptDbl'); - //fast - var enemyFast = (game.global.challengeActive == "Slow" || ((game.badGuys[enemy.name].fast || enemy.mutation == "Corruption") && game.global.challengeActive != "Coordinate" && game.global.challengeActive != "Nom")) || isDoubleAttack; - // - if (enemy.corrupted == 'corruptStrong') - enemyDamage *= 2; - if (enemy.corrupted == 'corruptTough') - enemyHealth *= 5; - - //calc X,D,B: - var xDamage = (enemyDamage - baseBlock); - var dDamage = (enemyDamage - baseBlock / 2); - var bDamage = (enemyDamage - baseBlock * 4); - var dDamageNoCrit = (enemyDamage/critMulti - baseBlock/2); - var xDamageNoCrit = (enemyDamage/critMulti - baseBlock); - var pierce = 0; - if (game.global.brokenPlanet && !game.global.mapsActive) { - pierce = getPierceAmt(); - var atkPierce = pierce * enemyDamage; - var atkPierceNoCrit = pierce * (enemyDamage/critMulti); - if (xDamage < atkPierce) xDamage = atkPierce; - if (dDamage < atkPierce) dDamage = atkPierce; - if (bDamage < atkPierce) bDamage = atkPierce; - if (dDamageNoCrit < atkPierceNoCrit) dDamageNoCrit = atkPierceNoCrit; - if (xDamageNoCrit < atkPierceNoCrit) xDamageNoCrit = atkPierceNoCrit; - } - if (xDamage < 0) xDamage = 0; - if (dDamage < 0) dDamage = 0; - if (bDamage < 0) bDamage = 0; - if (dDamageNoCrit < 0) dDamageNoCrit = 0; - if (xDamageNoCrit < 0) xDamageNoCrit = 0; - var isdba = isDoubleAttack ? 2 : 1; - xDamage *= isdba; - dDamage *= isdba; - bDamage *= isdba; - dDamageNoCrit *= isdba; - xDamageNoCrit *= isdba; - - var drainChallenge = game.global.challengeActive == 'Nom' || game.global.challengeActive == "Toxicity"; - var dailyPlague = game.global.challengeActive == 'Daily' && (typeof game.global.dailyChallenge.plague !== 'undefined'); - var dailyBogged = game.global.challengeActive == 'Daily' && (typeof game.global.dailyChallenge.bogged !== 'undefined'); - var leadChallenge = game.global.challengeActive == 'Lead'; - if (drainChallenge) { - var hplost = 0.20; //equals 20% of TOTAL health - dDamage += dHealth * hplost; - xDamage += xHealth * hplost; - bDamage += bHealth * hplost; - } else if (dailyPlague) { - drainChallenge = true; - // 1 + was added to the stacks to anticipate the next stack ahead of time. - var hplost = dailyModifiers.plague.getMult(game.global.dailyChallenge.plague.strength, 1 + game.global.dailyChallenge.plague.stacks); - //x% of TOTAL health; - dDamage += dHealth * hplost; - xDamage += xHealth * hplost; - bDamage += bHealth * hplost; - } else if (dailyBogged) { - drainChallenge = true; - // 1 + was added to the stacks to anticipate the next stack ahead of time. - var hplost = dailyModifiers.bogged.getMult(game.global.dailyChallenge.bogged.strength); - //x% of TOTAL health; - dDamage += dHealth * hplost; - xDamage += xHealth * hplost; - bDamage += bHealth * hplost; - } else if (leadChallenge) { - var leadDamage = game.challenges.Lead.stacks * 0.0003; //0.03% of their health per enemy stack. - var added = game.global.soldierHealthMax * leadDamage; - dDamage += added; - xDamage += added; - bDamage += added; - } - //^dont attach^. - if (game.global.voidBuff == "bleed" || (enemy.corrupted == 'corruptBleed')) { - //20% of CURRENT health; - var added = game.global.soldierHealth * 0.20; - dDamage += added; - xDamage += added; - bDamage += added; + var enemyDamage = calcSpecificEnemyAttack(critPower); + + //Active Challenges + var leadChallenge = challengeActive("Lead"); + var electricityChallenge = challengeActive("Electricty") || game.global.challengeActive == "Mapocalypse"; + var dailyPlague = game.global.challengeActive == "Daily" && typeof game.global.dailyChallenge.plague !== "undefined"; + var dailyBogged = game.global.challengeActive == "Daily" && typeof game.global.dailyChallenge.bogged !== "undefined"; + var dailyExplosive = game.global.challengeActive == "Daily" && typeof game.global.dailyChallenge.explosive !== "undefined"; + var dailyMirrored = game.global.challengeActive == "Daily" && typeof game.global.dailyChallenge.mirrored !== "undefined"; + var drainChallenge = challengeActive("Nom") || challengeActive("Toxicity") || dailyPlague || dailyBogged; + var challengeDamage = 0, harm = 0; + + //Electricity Lead - Tox/Nom + if (electricityChallenge) challengeDamage = game.challenges.Electricity.stacks * 0.1; + else if (drainChallenge) challengeDamage = 0.05; + + //Plague & Bogged (Daily) + if (dailyPlague) challengeDamage = dailyModifiers.plague.getMult(game.global.dailyChallenge.plague.strength, 1 + game.global.dailyChallenge.plague.stacks); + if (dailyBogged) challengeDamage = dailyModifiers.bogged.getMult(game.global.dailyChallenge.bogged.strength); + + //Lead - Only takes damage if the enemy doesn't die + if (leadChallenge && minDamage < enemyHealth) harm += maxHealth * game.challenges.Lead.stacks * 0.0003; + + //Adds Drain Damage -- % of max health + harm += maxHealth * challengeDamage; + + //Adds Bleed Damage -- % of current health + if (game.global.voidBuff == "bleed" || (enemy.corrupted == 'corruptBleed') || enemy.corrupted == 'healthyBleed') { + challengeDamage = (enemy.corrupted == 'healthyBleed') ? 0.30 : 0.20; + harm += (maxHealth - missingHealth) * challengeDamage; } - baseDamage *= (game.global.titimpLeft > 0 ? 2 : 1); //consider titimp - baseDamage *= (!game.global.mapsActive && game.global.mapBonus > 0) ? ((game.global.mapBonus * .2) + 1) : 1; //consider mapbonus - - //handle Daily Challenge explosion/suicide - var xExplosionOK = true; - var dExplosionOK = true; - if (typeof game.global.dailyChallenge['explosive'] !== 'undefined') { - var explosionDmg = 0; - var explosiveDamage = 1 + game.global.dailyChallenge['explosive'].strength; - - var playerCritMult = getPlayerCritChance() ? getPlayerCritDamageMult() : 1; - var playerDCritDmg = (baseDamage*4) * playerCritMult; - var playerXCritDmg = (baseDamage) * playerCritMult; - - // I don't know if I have to use x or d damage or just the base damage multiplier for this calculation. - explosionDmg = calcBadGuyDmg(enemy,null,true,true) * explosiveDamage; - xExplosionOK = ((xHealth - missingHealth > explosionDmg) || (enemyHealth > playerXCritDmg)); - dExplosionOK = (newSquadRdy || (dHealth - missingHealth > explosionDmg) || (enemyHealth > playerDCritDmg)); + + //Explosive Daily + if (dailyExplosive && critPower >= 0) { + var explosionDmg = enemyDamage * dailyModifiers.explosive.getMult(game.global.dailyChallenge.explosive.strength); + if (maxDamage >= enemyHealth && maxHealth > block) harm += Math.max(explosionDmg - block, explosionDmg * pierce); } - //lead attack ok if challenge isn't lead, or we are going to one shot them, or we can survive the lead damage - var oneshotFast = enemyFast ? enemyHealth <= baseDamage : false; - var surviveD = ((newSquadRdy && dHealth > dDamage) || (dHealth - missingHealth > dDamage)); - var surviveX = ((newSquadRdy && xHealth > xDamage) || (xHealth - missingHealth > xDamage)); - var surviveB = ((newSquadRdy && bHealth > bDamage) || (bHealth - missingHealth > bDamage)); - var leadAttackOK = !leadChallenge || oneshotFast || surviveD; - var drainAttackOK = !drainChallenge || oneshotFast || surviveD; - var isCritThing = isCritVoidMap || isCritDaily || isCrushed; - var voidCritinDok = !isCritThing || oneshotFast || surviveD; - var voidCritinXok = !isCritThing || oneshotFast || surviveX; + //Mirrored (Daily) -- Unblockable, unpredictable + if (dailyMirrored && critPower >= -1) + harm += Math.min(maxDamage - addPoison(true), enemyHealth) * dailyModifiers.mirrored.getMult(game.global.dailyChallenge.mirrored.strength); - if (!game.global.preMapsActive && game.global.soldierHealth > 0) { - //use D stance if: new army is ready&waiting / can survive void-double-attack or we can one-shot / can survive lead damage / can survive void-crit-dmg - if (game.upgrades.Dominance.done && surviveD && leadAttackOK && drainAttackOK && voidCritinDok && dExplosionOK) { - setFormation(2); - //if CritVoidMap, switch out of D stance if we cant survive. Do various things. - } else if (isCritThing && !voidCritinDok) { - //if we are already in X and the NEXT potential crit would take us past the point of being able to return to D/B, switch to B. - if (game.global.formation == "0" && game.global.soldierHealth - xDamage < bHealth){ - if (game.upgrades.Barrier.done && (newSquadRdy || missingHealth < bHealth)) - setFormation(3); - } - //else if we can totally block all crit damage in X mode, OR we can't survive-crit in D, but we can in X, switch to X. - // NOTE: during next loop, the If-block above may immediately decide it wants to switch to B. - else if (xDamage == 0 || ((game.global.formation == 2 || game.global.formation == 4) && voidCritinXok)){ - setFormation("0"); - } - //otherwise, stuff: (Try for B again) - else { - if (game.global.formation == "0"){ - if (game.upgrades.Barrier.done && (newSquadRdy || missingHealth < bHealth)) - setFormation(3); - else - setFormation(1); - } - else if (game.upgrades.Barrier.done && (game.global.formation == 2 || game.global.formation == 4)) - setFormation(3); - } - } else if (game.upgrades.Formations.done && !xExplosionOK) { - // Set to H if killing badguys will cause your trimps to die - setFormation(1); - } else if (game.upgrades.Formations.done && surviveX) { - //in lead challenge, switch to H if about to die, so doesn't just die in X mode without trying - if ((game.global.challengeActive == 'Lead') && (xHealth - missingHealth < xDamage + (xHealth * leadDamage))) - setFormation(1); - else - setFormation("0"); - } else if (game.upgrades.Barrier.done && surviveB) { - if (game.global.formation != 3) { - setFormation(3); //does this ever run? - //TODO Check this with analytics instead. - debug("AutoStance B/3","other"); - } - } else { - if (game.global.formation != 1) - setFormation(1); //the last thing that runs - } + return harm; +} + +function directDamage(block, pierce, currentHealth, minDamage, critPower = 2) { + //Pre Init + if (!block) block = calcOurBlock(false); + if (!pierce) pierce = (game.global.brokenPlanet && !game.global.mapsActive) ? getPierceAmt() : 0; + if (!currentHealth) currentHealth = calcOurHealth(true) - (game.global.soldierHealthMax - game.global.soldierHealth); + if (!minDamage) minDamage = calcOurDmg("min", false, true) + addPoison(true); + + //Enemy + var enemy = getCurrentEnemy(); + var enemyHealth = enemy.health; + var enemyDamage = calcSpecificEnemyAttack(critPower, block, currentHealth); + + //Applies pierce + var harm = Math.max(enemyDamage - block, pierce * enemyDamage, 0); + + //Fast Enemies + var isDoubleAttack = game.global.voidBuff == "doubleAttack" || (enemy.corrupted == "corruptDbl") || enemy.corrupted == "healthyDbl"; + var enemyFast = isDoubleAttack || challengeActive("Slow") || ((game.badGuys[enemy.name].fast || enemy.mutation == "Corruption") && game.global.challengeActive != "Coordinate" && challengeActive("Nom") == false); + + //Dodge Dailies + if (game.global.challengeActive == "Daily" && typeof game.global.dailyChallenge.slippery !== "undefined") { + var slipStr = game.global.dailyChallenge.slippery.strength; + var dodgeDaily = (slipStr > 15 && game.global.world % 2 == 0) || (slipStr <= 15 && game.global.world % 2 == 1); } - baseDamage /= (game.global.titimpLeft > 0 ? 2 : 1); //unconsider titimp - baseDamage /= (!game.global.mapsActive && game.global.mapBonus > 0) ? ((game.global.mapBonus * .2) + 1) : 1; //unconsider mapbonus - return true; + + //Double Attack and One Shot situations + if (isDoubleAttack && minDamage < enemyHealth) harm *= 2; + if (!enemyFast && !dodgeDaily && minDamage > enemyHealth) harm = 0; + + return harm; } -function autoStanceCheck(enemyCrit) { - if (game.global.gridArray.length === 0) return [true,true]; - //baseDamage //in stance attack, //min, //disable stances, //enable flucts - var ourDamage = calcOurDmg(game.global.soldierCurrentAttack,true,true,true); - //baseBlock - var ourBlock = game.global.soldierCurrentBlock; - //baseHealth - var ourHealth = game.global.soldierHealthMax; +function survive(formation = "S", critPower = 2, ignoreArmy) { + //Check if the formation is valid + if (formation == "D" && !game.upgrades.Dominance.done) return false; + if (formation == "XB" && !game.upgrades.Barrier.done) return false; + if (formation == "B" && !game.upgrades.Barrier.done) return false; + if (formation == "H" && !game.upgrades.Formations.done) return false; + if (formation == "S" && (game.global.world < 60 || game.global.highestLevelCleared < 180)) return false; - //start analyzing autostance + //Base stats + var health = baseHealth; + var block = baseBlock; var missingHealth = game.global.soldierHealthMax - game.global.soldierHealth; - var newSquadRdy = game.resources.trimps.realMax() <= game.resources.trimps.owned + 1; - //COMMON: - var corrupt = game.global.world >= mutations.Corruption.start(); - var enemy = getCurrentEnemy(); - if (typeof enemy === 'undefined') return [true,true]; - var enemyHealth = enemy.health; - var enemyDamage = calcBadGuyDmg(enemy,null,true,true,true); //(enemy,attack,daily,maxormin,disableFlucts) - //crits - var critMulti = 1; - const ignoreCrits = getPageSetting('IgnoreCrits'); - var isCrushed = false; - var isCritVoidMap = false; - var isCritDaily = false; - if (ignoreCrits == 2) { // Ignored all! - (isCrushed = game.global.challengeActive == "Crushed" && game.global.soldierHealth > game.global.soldierCurrentBlock) - && enemyCrit && (critMulti *= 5); - (isCritVoidMap = game.global.voidBuff == 'getCrit' || enemy.corrupted == 'corruptCrit') - && enemyCrit && (critMulti *= 5); - (isCritDaily = game.global.challengeActive == "Daily" && typeof game.global.dailyChallenge.crits !== 'undefined') - && enemyCrit && (critMulti *= dailyModifiers.crits.getMult(game.global.dailyChallenge.crits.strength)); - if (enemyCrit) - enemyDamage *= critMulti; - } - //double attacks - var isDoubleAttack = game.global.voidBuff == 'doubleAttack' || (enemy.corrupted == 'corruptDbl'); - //fast - var enemyFast = (game.global.challengeActive == "Slow" || ((game.badGuys[enemy.name].fast || enemy.mutation == "Corruption") && game.global.challengeActive != "Coordinate" && game.global.challengeActive != "Nom")) || isDoubleAttack; - if (enemy.corrupted == 'corruptStrong') - enemyDamage *= 2; - if (enemy.corrupted == 'corruptTough') - enemyHealth *= 5; - //calc X,D,B: - enemyDamage -= ourBlock; - var pierce = 0; - if (game.global.brokenPlanet && !game.global.mapsActive) { - pierce = getPierceAmt(); - var atkPierce = pierce * enemyDamage; - if (enemyDamage < atkPierce) enemyDamage = atkPierce; - } - if (enemyDamage < 0) enemyDamage = 0; - var isdba = isDoubleAttack ? 2 : 1; - enemyDamage *= isdba; - var drainChallenge = game.global.challengeActive == 'Nom' || game.global.challengeActive == "Toxicity"; - var dailyPlague = game.global.challengeActive == 'Daily' && (typeof game.global.dailyChallenge.plague !== 'undefined'); - var dailyBogged = game.global.challengeActive == 'Daily' && (typeof game.global.dailyChallenge.bogged !== 'undefined'); - var leadChallenge = game.global.challengeActive == 'Lead'; - if (drainChallenge) { - var hplost = 0.20; //equals 20% of TOTAL health - enemyDamage += ourHealth * hplost; - } else if (dailyPlague) { - drainChallenge = true; - var hplost = dailyModifiers.plague.getMult(game.global.dailyChallenge.plague.strength, 1 + game.global.dailyChallenge.plague.stacks); - //x% of TOTAL health; - enemyDamage += ourHealth * hplost; - } else if (dailyBogged) { - drainChallenge = true; - var hplost = dailyModifiers.bogged.getMult(game.global.dailyChallenge.bogged.strength); - //x% of TOTAL health; - enemyDamage += ourHealth * hplost; - } else if (leadChallenge) { - var leadDamage = game.challenges.Lead.stacks * 0.0003; - enemyDamage += game.global.soldierHealthMax * leadDamage; + //More stats + var minDamage = baseMinDamage; + var maxDamage = baseMaxDamage; + var newSquadRdy = !ignoreArmy && game.resources.trimps.realMax() <= game.resources.trimps.owned + 1; + + //Applies the formation modifiers + if (formation == "XB") {health /= 2;} + else if (formation == "D") {minDamage *= 4; maxDamage *= 4; health /= 2; block /= 2;} + else if (formation == "B") {minDamage /= 2; maxDamage /= 2; health /= 2; block *= 4;} + else if (formation == "H") {minDamage /= 2; maxDamage /= 2; health *= 4; block /= 2;} + else if (formation == "S") {minDamage /= 2; maxDamage /= 2; health /= 2; block /= 2;} + + //Max health for XB formation + var maxHealth = health * (formation == "XB" ? 2 : 1); + + //Empowerments - Poison + minDamage += addPoison(true) + maxDamage += addPoison(true) + + //Pierce + var pierce = (game.global.brokenPlanet && !game.global.mapsActive) ? getPierceAmt() : 0; + if (formation != "B" && game.global.formation == 3) pierce *= 2; + + //Decides if the trimps can survive in this formation + var notSpire = game.global.mapsActive || !game.global.spireActive; + var harm = directDamage(block, pierce, health - missingHealth, minDamage, critPower) + challengeDamage(maxHealth, minDamage, maxDamage, missingHealth, block, pierce, critPower); + + //Updated Genes and Block + var blockier = calcOurBlock(false); + var healthier = health * Math.pow(1.01, game.jobs.Geneticist.owned - game.global.lastLowGen); + var maxHealthier = maxHealth * Math.pow(1.01, game.jobs.Geneticist.owned - game.global.lastLowGen); + var harm2 = directDamage(blockier, pierce, healthier, minDamage, critPower) + challengeDamage(maxHealthier, minDamage, maxDamage, 0, blockier, pierce, critPower); + + return (newSquadRdy && notSpire && healthier > harm2) || (health - missingHealth > harm); +} + +function autoStance() { + calcBaseDamageInX(); + + //Invalid Map - Dead Soldiers - Auto Stance Disabled - Formations Unavailable - No Enemy + if (game.global.soldierHealth <= 0) return; + if (game.global.gridArray.length === 0) return true; + if (!getPageSetting('AutoStance')) return true; + if (!game.upgrades.Formations.done) return true; + if (typeof getCurrentEnemy() === 'undefined') return true; + + //Keep on D vs the Domination bosses + if (game.global.challengeActive == "Domination" && (game.global.lastClearedCell == 98 || getCurrentEnemy() && getCurrentEnemy().name == "Cthulimp")) { + autoStance2(); + return; } - //^dont attach^. - if (game.global.voidBuff == "bleed" || (enemy.corrupted == 'corruptBleed')) { - enemyDamage += game.global.soldierHealth * 0.2; + + //Stance Selector + if (!game.global.preMapsActive && game.global.soldierHealth > 0) { + //If no formation can survive a mega crit, it ignores it, and recalculates for a regular crit, then no crit + //If even that is not enough, then it ignore Explosive Daily, and finally it ignores Reflect Daily + var critPower; + for (critPower=2; critPower >= -2; critPower--) { + if (survive("D", critPower)) {setFormation(2); break;} + else if (survive("XB", critPower)) {setFormation("0"); break;} + else if (survive("B", critPower)) {setFormation(3); break;} + else if (survive("X", critPower)) {setFormation("0"); break;} + else if (survive("H", critPower)) {setFormation(1); break;} + } + + //If it cannot survive the worst case scenario on any formation, attempt it's luck on H, if available, or X + if (critPower < -2) { + if (game.upgrades.Formations.done) setFormation(1); + else setFormation("0"); + } } - ourDamage *= (game.global.titimpLeft > 0 ? 2 : 1); //consider titimp - ourDamage *= (!game.global.mapsActive && game.global.mapBonus > 0) ? ((game.global.mapBonus * .2) + 1) : 1; //consider mapbonus - - //lead attack ok if challenge isn't lead, or we are going to one shot them, or we can survive the lead damage - var oneshotFast = enemyFast ? enemyHealth <= ourDamage : false; - var survive = ((newSquadRdy && ourHealth > enemyDamage) || (ourHealth - missingHealth > enemyDamage)); - var leadAttackOK = !leadChallenge || oneshotFast || survive; - var drainAttackOK = !drainChallenge || oneshotFast || survive; - var isCritThing = isCritVoidMap || isCritDaily || isCrushed; - var voidCritok = !isCritThing || oneshotFast || survive; - - if (!game.global.preMapsActive) { - var enoughDamage2 = enemyHealth <= ourDamage; - var enoughHealth2 = survive && leadAttackOK && drainAttackOK && voidCritok; - // } else { - // var ourCritMult = getPlayerCritChance() ? getPlayerCritDamageMult() : 1; - // var ourDmg = (ourDamage)*ourCritMult; - // var enoughDamage2 = enemyHealth <= ourDmg; - // var surviveOneShot = enemyFast ? ourHealth > xDamageNoCrit : enemyHealth < ourDmg; - // var enoughHealth2 = surviveOneShot && leadAttackOK && drainAttackOK && voidCritok; - // } - ourDamage /= (game.global.titimpLeft > 0 ? 2 : 1); //unconsider titimp - ourDamage /= (!game.global.mapsActive && game.global.mapBonus > 0) ? ((game.global.mapBonus * .2) + 1) : 1; //unconsider mapbonus - return [enoughHealth2,enoughDamage2]; - } else - return [true,true]; + + return true; } -function autoStance3() { - //get back to a baseline of no stance (X) - calcBaseDamageinX(); - //no need to continue +function autoStance2() { if (game.global.gridArray.length === 0) return; - if (game.global.soldierHealth <= 0) return; //dont calculate stances when dead, cause the "current" numbers are not updated when dead. - if (!getPageSetting('AutoStance')) return; + if (game.global.soldierHealth <= 0) return; + if (getPageSetting('AutoStance') == 0) return; if (!game.upgrades.Formations.done) return; + if (game.global.world <= 70) return; + if (game.global.formation != 2) + setFormation(2); +} - if(game.global.world>=80) { - if( getEmpowerment() != "Wind" || game.global.mapsActive || game.empowerments.Wind.currentDebuffPower==200) { - setFormation(2); - } - else if (getPageSetting('WindStacking')) { - setFormation(4); - } +function windStance() { + //Fail safes + if (game.global.gridArray.length === 0) return; + if (game.global.soldierHealth <= 0) return; + if (!game.upgrades.Formations.done) return; + if (game.global.world <= 70) return; + var stancey = 2; + if (game.global.challengeActive != "Daily") { + if (calcCurrentStance() == 5) { + stancey = 5; + lowHeirloom(); + } + if (calcCurrentStance() == 2) { + stancey = 2; + lowHeirloom(); + } + if (calcCurrentStance() == 0) { + stancey = 0; + lowHeirloom(); + } + if (calcCurrentStance() == 1) { + stancey = 1; + lowHeirloom(); + } + if (calcCurrentStance() == 15) { + stancey = 5; + highHeirloom(); + } + if (calcCurrentStance() == 12) { + stancey = 2; + highHeirloom(); + } + if (calcCurrentStance() == 10) { + stancey = 0; + highHeirloom(); + } + if (calcCurrentStance() == 11) { + stancey = 1; + highHeirloom(); + } + } + if (game.global.challengeActive == "Daily") { + if (calcCurrentStance() == 5) { + stancey = 5; + dlowHeirloom(); + } + if (calcCurrentStance() == 2) { + stancey = 2; + dlowHeirloom(); + } + if (calcCurrentStance() == 0) { + stancey = 0; + dlowHeirloom(); + } + if (calcCurrentStance() == 1) { + stancey = 1; + dlowHeirloom(); + } + if (calcCurrentStance() == 15) { + stancey = 5; + dhighHeirloom(); + } + if (calcCurrentStance() == 12) { + stancey = 2; + dhighHeirloom(); + } + if (calcCurrentStance() == 10) { + stancey = 0; + dhighHeirloom(); + } + if (calcCurrentStance() == 11) { + stancey = 1; + dhighHeirloom(); + } } + setFormation(stancey); } diff --git a/modules/upgrades.js b/modules/upgrades.js index 6bc63509b..5da84c341 100644 --- a/modules/upgrades.js +++ b/modules/upgrades.js @@ -1,25 +1,213 @@ -//MODULES["upgrades"] = {}; +//Helium + var upgradeList = ['Miners', 'Scientists', 'Coordination', 'Speedminer', 'Speedlumber', 'Speedfarming', 'Speedscience', 'Speedexplorer', 'Megaminer', 'Megalumber', 'Megafarming', 'Megascience', 'Efficiency', 'TrainTacular', 'Trainers', 'Explorers', 'Blockmaster', 'Battle', 'Bloodlust', 'Bounty', 'Egg', 'Anger', 'Formations', 'Dominance', 'Barrier', 'UberHut', 'UberHouse', 'UberMansion', 'UberHotel', 'UberResort', 'Trapstorm', 'Gigastation', 'Shieldblock', 'Potency', 'Magmamancers']; +MODULES["upgrades"] = {}; +MODULES["upgrades"].targetFuelZone = true; +MODULES["upgrades"].customMetalRatio = 0.5; //Change the Custom Delta factor instead + +function gigaTargetZone() { + //Init + var targetZone = 59; + var daily = game.global.challengeActive == 'Daily'; + var runningC2 = game.global.runningChallengeSquared; + var heliumChallengeActive = game.global.challengeActive && game.challenges[game.global.challengeActive].heliumThrough; + + //Try setting target zone to the zone we finish our current challenge or do our void maps + var voidZone = (daily) ? getPageSetting('DailyVoidMod') : getPageSetting('VoidMaps'); + var challengeZone = (heliumChallengeActive) ? game.challenges[game.global.challengeActive].heliumThrough : 0; + + //Also consider the zone we configured our portal to be used + var portalZone = 0; + if (autoTrimpSettings.AutoPortal.selected == "Helium Per Hour") portalZone = (daily) ? getPageSetting('dHeHrDontPortalBefore') : getPageSetting('HeHrDontPortalBefore'); + else if (autoTrimpSettings.AutoPortal.selected == "Custom") portalZone = (daily) ? getPageSetting('dCustomAutoPortal') : getPageSetting('CustomAutoPortal'); + + //Finds a target zone for when doing c2 + var c2zone = 0; + if (getPageSetting('c2runnerstart') == true && getPageSetting("c2runnerportal") > 0) c2zone = getPageSetting("c2runnerportal"); + else if (getPageSetting("FinishC2") > 0) c2zone = getPageSetting("FinishC2"); + + //Set targetZone + if (!runningC2) targetZone = Math.max(targetZone, voidZone, challengeZone, portalZone-1); + else targetZone = Math.max(targetZone, c2zone-1); + + //Target Fuel Zone + if (daily && getPageSetting("AutoGenDC") != 0) targetZone = Math.min(targetZone, 230); + if (runningC2 && getPageSetting("AutoGenC2") != 0) targetZone = Math.min(targetZone, 230); + if (MODULES.upgrades.targetFuelZone && (getPageSetting("fuellater") >= 1 || getPageSetting("beforegen") != 0)) targetZone = Math.min(targetZone, Math.max(230, getPageSetting("fuellater"))); + + //Failsafe + if (targetZone < 60) { + targetZone = Math.max(65, game.global.highestLevelCleared); + debug("Auto Gigastation: Warning! Unable to find a proper targetZone. Using your HZE instead", "general", "*rocket"); + } + + return targetZone; +} -//Buys all available non-equip upgrades listed in var upgradeList +function autoGiga(targetZone, metalRatio = 0.5, slowDown = 10, customBase) { + //Pre Init + if (!targetZone || targetZone < 60) targetZone = gigaTargetZone(); + + //Init + var base = (customBase) ? customBase : getPageSetting('FirstGigastation'); + var baseZone = game.global.world; + var rawPop = game.resources.trimps.max - game.unlocks.impCount.TauntimpAdded; + var gemsPS = getPerSecBeforeManual("Dragimp"); + var metalPS = getPerSecBeforeManual("Miner"); + var megabook = (game.global.frugalDone) ? 1.6 : 1.5; + + //Calculus + var nGigas = Math.min(Math.floor(targetZone-60), Math.floor(targetZone/2 - 25), Math.floor(targetZone/3 - 12), Math.floor(targetZone/5), Math.floor(targetZone/10 + 17), 39); + var metalDiff = Math.max(0.1 * metalRatio * metalPS / gemsPS, 1); + + var delta = 3; + for (var i=0; i<10; i++) { + //Population guess + var pop = 6 * Math.pow(1.2, nGigas)*10000; + pop *= base * (1 - Math.pow(5/6, nGigas+1)) + delta*(nGigas+1 - 5*(1 - Math.pow(5/6, nGigas+1))); + pop += rawPop - base*10000; + pop /= rawPop; + + //Delta + delta = Math.pow(megabook, targetZone - baseZone); + delta *= metalDiff * slowDown * pop; + delta /= Math.pow(1.75, nGigas); + delta = Math.log(delta); + delta /= Math.log(1.4); + delta /= nGigas; + } + + //Returns a number in the x.yy format, and as a number, not a string + return +(Math.round(delta + "e+2") + "e-2"); +} + +function firstGiga(forced) { + //Build our first giga if: A) Has more than 2 Warps & B) Can't afford more Coords & C)* Lacking Health or Damage & D)* Has run at least 1 map stack or if forced to + const maxHealthMaps = game.global.challengeActive === "Daily" ? getPageSetting('dMaxMapBonushealth') : getPageSetting('MaxMapBonushealth'); + const s = !(getPageSetting('CustomDeltaFactor') > 20); + const a = game.buildings.Warpstation.owned >= 2; + const b = !canAffordCoordinationTrimps() || game.global.world >= 230 && !canAffordTwoLevel(game.upgrades.Coordination); + const c = s || !enoughHealth || !enoughDamage; + const d = s || game.global.mapBonus >= 2 || game.global.mapBonus >= getPageSetting('MaxMapBonuslimit') || game.global.mapBonus >= maxHealthMaps; + if (!forced && !(a && b && c && d)) return false; + + //Define Base and Delta for this run + const base = game.buildings.Warpstation.owned; + const deltaZ = (getPageSetting('CustomTargetZone') >= 60) ? getPageSetting('CustomTargetZone') : undefined; + const deltaM = (MODULES["upgrades"].customMetalRatio > 0) ? MODULES["upgrades"].customMetalRatio : undefined; + const deltaS = (getPageSetting('CustomDeltaFactor') >= 1) ? getPageSetting('CustomDeltaFactor') : undefined; + const delta = autoGiga(deltaZ, deltaM, deltaS); + + //Save settings + setPageSetting('FirstGigastation', base); + setPageSetting('DeltaGigastation', delta); + + //Log + debug("Auto Gigastation: Setting pattern to " + base + "+" + delta, "general", "*rocket"); + + return true; +} + +function needGymystic() { + return game.upgrades['Gymystic'].allowed - game.upgrades['Gymystic'].done > 0; +} function buyUpgrades() { + for (var upgrade in upgradeList) { upgrade = upgradeList[upgrade]; var gameUpgrade = game.upgrades[upgrade]; var available = (gameUpgrade.allowed > gameUpgrade.done && canAffordTwoLevel(gameUpgrade)); - if (upgrade == 'Coordination' && (getPageSetting('ManualCoords') || !canAffordCoordinationTrimps())) continue; + var fuckbuildinggiga = (bwRewardUnlocked("AutoStructure") == true && bwRewardUnlocked("DecaBuild") && getPageSetting('hidebuildings')==true && getPageSetting('BuyBuildingsNew')==0); + + //Coord & Amals + if (upgrade == 'Coordination' && (getPageSetting('BuyUpgradesNew') == 2 || !canAffordCoordinationTrimps())) continue; + if (upgrade == 'Coordination' && getPageSetting('amalcoord')==true && getPageSetting('amalcoordhd') > 0 && calcHDratio() < getPageSetting('amalcoordhd') && ((getPageSetting('amalcoordt') < 0 && (game.global.world < getPageSetting('amalcoordz') || getPageSetting('amalcoordz') < 0)) || (getPageSetting('amalcoordt') > 0 && getPageSetting('amalcoordt') > game.jobs.Amalgamator.owned && (game.resources.trimps.realMax() / game.resources.trimps.getCurrentSend()) > 2000))) continue; + + //WS + if ( + upgrade == 'Coordination' && getEmpowerment() == "Wind" && + ( + (getPageSetting('AutoStance') == 3 && game.global.challengeActive != "Daily" && getPageSetting('WindStackingMin') > 0 && game.global.world >= getPageSetting('WindStackingMin') && calcHDratio() < 5) || + (getPageSetting('use3daily') == true && game.global.challengeActive == "Daily" && getPageSetting('dWindStackingMin') > 0 && game.global.world >= getPageSetting('dWindStackingMin') && calcHDratio() < 5) + ) + ) continue; + + if ( + upgrade == 'Coordination' && + ( + (getPageSetting('AutoStance') == 3 && game.global.challengeActive != "Daily" && getPageSetting('wsmax') > 0 && getPageSetting('wsmaxhd') > 0 && game.global.world >= getPageSetting('wsmax') && calcHDratio() < getPageSetting('wsmaxhd')) || + (getPageSetting('use3daily') == true && game.global.challengeActive == "Daily" && getPageSetting('dwsmax') > 0 && getPageSetting('dwsmaxhd') > 0 && game.global.world >= getPageSetting('dwsmax') && calcHDratio() < getPageSetting('dwsmaxhd')) + ) + ) continue; + + //Gigastations + if (upgrade == 'Gigastation' && !fuckbuildinggiga) { + if (getPageSetting("AutoGigas") && game.upgrades.Gigastation.done == 0 && !firstGiga()) continue; + else if (game.buildings.Warpstation.owned < (Math.floor(game.upgrades.Gigastation.done * getPageSetting('DeltaGigastation')) + getPageSetting('FirstGigastation'))) continue; + } + + //Other if (upgrade == 'Shieldblock' && !getPageSetting('BuyShieldblock')) continue; - if (upgrade == 'Gigastation' && (game.global.lastWarp ? game.buildings.Warpstation.owned < (Math.floor(game.upgrades.Gigastation.done * getPageSetting('DeltaGigastation')) + getPageSetting('FirstGigastation')) : game.buildings.Warpstation.owned < getPageSetting('FirstGigastation'))) continue; - //skip bloodlust during scientist challenges and while we have autofight enabled. + if (upgrade == 'Gigastation' && !fuckbuildinggiga && (game.global.lastWarp ? game.buildings.Warpstation.owned < (Math.floor(game.upgrades.Gigastation.done * getPageSetting('DeltaGigastation')) + getPageSetting('FirstGigastation')) : game.buildings.Warpstation.owned < getPageSetting('FirstGigastation'))) continue; if (upgrade == 'Bloodlust' && game.global.challengeActive == 'Scientist' && getPageSetting('BetterAutoFight')) continue; - //skip potency when autoBreedTimer is disabled - if (upgrade == 'Potency' && getPageSetting('GeneticistTimer') >= 0) continue; - //Main logics: if (!available) continue; if (game.upgrades.Scientists.done < game.upgrades.Scientists.allowed && upgrade != 'Scientists') continue; buyUpgrade(upgrade, true, true); debug('Upgraded ' + upgrade, "upgrades", "*upload2"); - //loop again. + } +} + +//Radon + +var RupgradeList = ['Miners', 'Scientists', 'Coordination', 'Speedminer', 'Speedlumber', 'Speedfarming', 'Speedscience', 'Speedexplorer', 'Megaminer', 'Megalumber', 'Megafarming', 'Megascience', 'Efficiency', 'Explorers', 'Battle', 'Bloodlust', 'Bounty', 'Egg', 'Rage', 'Prismatic', 'Prismalicious', 'Formations', 'Dominance', 'UberHut', 'UberHouse', 'UberMansion', 'UberHotel', 'UberResort', 'Trapstorm', 'Potency']; + +function RbuyUpgrades() { + + for (var upgrade in RupgradeList) { + upgrade = RupgradeList[upgrade]; + var gameUpgrade = game.upgrades[upgrade]; + var available = (gameUpgrade.allowed > gameUpgrade.done && canAffordTwoLevel(gameUpgrade)); + + //Coord + if (upgrade == 'Coordination' && (getPageSetting('RBuyUpgradesNew') == 2 || !canAffordCoordinationTrimps())) continue; + + //Hypo + if (upgrade == 'Supershield' && !Rhyposhouldwood) continue; + + //Other + if (!available) continue; + if (game.upgrades.Scientists.done < game.upgrades.Scientists.allowed && upgrade != 'Scientists') continue; + buyUpgrade(upgrade, true, true); + debug('Upgraded ' + upgrade, "upgrades", "*upload2"); + } +} + +function RautoGoldenUpgradesAT(setting) { + var num = getAvailableGoldenUpgrades(); + var setting2; + if (num == 0) return; + if (setting == "Radon") + setting2 = "Helium"; + if ((!game.global.dailyChallenge.seed && !game.global.runningChallengeSquared && autoTrimpSettings.RAutoGoldenUpgrades.selected == "Radon" && getPageSetting('Rradonbattle') > 0 && game.goldenUpgrades.Helium.purchasedAt.length >= getPageSetting('Rradonbattle')) || (game.global.dailyChallenge.seed && autoTrimpSettings.RdAutoGoldenUpgrades.selected == "Radon" && getPageSetting('Rdradonbattle') > 0 && game.goldenUpgrades.Helium.purchasedAt.length >= getPageSetting('Rdradonbattle'))) + setting2 = "Battle"; + if (setting == "Battle") + setting2 = "Battle"; + if ((!game.global.dailyChallenge.seed && !game.global.runningChallengeSquared && autoTrimpSettings.RAutoGoldenUpgrades.selected == "Battle" && getPageSetting('Rbattleradon') > 0 && game.goldenUpgrades.Battle.purchasedAt.length >= getPageSetting('Rbattleradon')) || (game.global.dailyChallenge.seed && autoTrimpSettings.RdAutoGoldenUpgrades.selected == "Battle" && getPageSetting('Rdbattleradon') > 0 && game.goldenUpgrades.Battle.purchasedAt.length >= getPageSetting('Rdbattleradon'))) + setting2 = "Helium"; + if (setting == "Void" || setting == "Void + Battle") + setting2 = "Void"; + if (game.global.challengeActive == "Mayhem" || game.global.challengeActive == "Pandemonium" || game.global.challengeActive == "Desolation") { + setting2 = "Battle"; + } + var success = buyGoldenUpgrade(setting2); + if (!success && setting2 == "Void") { + num = getAvailableGoldenUpgrades(); + if (num == 0) return; + if ((autoTrimpSettings.RAutoGoldenUpgrades.selected == "Void" && !game.global.dailyChallenge.seed && !game.global.runningChallengeSquared) || (autoTrimpSettings.RdAutoGoldenUpgrades.selected == "Void" && game.global.dailyChallenge.seed)) + setting2 = "Helium"; + if (((autoTrimpSettings.RAutoGoldenUpgrades.selected == "Void" && getPageSetting('Rvoidheliumbattle') > 0 && game.global.world >= getPageSetting('Rvoidheliumbattle')) || (autoTrimpSettings.RdAutoGoldenUpgrades.selected == "Void" && getPageSetting('Rdvoidheliumbattle') > 0 && game.global.world >= getPageSetting('Rdvoidheliumbattle'))) || ((autoTrimpSettings.RAutoGoldenUpgrades.selected == "Void + Battle" && !game.global.dailyChallenge.seed && !game.global.runningChallengeSquared) || (autoTrimpSettings.RdAutoGoldenUpgrades.selected == "Void + Battle" && game.global.dailyChallenge.seed) || (autoTrimpSettings.RcAutoGoldenUpgrades.selected == "Void + Battle" && game.global.runningChallengeSquared))) + setting2 = "Battle"; + buyGoldenUpgrade(setting2); } } diff --git a/modules/utils.js b/modules/utils.js index e7e392417..6dce56214 100644 --- a/modules/utils.js +++ b/modules/utils.js @@ -1,9 +1,3 @@ -//MODULES["utils"] = {}; -//////////////////////////////////////// -//Utility Functions///////////////////// -//////////////////////////////////////// - -//polyfill for includes function if (!String.prototype.includes) { String.prototype.includes = function(search, start) { 'use strict'; @@ -18,79 +12,15 @@ if (!String.prototype.includes) { }; } -//Loads the automation settings from browser cache function loadPageVariables() { var tmp = JSON.parse(localStorage.getItem('autoTrimpSettings')); - if (tmp !== null) { - debug('ATsettings: Checking version...'); - if (tmp['ATversion'] != undefined && !versionIsOlder(tmp['ATversion'], ATversion)) autoTrimpSettings = tmp; - else { debug("ATsettings: Old version. There was a format change."); updateOldSettings(tmp);}; - } -} - -//Safe Set a single generic item into localstorage ( -function safeSetItems(name,data) { - try { - localStorage.setItem(name, data); - } catch(e) { - if (e.code == 22) { - // Storage full, maybe notify user or do some clean-up - debug("Error: LocalStorage is full, or error. Attempt to delete some portals from your graph or restart browser."); - } - } -} - -//returns true if old is older than testcase -function versionIsOlder(old, testcase) { - var oldVer = parseVersion(old); - var testVer = parseVersion(testcase); - - if (oldVer.length == 0) return true; - //compare major to minor numbers, if older it's older, if newer it's not - for (var i=0; i < oldVer.length; i++) { - if (oldVer[i] < testVer[i]) return true; - else if ( oldVer[i] > testVer[i]) return false; + if (tmp !== null && tmp['ATversion'] != undefined) { + autoTrimpSettings = tmp; } - if (oldVer.length < testVer.length) return true; //assume added numbers mean a newer subversioning scheme - return false; -} - -//takes a version string, returns an array -function parseVersion(version) { - if (version == null || version === undefined || typeof(version) != "string") return {}; //invalid = older or corrupt - version = version.split("-", 1); //anything after the dash doesn't matter - return version[0].split("."); } -function updateOldSettings(oldSettings) { - var oldVer = oldSettings['ATversion']; - debug("ATsettings: Updating v" + oldVer + " to v" + ATversion); - if (versionIsOlder(oldVer, '2.1.6.9')) { - debug("ATsettings: Migrating AutoMaps + RunUniqueMaps to new AutoMaps."); - //migrate AutoMaps + RunUniqueMaps to new AutoMaps - var am = (oldSettings['AutoMaps']); - oldSettings['AutoMaps'] = am ? 1 : 0; - if (!oldSettings['RunUniqueMaps']) - oldSettings['AutoMaps']++; - delete oldSettings['RunUniqueMaps']; - } - /* - if (versionIsOlder(oldVer, '2.1.7.0')) { - debug("ATsettings: Migrating X + Y to new Z."); - //migrate X + Y to new Z - var am = (oldSettings['X']); - oldSettings['X'] = am ? 1 : 0; - if (!oldSettings['Y']) - oldSettings['X']++; - delete oldSettings['Y']; - } - */ +function safeSetItems(a,b){try{localStorage.setItem(a,b)}catch(c){22==c.code&&debug("Error: LocalStorage is full, or error. Attempt to delete some portals from your graph or restart browser.")}} - autoTrimpSettings = oldSettings; -} - -//The Overall Export function to output an autoTrimpSettings file. -//Serializes automation settings, remove long descriptions in autoTrimpSettings and only keep valid data. function serializeSettings() { return JSON.stringify(Object.keys(autoTrimpSettings).reduce((v, k) => { const el = autoTrimpSettings[k]; @@ -98,65 +28,68 @@ function serializeSettings() { case 'boolean': return v[k] = el.enabled, v; case 'value': + case 'multiValue': + case 'textValue': case 'valueNegative': case 'multitoggle': return v[k] = el.value, v; case 'dropdown': return v[k] = el.selected, v; } - return v[k] = el, v; // ATversion, anything else unhandled by SettingsGUI + return v[k] = el, v; }, {})); } -//Saves autoTrimpSettings to browser cache -function saveSettings() { - safeSetItems('autoTrimpSettings', serializeSettings()); +function serializeSettings60() { + return '{"ManualGather2":1,"ATversion":"2.1.6.9b-genbtc-4-2-2018 + KFrowde + Zeker0","BuyUpgrades":true,"TrapTrimps":true,"ManageBreedtimer":false,"UsePatience":true,"GeneticistTimer":-1,"SpireBreedTimer":60,"AutoAllocatePerks":0,"AutoStartDaily":false,"AutoFinishDaily":false,"AutoFinishDailyZone":-30,"FinishC2":-1,"AutoEggs":true,"ManualCoords":2,"AutoPortal":"Off","HeliumHourChallenge":"None","CustomAutoPortal":999,"HeHrDontPortalBefore":496,"HeliumHrBuffer":1,"PauseScript":false,"BuyStorage":true,"BuyBuildings":true,"WarpstationCap":true,"WarpstationCoordBuy":true,"MaxHut":100,"MaxHouse":100,"MaxMansion":100,"MaxHotel":100,"MaxResort":100,"MaxGateway":50,"MaxWormhole":"0","MaxCollector":-1,"MaxGym":"-1","MaxTribute":"-1","GymWall":-1,"FirstGigastation":10,"DeltaGigastation":2,"WarpstationWall3":1,"MaxNursery":-1,"NoNurseriesUntil":-1,"PreSpireNurseries":-1,"BuyJobs":true,"WorkerRatios":true,"AutoMagmamancers":true,"FarmerRatio":1,"LumberjackRatio":11,"MinerRatio":12,"MaxScientists":-1,"MaxExplorers":"-1","MaxTrainers":"-1","TrainerCaptoTributes":10,"BreedFire":false,"BuyArmor":true,"BuyArmorUpgrades":true,"BuyWeapons":true,"BuyWeaponUpgrades":true,"CapEquip2":15,"DynamicPrestige2":-1,"Prestige":"Dagadder","PrestigeBackup":{"selected":"Dagadder","id":"PrestigeBackup","name":"PrestigeBackup"},"ForcePresZ":-1,"PrestigeSkipMode":false,"PrestigeSkip2":false,"DelayArmorWhenNeeded":false,"BuyShieldblock":true,"AutoMaps":1,"DynamicSiphonology":true,"PreferMetal":false,"MaxMapBonusAfterZone":-1,"DisableFarm":16,"LowerFarmingZone":true,"MaxStacksForSpire":true,"MinutestoFarmBeforeSpire":0,"IgnoreSpiresUntil":0,"RunBionicBeforeSpire":false,"ExitSpireCell":-1,"CorruptionCalc":true,"FarmWhenNomStacks7":true,"VoidMaps":-1,"RunNewVoids":true,"RunNewVoidsUntil":-1,"VoidCheck":6,"MaxTox":false,"TrimpleZ":0,"AdvMapSpecialModifier":false,"BetterAutoFight":2,"AutoStance":1,"IgnoreCrits":0,"PowerSaving":0,"ForceAbandon":true,"DynamicGyms":true,"AutoRoboTrimp":60,"UseScryerStance":true,"ScryerUseWhenOverkill":true,"ScryerMinZone":181,"ScryerMaxZone":-1,"ScryerUseinMaps2":0,"ScryerUseinVoidMaps2":0,"ScryerUseinSpire2":0,"ScryerSkipBoss2":0,"ScryerSkipCorrupteds2":2,"ScryerDieToUseS":false,"ScryerDieZ":181,"UseAutoGen":true,"AutoGen2":1,"AutoGen2End":400,"AutoGen2SupplyEnd":true,"AutoGen3":0,"AutoGenDC":1,"AutoGenC2":1,"AutoGen2Override":1,"AutoMagmiteSpender2":1,"SupplyWall":2.4,"OneTimeOnly":false,"BuyOvclock":false,"AutoHeirlooms":true,"AutoHeirlooms2":true,"AutoUpgradeHeirlooms":false,"AutoGoldenUpgrades":"Helium","goldStrat":"Max then Helium","goldAlternating":1.5,"goldZone":401,"goldNoBattle":false,"AutoNatureTokens":true,"AutoPoison":"Empowerment","AutoWind":"Empowerment","AutoIce":"Empowerment","EnhanceGrids":false,"SpamGeneral":true,"SpamUpgrades":false,"SpamEquipment":false,"SpamMaps":true,"SpamOther":true,"SpamBuilding":false,"SpamJobs":false,"SpamGraphs":false,"SpamMagmite":true,"SpamPerks":true,"allowSettingsUpload":true,"analyticsID":"b93c4930-760d-4feb-9330-f72041b1d362","BuyUpgradesNew":1,"fastallocate":false,"lootdumpz":-1,"lootdumpa":-1,"AutoFinishDailyNew":1,"BuyBuildingsNew":1,"BuyJobsNew":1,"BuyArmorNew":1,"BuyWeaponsNew":1,"PrestigeSkip1_2":0,"RunNewVoidsUntilNew":-1,"DailyVoidMod":-1,"VoidPraid":false,"Praidingzone":[-1],"BWraid":false,"BWraidingz":[-1],"BWraidingmax":[-1],"WindStackingMin":100,"ScryUseinPoison":-1,"ScryUseinWind":0,"ScryUseinIce":-1,"BuyOneTimeOC":2,"AutoHeirloomsNew":2,"ShowSettings":true,"Raiding":false,"RaidingStartZone":506,"PrestigeRaiding":0,"AutomateAT":true,"DailyVMZone":525,"FillerVMZone":510,"FillerSpireCell":40,"WindStack":true,"WindStackCutOff":60,"Dailyportal":546,"dVoidPraid":true,"dPraidingzone":[-1],"dExitSpireCell":-1,"Dailybwraid":false,"dBWraidingz":[-1],"dBWraidingmax":[-1],"trimpsnotdie":true,"gearamounttobuy":1,"WindStackingMax":195,"buyheliumy":-1,"use3daily":false,"buynojobsc":true,"fightforever":-1,"windcutoff":-1,"spireshitbuy":true,"hardcorewind":-1,"dPraidHarder":false,"dMaxPraidZone":[-1],"dPraidFarmFragsZ":[-1],"dPraidBeforeFarmZ":[-1],"dWindStackingMin":100,"dWindStackingMax":195,"dwindcutoff":-1,"dhardcorewind":-1,"PraidHarder":false,"MaxPraidZone":[-1],"PraidFarmFragsZ":[-1],"PraidBeforeFarmZ":[-1],"fuellater":300,"ScryerSkipHealthy":2,"addpoison":false,"amalcoord":false,"dhardcorewindmax":-1,"cfightforever":true,"work":"false","in":"false","progress":"false","hardcorewindmax":"-1","dAutoGoldenUpgrades":"Helium","cAutoGoldenUpgrades":"Battle","dfightforever":2,"fuelend":260,"defaultgen":2,"spendmagmite":2,"spendmagmitesetting":0,"amalcoordhd":0.000025,"amalcoordz":-1,"dultwind":-1,"dultwindcut":-1,"dwindhealthy":"false","darmormagic":3,"carmormagic":1,"CapEquiparm":15,"ultwind":-1,"ultwindcut":"0.00025","windhealthy":false,"onlyminmaxworld":true,"fuckanti":-1,"dscryvoidmaps":false,"scryvoidmaps":false,"dusebstance":false,"AutoPortalDaily":0,"dHeliumHourChallenge":"None","dCustomAutoPortal":560,"dHeHrDontPortalBefore":"999","dHeliumHrBuffer":"0","usebstance":"false","hidebuildings":false,"fuckjobs":false,"amalcoordt":-1,"screwessence":true,"beforegen":2,"c2runnerstart":false,"c2runnerportal":"999","mapc2hd":6,"buywepsvoid":true,"ScryerUseinBW":0,"dwindcutoffmap":-1,"windcutoffmap":-1}'; +} +function serializeSettings550() { + return '{"ManualGather2":2,"ATversion":"2.1.6.9b-genbtc-4-2-2018 + KFrowde + Zeker0","BetterAutoFight":3,"AutoStance":2,"BuyStorage":true,"BuyBuildings":true,"BuyUpgrades":true,"BuyJobs":true,"TrapTrimps":false,"AutoHeirlooms":true,"HireScientists":true,"WorkerRatios":false,"ManageBreedtimer":false,"AutoPortal":"Custom","HeliumHourChallenge":"Corrupted","CustomAutoPortal":560,"HeHrDontPortalBefore":496,"HeliumHrBuffer":3,"AutoFinishDaily":true,"AutoFinishDailyZone":0,"AutoStartDaily":true,"PauseScript":false,"BuyArmor":true,"BuyArmorUpgrades":true,"BuyWeapons":true,"BuyWeaponUpgrades":true,"BuyShieldblock":false,"Prestige":"Dagadder","PrestigeBackup":{"selected":"Dagadder","id":"PrestigeBackup","name":"PrestigeBackup"},"DynamicPrestige2":-1,"PrestigeSkipMode":false,"AlwaysArmorLvl2":true,"WaitTill60":true,"DelayArmorWhenNeeded":false,"CapEquip2":200,"AutoMaps":1,"DynamicSiphonology":true,"LowerFarmingZone":true,"MinutestoFarmBeforeSpire":0,"RunBionicBeforeSpire":false,"ExitSpireCell":-1,"CorruptionCalc":true,"FarmWhenNomStacks7":true,"VoidMaps":555,"RunNewVoids":false,"RunNewVoidsUntil":600,"VoidCheck":1,"MaxTox":false,"DisableFarm":-1,"FarmerRatio":20,"LumberjackRatio":10,"MinerRatio":1000,"MaxScientists":"-1","MaxExplorers":3000,"MaxTrainers":-1,"MaxHut":100,"MaxHouse":0,"MaxMansion":0,"MaxHotel":0,"MaxResort":0,"MaxGateway":0,"MaxWormhole":0,"MaxCollector":0,"FirstGigastation":1,"DeltaGigastation":1,"MaxGym":"-1","MaxTribute":"-1","MaxNursery":-1,"BreedFire":false,"AutoMagmamancers":false,"WarpstationCap":false,"WarpstationWall3":-1,"WarpstationCoordBuy":false,"AutoRoboTrimp":270,"AutoGoldenUpgrades":"Void 60","AutoHeirlooms2":false,"AutoUpgradeHeirlooms":false,"TrainerCaptoTributes":"-1","NoNurseriesUntil":498,"AutoMagmiteSpender2":2,"ForceAbandon":true,"GymWall":-1,"DynamicGyms":true,"AutoAllocatePerks":2,"SpireBreedTimer":-1,"UseScryerStance":false,"ScryerUseWhenOverkill":false,"ScryerMinZone":530,"ScryerMaxZone":-1,"ScryerUseinMaps2":0,"ScryerUseinVoidMaps2":0,"ScryerUseinSpire2":0,"ScryerSkipBoss2":0,"ScryerSkipCorrupteds2":2,"ScryerDieToUseS":true,"SpamGeneral":true,"SpamUpgrades":false,"SpamEquipment":false,"SpamMaps":false,"SpamOther":false,"SpamBuilding":false,"SpamJobs":false,"ManualCoords":false,"TrimpleZ":0,"ScryerDieZ":230.6,"IgnoreCrits":2,"ForcePresZ":-1,"PreferMetal":false,"PreSpireNurseries":7000,"FinishC2":-1,"PowerSaving":0,"PrestigeSkip2":false,"AutoEggs":false,"UseAutoGen":1,"AutoGen2":3,"AutoGen2End":320,"AutoGen2SupplyEnd":false,"AutoGen3":0,"AutoGenDC":1,"AutoGenC2":1,"AutoGen2Override":1,"SupplyWall":1,"OneTimeOnly":false,"BuyOvclock":false,"IgnoreSpiresUntil":500,"goldStrat":"Max then Helium","goldAlternating":2,"goldZone":600,"MaxStacksForSpire":true,"UsePatience":false,"AutoNatureTokens":true,"AutoPoison":"Empowerment","AutoWind":"Convert to Poison","AutoIce":"Convert to Poison","MaxMapBonusAfterZone":-1,"SpamGraphs":false,"allowSettingsUpload":false,"EnhanceGrids":false,"EnableAFK":{"id":"EnableAFK","name":"Enable AFK","description":"Enables CPU and RAM saving AFK-mode","type":"action","value":1},"SpamMagmite":false,"SpamPerks":true,"analyticsID":"7f11701e-adc9-477c-a08d-2b66fe3ec2a2","ChangeLog":{"id":"ChangeLog","name":"Show Changelog","description":"Shows the changelog popup message that AT loads on startup in case you missed it.","type":"action","value":1},"AdvMapSpecialModifier":false,"GeneticistTimer":-1,"goldNoBattle":true,"BuyUpgradesNew":1,"AutoFinishDailyNew":0,"BuyBuildingsNew":0,"BuyJobsNew":0,"BuyArmorNew":1,"BuyWeaponsNew":1,"PrestigeSkip1_2":0,"RunNewVoidsUntilNew":0,"DailyVoidMod":570,"PlusMapVoidToggle":0,"Praidingzone":[495,546,555,561,566,570],"BWraid":false,"BWraidingmin":-1,"BWraidingmax":[640],"lootdumpz":265,"lootdumpa":10000,"WindStackingMin":-1,"ScryUseinPoison":-1,"ScryUseinWind":-1,"ScryUseinIce":-1,"BuyOneTimeOC":2,"AutoHeirloomsNew":2,"ShowSettings":true,"BWraidingz":[597],"fastallocate":true,"VoidPraid":true,"trimpsnotdie":true,"gearamounttobuy":5,"Dailyportal":560,"dVoidPraid":true,"dPraidingzone":[495,510,525,540,555,570],"Dailybwraid":false,"dBWraidingz":[495],"dBWraidingmax":[515],"dExitSpireCell":-1,"WindStackingMax":190,"buyheliumy":-1,"buynojobsc":true,"Trimpicide":true,"fightforever":0,"use3daily":true,"windcutoff":-1,"spireshitbuy":true,"hardcorewind":-1,"PraidHarder":false,"PraidFarmFrags":false,"PraidBeforeFarm":false,"dPraidHarder":false,"dMaxPraidZone":[-1],"dPraidFarmFragsZ":[-1],"dPraidBeforeFarmZ":[-1],"MaxPraidZone":[505,535,545,555,561],"PraidFarmFragsZ":[495],"PraidBeforeFarmZ":[-1],"fuellater":260,"dWindStackingMin":450,"dWindStackingMax":190,"dwindcutoff":160,"dhardcorewind":480,"ScryerSkipHealthy":2,"addpoison":true,"amalcoord":true,"dAutoGoldenUpgrades":"Void 60","cAutoGoldenUpgrades":"Battle","dhardcorewindmax":"-1","cfightforever":true,"work":false,"in":false,"progress":false,"hardcorewindmax":"-1","dfightforever":2,"fuelend":320,"defaultgen":0,"spendmagmite":2,"spendmagmitesetting":1,"ultwind":-1,"ultwindcut":0.05,"CapEquiparm":100,"amalcoordhd":0.0000025,"onlyminmaxworld":false,"amalcoordz":398,"dultwind":"-1","dultwindcut":"0.00025","dwindhealthy":"false","windhealthy":false,"mapcutoff":4,"darmormagic":3,"carmormagic":3,"fuckanti":"-1","dscryvoidmaps":true,"scryvoidmaps":true,"dusebstance":true,"usebstance":true,"AutoPortalDaily":2,"dCustomAutoPortal":575,"dHeHrDontPortalBefore":"999","dHeliumHrBuffer":"0","dHeliumHourChallenge":"Corrupted","hidebuildings":true,"fuckjobs":true,"amalcoordt":6,"screwessence":false,"beforegen":0,"c2runnerstart":false,"c2runnerportal":"999","buywepsvoid":true,"mapc2hd":"-1","ScryerUseinBW":0,"dwindcutoffmap":160,"windcutoffmap":"-1"}'; } -//Grabs the automation settings from the page function getPageSetting(setting) { if (autoTrimpSettings.hasOwnProperty(setting) == false) { return false; } if (autoTrimpSettings[setting].type == 'boolean') { - // debug('found a boolean'); return autoTrimpSettings[setting].enabled; + } else if (autoTrimpSettings[setting].type == 'multiValue') { + return Array.from(autoTrimpSettings[setting].value) + .map(x => parseInt(x)); + } else if (autoTrimpSettings[setting].type == 'textValue') { + return autoTrimpSettings[setting].value; } else if (autoTrimpSettings[setting].type == 'value' || autoTrimpSettings[setting].type == 'valueNegative') { - // debug('found a value'); return parseFloat(autoTrimpSettings[setting].value); } else if (autoTrimpSettings[setting].type == 'multitoggle') { - // debug('found a multitoggle'); return parseInt(autoTrimpSettings[setting].value); } else if (autoTrimpSettings[setting].type == 'dropdown') { - // debug('found a dropdown') return autoTrimpSettings[setting].selected; } } -//programmatically sets the underlying variable of the UI Setting and the appropriate Button CSS style&color function setPageSetting(setting, value) { if (autoTrimpSettings.hasOwnProperty(setting) == false) { return false; } if (autoTrimpSettings[setting].type == 'boolean') { - // debug('found a boolean'); autoTrimpSettings[setting].enabled = value; document.getElementById(setting).setAttribute('class', 'noselect settingsBtn settingBtn' + autoTrimpSettings[setting].enabled); } else if (autoTrimpSettings[setting].type == 'value' || autoTrimpSettings[setting].type == 'valueNegative') { - // debug('found a value'); + autoTrimpSettings[setting].value = value; + } else if (autoTrimpSettings[setting].type == 'textValue') { + autoTrimpSettings[setting].value = value; + } else if (autoTrimpSettings[setting].type == 'multiValue' || autoTrimpSettings[setting].type == 'valueNegative') { autoTrimpSettings[setting].value = value; } else if (autoTrimpSettings[setting].type == 'multitoggle') { - // debug('found a value'); autoTrimpSettings[setting].value = value; document.getElementById(setting).setAttribute('class', 'noselect settingsBtn settingBtn' + autoTrimpSettings[setting].value); } else if (autoTrimpSettings[setting].type == 'dropdown') { - // debug('found a dropdown'); autoTrimpSettings[setting].selected = value; } } -//Global debug message -//type: general, upgrades, equips, buildings, jobs, maps, other, graphs +function saveSettings(){safeSetItems('autoTrimpSettings',serializeSettings())} + function debug(message, type, lootIcon) { var general = getPageSetting('SpamGeneral'); var upgrades = getPageSetting('SpamUpgrades'); @@ -210,134 +143,17 @@ function debug(message, type, lootIcon) { } } -//Simply returns a formatted text timestamp -function timeStamp() { - var now = new Date(); - - // Create an array with the current hour, minute and second - var time = [now.getHours(), now.getMinutes(), now.getSeconds()]; - - // If seconds and minutes are less than 10, add a zero - for (var i = 1; i < 3; i++) { - if (time[i] < 10) { - time[i] = "0" + time[i]; - } - } - return time.join(":"); -} - -//Called before buying things that can be purchased in bulk -function preBuy() { - preBuyAmt = game.global.buyAmt; - preBuyFiring = game.global.firing; - preBuyTooltip = game.global.lockTooltip; - preBuymaxSplit = game.global.maxSplit; -} - -//Called after buying things that can be purchased in bulk -function postBuy() { - game.global.buyAmt = preBuyAmt; - game.global.firing = preBuyFiring; - game.global.lockTooltip = preBuyTooltip; - game.global.maxSplit = preBuymaxSplit; -} -//#2 Called before buying things that can be purchased in bulk -function preBuy2() { - return [game.global.buyAmt,game.global.firing,game.global.lockTooltip,game.global.maxSplit]; -} - -//#2 Called after buying things that can be purchased in bulk -function postBuy2(old) { - game.global.buyAmt = old[0]; - game.global.firing = old[1]; - game.global.lockTooltip = old[2]; - game.global.maxSplit = old[3]; -} - -function setTitle() { - if (aWholeNewWorld) - document.title = '(' + game.global.world + ')' + ' Trimps ' + document.getElementById('versionNumber').innerHTML; -} - -//we copied message function because this was not able to be called from function debug() without getting a weird scope? related "cannot find function" error. +function timeStamp(){for(var a=new Date,b=[a.getHours(),a.getMinutes(),a.getSeconds()],c=1;3>c;c++)10>b[c]&&(b[c]="0"+b[c]);return b.join(":")} +function preBuy(){preBuyAmt=game.global.buyAmt,preBuyFiring=game.global.firing,preBuyTooltip=game.global.lockTooltip,preBuymaxSplit=game.global.maxSplit} +function postBuy(){game.global.buyAmt=preBuyAmt,game.global.firing=preBuyFiring,game.global.lockTooltip=preBuyTooltip,game.global.maxSplit=preBuymaxSplit} +function preBuy2(){return[game.global.buyAmt,game.global.firing,game.global.lockTooltip,game.global.maxSplit]} +function postBuy2(a){game.global.buyAmt=a[0],game.global.firing=a[1],game.global.lockTooltip=a[2],game.global.maxSplit=a[3]} +function setTitle(){aWholeNewWorld&&(document.title='('+game.global.world+') Trimps '+document.getElementById('versionNumber').innerHTML)} var lastmessagecount = 1; -function message2(messageString, type, lootIcon, extraClass) { - var log = document.getElementById("log"); - var needsScroll = ((log.scrollTop + 10) > (log.scrollHeight - log.clientHeight)); - var displayType = (ATmessageLogTabVisible) ? "block" : "none"; - var prefix = ""; - if (lootIcon && lootIcon.charAt(0) == "*") { - lootIcon = lootIcon.replace("*", ""); - prefix = "icomoon icon-"; - } - else prefix = "glyphicon glyphicon-"; - //add timestamp - if (game.options.menu.timestamps.enabled){ - messageString = ((game.options.menu.timestamps.enabled == 1) ? getCurrentTime() : updatePortalTimer(true)) + " " + messageString; - } - //add a suitable icon for "AutoTrimps" - if (lootIcon) - messageString = " " + messageString; - messageString = " " + messageString; - messageString = "" + messageString; +function message2(a,b,c,d){var e=document.getElementById("log"),f=e.scrollTop+10>e.scrollHeight-e.clientHeight,g=ATmessageLogTabVisible?"block":"none",h="";c&&"*"==c.charAt(0)?(c=c.replace("*",""),h="icomoon icon-"):h="glyphicon glyphicon-",game.options.menu.timestamps.enabled&&(a=(1==game.options.menu.timestamps.enabled?getCurrentTime():updatePortalTimer(!0))+" "+a),c&&(a=" "+a),a=" "+a,a=""+a;var i=""+a+"",j=document.getElementsByClassName(b+"Message");if(1" + messageString + ""; - var toChange = document.getElementsByClassName(type + "Message"); - if (toChange.length > 1 && toChange[toChange.length-1].innerHTML.indexOf(messageString) > -1){ - var msgToChange = toChange[toChange.length-1].innerHTML; - lastmessagecount++; - //search string backwards for the occurrence of " x" (meaning x21 etc) - var foundXat = msgToChange.lastIndexOf(" x"); - if (foundXat != -1){ - toChange[toChange.length-1].innerHTML = msgToChange.slice(0, foundXat); //and slice it out. - } - //so we can add a new number in. - toChange[toChange.length-1].innerHTML += " x" + lastmessagecount; - } - else { - lastmessagecount =1; - log.innerHTML += add; - } - if (needsScroll) log.scrollTop = log.scrollHeight; - trimMessages(type); -} - -//HTML For adding a 5th tab to the message window -// -var ATbutton = document.createElement("button"); -ATbutton.innerHTML = 'AutoTrimps'; -ATbutton.setAttribute('id', 'AutoTrimpsFilter'); -ATbutton.setAttribute('type', 'button'); -ATbutton.setAttribute('onclick', "filterMessage2('AutoTrimps')"); -ATbutton.setAttribute('class', "btn btn-success logFlt"); -// -var tab = document.createElement("DIV"); -tab.setAttribute('class', 'btn-group'); -tab.setAttribute('role', 'group'); -tab.appendChild(ATbutton); -document.getElementById('logBtnGroup').appendChild(tab); -//Toggle settings button & filter messages accordingly. -function filterMessage2(what){ - var log = document.getElementById("log"); - - displayed = (ATmessageLogTabVisible) ? false : true; - ATmessageLogTabVisible = displayed; - - var toChange = document.getElementsByClassName(what + "Message"); - var btnText = (displayed) ? what : what + " off"; - var btnElem = document.getElementById(what + "Filter"); - btnElem.innerHTML = btnText; - btnElem.className = ""; - btnElem.className = getTabClass(displayed); - displayed = (displayed) ? "block" : "none"; - for (var x = 0; x < toChange.length; x++){ - toChange[x].style.display = displayed; - } - log.scrollTop = log.scrollHeight; -} - - //Replacement function for "World Info" tooltip to show current amount in seconds (Just adds the seconds) - //Overwrites game function. function formatMinutesForDescriptions(number){ var text; var seconds = Math.floor((number*60) % 60); @@ -356,30 +172,8 @@ function formatMinutesForDescriptions(number){ var ss = (seconds > 1) ? "s" : ""; text = hours + " hour" + hs + " " + minutes + " minute" + ms + " " + seconds + " second" + ss; } - //text += '
AutoTrimps: Click anywhere in this World Info box to Go AFK!'; return text; } -//Log all javascript errors and catch them. -window.onerror = function catchErrors(msg, url, lineNo, columnNo, error) { - var message = [ - 'Message: ' + msg, - 'URL: ' + url, - 'Line: ' + lineNo, - 'Column: ' + columnNo, - 'Error object: ' + JSON.stringify(error) - ].join(' - '); - if (lineNo !=0) - console.log("AT logged error: " + message); - //ATServer.Upload(message); -}; -/* -window.addEventListener('error', function(event) { - var message = JSON.stringify(event); - console.log("logged error: " + message); - //ATServer.Upload(message); -}); -*/ -function throwErrorfromModule() { - throw new Error("We have successfully read the thrown error message out of a module"); -} +window.onerror=function(b,c,d,e,f){var g=['Message: '+b,'URL: '+c,'Line: '+d,'Column: '+e,'Error object: '+JSON.stringify(f)].join(' - ');0!=d&&console.log('AT logged error: '+g)}; +function throwErrorfromModule(){throw new Error("We have successfully read the thrown error message out of a module")} diff --git a/params.json b/params.json deleted file mode 100644 index aa9b8b8ac..000000000 --- a/params.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "Autotrimps", - "tagline": "Automation for the idle incremental game 'Trimps'", - "body": "### Welcome to GitHub Pages.\r\nThis automatic page generator is the easiest way to create beautiful pages for all of your projects. Author your page content here [using GitHub Flavored Markdown](https://guides.github.com/features/mastering-markdown/), select a template crafted by a designer, and publish. After your page is generated, you can check out the new `gh-pages` branch locally. If you’re using GitHub Desktop, simply sync your repository and you’ll see the new branch.\r\n\r\n### Designer Templates\r\nWe’ve crafted some handsome templates for you to use. Go ahead and click 'Continue to layouts' to browse through them. You can easily go back to edit your page before publishing. After publishing your page, you can revisit the page generator and switch to another theme. Your Page content will be preserved.\r\n\r\n### Creating pages manually\r\nIf you prefer to not use the automatic generator, push a branch named `gh-pages` to your repository to create a page manually. In addition to supporting regular HTML content, GitHub Pages support Jekyll, a simple, blog aware static site generator. Jekyll makes it easy to create site-wide headers and footers without having to copy them across every page. It also offers intelligent blog support and other advanced templating features.\r\n\r\n### Authors and Contributors\r\nYou can @mention a GitHub username to generate a link to their profile. The resulting `` element will link to the contributor’s GitHub Profile. For example: In 2007, Chris Wanstrath (@defunkt), PJ Hyett (@pjhyett), and Tom Preston-Werner (@mojombo) founded GitHub.\r\n\r\n### Support or Contact\r\nHaving trouble with Pages? Check out our [documentation](https://help.github.com/pages) or [contact support](https://github.com/contact) and we’ll help you sort it out.\r\n", - "note": "Don't delete this file! It's used internally to help with page regeneration." -} \ No newline at end of file diff --git a/sparecode/HiderTrimp.js b/sparecode/HiderTrimp.js deleted file mode 100644 index 348c3df11..000000000 --- a/sparecode/HiderTrimp.js +++ /dev/null @@ -1,208 +0,0 @@ - -//original globals -var buildcounter = 0; -var autoTSettings = {}; -var version = "0.37b.17T2"; - -//setup talk button -document.getElementById("buildingsQueue").style = "width: 70%; float: left;"; -document.getElementById("queueContainer").insertAdjacentHTML('beforeend', '

'); -letMeTalk = document.getElementById("talkingBtn"); -letMeTalk.setAttribute("onmouseover", 'tooltip(\"Talk\", \"customText\", event, \"It knows a lot about how Trimps works.\")'); -letMeTalk.setAttribute("onmouseout", 'tooltip("hide")'); -//setup talk window -document.getElementById("boneWrapper").insertAdjacentHTML('beforebegin', ''); -document.getElementById("autotrimp").insertAdjacentHTML('beforeend', ''); - -//setup paint button -document.getElementById("queueContainer").insertAdjacentHTML('beforeend', '
Paint
'); -letMePaint = document.getElementById("paintingBtn"); -letMePaint.setAttribute("onmouseover", 'tooltip(\"Paint\", \"customText\", event, \"It can paint things.\")'); -letMePaint.setAttribute("onmouseout", 'tooltip("hide")'); -//setup paint window -document.getElementById("queueContainer").insertAdjacentHTML('beforebegin', ''); -//HiderTryThatFailed//document.getElementById("boneWrapper").insertAdjacentHTML('beforebegin', ''); -//beforebegin //afterbegin //beforeend //afterend - -function getNiceThingsDone() { - var zp = document.getElementById("zonePic").value; - var pp = document.getElementById("prePic").value; - var vp = document.getElementById("voidPic").value; - var mp = document.getElementById("mapPic").value; - var sp = document.getElementById("spirePic").value; - if (zp.length > 5 || pp.length > 5 || vp.length > 5 || mp.length > 5 || sp.length > 5) { - //bring the art. (mp.length > 5) - if (zp.length > 5 && !game.global.preMapsActive && !game.global.mapsActive && !game.global.spireActive) { - document.getElementById("trimps").insertAdjacentHTML('afterend', '
'); - } else if (pp.length > 5 && game.global.preMapsActive) { - document.getElementById("trimps").insertAdjacentHTML('afterend', '
'); - } else if (vp.length > 5 && game.global.mapsActive && getCurrentMapObject().location == "Void") { - document.getElementById("trimps").insertAdjacentHTML('afterend', '
'); - } else if (mp.length > 5 && game.global.mapsActive && getCurrentMapObject().location != "Void") { - document.getElementById("trimps").insertAdjacentHTML('afterend', '
'); - } else if (sp.length > 5 && game.global.world >= getPageSetting('IgnoreSpiresUntil') && (game.global.world == 200 || game.global.world == 300 || game.global.world == 400 || game.global.world == 500 || game.global.world == 600) && game.global.spireActive) { - document.getElementById("trimps").insertAdjacentHTML('afterend', '
'); - } - if ((sp.length > 5 || zp.length > 5) && game.resources.trimps.soldiers != 0 && !game.global.preMapsActive && !game.global.mapsActive && (new Date().getTime() - game.global.zoneStarted) > 1600 && game.global.gridArray.length != 0) { - var cells = document.getElementById("grid").getElementsByClassName("battleCell cellColorBeaten"); var oldstyle = cells[0].getAttribute('style'); for (var i=0; i < cells.length; i++) cells[i].setAttribute('style', oldstyle + '; background-color: rgba(0,0,0,0.3);'); - } - if ((mp.length > 5 || vp.length > 5) && game.resources.trimps.soldiers != 0 && game.global.mapsActive && (new Date().getTime() - game.global.mapStarted) > 1600 && game.global.mapGridArray.length != 0) { - var cells = document.getElementById("mapGrid").getElementsByClassName("battleCell cellColorBeaten"); var oldstyle = cells[0].getAttribute('style'); for (var i=0; i < cells.length; i++) cells[i].setAttribute('style', oldstyle + '; background-color: rgba(0,0,0,0.3);'); - } - } - //bring the light. - var BR0 = document.getElementById("BR").value*1; - var BG0 = document.getElementById("BG").value*1; - var BB0 = document.getElementById("BB").value*1; - var CR0 = document.getElementById("CR").value*1; - var CG0 = document.getElementById("CG").value*1; - var CB0 = document.getElementById("CB").value*1; - if ((BR0 > 0 && BG0 > 0 && BB0 > 0) || (CR0 > 0 && CG0 > 0 && CB0 > 0)) { - var colB = "background: rgb("+BR0+"," +BG0+","+ BB0+");"; - var colC = "background: rgb("+CR0+"," +CG0+","+ CB0+");"; - //document.getElementById("innerWrapper").style = "background: rgb(BR, BG, BB);"; - document.getElementById("innerWrapper").style = colB; - document.getElementById("battleContainer").style = colC; - document.getElementById("gridContainer").style = colC; - document.getElementById("science").style = colC; - document.getElementById("selectedMapContainer").style = colC; - document.getElementById("helium").style = colC; - document.getElementById("achievementWrapper").style = colC; - document.getElementById("buyContainer").style = colC; - document.getElementById("logContainer").style = colC; - document.getElementById("queueContainer").style = colC; - document.getElementById("wood").style = colC; - document.getElementById("fragments").style = colC; - document.getElementById("heirloomWrapper").style = colC; - document.getElementById("food").style = colC; - document.getElementById("metal").style = colC; - document.getElementById("gems").style = colC; - document.getElementById("trimps").style = colC; - } -} - -//setup options -function createInputSetting(pic,div) { - var picInput = document.createElement("Input"); - picInput.id = pic + "URL"; - picInput.setAttribute('style', 'text-align: center; width: 60px; color: black;'); - picInput.setAttribute('class', 'picInput'); - var perk1label = document.createElement("Label"); - picLable.id = pic + 'Label'; - picLable.innerHTML = pic; - picLable.setAttribute('style', 'margin-right: 1vw; width: 120px; color: white;'); - //add to the div. - div.appendChild(picInput); - div.appendChild(picLable); -} - -//Add new css rule -//document.styleSheets[2].insertRule(".settingBtn3 {background-color: #337AB7;}", 84); - -var getPercent = 0; -var reactPercent = 0; -function getStats() { - reactPercent = 0; - getPercent = (game.stats.heliumHour.value() / (game.global.totalHeliumEarned - (game.global.heliumLeftover + game.resources.helium.owned)))*100; - if (getPercent.toFixed(3) > 0.54) { - reactPercent = " An amazing result, share it with others, they will appriciate it."; - } else if (getPercent.toFixed(3) > 0.53) { - reactPercent = " GRATZ, A NEW WORLD RECORD!"; - } else if (getPercent.toFixed(3) > 0.52) { - reactPercent = " Only a few ever got this far."; - } else if (getPercent.toFixed(3) > 0.50) { - reactPercent = " it's not shameful to give up."; - } else if (getPercent.toFixed(3) > 0.40) { - reactPercent = " It's the final push."; - } else if (getPercent.toFixed(3) > 0.30) { - reactPercent = " Keep it comming..."; - } else if (getPercent.toFixed(3) <= 0.30) { - reactPercent = " Did you just portal?"; - } - return getPercent.toFixed(3) + '%'; //return -} - -var getGigaDelta = false; -var reactGigaDelta = false; -function getStats2() { - reactGigaDelta = true; - getGigaDelta = (getPageSetting('FirstGigastation') > 40 || getPageSetting('DeltaGigastation') > 2); - if (getGigaDelta == true) { - reactGigaDelta = "First Gigastation must be under 41 and Min Warpstation must be under two, if you don't know how it works, why don't you click on the chat and ask?"; - } else if (getGigaDelta == false) { - reactGigaDelta = "You know the Truth."; - } - return getGigaDelta; -} - -var getAutoPortal = false; -var reactAutoPortal = false; -function getStats3() { - reactAutoPortal = true; - getAutoPortal = (getPageSetting('HeliumHrBuffer') > 0 || autoTrimpSettings.AutoPortal.selected != "Helium Per Hour"); - if (getAutoPortal == true) { - reactAutoPortal = "The Helium/Hr Buffer must be set to 0 and Auto Portal is there in order to help you get better Helium per hour, if you don't know how it works, why don't you click on the chat and ask?"; - } else if (getAutoPortal == false) { - reactAutoPortal = "You know the Truth."; - } - return getAutoPortal; -} - -//setup convo array -var conversation = []; -conversation[0] = {Q:"Hello.",R1:"Tell me the Truth.",L1:1,R2:"How am i doing so far?",L2:5,R3:"Tell me what to do.",L3:3}; -conversation[1] = {Q:"" +reactGigaDelta,R1:"Be more honest please.",L1:6,R2:"What can go wrong in the Don't Touch Zone?",L2:4,R3:"I know the Truth.",L3:0}; -conversation[2] = {Q:"OK.",R1:"Again.",L1:0,R2:"How am i doing so far?",L2:5,R3:"What can go wrong in the Don't Touch Zone?",L3:4}; -conversation[3] = {Q:"Please set Auto Portal to Helium Per Hour and set First Gigastation to 40 (or less). Make sure that Min Warpstation is set to two (or less). And notice that some of the Void Maps will be done before your Void Maps settings, so please use it and set the Void Maps to no more then 10 Zones before you predict that you will Auto Portal. Have a nice AutoAutoTrimps experience.",R1:"Wow, HelpfulTrimp!",L1:0}; -conversation[4] = {Q:"You.",R1:"Meh.",L1:0}; -conversation[5] = {Q:"Your current Helium per hour gain is " + getStats() + "" +reactPercent,R1:"Cool.",L1:0,R2:"What can go wrong in the Don't Touch Zone?",L2:4,R3:"I know the Truth.",L3:0}; -conversation[6] = {Q:"" +reactAutoPortal,R1:"Please be much more honest.",L1:7,R2:"What can go wrong in the Don't Touch Zone?",L2:4,R3:"I know the Truth.",L3:0}; -conversation[7] = {Q:"I am not a real Trimp.",R1:"I knew the Truth.",L1:0}; -updateConvo(0); - -/* -conversation[0] = {Q:"Hello.",R1:"What?!?!",L1:3,R2:"Oh.",L2:1}; -conversation[1] = {Q:"What do you want to change? Click the buttons below.",R1:"Nothing.",L1:2,R2:"That's it.",L2:2}; -conversation[2] = {Q:"Ok.",R1:"Hello?",L1:0}; -conversation[3] = {Q:"I figured you'd find me eventually. Before you ask...yes, I can talk. No, none of the other trimps seem to be able to.",R1:"What else do you know?",L1:4}; -conversation[4] = {Q:"Not much more than you, unfortunately. Whatever brought you here is also what made me...smarter than the average trimp. Before you got here, I wasn't anymore self-aware than any other trimp.",R1:"What are we doing here?",L1:5}; -conversation[5] = {Q:"I don't know--I don't even know where here is. This is all new to me too.",R1:"Well, what do you suggest we do?",L1:6}; -conversation[6] = {Q:"Keep going. Maybe we'll find some answers. Since we're friends now, I've picked up a few tricks that will help us.",R1:"Like what?",L1:7}; -conversation[7] = {Q:"I can tell the trimps to build storage buildings before they get full. I can also buy Gyms and Tributes as soon as we can afford them, and read some upgrade books to you and the trimps when you're not available.",R1:"Which upgrade books?",L1:8, R2:"What else?", L2:9}; -conversation[8] = {Q:"The upgrades I can read are: Speedfarming, Speedlumber, Speedminer, Speedscience, (all the Mega versions too), Efficiency, TrainTacular, Gymystic, Potency, Egg, UberHut, UberHouse, UberMansion, UberHotel, UberResort, and Bounty",R1:"Ok, cool",L1:9}; -conversation[9] = {Q:"I can also highlight the housing that makes the most use of our gems, and the equipment that makes the best use of our metal.",R1:"Cool, what else?",L1:10}; -conversation[10] = {Q:"I'll bring us back to the world if we idle on the premap screen too long and I'll send you back to science-ing if you stay building on an empty queue. I can also unteach Shieldblock.",R1:"Why unteach Shieldblock?",L1:11, R2:"Anything else?",L2:12}; -conversation[11] = {Q:"As we learn more and more Gymystic, our shields becomes less and less useful for blocking. The extra health comes in real handy post z60.",R1:"I get it.",L1:12}; -conversation[12] = {Q:"I can help you respec the portal perks if you've already done it this round, and I can automatically flip between Dominance and Heap formations depending on the enemy we're facing.",R1:"Ok.",L1:13}; -conversation[13] = {Q:"That's it for now, but I'll let you know if I pick up any more tricks. Use the buttons below to let me know what you'd like done.",R1:"Ok.",L1:2}; -updateConvo(0); -*/ - - -//only functions below here -function updateConvo (place) { - conversation[1] = {Q:"" +reactGigaDelta,R1:"Be more honest please.",L1:6,R2:"What can go wrong in the Don't Touch Zone?",L2:4,R3:"I know the Truth.",L3:0}; - conversation[5] = {Q:"Your current Helium per hour gain is " + getStats() + "" +reactPercent,R1:"Cool.",L1:0,R2:"What can go wrong in the Don't Touch Zone?",L2:4,R3:"I know the Truth.",L3:0}; - conversation[6] = {Q:"" +reactAutoPortal,R1:"Please be much more honest.",L1:7,R2:"What can go wrong in the Don't Touch Zone?",L2:4,R3:"I know the Truth.",L3:0}; - document.getElementById("q").innerHTML = conversation[place].Q; - document.getElementById("1").innerHTML = conversation[place].R1; - document.getElementById("1").onclick = (function() { var test = conversation[place].L1; return function() {updateConvo(test + '');}})(); - if ("R2" in conversation[place]) {document.getElementById("2").innerHTML = conversation[place].R2;} - else {document.getElementById("2").innerHTML = "";} - if ("L2" in conversation[place]) {document.getElementById("2").onclick = (function() { var test = conversation[place].L2; return function() {updateConvo(test + '');}})();} - if ("R3" in conversation[place]) {document.getElementById("3").innerHTML = conversation[place].R3;} - else {document.getElementById("3").innerHTML = "";} - if ("L3" in conversation[place]) {document.getElementById("3").onclick = (function() { var test = conversation[place].L3; return function() {updateConvo(test + '');}})();} -} - -function talk() { - getStats(); - getStats2(); - getStats3(); - document.getElementById("autotrimp").style.display = "block"; -} - -function paint() { - getNiceThingsDone(); - document.getElementById("paintTrimp").style.display = "block"; -} diff --git a/tabs.css b/tabs.css index f409ff489..4b5110706 100644 --- a/tabs.css +++ b/tabs.css @@ -1,92 +1,252 @@ -/*For the autotrimps Top right Story/Loot/Unlocks/Combat/Settings/AutoTrimps Tabs, so they dont overlap*/ -#logBtnGroup div { - width: 19%!important; -} -div#logConfigHolder.btn-group { - width: 5%!important; /* overriding like 3 previous things :/ */ -} -#logConfigBtn { - padding: 6px 0px!important; -} -/*For the SettingsGUI.js settings window*/ - -/* Style the list */ -ul.tab { - list-style-type: none; - margin: 0; - padding: 0; - overflow: hidden; - border: 1px solid #ccc; - background-color: #f1f1f1; -} - -/* Float the list items side by side */ -ul.tab li {float: left;} - -/* Style the links inside the list items */ -ul.tab li a { - display: inline-block; - color: black; - text-align: center; - padding: 0.5vh 1vw; - text-decoration: none; - transition: 0.3s; - font-size: 2vh; -} -/* Create an active/current tablink class */ -ul.tab li a.active {background-color: #ccc;} - -/* Change background color of links on hover */ -ul.tab li a:hover {background-color: #ddd;} - -/* Style the tab content */ -.tabcontent { - display: none; - border: 1px solid #ccc; - border-top: none; - -webkit-animation: fadeEffect 1s; - animation: fadeEffect 1s; /* Fading effect takes 1 second */ - transform: translateZ(0); -} - -@-webkit-keyframes fadeEffect { - from {opacity: 0;} - to {opacity: 1;} -} - -@keyframes fadeEffect { - from {opacity: 0;} - to {opacity: 1;} -} - -#tipText b.AutoEggs, -#AutoEggs.settingBtntrue { - -webkit-animation: eggGradient 3s infinite; - animation: eggGradient 3s infinite; - color: black; -} - -@keyframes eggGradient { - 0% { background-color: #83ddd6; } - 25% { background-color: #f4c7c7; } - 50% { background-color: #8beab7; } - 75% { background-color: #f6f297; } - 100% { background-color: #83ddd6; } -} - -/* stop the additional breed timer we added from pushing down the whole Breeding area and pushing Traps out */ -#trapArea { - border: 1px solid white; - display: inline-block; - margin-bottom: 2%; - margin-top: 0; - padding: 0; -} - -/* stop the Traps building progress from showing through the AT settings screen */ -#animationDiv { - z-index: -1!important; -} -.queueItemName, #queueTimeRemaining { - z-index: 0!important; -} +#logBtnGroup div { + width: 19%!important; +} +div#logConfigHolder.btn-group { + width: 5%!important; +} +#logConfigBtn { + padding: 6px 0!important; +} + +ul.tab { + list-style-type: none; + margin: 0; + padding: 0; + overflow: hidden; + border: 1px solid #ccc; + background-color: #f1f1f1; +} + +ul.tab li {float: left;} + +ul.tab li a { + display: inline-block; + color: black; + text-align: center; + padding: 0.5vh 1vw; + text-decoration: none; + transition: 0.3s; + font-size: 2vh; +} + +ul.tab li .active {background-color: #ccc;} + +ul.tab li a:hover {background-color: #ddd;} + +.tabcontent { + display: none; + border: 1px solid #ccc; + border-top: none; + -webkit-animation: fadeEffect 1s; + animation: fadeEffect 1s; /* Fading effect takes 1 second */ + transform: translateZ(0); +} + +@-webkit-keyframes fadeEffect { + from {opacity: 0;} + to {opacity: 1;} +} + +@keyframes fadeEffect { + from {opacity: 0;} + to {opacity: 1;} +} + +#tipText .AutoEggs, +#AutoEggs.settingBtntrue { + -webkit-animation: eggGradient 3s infinite; + animation: eggGradient 3s infinite; + color: black; +} + +@keyframes eggGradient { + 0% { background-color: #83ddd6; } + 25% { background-color: #f4c7c7; } + 50% { background-color: #8beab7; } + 75% { background-color: #f6f297; } + 100% { background-color: #83ddd6; } +} + +#trapArea { + border: 1px solid white; + display: inline-block; + margin-bottom: 2%; + margin-top: 0; + padding: 0; +} + +#animationDiv { + z-index: -1!important; +} +.queueItemName, #queueTimeRemaining { + z-index: 0!important; +} + +.heirloomRare8 { +text-shadow: none; +} + +.litScroll { + overflow:scroll; + height:500px; +} + +#wrapper { +background: none; +} + +#wrapper { +background: -webkit-linear-gradient(left, #323341 12%,#626368 29.5%,#727275 47%,#727275 53%,#4c4d56 70.5%,#323341 88%); +} + + +.windowRow div input{ + width: 100%; +} + +.windowRow div select{ + width: 100%; +} + +.windowRow{ + padding: 0 2%; + margin: 0 1%; + font-weight: bold; +} + +.windowRow.titles div{ + text-align: center; + font-weight: bold; +} + +.windowRow.titles{ + border: 1px solid black; + margin: 0 1%; + padding: 0.2% 2%; +} + +#windowAddRowBtn, #windowSwapPresetBtn{ + margin-top: 0.5vw; +} + +.windowDelete, .windowWorld, .windowZone, .windowCheckbox, .windowPreset, .windowRepeat, .windowRepeatUntil, .windowExit, .windowBwWorld, .windowCell, .windowMap, .windowTimes, .windowThrough, .windowRx, .windowPrio, .windowTx, .windowLevel, .windowSetting, .windowRepeat, .windowGather, .windowSpecial, .windowTributes, .windowMets, .windowBogs, .windowInsanity, .windowPotionType, .windowPotionNumber, .windowBonfire, .windowBoneDropdown, .windowBoneBelow, .windowBoneAmount, .windowBoneGather, .windowJobRatio { + display: inline-block; +} + +.windowDelete .icomoon{ + position: relative; + top: 0.6vw; + left: -0.55vw; + color: red; + font-weight: bold; + font-size: 2vw; +} + +#windowError{ + font-weight: bold; + color: red; +} + +.windowDelete{ + width: 4%; + cursor: pointer; +} + +.windowJobRatio{ + width: 15%; + cursor: pointer; +} + +.windowWorld, .windowZone, .windowCell, .windowThrough, .windowLevel, .windowRepeat, .windowPotionNumber{ + width: 9%; +} + +.windowTributes, .windowMets, .windowBogs, .windowInsanity, .windowBonfire, .windowMap, .windowSetting{ + width: 16%; +} + +.windowCheckbox{ + width: 4%; +} + +.windowPotionType { + width: 18%; +} +.windowPreset, .windowSpecial{ + width: 16%; +} +.windowGather{ + width: 12%; +} + +.windowRepeat{ + width: 8.5%; +} + +.windowRepeatUntil{ + width: 15%; +} + +.windowExit{ + width: 8%; +} + +.windowTimes{ + width: 17%; +} + +.windowBoneGather { + width: 10%; +} + +.windowBoneDropdown, .windowBoneBelow, .windowBoneAmount { + width: 10%; +} + +.windowBwZoneOn .windowRepeatUntil, .windowGatherOn .windowSpecial{ + width: 16%; +} + +.windowBwZoneOff .windowBwWorld, .windowGatherOff .windowGather{ + display: none; +} + +.windowBwZoneOn .windowBwWorld, .windowGatherOn .windowGather{ + width: 10%; +} + +.windowTxOn .windowTimes{ + width: 11.5% !important; +} + +.windowTxOff .windowTx{ + display: none; +} + +.windowTx{ + width: 5.5%; +} + +.windowBwMainOff .windowRepeatUntil select .windowBwClimbOption{ + display: none; +} + +#tooltipDiv.tooltipWindowLg{ + width: 60%; + overflow-y: scroll; +} +#tooltipDiv.tooltipExtraLg{ + width: 50%; +} + +#tooltipDiv.tooltipExtraSuperLg{ + width: 65%; +} + +#tooltipDiv.tooltipExtraGigantic{ + width: 80%; +} + +#tooltipDiv.tooltipExtraBiggest{ + width: 90%; +} diff --git a/user.js b/user.js deleted file mode 100644 index 46ddf46a3..000000000 --- a/user.js +++ /dev/null @@ -1,26 +0,0 @@ -// ==UserScript== -// @name AutoTrimps-genBTC -// @namespace https://github.com/genbtc/AutoTrimps -// @version 2.1.6.9-genbtc-3-23-2018 -// @updateURL https://github.com/genbtc/AutoTrimps/user.js -// @description Automate all the trimps! -// @author zininzinin, spindrjr, Ishkaru, genBTC -// @include *trimps.github.io* -// @include *kongregate.com/games/GreenSatellite/trimps -// @grant none -// ==/UserScript== - -var script = document.createElement('script'); -script.id = 'AutoTrimps-script'; -//This can be edited to point to your own Github Repository URL. -script.src = 'https://genBTC.github.io/AutoTrimps/AutoTrimps2.js'; -//script.setAttribute('crossorigin',"use-credentials"); -//script.setAttribute('crossorigin',"anonymous"); -document.head.appendChild(script); - -// This File is Deprecated, please use .user.js instead (with the leading dot) so TamperMonkey/Greasemonkey can detect it as a script automatically. -// Other than that they are identical and no change is required on your part if everything is working already. - -//You can use the following to auto-load your own forked repo as a local directory served from a local HTTPS webserver. -//the other bookmarklet wont load locally - the script.id will tell it to pull the rest of modules from the given URL. -//javascript:with(document)(script = createElement('script'), script.src='https://localhost:4443/AutoTrimps2.js', script.id='AutoTrimps-script',head.appendChild(script))._ \ No newline at end of file