// ==UserScript==
// @name IdlePixel Lucky
// @namespace com.missnobody.idlepixel.lucky
// @version 1.0.64
// @description Calculates how lucky you are with your drops.
// @author MissNobody
// @license MIT
// @match *://idle-pixel.com/login/play*
// @grant none
// @require https://gf.qytechs.cn/scripts/441206-idlepixel/code/IdlePixel+.js
// ==/UserScript==
(function()
{
'use strict';
let loaded = false;
let hooked = false;
class LuckyPlugin extends IdlePixelPlusPlugin
{
constructor()
{
super("Lucky",
{
about:
{
name: GM_info.script.name,
version: GM_info.script.version,
author: GM_info.script.author,
description: GM_info.script.description
}
});
}
/*
luckFactor(K, minA, maxA, N, L)
{
K = parseFloat(K);
minA = parseFloat(minA);
maxA = parseFloat(maxA);
N = parseFloat(N);
L = parseFloat(L);
if (L === 0) return -Math.min(1.0*K/N, 1);
if (minA === maxA)
{
let Lavg = K*minA/N;
return (L - Lavg)/Lavg;
}
let Lmin = K*minA/N;
let Lmax = K*maxA/N;
let Lavg = (Lmin + Lmax)/2.0;
// if (L > Lmax) return (L - Lmax)/Lmax + 1.0;
// if (L > Lavg) return (L - Lavg)/(Lmax - Lavg);
let f_num = (a, L, Lavg) => 2.0/(1 + Math.exp(Math.max(-a*(L - Lavg), -100))) - 1;
let eq_num = (a) => f_num(a, Lmax, Lavg) - 1;
let a = 0.1;
let fx = eq_num(a);
let dfx;
let epsilon = 1e-7;
for (let i = 0; i < 100; i++)
{
if (Math.abs(fx) < epsilon) break;
dfx = (eq_num(a + epsilon) - fx) / epsilon; // Numerical derivative
a = a - fx / dfx; // Newton-Raphson update
fx = eq_num(a);
}
return f_num(a, L, Lavg);
}
*/
luckFactor(K, minA, maxA, N, L)
{
K = parseFloat(K);
minA = parseFloat(minA);
maxA = parseFloat(maxA);
N = parseFloat(N);
L = parseFloat(L);
let Lmin = K * minA / N;
let Lavg = K * (minA + maxA) / (2 * N);
let Lmax = K * maxA / N;
if (L === 0)
{
if (K <= N)
{
return 0.0;
} else
{
return -Math.min(Math.log2(K/N), 10);
}
}
if (L === Lmin)
{
return -1.0;
} else if (L === Lmax)
{
return 1.0;
}
let x = (L - Lavg) / Lavg;
let f_num = (a, x) => Math.tanh(a * x);
let eq_num = (a) => f_num(a, 2) - 1;
let a = 1;
let fx = eq_num(a);
let epsilon = 1e-7;
for (let i = 0; i < 100; i++)
{
if (Math.abs(fx) < epsilon) break;
let dfx = (eq_num(a + epsilon) - fx)/epsilon;
if (Math.abs(dfx) > 1e-7) a = a - fx/dfx;
fx = eq_num(a);
}
return Math.max(Math.min(f_num(a, x), 1), -1);
}
updateCombat(calc)
{
try
{
let enemy = $('#modal-monster-lookup-content').find('center').first().text();
let kills = $('#combat-log-body tr:has(td:contains("' + enemy + '")) td:nth-child(4)').text().replace(" Kills", "");
let table = $('.combat-log-table');
let header = table.find('th:contains("Luck")');
let rows = table.find("tr");
let column;
if (header.length <= 0)
{
column = rows.first().children().length;
rows.first().append('<th style="background-color:#DEDEED;padding:10px;text-align:center;">Luck</th>');
}
else
{
column = header.parent().children().index(header);
header.text("0.0");
}
$.each(rows, function(index, row)
{
if (index > 0)
{
let columns = $(row).find('td');
let looted = $(columns[4]).text();
let amounts = $(columns[2]).text().split(' - ');
let minAmount, maxAmount;
switch (amounts.length)
{
case 1: minAmount = maxAmount = amounts[0]; break;
case 2: minAmount = 1.0*amounts[0]; maxAmount = 1.0*amounts[1]; break;
default: minAmount = maxAmount = 1;
}
let chance = $(columns[3]).text();
let factor;
if (chance === "Always")
{
factor = calc(kills, minAmount, maxAmount, 1, looted);
factor = Math.round(factor*100.0)/100.0;
}
else
{
let chances = chance.split('/');
switch (chances.length)
{
case 2:
{
factor = calc(kills, minAmount, maxAmount, chances[1], looted);
factor = Math.round(factor*100.0)/100.0;
break;
}
default: factor = "N/A";
}
}
if (column >= columns.length)
{
$(row).append('<td>' + factor + '</td>');
}
else
{
columns[column].text(factor);
}
}
});
}
catch (error)
{
console.error(error);
}
}
onLogin()
{
loaded = true;
}
onVariableSet(key, before, after)
{
if (!loaded) return;
if (before != after)
{
// this.updateCombat();
}
}
onCombatEnd()
{
this.updateCombat();
}
onPanelChanged(before, after)
{
if (before != after)
{
if (!hooked && after === 'combat-log')
{
hooked = true;
let calc = this.luckFactor;
let update = this.updateCombat;
let lookup = $('#modal-monster-lookup');
if (lookup.length > 0)
{
let observer = new MutationObserver(function(mutations) { update(calc); });
observer.observe(lookup[0], { attributes: true });
}
}
}
}
}
const plugin = new LuckyPlugin();
IdlePixelPlus.registerPlugin(plugin);
})();