Item Dashboard

Item fluctuations over time.

目前为 2021-02-22 提交的版本。查看 最新版本

// ==UserScript==
// @name        Item Dashboard
// @namespace   http://tampermonkey.net
// @match       https://melvoridle.com
// @match       https://melvoridle.com/*
// @match       https://www.melvoridle.com/*
// @match       https://test.melvoridle.com/*
// @grant       none
// @version     1.0
// @author      Gardens#3738
// @description Item fluctuations over time.
// ==/UserScript==

window.banked = function(itemID) {
    let qty = 0;
    if (checkBankForItem(itemID)) {
        let bankID = getBankId(itemID);
        qty = bank[bankID].qty;
    }
    return qty;
}

window.equipped = function(itemID) {
    let qty = 0;
    // malcs please, logs aren't equipment
    if (itemID === 0) return 0;
    // check equipment sets, ignore golbin loadout
    for (let eqI = 0; eqI < 3; eqI++) {
        let equipmentSet = equipmentSets[eqI]["equipment"];
        // console.log("checking set", equipmentSet)
        for (let slot = 0; slot < equipmentSet.length; slot++) {
            let id = equipmentSet[slot];
            // console.log("equipped item", slot, id, items[id].name)
            if (itemID === id) {
                // console.log("found equipped item at", eqI, slot)
                if (slot === CONSTANTS.equipmentSlot.Quiver) {
                    qty += equipmentSets[eqI].ammo;
                } else
                    qty += 1;
            }
        }
        // check ammo
    }
    // tally food, ignore golbin food at equippedFood[3]
    for (let i = 0; i < 3; i++) {
        if (equippedFood[i].itemID == itemID) return equippedFood[i].qty;
    }
    return qty;
}

window.owned = function(itemID) {
    let qty = banked(itemID) + equipped(itemID);
    return qty;
}

window.effHp = function() {
    // return equippedFood.map(({ itemID, qty }) => (getFoodHealValue(itemID) || 0) * qty).reduce((a, b) => a + b)
    let foodID = equippedFood[currentCombatFood].itemID
    let foodQty = equippedFood[currentCombatFood].qty;
    if (foodQty == 0) return combatData.player.hitpoints;
    return equippedFood[currentCombatFood].qty * getFoodHealValue(foodID) + combatData.player.hitpoints;
}

window.totalKills = function() {
    return monsterStats.map(mon => mon.stats[2]).reduce((a, b) => a + b);
}

// equipped(CONSTANTS.item.Bronze_Arrows)
// owned(CONSTANTS.item.Bronze_Arrows)

// let itemTracker = {
//     start: {
//         bulkItems: [
//             0: 34,
//             1: 356
//         ],
//         gp: 2444,
//         prayerPoints: 54243,
//     },
//     curr: {... }

getSnapshot = function() {
    let resources = {
        date: (new Date()).getTime(),
        bulkItems: [],
        prayerPoints: prayerPoints,
        slayerCoins: slayerCoins,
        gp: gp,
        hp: effHp(),
        kills: totalKills(),
    };
    // get bank items
    for (let itemID = 0; itemID < items.length; itemID++) {
        resources.bulkItems[itemID] = owned(itemID);
    }
    // get glove charges
    return resources;
}

resetItemTracker = function() {
    window.itemTracker = {
        start: getSnapshot(),
        curr: getSnapshot(),
    }
    trackerTick();
}

// resetItemTracker();

setupItemTracker = function() {
    let localCopy = localStorage.getItem("itemTracker")
    if (localCopy == null) {
        resetItemTracker();
    } else {
        window.itemTracker = JSON.parse(localCopy);
    }
}

roundCustom = function(nr, roundDigits) {
    return Math.round(nr * Math.pow(10, roundDigits)) / Math.pow(10, roundDigits);
}

