MediaWiki:Common.js: Difference between revisions
No edit summary |
Automated page publish |
||
| Line 28: | Line 28: | ||
}; | }; | ||
Object.keys(GATHER).forEach(function(k){ GATHER[k].sort(function(a,b){ return a.xp-b.xp; }); }); | Object.keys(GATHER).forEach(function(k){ GATHER[k].sort(function(a,b){ return a.xp-b.xp; }); }); | ||
// Smithing crafting tree, sourced from the game's own recipe data (not fan-site numbers). | |||
// Each entry: item name -> array of {name, count} ingredients needed to craft ONE of that item. | |||
// Items with no entry here are raw/gathered materials (chain terminates). | |||
var RECIPES = { | |||
'Iron Rod': [{name:'Iron Bar', count:1}], | |||
'Large Mithril Rod': [{name:'Mithril Rod', count:2}], | |||
'Mithril Rod': [{name:'Mithril Bar', count:2}], | |||
'Steel Rod': [{name:'Steel Bar', count:1}], | |||
'Iron Plate': [{name:'Iron Bar', count:2}], | |||
'Large Steel Rod': [{name:'Steel Rod', count:2}], | |||
'Silver Plate': [{name:'Silver Bar', count:7}], | |||
'Silver Foil': [{name:'Silver Plate', count:1}], | |||
'Gold Plate': [{name:'Gold Bar', count:8}], | |||
'Steel Plate': [{name:'Steel Bar', count:2}], | |||
'Large Steel Plate': [{name:'Steel Plate', count:2}], | |||
'Large Mithril Plate': [{name:'Mithril Plate', count:4}], | |||
'Mithril Plate': [{name:'Mithril Bar', count:4}], | |||
'Golden Shield Frame': [{name:'Gold Plate', count:5},{name:'Gold Bar', count:3},{name:'Steel Rod', count:2},{name:'Steel Bar', count:2}], | |||
'Small Ebony Rod': [{name:'Ebony Bar', count:2}], | |||
'Large Ebony Rod': [{name:'Ebony Rod', count:4},{name:'Ebony Bar', count:3}], | |||
'Ebony Rod': [{name:'Small Ebony Rod', count:4},{name:'Ebony Bar', count:3}], | |||
'Small Ebony Plate': [{name:'Ebony Bar', count:4}], | |||
'Ebony Plate': [{name:'Small Ebony Plate', count:4},{name:'Ebony Bar', count:3}], | |||
'Large Ebony Plate': [{name:'Ebony Plate', count:4},{name:'Ebony Bar', count:3}], | |||
'Duskknight Boot Left Sabaton': [{name:'Ebony Plate', count:1},{name:'Silver Foil', count:2}], | |||
'Duskknight Boot Right Sabaton': [{name:'Ebony Plate', count:1},{name:'Silver Foil', count:2}], | |||
'Duskknight Leg Tuille': [{name:'Ebony Plate', count:1},{name:'Silver Foil', count:1}], | |||
'Duskknight Leg Poleyn': [{name:'Ebony Plate', count:1},{name:'Silver Foil', count:1}], | |||
'Duskknight Body Pauldron': [{name:'Ebony Plate', count:1},{name:'Silver Foil', count:1}], | |||
'Duskknight Body Couter': [{name:'Ebony Plate', count:1},{name:'Silver Foil', count:1}], | |||
'Duskknight Body Rerebrace': [{name:'Ebony Plate', count:2},{name:'Silver Foil', count:2}], | |||
'Duskknight Body Vambrace': [{name:'Ebony Plate', count:2},{name:'Silver Foil', count:2}], | |||
'Duskknight Leg Tasset': [{name:'Ebony Plate', count:3},{name:'Silver Foil', count:3}], | |||
'Duskknight Boot Greave': [{name:'Large Ebony Plate', count:1},{name:'Silver Foil', count:2}], | |||
'Duskknight Leg Cuisses': [{name:'Large Ebony Plate', count:2},{name:'Silver Foil', count:2}], | |||
'Duskknight Helmet Face Plate': [{name:'Large Ebony Plate', count:1},{name:'Silver Foil', count:2}], | |||
'Duskknight Helmet Head Plate': [{name:'Large Ebony Plate', count:1},{name:'Silver Foil', count:2}], | |||
'Duskknight Helmet Spike': [{name:'Large Ebony Rod', count:1},{name:'Silver Foil', count:1}], | |||
'Duskknight Body Breastplate': [{name:'Large Ebony Plate', count:4},{name:'Silver Foil', count:8}], | |||
'Iron Bar': [{name:'Iron Ore', count:2}], | |||
'Steel Bar': [{name:'Iron Ore', count:1},{name:'Coal Ore', count:1}], | |||
'Mithril Bar': [{name:'Mithril Ore', count:1},{name:'Coal Ore', count:2}], | |||
'Gold Bar': [{name:'Gold Ore', count:8}], | |||
'Silver Bar': [{name:'Silver Ore', count:7}], | |||
'Ebony Bar': [{name:'Ebony Ore', count:7}] | |||
}; | |||
// Walks RECIPES tier-by-tier from `qty` of `name`, merging same-name items within a tier. | |||
// Returns {tierLines: [string,...], totals: {rawItemName: qty,...}} or null if `name` has no recipe. | |||
function buildMaterialBreakdown(name, qty){ | |||
if (!RECIPES[name]) return null; | |||
var tierLines = []; | |||
var totals = {}; | |||
var currentTier = [{name:name, qty:qty}]; | |||
tierLines.push(currentTier.map(function(e){ return fmt(e.qty) + ' ' + e.name; }).join(' & ')); | |||
while (true){ | |||
var nextMap = {}; | |||
var expandedAny = false; | |||
currentTier.forEach(function(e){ | |||
var recipe = RECIPES[e.name]; | |||
if (!recipe){ totals[e.name] = (totals[e.name] || 0) + e.qty; return; } | |||
expandedAny = true; | |||
recipe.forEach(function(ing){ nextMap[ing.name] = (nextMap[ing.name] || 0) + e.qty * ing.count; }); | |||
}); | |||
if (!expandedAny) break; | |||
var nextTier = Object.keys(nextMap).map(function(n){ return {name:n, qty:nextMap[n]}; }); | |||
tierLines.push(nextTier.map(function(e){ return fmt(e.qty) + ' ' + e.name; }).join(' & ')); | |||
currentTier = nextTier; | |||
} | |||
return { tierLines: tierLines, totals: totals }; | |||
} | |||
var MONSTERS = [ | var MONSTERS = [ | ||
| Line 111: | Line 183: | ||
'<div class="vl-xp-pair"><div class="vl-xp-box"><label>Current XP</label><div class="vl-num" id="vl-cur-xp">0</div></div><div class="vl-xp-box"><label>Target XP</label><div class="vl-num" id="vl-tgt-xp">0</div></div></div>' + | '<div class="vl-xp-pair"><div class="vl-xp-box"><label>Current XP</label><div class="vl-num" id="vl-cur-xp">0</div></div><div class="vl-xp-box"><label>Target XP</label><div class="vl-num" id="vl-tgt-xp">0</div></div></div>' + | ||
'<div class="vl-result"><p class="vl-result-head">Reckoning</p><p class="vl-result-text" id="vl-gather-result">Pick a skill and an action to begin.</p><div class="vl-bar-track"><div class="vl-bar-fill" id="vl-gather-fill"></div></div></div>' + | '<div class="vl-result"><p class="vl-result-head">Reckoning</p><p class="vl-result-text" id="vl-gather-result">Pick a skill and an action to begin.</p><div class="vl-bar-track"><div class="vl-bar-fill" id="vl-gather-fill"></div></div></div>' + | ||
'<div class="vl-result" id="vl-breakdown-section" style="display:none;"><p class="vl-result-head">Material Breakdown</p><p class="vl-result-text" id="vl-breakdown-text"></p></div>' + | |||
'</div>' + | '</div>' + | ||
'<div id="vl-combat-view" style="display:none;">' + | '<div id="vl-combat-view" style="display:none;">' + | ||
| Line 203: | Line 276: | ||
var gatherResult = mount.querySelector('#vl-gather-result'); | var gatherResult = mount.querySelector('#vl-gather-result'); | ||
var gatherFill = mount.querySelector('#vl-gather-fill'); | var gatherFill = mount.querySelector('#vl-gather-fill'); | ||
var breakdownSection = mount.querySelector('#vl-breakdown-section'); | |||
var breakdownText = mount.querySelector('#vl-breakdown-text'); | |||
function populateActions(){ | function populateActions(){ | ||
| Line 238: | Line 313: | ||
gatherResult.textContent = 'Level ' + tgtLevel + ' calls for ' + fmt(tgtXp) + ' xp. You already have that at level ' + curLevel + ' (' + fmt(curXp) + ' xp). Nothing left to gather.'; | gatherResult.textContent = 'Level ' + tgtLevel + ' calls for ' + fmt(tgtXp) + ' xp. You already have that at level ' + curLevel + ' (' + fmt(curXp) + ' xp). Nothing left to gather.'; | ||
gatherFill.style.width = '100%'; | gatherFill.style.width = '100%'; | ||
breakdownSection.style.display = 'none'; | |||
return; | return; | ||
} | } | ||
| Line 245: | Line 321: | ||
gatherResult.textContent = 'Level ' + curLevel + ' -> Level ' + tgtLevel + '\nNeed ' + fmt(needed) + ' more xp\n= ' + fmt(actions) + ' x ' + entry.name; | gatherResult.textContent = 'Level ' + curLevel + ' -> Level ' + tgtLevel + '\nNeed ' + fmt(needed) + ' more xp\n= ' + fmt(actions) + ' x ' + entry.name; | ||
gatherFill.style.width = '0%'; | gatherFill.style.width = '0%'; | ||
var breakdown = state.tab === 'smithing' ? buildMaterialBreakdown(entry.name, actions) : null; | |||
if (!breakdown){ | |||
breakdownSection.style.display = 'none'; | |||
} else { | |||
breakdownSection.style.display = 'block'; | |||
var text = breakdown.tierLines.join('\n-> '); | |||
var rawNames = Object.keys(breakdown.totals); | |||
if (rawNames.length){ | |||
text += '\n\nTotal raw materials: ' + rawNames.map(function(n){ return fmt(breakdown.totals[n]) + ' ' + n; }).join(', '); | |||
} | |||
breakdownText.textContent = text; | |||
} | |||
} | } | ||