NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name Max stat calculator v0.7.1 // @namespace http://tampermonkey.net/ // @version 0.7.1 // @description Max stat calculator /* USAGE INSTRUCTIONS: 1) Open initium in a fresh tab (DO NOT DUPLICATE CURRENT TAB!) and switch to the character you want to test. 2) Hit the reset button 3) Start bashing monsters and watch the stat calculator estimate your max stats. The precision of the estimate increases with each hit. // @acknowledgements The stat calculation code comes directly from Marcus stats calculator, with minor adaptations to function in this setting. Many thanks // to Marcus for his calculator. // @author Noldor // @match https://www.playinitium.com/* // @grant none // ==/UserScript== /* jshint -W097 */ /* [10:44] KingdomDrake: You can get the character ID using window.characterId [10:44] KingdomDrake: var charStatMap = {}; charStatMap[characterID] = {stats: ...., blah:...} Object Map */ (function() { 'use strict'; var $ = window.jQuery; // runs add click event function on page refresh vv addClickEvent(); // select the target node var buttonList = document.getElementById('main-button-list'); // create an observer instance var observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { addClickEvent(); }); }); // pass in the target node, as well as the observer options observer.observe(buttonList, { childList: true, subtree: true, characterData: true }); var swingCount; var statsInit; var statsCur; var statsMax; var charStatsMap = {}; var charStats = {}; // clear swings count vv function resetCalc(){ statsInit = document.getElementById("newui").children[0].getAttribute('minitip').split(/[/<]/); // remove unwanted bits from statsInit vv statsInit.splice(3,4); // transform array strings to floating numbers vv for (var i=0; i < statsInit.length; i++) { statsInit[i] = parseFloat(statsInit[i]); } charStatsMap = JSON.parse(localStorage.getItem('charStats')); if (charStatsMap === null) { charStatsMap = {}; } // set initial conditions vv charStatsMap [window.characterId] = {'initial': statsInit, 'diff': [0, 0, 0], 'saved': [0, 0, 0], 'hits': 0 }; localStorage.setItem('charStats', JSON.stringify(charStatsMap)); // transform arrays to strings, store as initial stats vv //localStorage.setItem('initialstats', JSON.stringify(statsInit)); // localStorage.setItem('swings', 0); // localStorage.setItem('characterName', document.getElementById('newui').children[2].children[0].innerHTML); // localStorage.setItem('statsDiff', '[0, 0, 0]'); // localStorage.setItem('savedstatsMax', '[0, 0, 0]'); } // clear swings button vv var clearButton = document.createElement("input"); clearButton.type = "button"; clearButton.value = "Reset"; clearButton.id = "resetCalculator"; clearButton.style = "margin-left:10px"; var getElement = document.getElementsByClassName("header"); getElement[0].appendChild(clearButton); document.getElementById("resetCalculator").addEventListener("click", resetCalc); // create and display stats span vv // var charDiv = $('.character-display-box').children(" div:nth-child(3)").children( 'a' ); var statSpan = document.createElement("SPAN"); statSpan.style = "margin-left:10px; font-size:medium"; statSpan.id = "statsDisplay"; getElement[0].appendChild(statSpan); // add click event listeners to all attack buttons. vv function addClickEvent(){ if(document.getElementById('banner-text-overlay').children[0] !== undefined) { document.getElementById('banner-text-overlay').children[0].addEventListener("click", countSwing); document.getElementById('banner-text-overlay').children[1].addEventListener("click", countSwing); document.getElementById('main-button-list').children[0].addEventListener("click", countSwing); document.getElementById('main-button-list').children[1].addEventListener('click', countSwing); } else { if (statSpan !== undefined) { charStatsMap = JSON.parse(localStorage.getItem('charStats')); var spanStats = {}; for (var i = 0; i < 3; i++) { if (charStatsMap[window.characterId].saved[i] === null || charStatsMap[window.characterId].saved[i] === undefined){ charStatsMap[window.characterId].saved[i] = 0; } spanStats[i] = Math.round(charStatsMap[window.characterId].saved[i] * 100)/100; } statSpan.textContent = "Cap: " + "S: " + spanStats[0] + " " + "D: " + spanStats[1] + " " + "I: " + spanStats[2]; } } } // get swings, increment swing count, store swings, call read getStats() into statsMax and display vv function countSwing(){ charStatsMap = JSON.parse(localStorage.getItem('charStats')); swingCount = charStatsMap[window.characterId].hits; // swingCount = localStorage.getItem('swings'); /*if (swingCount === null){ alert("You need to hit the reset button first!"); return; } This needs re-write to be functional ^^*/ statsCur = document.getElementById("newui").children[0].getAttribute('minitip').split('/'); statsCur.splice(3,4); for (var i=0; i < statsCur.length; i++) { statsCur[i] = parseFloat(statsCur[i]); } console.log("new iteration"); // note: mini tool tip update is not instantaneous, and so the data gathered in the previous steps is actually the stats from the previous swing. // therefore, the this script is configured to pass the previous swing count the calculator as well, and the swing count is not incremented // until after the calculator has finished running. console.log(statsCur); if (swingCount !== 0) { statsMax = getStats(); // Take the results of statsmax and read in older calculations where no new calculation was made vv for (i = 0; i < 3; i++) { if (statsMax[i] === 0 || statsMax[i] === null || isNaN(statsMax[i]) ) { statsMax[i] = charStatsMap[window.characterId].saved[i]; } } // display stats statSpan.textContent = "Cap: " + "S: " + statsMax[0].toFixed(2) + " " + "D: " +statsMax[1].toFixed(2) + " " + "I: " + statsMax[2].toFixed(2); charStatsMap[window.characterId].saved = statsMax; } swingCount = swingCount + 1; console.log(swingCount); charStatsMap[window.characterId].hits = swingCount; localStorage.setItem('charStats', JSON.stringify(charStatsMap)); } // define remaining variables and run calculations function getStats() { statsInit = charStatsMap[window.characterId].initial; console.log(statsInit); var hits = swingCount; console.log(hits); var stats; var compMod = [0, 0, 0]; var diff = [0, 0, 0]; if (statsInit[0]==5) {compMod[0]=0.005; } diff[0] = Math.round((statsCur[0]-statsInit[0])*100)/100-compMod[0]; if (statsInit[1]==5) { compMod[1]=0.005; } diff[1] = Math.round((statsCur[1]-statsInit[1])*100)/100-compMod[1]; if (statsInit[2]==5) { compMod[2]=0.005; } diff[2] = Math.round((statsCur[2]-statsInit[2])*100)/100-compMod[2]; console.log(diff); console.log(charStatsMap[window.characterId].diff); var mod = [0.0009954, 0.00057334, 0.0001414791]; var modmax = [0.0012947, 0.00072171, 0.000199425]; var modin = [0.0000014965, 0.0000007418493, 0.0000002897295]; var max = [11, 10, 10]; var minmax = [9, 8, 8]; var i, j, g, k; var statMax = [0,0,0]; // This part only calculates and updates statMax if the stat has increased between iterations if ( charStatsMap[window.characterId].diff[0] != diff[0] ) { statMax[0]=(evalmaxStats(statsInit[0], statsCur[0], hits, diff[0], stats, mod[0], modmax[0], modin[0], max[0], minmax[0], i, j, g, 0) + evalminStats(statsInit[0], statsCur[0], hits, diff[0], stats, mod[0], modmax[0], modin[0], max[0], minmax[0], i, j, g, 0))/2; } if ( charStatsMap[window.characterId].diff[1] != diff[1] ) { statMax[1]=(evalmaxStats(statsInit[1], statsCur[1], hits, diff[1], stats, mod[1], modmax[1], modin[1], max[1], minmax[1], i, j, g, 1) + evalminStats(statsInit[1], statsCur[1], hits, diff[1], stats, mod[1], modmax[1], modin[1], max[1], minmax[1], i, j, g, 1))/2; } if ( charStatsMap[window.characterId].diff[2] != diff[2] ) { statMax[2]=(evalmaxStats(statsInit[2], statsCur[2], hits, diff[2], stats, mod[2], modmax[2], modin[2], max[2], minmax[2], i, j, g, 2) + evalminStats(statsInit[2], statsCur[2], hits, diff[2], stats, mod[2], modmax[2], modin[2], max[2], minmax[2], i, j, g, 2))/2; } // store stats difference for future reference vv charStatsMap[window.characterId].diff = diff; console.log(statMax); return statMax; } //calculator functions (with thanks to Marcus) vv function evalmaxStats(initial, current, hits, diff, stats, mod, modmax, modin, max, minmax, i, j, g, k) { j=mod; for (g=max; g>=minmax; g=g-0.01) { initial = statsInit[k]; for (i=1; i<=hits; i++) { stats=initial+(g-initial)*j; initial=stats; if (((Math.round(stats*100))/100)==current && i==hits) { return g; } } j=j+modin; } } function evalminStats(initial, current, hits, diff, stats, mod, modmax, modin, max, minmax, i, j, g, k) { j=modmax; for (g=minmax; g<=max; g=g+0.01) { initial = statsInit[k]; for (i=1; i<=hits; i++) { stats=initial+(g-initial)*j; initial=stats; if (((Math.round(stats*100))/100)==current && i==hits) { return g; } } j=j-modin; } } })();