trackerTick = function(silent = true) {
    itemTracker.curr = getSnapshot();
    let { start, curr } = itemTracker;
    let timePassed = (curr.date - start.date) / 1000;
    localStorage.setItem("itemTracker", JSON.stringify(itemTracker));
    itemTracker = JSON.parse(localStorage.getItem("itemTracker"));
    //snap = {
    //     date: timePassed,
    //     bulkItems: [],
    //     prayerPoints: prayerPoints,
    //     slayerCoins: slayerCoins,
    //     gp: gp
    // };
    // items
    for (let itemID = 0; itemID < items.length; itemID++) {
        let startQty = start.bulkItems[itemID];
        let currQty = curr.bulkItems[itemID];
        let change = currQty - startQty;
        if (change !== 0) {
            let rate = roundCustom(change / timePassed * 60, 4);
            if (!silent) console.log(items[itemID].name, "changed by", rate, "/m")
        }
    }
    // points
    let pointNames = ["gp", "prayerPoints", "slayerCoins", "hp"]
    for (let pointName of pointNames) {
        let startQty = start[pointName];
        let currQty = curr[pointName];
        let change = currQty - startQty;
        if (change !== 0) {
            let rate = roundCustom(change / timePassed * 60, 4);
            if (!silent) console.log(pointName, " differ by", rate, "/m")
        }
    }
    // glove charges (todo)
}

checkPreservation = function(obj) {
    return (JSON.stringify(obj) === JSON.stringify(JSON.parse(JSON.stringify(obj))))
}

function blerg() {
    console.log("blerg!")
}

window.getDashItemRows = function(perSec = true) {
    // use curr and start to generate some item rows, and change #dashItems for it
    let { start, curr } = itemTracker;
    let timePassed = (curr.date - start.date) / 1000;
    let content = "";
    let totalItemChange = 0;
    let totalGoldChange = 0;
    let doTrack = false //(Math.random() < 0.05);
    doTrack && console.log("itemchange first:", totalItemChange);
    for (let itemID = 0; itemID < items.length; itemID++) {
        let startQty = start.bulkItems[itemID];
        let currQty = curr.bulkItems[itemID];
        let change = currQty - startQty;
        let goldChange = change * items[itemID].sellsFor;

        // might bother with extra value changers
        if (change !== 0) {
            totalItemChange += change;
            totalGoldChange += goldChange;
            doTrack && console.log("itemchange next:", totalItemChange, "after", items[itemID].name, "*", change);
            let itemRate = roundCustom(change / timePassed * 60, 2);
            let goldRate = roundCustom(goldChange / timePassed * 60, 2)
            content += ` <div class="row">
                <div class="col-4">
                    <img class="nav-img" src="${items[itemID].media}"></img>
                    ${items[itemID].name}
                    </div>
                <div class="col-4">${itemRate}/m</div>
                <div class="col-4">
                    <img class="nav-img" src="https://cdn.melvor.net/core/v018/assets/media/main/coins.svg"></img>
                    ${goldRate}/m
                </div>
            </div>`;
        }
    }
    content += ` <div class="row">
                <div class="col-4">
                    <img class="nav-img" src="https://cdn.melvor.net/core/v018/assets/media/main/bank_header.svg"></img>
                    All Items
                    </div>
                <div class="col-4">${roundCustom(totalItemChange / timePassed * 60, 2)}/m</div>
                <div class="col-4">
                    <img class="nav-img" src="https://cdn.melvor.net/core/v018/assets/media/main/coins.svg"></img>
                    ${roundCustom(totalGoldChange / timePassed * 60, 2)}/m
                </div>
            </div>`
    let netWealthChange = (totalGoldChange + curr.gp - start.gp) / timePassed;
    $("#dashWealthChange").text(`${roundCustom(netWealthChange, 0)}/s`)
    return content;
}

window.getDashPointRows = function(perSec = true) {
    let { start, curr } = itemTracker;
    let timePassed = (curr.date - start.date) / 1000;
    let content = ``;
    let cashRate = roundCustom((curr.gp - start.gp) / timePassed * 60, 2);
    let prayerRate = roundCustom((curr.prayerPoints - start.prayerPoints) / timePassed * 60, 2);
    let slayerRate = roundCustom((curr.slayerCoins - start.slayerCoins) / timePassed * 60, 2);
    let hpRate = roundCustom((curr.hp - start.hp) / timePassed * 60, 2);
    let killRate = roundCustom((curr.kills - start.kills) / timePassed * 60, 2);

    function pointDiv(nr, desc, src) {
        return ` <div class="row no-gutters">
                <div class="col-6">
                    <img class="nav-img" src="${src}"></img>
                    ${desc}
                    </div>
                <div class="col-6">
                    ${nr}/m
                </div>
            </div>`
    }
    content += pointDiv(cashRate, "Cash", "https://cdn.melvor.net/core/v018/assets/media/main/coins.svg");
    content += pointDiv(prayerRate, "Prayer Points", "https://cdn.melvor.net/core/v018/assets/media/skills/prayer/prayer.svg");
    content += pointDiv(slayerRate, "Slayer Coins", "https://cdn.melvor.net/core/v018/assets/media/main/slayer_coins.svg");
    content += pointDiv(hpRate, "Total Hitpoints", "https://cdn.melvor.net/core/v018/assets/media/skills/combat/hitpoints.svg");
    content += pointDiv(killRate, "Kills", "https://cdn.melvor.net/core/v018/assets/media/skills/combat/combat.svg");
    return content;
}

