MediaWiki:Common.js: Difference between revisions
Force sidebar pin and light mode |
Switched to use CSS class for passing arguments |
||
| (10 intermediate revisions by the same user not shown) | |||
| Line 1: | Line 1: | ||
$(document).ready(function() { | |||
$('#ca-nstab-main a').text('Article'); | |||
$('#ca-history a').text('History'); | |||
$('#ca-view a').text('Read'); | |||
}); | |||
// Skill Calculator logic to be embedded in MediaWiki:Common.js | |||
mw.hook('wikipage.content').add(function($content) { | |||
// Only run if the page contains a calculator container | |||
const calcContainer = $content.find('#wiki-skill-calc')[0]; | |||
if (!calcContainer) return; | |||
if (calcContainer.dataset.initialized) return; | |||
calcContainer.dataset.initialized = 'true'; | |||
const skillClass = Array.from(calcContainer.classList).find(c => c.startsWith('skill-')); | |||
( | if (!skillClass) { | ||
calcContainer.innerHTML = "<p style='color:red;'>Error: No skill class found on container.</p>"; | |||
return; | |||
} | |||
const currentSkill = skillClass.replace('skill-', ''); // e.g., "Mining" | |||
document. | |||
// Raw XP Table (Level 1 to 99) | |||
const xpTable = [ | |||
0, 0, 74, 160, 258, 371, 500, 649, 820, 1016, 1241, 1500, 1797, 2139, 2531, 2982, 3500, 4095, 4778, 5563, 6464, 7500, 8690, 10056, 11626, 13429, 15500, 17879, 20612, 23751, 27358, 31500, 36258, 41724, 48003, 55215, 63500, 73017, 83949, 96506, 110930, 127500, 146533, 168397, 193512, 222361, 255500, 293567, 337294, 387523, 445222, 511500, 587634, 675088, 775547, 890944, 1023500, 1175767, 1350676, 1551594, 1782388, 2047500, 2352034, 2701852, 3103688, 3565275, 4095500, 4704568, 5404204, 6207875, 7131050, 8191500, 9409637, 10808909, 12416250, 14262600, 16383500, 18819774, 21618318, 24833000, 28525701, 32767500, 37640048, 43237135, 49666500, 57051902, 65535500, 75280595, 86474770, 99333501, 114104303, 131071500, 150561691, 172950041, 198667502, 228209107, 262143500, 301123982, 345900582, 397335504 | |||
]; | |||
// Data compiled from the scraped files | |||
const skillData = { | |||
"Mining": [ | |||
{ "name": "Copper Ore", "reqLevel": 1, "xp": 15 }, | |||
{ "name": "Tin Ore", "reqLevel": 1, "xp": 15 }, | |||
{ "name": "Iron Ore", "reqLevel": 10, "xp": 30 }, | |||
{ "name": "Coal Ore", "reqLevel": 20, "xp": 80 }, | |||
{ "name": "Mithril Ore", "reqLevel": 30, "xp": 150 }, | |||
{ "name": "Gold Ore", "reqLevel": 40, "xp": 350 }, | |||
{ "name": "Essence Geode", "reqLevel": 50, "xp": 550 } | |||
], | |||
"Fishing": [ | |||
{ "name": "Minnow", "reqLevel": 1, "xp": 8 }, | |||
{ "name": "Common Trout", "reqLevel": 5, "xp": 75 }, | |||
{ "name": "Perch", "reqLevel": 10, "xp": 225 }, | |||
{ "name": "Bass", "reqLevel": 20, "xp": 200 }, | |||
{ "name": "Blue Gill", "reqLevel": 30, "xp": 75 }, | |||
{ "name": "Elder Trout", "reqLevel": 40, "xp": 500 }, | |||
{ "name": "Carp", "reqLevel": 50, "xp": 1250 } | |||
], | |||
"PotionMaking": [ | |||
{ "name": "Weak Health Potion", "reqLevel": 1, "xp": 25 }, | |||
{ "name": "Health Potion", "reqLevel": 10, "xp": 100 }, | |||
{ "name": "Attack Potion", "reqLevel": 25, "xp": 1500 }, | |||
{ "name": "Fishing Potion", "reqLevel": 30, "xp": 2000 }, | |||
{ "name": "Mining Potion", "reqLevel": 30, "xp": 2000 }, | |||
{ "name": "Shield Potion", "reqLevel": 40, "xp": 3500 }, | |||
{ "name": "Strong Health Potion", "reqLevel": 50, "xp": 5000 }, | |||
{ "name": "Strong Shield Potion", "reqLevel": 60, "xp": 8000 } | |||
] | |||
}; | |||
const actions = skillData[currentSkill]; | |||
if (!actions) { | |||
calcContainer.innerHTML = "<p style='color:red;'>Calculator data not found for " + currentSkill + ".</p>"; | |||
return; | |||
} | |||
// Convert level to XP | |||
function levelToXP(level) { | |||
if (level < 1) return xpTable[1]; | |||
if (level > 99) return xpTable[99]; | |||
return xpTable[level]; | |||
} | |||
function calculateActions(currentXP, targetXP) { | |||
const xpNeeded = targetXP - currentXP; | |||
if (xpNeeded <= 0) return []; | |||
return actions.map(action => { | |||
const amount = Math.ceil(xpNeeded / action.xp); | |||
return { ...action, amount, xpNeeded }; | |||
}).sort((a, b) => a.reqLevel - b.reqLevel); | |||
} | |||
function renderCalculator() { | |||
const currentLvl = parseInt(document.getElementById('calc-current-lvl').value) || 1; | |||
const targetLvl = parseInt(document.getElementById('calc-target-lvl').value) || (currentLvl + 1); | |||
const currentXP = levelToXP(currentLvl); | |||
const targetXP = levelToXP(targetLvl); | |||
const xpNeeded = targetXP - currentXP; | |||
let html = ` | |||
<div class="calc-results-header"> | |||
<h3>XP Required: <span>${xpNeeded.toLocaleString()}</span></h3> | |||
<p>From Level ${currentLvl} (${currentXP.toLocaleString()} XP) to Level ${targetLvl} (${targetXP.toLocaleString()} XP)</p> | |||
</div> | |||
<table class="wikitable calc-table"> | |||
<tr><th>Action</th><th>Level Req.</th><th>XP/Action</th><th>Total Actions</th></tr> | |||
`; | |||
if (xpNeeded <= 0) { | |||
html += `<tr><td colspan="4" style="text-align:center;">You have already reached the target level!</td></tr>`; | |||
} else { | |||
const results = calculateActions(currentXP, targetXP); | |||
results.forEach(res => { | |||
const available = currentLvl >= res.reqLevel; | |||
const rowClass = available ? '' : 'calc-unavailable'; | |||
const opacity = available ? '1' : '0.5'; | |||
html += ` | |||
<tr class="${rowClass}" style="opacity: ${opacity}"> | |||
<td><strong>${res.name}</strong></td> | |||
<td>${res.reqLevel}</td> | |||
<td>${res.xp}</td> | |||
<td><strong>${res.amount.toLocaleString()}</strong></td> | |||
</tr> | |||
`; | |||
}); | |||
} | } | ||
html += `</table>`; | |||
document.getElementById('calc-results').innerHTML = html; | |||
} | } | ||
// | // Inject CSS | ||
const style = document.createElement('style'); | |||
style.innerHTML = ` | |||
.calc-wrapper { | |||
background: #1a1b26; | |||
color: #a9b1d6; | |||
padding: 20px; | |||
border-radius: 8px; | |||
border: 1px solid #414868; | |||
max-width: 600px; | |||
margin: 20px 0; | |||
font-family: 'Inter', sans-serif; | |||
box-shadow: 0 10px 25px rgba(0,0,0,0.5); | |||
} | |||
.calc-wrapper h2 { | |||
margin-top: 0; | |||
color: #7aa2f7; | |||
border-bottom: 2px solid #24283b; | |||
padding-bottom: 10px; | |||
} | |||
.calc-inputs { | |||
display: flex; | |||
gap: 20px; | |||
margin-bottom: 20px; | |||
} | |||
.calc-input-group { | |||
display: flex; | |||
flex-direction: column; | |||
gap: 5px; | |||
} | |||
.calc-input-group label { | |||
font-size: 12px; | |||
text-transform: uppercase; | |||
font-weight: bold; | |||
color: #565f89; | |||
} | |||
.calc-input-group input { | |||
background: #24283b; | |||
border: 1px solid #414868; | |||
color: #c0caf5; | |||
padding: 10px; | |||
border-radius: 4px; | |||
width: 100px; | |||
font-size: 16px; | |||
font-weight: bold; | |||
} | |||
.calc-input-group input:focus { | |||
outline: none; | |||
border-color: #7aa2f7; | |||
} | |||
.calc-results-header h3 { | |||
color: #bb9af7; | |||
margin: 0 0 5px 0; | |||
} | |||
.calc-table { | |||
width: 100%; | |||
background: transparent !important; | |||
border: none !important; | |||
border-collapse: collapse; | |||
} | |||
.calc-table th { | |||
background: #24283b !important; | |||
color: #7dcfff !important; | |||
border: none !important; | |||
text-align: left; | |||
padding: 10px; | |||
} | |||
.calc-table td { | |||
border: none !important; | |||
border-bottom: 1px solid #24283b !important; | |||
padding: 10px; | |||
color: #c0caf5; | |||
} | |||
.calc-unavailable td { | |||
color: #565f89; | |||
} | |||
.calc-btn { | |||
margin-top: 19px; | |||
background: #7aa2f7; | |||
color: #1a1b26; | |||
border: none; | |||
padding: 10px 20px; | |||
border-radius: 4px; | |||
font-weight: bold; | |||
cursor: pointer; | |||
transition: all 0.2s ease; | |||
} | |||
.calc-btn:hover { | |||
background: #8caaee; | |||
} | |||
`; | |||
document.head.appendChild(style); | |||
// Initial Layout Setup | |||
calcContainer.innerHTML = ` | |||
<div class="calc-wrapper"> | |||
<h2>${currentSkill} Calculator</h2> | |||
<div class="calc-inputs"> | |||
<div class="calc-input-group"> | |||
<label>Current Level</label> | |||
<input type="number" id="calc-current-lvl" value="1" min="1" max="99"> | |||
</div> | |||
<div class="calc-input-group"> | |||
<label>Target Level</label> | |||
<input type="number" id="calc-target-lvl" value="10" min="2" max="99"> | |||
</div> | |||
<button class="calc-btn" id="calc-refresh-btn">Calculate</button> | |||
</div> | |||
<div id="calc-results"></div> | |||
</div> | |||
`; | |||
document.getElementById('calc-current-lvl').addEventListener('change', renderCalculator); | |||
document.getElementById('calc-target-lvl').addEventListener('change', renderCalculator); | |||
document.getElementById('calc-refresh-btn').addEventListener('click', renderCalculator); | |||
// Render initially | |||
renderCalculator(); | |||
}); | }); | ||