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;
})();