window.dashItemRows = "";
window.dashPointRows = "";
window.dashContent = "";

window.updateDash = function() {
    let timePassed = itemTracker.curr.date - itemTracker.start.date;
    let s = Math.round(timePassed / 1000)
    let h = Math.floor(s / 3600)
    let m = Math.floor((s - h * 3600) / 60)
    s = s - 3600 * h - 60 * m
    h = (h < 10) ? "0" + h : h;
    m = (m < 10) ? "0" + m : m;
    s = (s < 10) ? "0" + s : s;
    // let timeString = ` h: ${h} m: ${m} s: ${s}`;
    let timeString = `${h}:${m}:${s}`;
    dashContent = `
    <p>Time tracked: ${timeString}</p>
    <div class="container" id="dashContainer">
    <div class = "row no-gutters">
        <h5 class = "font-w700 text-center text-combat-smoke col"> Item </h5>
        <h5 class = "font-w700 text-center text-combat-smoke col"> Change / min </h5>
        <h5 class = "font-w700 text-center text-combat-smoke col"> Gold Worth </h5>
    </div>
    ${getDashItemRows()}
    <br/>
    <div class="row no-gutters">
        <h5 class="font-w700 text-center text-combat-smoke col-sm">Points</h5>
        <h5 class="font-w700 text-center text-combat-smoke col-sm">Change</h5>
    </div>
    ${getDashPointRows()}
    </div>`
        // <button type="button" class="swal2-confirm swal2-styled onClick="resetItemTracker()">Reset</button>`
    if (document.getElementById("dashContent") != null) {
        $("#dashContent").html(dashContent);
    }
}
window.openItemDash = function() {
    Swal.fire({
        title: 'Item dashboard',
        html: `<div id="dashContent"></div>`,
        width: "50%",
        // openItemDash();
        confirmButtonColor: '#3085d6',
        cancelButtonColor: '#d33',
        confirmButtonText: 'Reset Tracker'
    }).then((result) => {
        if (result.value) {
            console.log("Resetting item tracker")
            resetItemTracker();
            setTimeout(openItemDash, 500);
        }
    })
}

function injectItemTrackerButton() {
    if (document.getElementById("dashWealthChange") == null) {
        let dashButton = `
        <li class="nav-main-item">
        <div class="nav-main-link nav-compact pointer-enabled" onclick="openItemDash();">
        <img class="nav-img" src="https://cdn.melvor.net/core/v018/assets/media/main/statistics_header.svg">
        <span class="nav-main-link-name">Item Dash</span>
        <img src="https://cdn.melvor.net/core/v018/assets/media/main/coins.svg" style="margin-right: 4px;" width="16px" height="16px">
        <small id="dashWealthChange" class="text-warning" data-toggle="tooltip" data-html="true" data-placement="bottom" title="" data-original-title="TEST"></small>
        </div>
        </li>`
        $("#nav-menu-show").before(dashButton);
        setupItemTracker();
        window.itemTrackBot = setInterval(() => {
            trackerTick();
            updateDash();
            // $("#dashItems").html(getDashItemRows())
        }, 500);
    }
}

function loadItemDashboard() {
    // if ((window.isLoaded && !window.currentlyCatchingUp) ||
    //     (typeof unsafeWindow !== 'undefined' && unsafeWindow.isLoaded && !unsafeWindow.currentlyCatchingUp) ||
    //     document.getElementById("nav-menu-show") == null ||
    if (!window.isLoaded || window.currentlyCatchingUp ||
        document.getElementById("nav-menu-show") == null
        // equipmentSets[1] == undefined
    ) {
        // console.log("Retrying...")
        setTimeout(loadItemDashboard, 300);
        return;
    } else {
        injectItemTrackerButton();
    }
}
loadItemDashboard();
// window.dashboardLoaderInterval = setInterval()

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址