// ==UserScript== // @name Real Profit Calculator // @namespace http://tampermonkey.net/ // @version 1.2 // @description Calculates real NoRNG profit and exp gain for MWI battle emulator. // @author guch8017 // @match https://shykai.github.io/MWICombatSimulatorTest/dist/ // @grant GM_registerMenuCommand // @grant GM_setValue // @grant GM_getValue // @license MIT // @downloadURL none // ==/UserScript== (function () { 'use strict'; GM_registerMenuCommand("设置社区掉落增益", async function () { const currentRate = await GM_getValue('buffRate', 1.295); const input = prompt("Enter new Buff Rate:", currentRate); if (input !== null) { const parsed = parseFloat(input); if (!isNaN(parsed) && parsed > 0) { await GM_setValue('buffRate', parsed); alert(`Buff rate set to ${parsed}. Reload the page to see changes.`); } else { alert("Invalid input. Please enter a positive number."); } } }); GM_registerMenuCommand("设置社区经验增益", async function () { const currentRate = await GM_getValue('expBuffRate', 0.295); const input = prompt("Enter new Exp Buff Rate:", currentRate); if (input !== null) { const parsed = parseFloat(input); if (!isNaN(parsed) && parsed > 0) { await GM_setValue('expBuffRate', parsed); alert(`Exp rate set to ${parsed}. Reload the page to see changes.`); } else { alert("Invalid input. Please enter a positive number."); } } }); const eliteMapExpBonus = { "/actions/combat/smelly_planet_elite": 0.1, "/actions/combat/swamp_planet_elite": 0.1, "/actions/combat/aqua_planet_elite": 0.1, "/actions/combat/jungle_planet_elite": 0.1, "/actions/combat/gobo_planet_elite": 0.15, "/actions/combat/planet_of_the_eyes_elite": 0.15, "/actions/combat/sorcerers_tower_elite": 0.15, "/actions/combat/bear_with_it_elite": 0.15, "/actions/combat/golem_cave_elite": 0.2, "/actions/combat/twilight_zone_elite": 0.2, "/actions/combat/infernal_abyss_elite": 0.2, } const enhancementLevelTotalMultiplierTable = [0, 1, 2.1, 3.3, 4.6, 6, 7.5, 9.1, 10.8, 12.600000000000001, 14.500000000000002, 16.5, 18.6, 20.8, 23.1, 25.5, 28, 30.6, 33.300000000000004, 36.1, 39]; // function waitForElement(selector, callback) { // const observer = new MutationObserver(() => { // const el = document.querySelector(selector); // if (el) { // observer.disconnect(); // callback(el); // } // }); // observer.observe(document.body, { childList: true, subtree: true }); // } function parseNumber(text) { const numericText = text.replace(/[^\d.,\-]/g, '').replace(/,/g, ''); return parseFloat(numericText); } function getDrinkConcentration(level) { return 0.1 + 0.002 * (enhancementLevelTotalMultiplierTable[level] || 0); } function getWisdomNeckBonus(level) { return 0.03 + 0.003 * (enhancementLevelTotalMultiplierTable[level] || 0); } async function calculateProfit() { const expenseText = document.getElementById('script_expense')?.textContent || ''; const noRngProfitText = document.getElementById('noRngProfitPreview')?.textContent || ''; const expense = parseNumber(expenseText); const noRngProfit = parseNumber(noRngProfitText); const buffRate = await GM_getValue('buffRate', 1.295); if (!isNaN(expense) && !isNaN(noRngProfit)) { const realProfit = ((noRngProfit + expense) * 1.295) - expense; const formattedProfit = realProfit.toLocaleString(undefined, { maximumFractionDigits: 3 }); const existingDiv = document.getElementById('realProfitDisplay'); if (existingDiv) { existingDiv.textContent = `实际期望利润: ${formattedProfit}`; return; } const displayDiv = document.createElement('div'); displayDiv.id = 'realProfitDisplay'; displayDiv.style.backgroundColor = '#FFD700'; displayDiv.style.color = 'black'; displayDiv.style.fontWeight = 'bold'; displayDiv.style.padding = '4px'; displayDiv.textContent = `实际期望利润: ${formattedProfit}`; const targetDiv = document.getElementById('noRngProfitPreview').parentElement.parentElement; targetDiv.parentNode.insertBefore(displayDiv, targetDiv.nextSibling); } } async function calculateExp() { let expBonus = 0; // 判断精英地图加成 const mapSelected = document.querySelector("#selectZone").value; const isEliteMap = mapSelected.includes("elite"); if (isEliteMap) { let mapBonus = eliteMapExpBonus[mapSelected]; if (mapBonus === undefined) { console.error(`No bonus found for elite map: ${mapSelected}`); } else { expBonus = mapBonus; } } // 判断咖啡加成,同时计算暴饮带来的额外增益 let coffeeBonus = 0; for (let drinkId = 0; drinkId < 3; drinkId++) { const drink = document.querySelector(`#selectDrink_${drinkId}`); if (drink && drink.value === "/items/wisdom_coffee") { coffeeBonus += 0.12; } } const pouchSel = document.querySelector("#selectEquipment_pouch"); if (pouchSel && pouchSel.value === "/items/guzzling_pouch") { const pouchEnhanceLv = Number.parseInt(document.querySelector("#inputEquipmentEnhancementLevel_pouch").value) || 0; const pouchConcentration = getDrinkConcentration(pouchEnhanceLv); coffeeBonus *= pouchConcentration; } expBonus += coffeeBonus; // 判断经验项链加成 if (document.querySelector("#selectEquipment_neck").value === "/items/necklace_of_wisdom") { const neckEnhanceLv = Number.parseInt(document.querySelector("#inputEquipmentEnhancementLevel_neck").value) || 0; expBonus += getWisdomNeckBonus(neckEnhanceLv); } // 判断房屋加成 let houseTotalLv = 0; for (const houseLv of document.querySelectorAll('input[data-house-hrid]')) { houseTotalLv += Number.parseInt(houseLv.value) || 0; } expBonus += houseTotalLv * 0.0005; // 读取经验值 const expRateBonus = await GM_getValue('expBuffRate', 0.295); for (let node of document.querySelector("#simulationResultExperienceGain").childNodes) { node = node.childNodes[1]; let expCurrent = Number.parseInt(node.innerText); let expNew = Math.floor(expCurrent / (1 + expBonus) * (1 + expBonus + 0.295)); node.innerText = `(${expNew})${expCurrent}`; } } const obConfig = {characterData: true, subtree: true, childList: true}; const ProfitNode = document.getElementById('noRngProfitPreview'); const ExpNode = document.getElementById('simulationResultExperienceGain'); new MutationObserver(() => {calculateProfit();}).observe(ProfitNode, obConfig); const expObserver = new MutationObserver(() => { expObserver.disconnect(); calculateExp(); expObserver.observe(ExpNode, obConfig); }); expObserver.observe(ExpNode, obConfig) })();