您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
For monster drops and pickpocketing: shows drop rates, avg drops per kill, and current number owned.
// ==UserScript== // @name Melvor Loot Container // @namespace github.com/gmiclotte // @version 0.1.3 // @description For monster drops and pickpocketing: shows drop rates, avg drops per kill, and current number owned. // @author GMiclotte // @include https://melvoridle.com/* // @include https://*.melvoridle.com/* // @exclude https://melvoridle.com/index.php // @exclude https://*.melvoridle.com/index.php // @exclude https://wiki.melvoridle.com/* // @exclude https://*.wiki.melvoridle.com/* // @inject-into page // @noframes // @grant none // ==/UserScript== ((main) => { const script = document.createElement('script'); script.textContent = `try { (${main})(); } catch (e) { console.log(e); }`; document.body.appendChild(script).parentNode.removeChild(script); })(() => { window.mlc = {}; mlc.tempContainer = (id, classNames, wrap) => { classNames = 'block block-rounded block-link-pop border-top border-4x ' + classNames; const container = '' + `<div class="${classNames}" style="overflow-x: auto;">` + ` <small id ="${id}">` + ' </small>' + '</div>'; if (wrap) { return '' + '<div class="col-12">' + container + '</div>'; } return container; } mlc.sortedLoot = {}; mlc.drawEmptyLootTable = (container) => { $(`#${container}`).replaceWith('' + `<small id=${container}>` + '</small>' ); } mlc.drawLootTable = () => { let name; let container; let loot; let id; let hasBones = false; let bones = undefined; let lootChance = 1; const isDungeon = combatManager.areaType === 'Dungeon'; const monster = MONSTERS[combatManager.selectedMonster]; let chanceToDouble = player.modifiers.combatLootDoubleChance / 100; if (npcID !== null) { container = 'pp-lootContainer'; if (isDungeon || thievingNPC[npcID] === undefined) { drawEmptyLootTable(container); return; } name = thievingNPC[npcID].name; loot = thievingNPC[npcID].lootTable; id = `pp-${npcID}`; chanceToDouble = calculateChanceToDouble(Skills.Thieving, false, 0, 0, 0, false) / 100; } else if (combatManager.isInCombat) { container = 'cb-lootContainer'; if (isDungeon || monster === undefined) { mlc.drawEmptyLootTable(container); return; } name = monster.name; loot = monster.lootTable; id = `cb-${combatManager.selectedMonster}`; bones = monster.bones; hasBones = bones !== undefined && bones !== null; if (monster.lootChance !== undefined) { lootChance = monster.lootChance / 100; } } else { return; } // sort the loot if it is not cached if (mlc.sortedLoot[id] === undefined) { console.log(`sorting ${name} loot`) let tmp = []; for (let i = 0; i < loot.length; i++) { const q = loot[i][2] === undefined ? 1 : loot[i][2]; const item = items[loot[i][0]]; if (item.dropTable !== undefined) { let s = item.dropTable.map(x => x[1]).reduce((acc, x) => acc + x, 0); for (let j = 0; j < item.dropTable.length; j++) { tmp.push({ itemID: item.dropTable[j][0], w: loot[i][1] * item.dropTable[j][1] / s, qty: q * item.dropQty[j], }); } } else { tmp.push({ itemID: loot[i][0], w: loot[i][1], qty: q, }); } } tmp.sort(function (a, b) { return b.w - a.w; }); mlc.sortedLoot[id] = tmp; } // compute values const lootTable = mlc.sortedLoot[id]; if (lootTable.length === 0 && !hasBones) { // no loot to insert, so insert an empty placeholder and return mlc.drawEmptyLootTable(container); return; } const lootSize = lootTable.map(x => x.w).reduce((acc, x) => acc + x, 0) / lootChance; const rate = lootTable.map(x => x.w / lootSize * 100); const avg = lootTable.map(x => x.w / lootSize * (1 + x.qty) / 2 * (1 + chanceToDouble)); const owned = lootTable.map(x => getBankQty(x.itemID)); const media = lootTable.map(x => items[x.itemID].media); // make table let header = '<tr>'; header += '<th scope="col"></th>'; if (hasBones) { header += `<td><img class="skill-icon-xs mr-2" src="${items[bones].media}"></td>`; } media.forEach(img => { header += `<td><img class="skill-icon-xs mr-2" src="${img}"></td>`; }); header += '</tr>'; let bodyRate = '<tr>'; bodyRate += '<th scope="col">drop %</th>'; if (hasBones) { bodyRate += `<td/>`; } rate.forEach(x => { bodyRate += `<td>${x.toFixed(2)}</td>`; }); bodyRate += '</tr>'; let bodyAvg = ''; bodyAvg += '<tr>'; bodyAvg += `<th scope="col">avg/${npcID === null ? "kill" : "steal"}</th>`; if (hasBones) { bodyAvg += `<td/>`; } avg.forEach(x => { bodyAvg += `<td>${formatNumber(1 * x.toFixed(3))}</td>`; }); bodyAvg += '</tr>'; let bodyOwned = '<tr>'; bodyOwned += '<th scope="col">owned</th>'; if (hasBones) { bodyOwned += `<td>${getBankQty(bones)}</td>`; } owned.forEach(x => { bodyOwned += `<td>${formatNumber(x)}</td>`; }); bodyOwned += '</tr>'; // insert table $(`#${container}`).replaceWith('' + `<small id=${container}>` + '<table class="table table-borderless table-sm">' + '<thead>' + header + '</thead>' + '<tbody>' + bodyRate + bodyAvg + bodyOwned + '</tbody>' + '</table>' + '</small>' ); } mlc.updateInterval = (interval) => { mlc.interval = interval; clearInterval(mlc.looper); mlc.looper = setInterval(mlc.drawLootTable, mlc.interval); console.log(`Started Melvor Loot Container with interval ${mlc.interval}`); } function startLootContainer() { $('#combat-area-selection').after(mlc.tempContainer('cb-lootContainer', 'border-combat', false)) $('#thieving-food-container').parent().parent().parent().next().after(mlc.tempContainer('pp-lootContainer', 'border-thieving', true)) mlc.updateInterval(500); /////// //log// /////// console.log("Melvor Loot Container Loaded"); } function loadScript() { if (typeof confirmedLoaded !== typeof undefined && confirmedLoaded) { // Only load script after game has opened clearInterval(scriptLoader); startLootContainer(); } } const scriptLoader = setInterval(loadScript, 200); });
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址