NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name Pet Farming enhancement // @namespace https://openuserjs.org/users/Krapotor // @version 1.4 // @description This scripts adds more advanced feature like planning and state export/import to the nice Pet Farming page for the Endless Frontier RPG game available on https://jared-g.github.io/pet-farming/ // @author Krapotor (Hunters), S8 // @match https://jared-g.github.io/pet-farming/ // @grant none // @license LGPL-3.0 // @copyright 2018, Krapotor (https://openuserjs.org/users/Krapotor) // @updateURL https://openuserjs.org/meta/Krapotor/Pet_Farming_enhancement.meta.js // @installURL https://openuserjs.org/install/Krapotor/Pet_Farming_enhancement.user.js // ==/UserScript== // ==OpenUserJS== // @author Krapotor // ==/OpenUserJS== (function() { 'use strict'; // replace the existing function function updateDaysRemaining() { updatePlanning(); for(let i = 0; i < petList.length; ++i) { const pet = petList[i]; const farmString = pet.duration > 0 ? " " + (pet.start > 1 ? pet.start +" + " : "") + pet.duration+" days" : " "; $($(".petinput span").get(i)).html(farmString); } } function getMaxFragmentsPerDay(pet) { var kltest = knightLevel % 2 === 0 ? knightLevel + 1 : knightLevel; //console.log(pet.reqs) return pet.reqs.reduce((acc, req) => { if (req <= kltest) { if(req % 2 === 0) { acc += 1; } else { acc += 3; }} return acc; }, 0); } function updatePlanning() { const petByName = petList.reduce((acc, value) => {acc[value.name] = value; return acc; }, {}); const nbEntriesPerDay = entries + (refills * 5); const dailyUse = []; let missingPetsDueToLowKL = false; for(let name of tierList) { //console.log(name) const pet = petByName[name]; const maxFragsPerDay = getMaxFragmentsPerDay(pet); if (maxFragsPerDay === 0) { // pet not available yet according to current KL level pet.duration = Infinity; pet.start = Infinity; missingPetsDueToLowKL = true; continue; } let remFrags = 330 - pet.fragments; // update frags consumption let startDay = -1; let i = 0; while (remFrags > 0) { if (!dailyUse.hasOwnProperty(i)) { dailyUse[i] = { nb: 0}; } let use = dailyUse[i]; if (use.nb < nbEntriesPerDay) { if (startDay === -1) { startDay = i; } const usedFrags = Math.min(maxFragsPerDay, remFrags, nbEntriesPerDay-use.nb); use.nb += usedFrags; if (!use.hasOwnProperty('pets')) { use.pets = {}; } if (!use.pets.hasOwnProperty(name)) { use.pets[name] = 0; } use.pets[name] += usedFrags; remFrags -= usedFrags; } i++; } if (startDay === -1) { pet.duration = 0; pet.start = -1; } else { pet.duration = i - startDay; pet.start = startDay + 1; } //if (pet.duration > 0) { // console.log(name+": "+pet.duration+" days (start in " + pet.start +" days)") //} } // check { let lastNb = nbEntriesPerDay; for(let use of dailyUse) { if(lastNb < use.nb) { throw 'lastNb: ' + lastNb + " < " + use.nb; } lastNb = use.nb; const total = Object.values(use.pets).reduce((acc, val) => acc + val); if (total !== use.nb) { throw 'total: '+total+ ' != ' + use.nb; } } } // display planning updatePlanningDiv(dailyUse, petByName); updatePlanningSummaryDiv(dailyUse, nbEntriesPerDay, missingPetsDueToLowKL); } function updatePlanningDiv(dailyUse, petByName) { let $planning = $('#planning'); $planning.empty(); for (let i = 0; i < dailyUse.length; ++i) { const use = dailyUse[i]; let str = '<div>Day ' + (i+1) + ': ' + use.nb + ' fragments '; for (let name in use.pets) { str += '<a href="https://www.endlessfrontierdata.com/pets/'+ petByName[name].img +'" style=""><img class="icon-32" src="files/img/' + petByName[name].img + '.png" style="opacity: 1;" alt="'+ name +'" title="'+ name +'"></a>x' + use.pets[name] + ' '; } str += '</div>'; $planning.append(str); } } function updatePlanningSummaryDiv(dailyUse, nbEntriesPerDay, missingPetsDueToLowKL) { let $summary = $('#planning-summary'); $summary.empty(); $summary.text("Duration: " + (dailyUse.length)+ " days"); if (missingPetsDueToLowKL) { $summary.append('<br/><span style="color: red; font-variant: italic;">Planning deosn\'t include all the required pets since they are not avalaible yet. Increase your knight level to be able to farm those pets.</span>'); } let i = dailyUse.length - 2; if (i >= 2 && dailyUse[i-2].nb < nbEntriesPerDay) { $summary.append('<br/><span style="color: red; font-variant: italic;">Planning is likely sub-optimal. You should re-order the pets in the tier list or increase your knight level to farm more fragments of the last pets</span>'); } } function restoreState() { const rawData = $('#rawState').val(); const data = JSON.parse(rawData); Object.keys(data).forEach(k => localStorage.setItem(k, data[k])); // needed since updatePetList reads value from here $("#input-kl").val(data.knightLevel); $("#input-entries").val(data.entries); $("#input-refills").val(data.refills); updatePetList(); } function dumpState() { const state = JSON.stringify(localStorage); $('#rawState').val(state); } //$('#petinputcontainer').parent().children().slice(-2).remove() $('#petinputcontainer').parent().append('<div style="margin-top: 1em; margin-left: 4px; display: inline-block;"><h2>Complete planning</h2></div><div style="margin: 4px; color: #bbb; background: #333; border: 1px solid #555; display: inline-block;"><div id="planning" style="max-height:300px; overflow: auto; padding: 2px;"></div><div id="planning-summary" style="margin-top: 2px; padding: 2px; border-top: 1px solid #555"></div></div><div style="margin: 4px; margin-top: 2em; display: inline-block;"><h2>Use this section to save/restore the state</h2><textarea id="rawState" style="width: auto; min-width: 600px; min-height: 100px;"></textarea><br/><button id="copyState" onclick="dumpState()" style="width: 100px; margin: 2px;">Get state</button><button id="restoreState" onclick="restoreState()" style="width: 100px; margin: 2px;">Restore state</button></div>'); // initialize updateDaysRemaining(); // export global functions window.updateDaysRemaining = updateDaysRemaining; //window.updatePlanning = updatePlanning; window.dumpState = dumpState; window.restoreState = restoreState; })();