Deepco Recursion Efficiency

Calculates efficiency of recursion upgrades according to algorithims by Emsou & Soda

// ==UserScript==
// @name         Deepco Recursion Efficiency
// @namespace    http://tampermonkey.net/
// @version      2.2
// @description  Calculates efficiency of recursion upgrades according to algorithims by Emsou & Soda
// @author       Bir & ChatGPT
// @match        https://deepco.app/upgrades
// @icon         https://www.google.com/s2/favicons?sz=64&domain=deepco.app
// @grant        none
// @license MIT
// ==/UserScript==

(function () {
    'use strict';

    console.log('[Deepco Efficiency] Script loaded');

    const style = `
        .deepco-efficiency-panel {
            position: fixed;
            top: 20px;
            right: 20px;
            width: 300px;
            background: #1e1e1e;
            color: #ddd;
            font-family: sans-serif;
            font-size: 14px;
            border: 1px solid #555;
            border-radius: 10px;
            padding: 10px;
            box-shadow: 0 0 10px #000;
            z-index: 9999;
        }
        .deepco-efficiency-panel h3 {
            margin: 0 0 10px;
            border-bottom: 1px solid #444;
            padding-bottom: 5px;
            font-size: 16px;
        }
        .deepco-efficiency-entry {
            margin: 5px 0;
            display: flex;
            justify-content: space-between;
        }
        .highlight-efficient {
            outline: 3px solid limegreen !important;
            outline-offset: 2px;
        }
    `;
    const styleTag = document.createElement('style');
    styleTag.textContent = style;
    document.head.appendChild(styleTag);

    function extractValueFromText(text) {
        const match = text.match(/([\d.]+)%/);
        return match ? parseFloat(match[1]) : null;
    }

   function extractCostFromText(text) {
    const match = text.match(/\(([\d.]+)\s*RC\)/); // now supports decimals like 123.0
    const cost = match ? parseFloat(match[1]) : null;
    return cost;
}


    function parseUpgrades() {
        const frame = document.querySelector('#recursive-upgrades');
        if (!frame) {
            return [];
        }

        const paragraphs = [...frame.querySelectorAll('p')];
        const upgrades = [];

        for (let i = 0; i < paragraphs.length - 1; i++) {
            const p = paragraphs[i];
            const text = p.textContent.trim();

            // Skip Queue Slots line
            if (/Queue Slots/i.test(text)) continue;

            const value = extractValueFromText(text);
            // Extract name more robustly
            const nameMatch = text.match(/^(.*?)(?: Bonus)?:/i);
            const name = nameMatch ? nameMatch[1].trim() : 'Unknown';

            // Find next FORM sibling, skipping any spacer <p>
            let next = p.nextElementSibling;
            while (next && next.tagName !== 'FORM') {
                next = next.nextElementSibling;
            }
            const form = next;
            if (!form) continue;

            const button = form.querySelector('button');
            if (!button) continue;

            const cost = extractCostFromText(button.textContent);


            if (value !== null && cost !== null) {
                upgrades.push({ name, value, cost, button });
            }
        }

        return upgrades;
    }

    function calculateEfficiencies(upgrades) {
    const minUpgrade = upgrades.find(u => u.name.toLowerCase().includes('min processing'));
    const maxUpgrade = upgrades.find(u => u.name.toLowerCase().includes('max processing'));
    const totalUpgrade = upgrades.find(u => u.name.toLowerCase().includes('total processing'));
    const dcYieldUpgrade = upgrades.find(u => u.name.toLowerCase().includes('dc yield'));

    if (!minUpgrade || !maxUpgrade || !totalUpgrade || !dcYieldUpgrade) {
        console.warn('[Deepco Efficiency] Missing one or more upgrades for calculation');
        return upgrades.map(u => ({ ...u, efficiency: 0 }));
    }

    const minVal = minUpgrade.value;
    const maxVal = maxUpgrade.value;
    const totalVal = totalUpgrade.value;
    const dcYieldVal = dcYieldUpgrade.value;

    const costMin = minUpgrade.cost;
    const costMax = maxUpgrade.cost;
    const costTotal = totalUpgrade.cost;
    const costDCYield = dcYieldUpgrade.cost;

    const minMult = ((minVal) / 100 + 1) * (totalVal / 100 + 1);
    const maxMult = ((maxVal) / 100 + 1) * (totalVal / 100 + 1);

    const minThresh = ((minVal + 1) / 100 + 1) * (totalVal / 100 + 1);
    const maxThresh = ((maxVal + 1) / 100 + 1) * (totalVal / 100 + 1);

    const totalDmgPlus = (totalVal + 1) / 100;
    const totalDmgBase = totalVal / 100;

    const dcYieldIncr = (dcYieldVal + 1) / dcYieldVal;

    return upgrades.map(u => {
        let efficiency = 0;
        const C = u.cost;

        const name = u.name.toLowerCase();

        if (name.includes('min processing')) {
            efficiency = (((minThresh / minMult) - 1) * 100 * 0.6) / C;
        } else if (name.includes('max processing')) {
            efficiency = (((maxThresh / maxMult) - 1) * 100) / C;
        } else if (name.includes('total processing')) {
            efficiency = ((((totalDmgPlus / totalDmgBase) - 1) * 100)) / C;
        } else if (name.includes('dc yield')) {
            efficiency = (((dcYieldIncr - 1) * 100) * 2) / C;
        }

        return { ...u, efficiency };
    });
}

    function displayEfficiencies(results) {
    let container = document.querySelector('.deepco-efficiency-panel');
    if (!container) {
        container = document.createElement('div');
        container.className = 'deepco-efficiency-panel';
        document.body.appendChild(container);
    }

    container.innerHTML = `<h3>Efficiency Panel</h3>`;

    results.forEach(upg => {
        const row = document.createElement('div');
        row.className = 'deepco-efficiency-entry';
        row.style.borderBottom = '1px solid #444';
        row.style.padding = '5px 0';

        // Format value display for clarity (could tweak if some upgrades are not %)
        const valueDisplay = upg.value !== null ? `${upg.value}${upg.name.includes('Yield') || upg.name.includes('Processing') ? '%' : '%'}` : 'N/A';

        row.innerHTML = `
            <div><strong>${upg.name}</strong></div>
            <div>Current Value: <span>${valueDisplay}</span></div>
            <div>Cost: <span>${upg.cost} RC</span></div>
            <div>Efficiency: <span>${upg.efficiency.toFixed(4)}</span></div>
        `;
        container.appendChild(row);
    });

    console.log('[Deepco Efficiency] Panel updated');
}
    function highlightBest(upgrades) {
        upgrades.forEach(u => u.button.classList.remove('highlight-efficient'));
        const best = upgrades.reduce((a, b) => (a.efficiency > b.efficiency ? a : b));
        best.button.classList.add('highlight-efficient');

        console.log(`[Deepco Efficiency] Highlighted: ${best.name}`);
    }

    function isRecursionTabVisible() {
        const tab = document.querySelector('[data-tab-id="recursive"]');
        return tab && getComputedStyle(tab).display !== 'none';
    }

    function tryRun() {
        if (isRecursionTabVisible()) {
            console.log('[Deepco Efficiency] Recursion tab visible');
            run();
        } else {
            console.log('[Deepco Efficiency] Recursion tab not visible');
        }
    }

    function run() {
        const raw = parseUpgrades();
        const calculated = calculateEfficiencies(raw);
        displayEfficiencies(calculated);
        highlightBest(calculated);
    }

    const interval = setInterval(() => {
        tryRun();
    }, 1000);

    window.addEventListener('beforeunload', () => clearInterval(interval));
})();