// ==UserScript==
// @name Melvor Idle Item Dashboard (MIID)
// @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 2.2
// @author Gardens#3738
// @description Track -everything- over time!
// ==/UserScript==
window.banked = function(itemID) {
let qty = 0;
if (checkBankForItem(itemID)) {
let bankID = getBankId(itemID);
qty = bank[bankID].qty;
}
return qty;
}
window.itemsOwned = function(silent = true) {
let bulk = new Array(items.length).fill(0);
// take everything in bank, pile it here
for (let i = 0; i < bank.length; i++) {
let stack = bank[i];
bulk[stack.id] += stack.qty;
}
// check equipment sets, ignore golbin loadout
for (let eqI = 0; eqI < 3; eqI++) {
let equipmentSet = equipmentSets[eqI]["equipment"];
for (let slot = 0; slot < equipmentSet.length; slot++) {
let gearID = equipmentSet[slot];
let qty = 0;
// malcs, nobody uses logs in battle
// malcs please just use -1 for no item
if (gearID !== 0) {
qty = (slot === CONSTANTS.equipmentSlot.Quiver) ? equipmentSets[eqI].ammo : 1;
!silent && console.log(`gear item:${items[gearID].name} qty ${qty}`)
}
bulk[gearID] += qty;
}
}
// tally food, ignore golbin food at equippedFood[3]
for (let i = 0; i < 3; i++) {
let foodID = equippedFood[i].itemID;
let qty = equippedFood[i].qty;
if (qty > 0) {
!silent && console.log(`food item:${items[foodID].name} qty ${qty}`);
bulk[foodID] += qty;
}
}
if (!silent) {
for (let i = 0; i < bulk.length - 1; i++) {
if (bulk[i] > 0) {
console.log(`has item:${items[i].name} qty ${bulk[i]}`);
}
}
}
return bulk;
}
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);
}
window.toggleIntervalSize = function() {
if (MIIDOptions.itemTracked != -1) {
MIIDOptions.itemTracked = -1;
MIIDOptions.intervalTracked = 0;
}
MIIDOptions.intervalTracked = (MIIDOptions.intervalTracked + 1) % MIIDOptions.trackIntervals.length;
}
window.getTimeString = function(sec) {
let s = Math.round(sec)
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;
// if (h == 0) {
// if (m == 0) {
// return `${s}s`;
// } else return `${m}m${s}s`;
// } else return `${h}h${m}m${s}s`;
// let timeString = ` h: ${h} m: ${m} s: ${s}`;
return `${h}:${m}:${s}`;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////// XP //////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////
levelToXp = function(level) {
let xp = 0;
for (let l = 1; l <= level - 1; l++) {
xp += Math.floor(l + 300 * Math.pow(2, l / 7))
}
return Math.floor(xp / 4);
}
levels = []
for (let i = 0; i < 200; i++) {
levels[i] = levelToXp(i)
}
xpToLevel = function(xp) {
let level = 1;
while (levels[level + 1] <= xp) level++;
return level;
}
window.idToSkillname = {};
// number to name
for (let key of Object.keys(CONSTANTS.skill)) {
idToSkillname[CONSTANTS.skill[key]] = key
}
// console.log(idToSkillname)
window.allXP = function(loud = false) {
let skills = [];
for (let i = 0; i < skillXP.length; i++) {
skills[i] = {
name: SKILLS[i].name,
xp: skillXP[i],
level: xpToLevel(skillXP[i]),
}
skills[i].xpToNext = levelToXp(skills[i].level + 1) - skillXP[i];
loud && console.log("skill", i, skills[i].name)
if (SKILLS[i].hasMastery) {
skills[i].pool = MASTERY[i].pool;
skills[i].mastery = MASTERY[i].xp.reduce((a, b) => a + b);
skills[i].poolMax = getMasteryPoolTotalXP(i);
skills[i].poolPerc = skills[i].pool / skills[i].poolMax * 100;
}
}
return skills;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////// SNAPSHOTS //////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// let itemTracker = {
// start: {
// bulkItems: [
// 0: 34,
// 1: 356
// ],
// gp: 2444,
// prayerPoints: 54243,
// },
// curr: {... }
window.getSnapshot = function() {
let resources = {
date: (new Date()).getTime(),
bulkItems: itemsOwned(),
skills: allXP(),
prayerPoints: prayerPoints,
slayerCoins: slayerCoins,
gp: gp,
hp: effHp(),
kills: totalKills(),
};
return resources;
}
window.resetItemTracker = function() {
window.itemTracker = {
start: getSnapshot(),
curr: getSnapshot(),
}
trackerTick();
}
// resetItemTracker();
window.setupItemTracker = function() {
let localCopy = localStorage.getItem("itemTracker")
if (localCopy == null) {
resetItemTracker();
} else {
window.itemTracker = JSON.parse(localCopy);
}
}
window.setupOptions = function() {
let localCopy = localStorage.getItem("MIIDOptions")
if (localCopy == null) {
console.log("Creating MIIDOptions")
resetOptions();
} else {
console.log("Found MIIDOptions")
window.MIIDOptions = JSON.parse(localCopy);
}
}
window.resetOptions = function() {
window.MIIDOptions = {
itemTracked: -1,
intervalTracked: 1,
trackIntervals: [
[0, 'reset'],
[1, 'sec'],
[60, 'min'],
[3600, 'hour'],
[3600 * 24, 'day']
],
blacklistMode: false,
blacklistItems: {
},
}
}
roundCustom = function(nr, roundDigits = 0, letters = true) {
// 12345.6789 --> roundDecs:
// 12345
if (Math.abs(nr) < 1000 || !letters) {
return Math.round(nr * Math.pow(10, roundDigits)) / Math.pow(10, roundDigits);
} else if (Math.abs(nr) < 1000000) {
// 32415 -> 32.4k
return Math.round(nr / (Math.pow(10, 3 - roundDigits))) / Math.pow(10, roundDigits) + "k";
} else {
// 12345678 -> 12.3m
return Math.round(nr / (Math.pow(10, 6 - roundDigits))) / Math.pow(10, roundDigits) + "m";
}
}
setItemTracked = function(itemID = -1) {
MIIDOptions.itemTracked = itemID;
}
window.resDiff = {};
trackerTick = function(silent = true) {
itemTracker.curr = getSnapshot();
let { start, curr } = itemTracker;
let timePassed = (curr.date - start.date) / 1000;
// save tracker
localStorage.setItem("itemTracker", JSON.stringify(itemTracker));
localStorage.setItem("MIIDOptions", JSON.stringify(MIIDOptions));
// why did I do this?
// itemTracker = JSON.parse(localStorage.getItem("itemTracker"));
window.resDiff = {
timePassed,
intervalDur: -1,
intervalLabel: "default",
itemChange: new Array(items.length).fill(0),
worthChange: new Array(items.length).fill(0),
itemRate: new Array(items.length).fill(0),
worthRate: new Array(items.length).fill(0),
itemRound: 2,
goldRound: 0,
generalItemRate: 0,
generalItemChange: 0,
generalWorthChange: 0,
generalWorthRate: 0,
generalChanges: false,
farmingItemRate: 0,
farmingItemChange: 0,
farmingWorthChange: 0,
farmingWorthRate: 0,
farmingChanges: false,
totalWorthChange: 0,
totalWorthRate: 0,
pointChange: {},
pointRate: {},
pointTimeLeft: {},
pointChanges: false,
xpChange: new Array(skillXP.length).fill(0),
xpRate: new Array(skillXP.length).fill(0),
poolChange: new Array(skillXP.length).fill(0),
poolRate: new Array(skillXP.length).fill(0),
poolPercChange: new Array(skillXP.length).fill(0),
poolPercRate: new Array(skillXP.length).fill(0),
masteryChange: new Array(skillXP.length).fill(0),
masteryRate: new Array(skillXP.length).fill(0),
skillChanges: false,
lossChanges: false,
timeLeft: new Array(items.length).fill(0),
};
!silent && console.log(`xp change: ${resDiff.xpChange}, skillXP.length: ${skillXP.length}`)
let rateFactor, intervalDur, intervalLabel;
if (MIIDOptions.itemTracked == -1) {
// time-based tracking
let interval = MIIDOptions.trackIntervals[MIIDOptions.intervalTracked];
resDiff.intervalDur = interval[0];
resDiff.intervalLabel = interval[1];
if (resDiff.intervalDur == 0) {
rateFactor = 1;
} else {
rateFactor = timePassed / resDiff.intervalDur;
}
} else {
// let itemTrackedChange = scrt
if (isNaN(MIIDOptions.itemTracked)) {
let pointNames = ["gp", "prayerPoints", "slayerCoins", "hp", "kills"];
if (pointNames.indexOf(MIIDOptions.itemTracked) != -1) {
rateFactor = curr[MIIDOptions.itemTracked] - start[MIIDOptions.itemTracked];
resDiff.intervalLabel = MIIDOptions.itemTracked;
} else
console.log(`Error tracking by ${MIIDOptions.itemTracked}`);
// point tracking
} else {
// track relative to a specific item's change
rateFactor = itemTracker.curr.bulkItems[MIIDOptions.itemTracked] -
itemTracker.start.bulkItems[MIIDOptions.itemTracked]
resDiff.intervalLabel = items[MIIDOptions.itemTracked].name;
!silent && console.log(`Tracking by ${MIIDOptions.itemTracked}`)
}
}
// items
for (let itemID = 0; itemID < items.length; itemID++) {
let startQty = start.bulkItems[itemID] || 0;
let currQty = curr.bulkItems[itemID] || 0;
let change = currQty - startQty;
if (change == 0) continue;
// absolute change, interval rate, time left
resDiff.itemChange[itemID] = change;
resDiff.itemRate[itemID] = change / rateFactor;
// register change
!silent && console.log(`${items[itemID].name} changed by ${resDiff.itemRate[itemID]} / ${resDiff.intervalLabel}`);
let worthChange = change * items[itemID].sellsFor;
resDiff.worthChange[itemID] = worthChange;
resDiff.worthRate[itemID] = worthChange / rateFactor;
// split by farming
// I miss you horsie
// Daisy, where are you now
if (items[itemID].category == "Farming") {
resDiff.farmingChanges = true;
resDiff.farmingItemChange += change;
resDiff.farmingWorthChange += worthChange;
} else {
resDiff.generalChanges = true;
resDiff.generalItemChange += change;
resDiff.generalWorthChange += worthChange;
}
if (change < 0 && currQty > 0) {
resDiff.lossChanges = true;
let timeLeft = currQty / (-change / timePassed);
resDiff.timeLeft[itemID] = timeLeft;
!silent && console.log(`${items[itemID].name} running out in ${resDiff.timeLeft[itemID]}`);
}
}
resDiff.generalItemRate = resDiff.generalItemChange / rateFactor;
resDiff.generalWorthRate = resDiff.generalWorthChange / rateFactor;
resDiff.farmingItemRate = resDiff.farmingItemChange / rateFactor;
resDiff.farmingWorthRate = resDiff.farmingWorthChange / rateFactor;
resDiff.totalWorthChange = resDiff.generalWorthChange + resDiff.farmingWorthChange;
resDiff.totalWorthRate = resDiff.totalWorthChange / rateFactor;
resDiff.netWealthChange = resDiff.totalWorthChange + curr.gp - start.gp;
resDiff.netWealthRate = (resDiff.totalWorthChange + curr.gp - start.gp) / rateFactor;
// points
let pointNames = ["gp", "prayerPoints", "slayerCoins", "hp", "kills"];
let trackTimeLeft = { "prayerPoints": true, "hp": true }
for (let pointName of pointNames) {
let startQty = start[pointName];
let currQty = curr[pointName];
let change = currQty - startQty;
let rate = change / rateFactor;
resDiff.pointRate[pointName] = rate;
resDiff.pointChange[pointName] = change;
if (!silent && change != 0) console.log(pointName, " differ by", rate, "/", resDiff.intervalLabel);
if (currQty > 0 && change < 0 && trackTimeLeft[pointName]) {
let timeLeft = currQty / (-change / timePassed);
resDiff.pointTimeLeft[pointName] = timeLeft;
!silent && console.log(`${pointName} point running out in ${resDiff.pointTimeLeft[pointName]}`);
}
}
// XP
for (let skillID = 0; skillID < skillXP.length; skillID++) {
resDiff.xpChange[skillID] = itemTracker.curr.skills[skillID].xp - start.skills[skillID].xp;
resDiff.xpRate[skillID] = resDiff.xpChange[skillID] / rateFactor
resDiff.poolPercChange[skillID] = itemTracker.curr.skills[skillID].poolPerc - start.skills[skillID].poolPerc;
resDiff.poolPercRate[skillID] = resDiff.poolPercChange[skillID] / rateFactor;
resDiff.poolChange[skillID] = itemTracker.curr.skills[skillID].pool - start.skills[skillID].pool;
resDiff.poolRate[skillID] = resDiff.poolChange[skillID] / rateFactor;
resDiff.masteryChange[skillID] = itemTracker.curr.skills[skillID].mastery - start.skills[skillID].mastery;
resDiff.masteryRate[skillID] = resDiff.masteryChange[skillID] / rateFactor;
}
resDiff.rateFactor = rateFactor;
// glove charges (todo)
if (document.getElementById("dashWealthChange") != null) {
$("#dashWealthChange").text(`${roundCustom(resDiff.netWealthRate, 0)}/${resDiff.intervalLabel}`);
}
return resDiff;
}
checkPreservation = function(obj) {
return (JSON.stringify(obj) === JSON.stringify(JSON.parse(JSON.stringify(obj))))
}
function blerg() {
console.log("blerg!")
}
window.handleItemClick = function(itemID) {
if (MIIDOptions.blacklistMode) {
if (MIIDOptions.blacklistItems[itemID]) {
MIIDOptions.blacklistItems[itemID] = false;
} else {
MIIDOptions.blacklistItems[itemID] = true;
}
} else {
setItemTracked(itemID);
}
updateDash();
}
window.getDashContent = function() {
let compact = $(window).width() < 1250;
// use curr and start to generate some item rows, and change #dashItems for it
let generalContent = ``
let farmingContent = ``;
let lossContent = ``;
let pointContent = ``;
let xpContent = ``;
let content = ``;
// each item row
for (let itemID = 0; itemID < items.length; itemID++) {
if (MIIDOptions.blacklistItems[itemID] && !MIIDOptions.blacklistMode) continue;
let change = resDiff.itemChange[itemID];
// each item's change, put in the right content chunk
// display if change is nonzero or blacklisted item in blacklist mode
if (change !== 0 || (MIIDOptions.blacklistItems[itemID] && MIIDOptions.blacklistMode)) {
let itemRate = roundCustom(resDiff.itemRate[itemID], resDiff.itemRound);
let worthRate = roundCustom(resDiff.worthRate[itemID], resDiff.goldRound);
let banned = MIIDOptions.blacklistItems[itemID];
let row;
// create item row
if (compact) {
row = `
<div class="pointer-enabled" onClick="handleItemClick(${itemID})">
<img width="32" height="32" src="${items[itemID].media}"></img>
<span>
${banned ? String(itemRate).strike():itemRate}
</span>
<br>
</div`;
} else {
row = `
<div class="row">
<div class="col-4 pointer-enabled" onClick="handleItemClick(${itemID})">
<img class="nav-img" src="${items[itemID].media}"></img>
${banned ? items[itemID].name.strike() : items[itemID].name}
</div>
<div class="col-4">${banned ? String(itemRate).strike():itemRate}</div>
<div class="col-4">
<img class="nav-img" src="https://cdn.melvor.net/core/v018/assets/media/main/coins.svg"></img>
${banned ? String(worthRate).strike():worthRate}
</div>
</div>`;
}
if (items[itemID].category == "Farming") {
farmingContent += row;
} else {
generalContent += row;
}
// Items running out --> lossContent
// add row to loss content
if (resDiff.timeLeft[itemID] > 0) {
let timeString = getTimeString(resDiff.timeLeft[itemID]);
let lossRow = ``;
if (compact) {
lossRow = `
<div class="pointer-enabled" onClick="handleItemClick(${itemID})">
<img width="32" height="32" src="${items[itemID].media}"></img>
<span>
${timeString} left
</span>
<br>
</div`;
} else {
lossRow = `
<div class="row pointer-enabled" onClick="handleItemClick(${itemID})">
<div class="col-6">
<img class="nav-img" src="${items[itemID].media}"></img>
${roundCustom(itemTracker.curr.bulkItems[itemID], 1)}
</div>
<div class="col-6">${timeString} left</div>
</div>`;
}
lossContent += lossRow;
}
}
}
// assemble general, farming, loss content with headers
if (compact) {
generalContent = `
<br>
<div class = "row no-gutters">
<h5 class = "font-w700 text-center text-combat-smoke col"> General items </h5>
</div>` + generalContent;
farmingContent = `
<br>
<div class = "row no-gutters">
<h5 class = "font-w700 text-center text-combat-smoke col"> Farming items </h5>
</div>` + farmingContent;
lossContent = `
<br>
<div class = "row no-gutters">
<h5 class = "font-w700 text-center text-combat-smoke col"> Items being used </h5>
</div>` + lossContent;
} else {
generalContent = `
<br>
<div class = "row no-gutters">
<h5 class = "font-w700 text-center text-combat-smoke col"> General items </h5>
<h5 class = "font-w700 text-center text-combat-smoke col"> Change </h5>
<h5 class = "font-w700 text-center text-combat-smoke col"> Gold Worth </h5>
</div>` + generalContent;
farmingContent = `
<br>
<div class = "row no-gutters">
<h5 class = "font-w700 text-center text-combat-smoke col"> Farming items </h5>
<h5 class = "font-w700 text-center text-combat-smoke col"> Change </h5>
<h5 class = "font-w700 text-center text-combat-smoke col"> Gold Worth </h5>
</div>` + farmingContent;
lossContent = `
<br>
<div class = "row no-gutters">
<h5 class = "font-w700 text-center text-combat-smoke col"> Items in use </h5>
<h5 class = "font-w700 text-center text-combat-smoke col"> Time left </h5>
</div>` + lossContent;
}
// item category rate and worth rate
if (compact) {
generalContent += `
<br>
<h5> General items </h5>
<img width="32" height="32" src="https://cdn.melvor.net/core/v018/assets/media/main/bank_header.svg"></img>
<br>
<span>${roundCustom(resDiff.generalItemRate, resDiff.itemRound)}</span>
<br>
<h5> Item worth </h5>
<img width="32" height="32" src="https://cdn.melvor.net/core/v018/assets/media/main/coins.svg"></img>
<br>
<span>${roundCustom(resDiff.generalWorthRate, resDiff.goldRound)}</span>
<br>`
farmingContent += `
<br>
<h5> Farming items </h5>
<img width="32" height="32" src="https://cdn.melvor.net/core/v018/assets/media/skills/farming/farming.svg"></img>
<br>
<span>${roundCustom(resDiff.farmingItemRate, resDiff.itemRound)}</span>
<br>
<h5> Item worth </h5>
<img width="32" height="32" src="https://cdn.melvor.net/core/v018/assets/media/main/coins.svg"></img>
<br>
<span>${roundCustom(resDiff.farmingWorthRate, resDiff.goldRound)}</span>
<br>`
} else {
// total item changes
generalContent += `
<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>
General Items
</div>
<div class="col-4">${roundCustom(resDiff.generalItemRate, resDiff.itemRound)}</div>
<div class="col-4">
<img class="nav-img" src="https://cdn.melvor.net/core/v018/assets/media/main/coins.svg"></img>
${roundCustom(resDiff.generalWorthRate, resDiff.goldRound)}
</div>
</div>`;
farmingContent += `
<div class="row">
<div class="col-4">
<img class="nav-img" src="https://cdn.melvor.net/core/v018/assets/media/skills/farming/farming.svg"></img>
Farming Items
</div>
<div class="col-4">${roundCustom(resDiff.farmingItemRate, resDiff.itemRound)}</div>
<div class="col-4">
<img class="nav-img" src="https://cdn.melvor.net/core/v018/assets/media/main/coins.svg"></img>
${roundCustom(resDiff.farmingWorthRate, resDiff.goldRound)}
</div>
</div>`;
}
if (resDiff.generalChanges)
content += generalContent
if (resDiff.farmingChanges)
content += farmingContent
if (resDiff.lossChanges)
content += lossContent
// points
pointContent = ``;
pointContent += makePointRow(compact, "gp", "https://cdn.melvor.net/core/v018/assets/media/main/coins.svg");
pointContent += makePointRow(compact, "hp", "https://cdn.melvor.net/core/v018/assets/media/skills/combat/hitpoints.svg", true);
pointContent += makePointRow(compact, "kills", "https://cdn.melvor.net/core/v018/assets/media/skills/combat/combat.svg");
pointContent += makePointRow(compact, "prayerPoints", "https://cdn.melvor.net/core/v018/assets/media/skills/prayer/prayer.svg", true);
pointContent += makePointRow(compact, "slayerCoins", "https://cdn.melvor.net/core/v018/assets/media/main/slayer_coins.svg");
pointContent = `<br/>
<div class="row no-gutters">
<h5 class="font-w700 text-center text-combat-smoke col-sm">Others</h5>
</div>` + pointContent;
if (resDiff.pointChanges) {
content += pointContent;
}
// xp
xpContent = `
<br>
<div class = "row no-gutters">
<h5 class = "font-w700 text-center text-combat-smoke col"> Skill </h5>
<h5 class = "font-w700 text-center text-combat-smoke col"> XP </h5>
<h5 class = "font-w700 text-center text-combat-smoke col"> Time to Lvl </h5>
</div>`
for (let skillID = 0; skillID < skillXP.length; skillID++) {
let xpRow = ``;
let skillName = SKILLS[skillID].name;
let hasMastery = SKILLS[skillID].hasMastery;
let xpRate = resDiff.xpRate[skillID];
let xpChange = resDiff.xpChange[skillID];
let poolPercRate = resDiff.poolPercRate[skillID]
let masteryRate = resDiff.masteryRate[skillID]
let xpToNext = itemTracker.curr.skills[skillID].xpToNext;
let timeToLevel = xpToNext / (xpChange / resDiff.timePassed);
let until100 = (itemTracker.curr.skills[skillID].poolMax / (resDiff.poolChange[skillID] - resDiff.timePassed)) * 100;
if (xpChange == 0) {
continue;
} else {
resDiff.skillChanges = true;
}
if (compact) {
// TODO: mobile version
} else {
xpRow = `
<div class="row">
<div class="col-4">
<img class="nav-img" src="${SKILLS[skillID].media}"></img>
${skillName}
</div>
<div class="col-4">
${roundCustom(xpRate, 2)}
</div>
<div class="col-4">
${getTimeString(timeToLevel)}
</div>
</div>`
if (hasMastery && itemTracker.curr.skills[skillID].poolPerc < 100) {
xpRow += `
<div class="row">
<div class="col-4">
<img class="nav-img" src="https://cdn.melvor.net/core/v018/assets/media/main/mastery_header.svg"></img>
${skillName}
</div>
<div class="col-4">
${roundCustom(poolPercRate, 2)}%
</div>
<div class="col-4">
to 100%: ${getTimeString(until100)}
</div>
</div>`
}
}
xpContent += xpRow
}
if (resDiff.skillChanges) {
content += xpContent;
}
return content;
}
makePointRow = function(compact, pointName, src) {
if (resDiff.pointChange[pointName] != 0) {
resDiff.pointChanges = true;
} else {
return ``;
}
let desc = {
"hp": "Hitpoints",
"prayerPoints": "Prayer Points",
"slayerCoins": "Slayer Coins",
"gp": "Cash",
"kills": "Kills"
}
let pointRow = ``;
if (compact) {
pointRow = `
<div class="pointer-enabled" onClick="handleItemClick('${pointName}')">
<img width="32" height="32" src="${src}"></img>
<span>${roundCustom(resDiff.pointRate[pointName], 1)}</span>
</div>`
if (resDiff.pointTimeLeft[pointName]) {
pointRow += `<div><span>${getTimeString(resDiff.pointTimeLeft[pointName])} left</span></div`
}
} else {
pointRow = `
<div class="row no-gutters pointer-enabled" onClick="handleItemClick('${pointName}')">
<div class="col-4">
<img class="nav-img" src="${src}"></img>
${desc[pointName]}
</div>
<div class="col-8">
${roundCustom(resDiff.pointRate[pointName], 2)}
</div>
</div>`
if (resDiff.pointTimeLeft[pointName]) {
pointRow += `
<div class="row no-gutters">
<div class="col-4">
<img class="nav-img" src="${src}"></img>
${roundCustom(itemTracker.curr[pointName], 2)}
</div>
<div class="col-8">
${getTimeString(resDiff.pointTimeLeft[pointName])} left
</div>
</div>`
}
}
return pointRow;
}
// window.dashItemRows = "";
// window.dashPointRows = "";
// window.dashContent = "";
window.toggleBlacklist = function() {
MIIDOptions.blacklistMode = !MIIDOptions.blacklistMode
}
window.updateDash = function() {
let interval = MIIDOptions.trackIntervals[MIIDOptions.intervalTracked];
let intervalLabel = interval[1];
let content = getDashContent();
let buttonLabel = (resDiff.intervalLabel == "reset") ? "Since last" : "Per:";
// <button type="button" class="swal2-confirm swal2-styled onClick="resetItemTracker()">Reset</button>`
if (document.getElementById("dashContent") != null) {
$("#dashContent").html(`
<p>Time tracked: ${getTimeString(resDiff.timePassed)}</p>
<button type="button" onClick="toggleIntervalSize()" class="swal2-confirm swal2-styled" aria-label="" style="display: inline-block; background-color: rgb(55, 200, 55); border-left-color: rgb(48, 133, 214); border-right-color: rgb(48, 133, 214);">
${buttonLabel} ${resDiff.intervalLabel}
</button>
<button type="button" onClick="toggleBlacklist()" class="swal2-confirm swal2-styled" aria-label="" style="display: inline-block; background-color: ${MIIDOptions.blacklistMode?"rgb(200, 55, 55)" : "rgb(55, 200, 55)"}; border-left-color: rgb(48, 133, 214); border-right-color: rgb(48, 133, 214);">
Blacklisting: ${MIIDOptions.blacklistMode}
</button>
${content}
`);
}
}
window.openItemDash = function() {
Swal.fire({
title: 'M.I.I.D. (Item Dash)',
html: `<small>by Gardens</small><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, 100);
}
})
}
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);
setupOptions();
setupItemTracker();
window.itemTrackBot = setInterval(() => {
trackerTick();
updateDash();
// HACK for initial ticker:
// $("#dashItems").html(getDashItemRows())
}, 1000);
}
}
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()