MediaWiki:MaxHitCalc.js
Note: After publishing, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
- Opera: Press Ctrl-F5.
// Formula mirrors OSRS (https://oldschool.runescape.wiki/w/Maximum_melee_hit):
// boostedStr = floor(strength + potionBoost)
// baseEff = boostedStr + styleBonus + 8
// effectiveStr = floor(baseEff * prayerMultiplier)
// maxHit = floor(effectiveStr * (strengthBonus + 64) / 640)
//
// Scythe of Vitur (OSRS): splits by NPC size, each hit rounds down:
// Small -> [max]
// Medium -> [max, floor(max/2)]
// Large -> [max, floor(max/2), floor(max/4)]
// Sanguine Scythe of Vitur: intended 4 hits on ALL NPC sizes —
// 2x2 is BUGGED and only deals 3 hits:
// [max, floor(max/2), floor(max/2), floor(max/4)] (2x2 bugged: [max, floor(max/2), floor(max/2)])
// Holy Scythe of Vitur: 3 hits on all NPC sizes:
// [max, floor(max/2), floor(max/4)]
// Example (max 51): Sanguine 51-25-25-12, OSRS scythe 51-25-12.
// Sanguine 2x2 max 15 -> 15-7-7, max 10 -> 10-5-5; 1x1 max 8 -> 8-4-4-2.
//
// Divine Overload estimate: assumed 5 + floor(level*0.22) -> +26 at 99 strength (125 total, per update notes "5-26 levels").
mw.hook('wikipage.content').add(function () {
if (mw.config.get('wgPageName') !== "DPS_calculator") return;
var container = document.getElementById("maxHitCalcContainer");
if (!container) return;
var BOOSTS = {
"none": { label: "None", boost: function (level) { return 0; } },
"super-combat": { label: "Super Combat Potion", boost: function (level) { return 5 + Math.floor(level * 0.15); } },
"cox-overload": { label: "Smouldering Heart/CoX Overload", boost: function (level) { return 6 + Math.floor(level * 0.16); } },
"divine-overload": { label: "Divine Overload estimate", boost: function (level) { return 5 + Math.floor(level * 0.22); } }
};
function scytheHits(weapon, npcSize, max) {
switch (weapon) {
case "scythe": // OSRS rules
if (npcSize === "small") return [max];
if (npcSize === "medium") return [max, Math.floor(max / 2)];
return [max, Math.floor(max / 2), Math.floor(max / 4)];
case "sanguine": // intended 4 hits on all sizes; 2x2 BUGGED → 3 hits
if (npcSize === "medium") return [max, Math.floor(max / 2), Math.floor(max / 2)];
return [max, Math.floor(max / 2), Math.floor(max / 2), Math.floor(max / 4)];
case "holy": // 3 hits on all NPC sizes
return [max, Math.floor(max / 2), Math.floor(max / 4)];
default:
return [max];
}
}
container.innerHTML =
'<table style="border-collapse:collapse; border:1px solid #596e96; background:#222e45; color:#fff;">' +
'<tbody>' +
'<tr><th colspan="2" style="padding:8px; text-align:left; border-bottom:1px solid #596e96; background:#222e45;">Max Hit Calculator</th></tr>' +
'<tr><td style="padding:8px; border-bottom:1px solid #596e96; background:#313e59;">Strength level</td>' +
'<td style="padding:8px; border-bottom:1px solid #596e96; border-left:1px solid #596e96; background:#222e45;">' +
'<input type="number" id="mhLevel" value="99" min="1" max="99" style="width:70px;"> (1–99)</td></tr>' +
'<tr><td style="padding:8px; border-bottom:1px solid #596e96; background:#222e45;">Prayer</td>' +
'<td style="padding:8px; border-bottom:1px solid #596e96; border-left:1px solid #596e96; background:#313e59;">' +
'<select id="mhPrayer">' +
'<option value="1">None</option>' +
'<option value="1.05">Burst of Strength (×1.05)</option>' +
'<option value="1.10">Superhuman Strength (×1.10)</option>' +
'<option value="1.15">Ultimate Strength (×1.15)</option>' +
'<option value="1.18">Chivalry (×1.18)</option>' +
'<option value="1.23" selected>Piety (×1.23)</option>' +
'</select></td></tr>' +
'<tr><td style="padding:8px; border-bottom:1px solid #596e96; background:#313e59;">Boost</td>' +
'<td style="padding:8px; border-bottom:1px solid #596e96; border-left:1px solid #596e96; background:#222e45;">' +
'<select id="mhBoost">' +
'<option value="none">None</option>' +
'<option value="super-combat" selected>Super Combat Potion</option>' +
'<option value="cox-overload">Smouldering Heart/CoX Overload</option>' +
'<option value="divine-overload">Divine Overload estimate</option>' +
'</select></td></tr>' +
'<tr><td style="padding:8px; border-bottom:1px solid #596e96; background:#222e45;">Weapon</td>' +
'<td style="padding:8px; border-bottom:1px solid #596e96; border-left:1px solid #596e96; background:#313e59;">' +
'<select id="mhWeapon">' +
'<option value="none" selected>Normal</option>' +
'<option value="scythe">Scythe of Vitur</option>' +
'<option value="sanguine">Sanguine Scythe of Vitur</option>' +
'<option value="holy">Holy Scythe of Vitur</option>' +
'</select>' +
'<span id="mhWeaponHint" style="display:none; color:#9aa5b5; font-size:12px;"></span></td></tr>' +
'<tr id="mhSizeRow" style="display:none;"><td style="padding:8px; border-bottom:1px solid #596e96; background:#313e59;">NPC size</td>' +
'<td style="padding:8px; border-bottom:1px solid #596e96; border-left:1px solid #596e96; background:#222e45;">' +
'<select id="mhSize">' +
'<option value="small">Small (1×1) – 1 hit</option>' +
'<option value="medium" selected>Medium (2×2) – 2 hits</option>' +
'<option value="large">Large (3×3+) – 3 hits</option>' +
'</select></td></tr>' +
'<tr><td style="padding:8px; border-bottom:1px solid #596e96; background:#222e45;">Strength bonus</td>' +
'<td style="padding:8px; border-bottom:1px solid #596e96; border-left:1px solid #596e96; background:#313e59;">' +
'<input type="number" id="mhStrBonus" value="0" min="0" style="width:80px;"> (visible gear stat)</td></tr>' +
'<tr><td style="padding:8px; border-bottom:1px solid #596e96; background:#313e59;">Attack style</td>' +
'<td style="padding:8px; border-bottom:1px solid #596e96; border-left:1px solid #596e96; background:#222e45;">' +
'<select id="mhStyle">' +
'<option value="3" selected>Aggressive (+3)</option>' +
'<option value="1">Controlled (+1)</option>' +
'<option value="0">Accurate / Defensive (+0)</option>' +
'</select></td></tr>' +
'<tr><td style="padding:8px; border-bottom:1px solid #596e96; background:#222e45;">Salve</td>' +
'<td style="padding:8px; border-bottom:1px solid #596e96; border-left:1px solid #596e96; background:#313e59;">' +
'<input type="checkbox" id="mhSalve"> +20% vs undead, applied before Royal/Divine zone</td></tr>' +
'<tr><td style="padding:8px; background:#222e45;">In Royal/Divine zone</td>' +
'<td style="padding:8px; border-left:1px solid #596e96; background:#313e59;">' +
'<input type="checkbox" id="mhZone"> +10% damage, applied last</td></tr>' +
'</tbody>' +
'</table>' +
'<p style="margin:14px 0 4px; font-size:16px;">' +
'Max hit: <strong id="mhMaxHit" style="font-size:26px; color:#7ec850;">–</strong>' +
'</p>' +
'<div id="mhHits" style="display:none; margin-bottom:4px;"></div>' +
'<details>' +
'<summary style="cursor:pointer; color:#f5b942;">Calculation breakdown</summary>' +
'<table style="border-collapse:collapse; border:1px solid #596e96; margin-top:8px; color:#fff;">' +
'<tbody>' +
'<tr><td style="padding:6px 12px; background:#313e59; border-bottom:1px solid #596e96;">Strength level</td><td id="mhBLevel" style="padding:6px 12px; background:#222e45; border-bottom:1px solid #596e96; border-left:1px solid #596e96;">–</td></tr>' +
'<tr><td style="padding:6px 12px; background:#222e45; border-bottom:1px solid #596e96;">Potion boost</td><td id="mhBPotion" style="padding:6px 12px; background:#313e59; border-bottom:1px solid #596e96; border-left:1px solid #596e96;">–</td></tr>' +
'<tr><td style="padding:6px 12px; background:#313e59; border-bottom:1px solid #596e96;">Boosted strength</td><td id="mhBBoosted" style="padding:6px 12px; background:#222e45; border-bottom:1px solid #596e96; border-left:1px solid #596e96;">–</td></tr>' +
'<tr><td style="padding:6px 12px; background:#222e45; border-bottom:1px solid #596e96;">Style bonus</td><td id="mhBStyle" style="padding:6px 12px; background:#313e59; border-bottom:1px solid #596e96; border-left:1px solid #596e96;">–</td></tr>' +
'<tr><td style="padding:6px 12px; background:#313e59; border-bottom:1px solid #596e96;">Base effective strength (boosted + style + 8)</td><td id="mhBBase" style="padding:6px 12px; background:#222e45; border-bottom:1px solid #596e96; border-left:1px solid #596e96;">–</td></tr>' +
'<tr><td style="padding:6px 12px; background:#222e45; border-bottom:1px solid #596e96;">Prayer multiplier</td><td id="mhBPrayer" style="padding:6px 12px; background:#313e59; border-bottom:1px solid #596e96; border-left:1px solid #596e96;">–</td></tr>' +
'<tr><td style="padding:6px 12px; background:#313e59; border-bottom:1px solid #596e96;">Effective strength (after prayer, floored)</td><td id="mhBEffective" style="padding:6px 12px; background:#222e45; border-bottom:1px solid #596e96; border-left:1px solid #596e96;">–</td></tr>' +
'<tr><td style="padding:6px 12px; background:#222e45; border-bottom:1px solid #596e96;">Strength bonus (gear)</td><td id="mhBGear" style="padding:6px 12px; background:#313e59; border-bottom:1px solid #596e96; border-left:1px solid #596e96;">–</td></tr>' +
'<tr><td style="padding:6px 12px; background:#313e59; border-bottom:1px solid #596e96;">Max hit (base)</td><td id="mhBFinal" style="padding:6px 12px; background:#222e45; border-bottom:1px solid #596e96; border-left:1px solid #596e96;">–</td></tr>' +
'<tr><td style="padding:6px 12px; background:#222e45; border-bottom:1px solid #596e96;">Salve Amulet (ei) vs undead (+20%)</td><td id="mhBSalve" style="padding:6px 12px; background:#313e59; border-bottom:1px solid #596e96; border-left:1px solid #596e96;">–</td></tr>' +
'<tr><td style="padding:6px 12px; background:#313e59; border-bottom:1px solid #596e96;">Royal/Divine zone (+10%)</td><td id="mhBZone" style="padding:6px 12px; background:#222e45; border-bottom:1px solid #596e96; border-left:1px solid #596e96;">–</td></tr>' +
'<tr><td style="padding:6px 12px; background:#313e59; border-bottom:1px solid #596e96;">Scythe hits</td><td id="mhBHits" style="padding:6px 12px; background:#222e45; border-bottom:1px solid #596e96; border-left:1px solid #596e96;">–</td></tr>' +
'<tr><td style="padding:6px 12px; background:#222e45;">Total damage</td><td id="mhBTotal" style="padding:6px 12px; background:#313e59; border-left:1px solid #596e96;">–</td></tr>' +
'</tbody>' +
'</table>' +
'</details>' +
'<p style="font-size:12px; color:#9aa5b5; margin-top:12px;">' +
'Formula (OSRS): maxHit = floor(effectiveStr × (strBonus + 64) / 640), ' +
'effectiveStr = floor((floor(level + potionBoost) + styleBonus + 8) × prayer). ' +
'Super Combat = 5 + floor(level × 0.15); Smouldering Heart/CoX Overload = 6 + floor(level × 0.16); ' +
'Divine Overload = 5 + floor(level × 0.22) (estimate). ' +
'Royal/Divine zone: +10%, applied last. ' +
'Salve Amulet (ei): +20% vs undead, applied before the zone. ' +
'Scythe of Vitur: 1 hit (small), [max, max/2] (medium), [max, max/2, max/4] (large), each hit rounded down. ' +
'Sanguine Scythe of Vitur: [max, max/2, max/2, max/4] on all NPC sizes; 2x2 is BUGGED, only 3 hits [max, max/2, max/2] (in-game verified). ' +
'Holy Scythe of Vitur: [max, max/2, max/4] on all NPC sizes.' +
'</p>';
function update() {
var level = parseInt(document.getElementById("mhLevel").value, 10);
if (isNaN(level)) level = 99;
level = Math.min(99, Math.max(1, level));
var prayer = parseFloat(document.getElementById("mhPrayer").value) || 1;
var boostKey = document.getElementById("mhBoost").value;
var potionBoost = BOOSTS[boostKey].boost(level);
var strBonus = parseInt(document.getElementById("mhStrBonus").value, 10);
if (isNaN(strBonus)) strBonus = 0;
strBonus = Math.max(0, strBonus);
var styleBonus = parseInt(document.getElementById("mhStyle").value, 10) || 0;
var weapon = document.getElementById("mhWeapon").value;
var npcSize = document.getElementById("mhSize").value;
var salve = document.getElementById("mhSalve").checked;
var zone = document.getElementById("mhZone").checked;
var boostedStr = Math.floor(level + potionBoost);
var baseEff = boostedStr + styleBonus + 8;
var effectiveStr = Math.floor(baseEff * prayer);
var maxHit = Math.floor(effectiveStr * (strBonus + 64) / 640);
var salveMax = salve ? Math.floor(maxHit * 1.20) : maxHit;
var zoneMax = zone ? Math.floor(salveMax * 1.10) : salveMax;
var hits = scytheHits(weapon, npcSize, zoneMax);
var total = 0;
for (var i = 0; i < hits.length; i++) total += hits[i];
// show/hide scythe-only UI
document.getElementById("mhSizeRow").style.display = (weapon === "scythe" || weapon === "sanguine") ? "" : "none";
var hint = document.getElementById("mhWeaponHint");
if (weapon === "sanguine") {
hint.style.display = "";
hint.textContent = "4 hits on all NPC sizes — 2×2 is bugged (only 3 hits)";
} else if (weapon === "holy") {
hint.style.display = "";
hint.textContent = "3 hits on all NPC sizes";
} else {
hint.style.display = "none";
}
document.getElementById("mhMaxHit").textContent = zoneMax;
var hitsDiv = document.getElementById("mhHits");
if (weapon === "none") {
hitsDiv.style.display = "none";
} else {
hitsDiv.style.display = "";
var weaponLabel;
if (weapon === "sanguine") weaponLabel = "Sanguine Scythe of Vitur (" + npcSize.charAt(0).toUpperCase() + npcSize.slice(1) + ")";
else if (weapon === "holy") weaponLabel = "Holy Scythe of Vitur";
else weaponLabel = "Scythe of Vitur (" + npcSize.charAt(0).toUpperCase() + npcSize.slice(1) + ")";
hitsDiv.innerHTML = weaponLabel + " hits: " + hits.join(" – ") +
' — <strong style="color:#7ec850;">Total: ' + total + '</strong>';
}
document.getElementById("mhBLevel").textContent = level;
document.getElementById("mhBPotion").textContent = "+" + potionBoost + " (" + BOOSTS[boostKey].label + ")";
document.getElementById("mhBBoosted").textContent = boostedStr;
document.getElementById("mhBStyle").textContent = "+" + styleBonus;
document.getElementById("mhBBase").textContent = baseEff;
document.getElementById("mhBPrayer").textContent = "×" + prayer;
document.getElementById("mhBEffective").textContent = effectiveStr;
document.getElementById("mhBGear").textContent = strBonus;
document.getElementById("mhBFinal").textContent = maxHit;
document.getElementById("mhBSalve").textContent = salve ? "×1.20 → " + salveMax : "off (" + maxHit + ")";
document.getElementById("mhBZone").textContent = zone ? "×1.10 → " + zoneMax : "off (" + salveMax + ")";
document.getElementById("mhBHits").textContent = hits.join(" – ");
document.getElementById("mhBTotal").textContent = total;
}
document.getElementById("mhLevel").addEventListener("input", update);
document.getElementById("mhPrayer").addEventListener("change", update);
document.getElementById("mhBoost").addEventListener("change", update);
document.getElementById("mhWeapon").addEventListener("change", update);
document.getElementById("mhSize").addEventListener("change", update);
document.getElementById("mhStrBonus").addEventListener("input", update);
document.getElementById("mhStyle").addEventListener("change", update);
document.getElementById("mhSalve").addEventListener("change", update);
document.getElementById("mhZone").addEventListener("change", update);
update();
});