Module:Skills: Difference between revisions
From Melvor Idle
Falterfire (talk | contribs) (Removed redundant references to getSkillID since that's now a Constants function) |
Falterfire (talk | contribs) (Fixed indenting) |
||
Line 24: | Line 24: | ||
function p.getMasteryUnlockTable(frame) | function p.getMasteryUnlockTable(frame) | ||
local skillName = frame.args ~= nil and frame.args[1] or frame | |||
local skillID = Constants.getSkillID(skillName) | |||
if skillID == nil then | |||
return "ERROR: Failed to find a skill ID for "..skillName | |||
end | |||
local unlockTable = SkillData.MasteryUnlocks[skillID] | |||
if unlockTable == nil then | |||
return 'ERROR: Failed to find Mastery Unlock data for '..skillName | |||
end | |||
local result = '{|class="wikitable"\r\n!Level!!Unlock' | |||
for i, unlock in Shared.skpairs(unlockTable) do | |||
result = result..'\r\n|-' | |||
result = result..'\r\n|'..unlock.level..'||'..unlock.unlock | |||
end | |||
result = result..'\r\n|}' | |||
return result | |||
end | end | ||
function p.getMasteryCheckpointTable(frame) | function p.getMasteryCheckpointTable(frame) | ||
local skillName = frame.args ~= nil and frame.args[1] or frame | |||
local skillID = Constants.getSkillID(skillName) | |||
if skillID == nil then | |||
return "ERROR: Failed to find a skill ID for "..skillName | |||
end | |||
if SkillData.MasteryCheckpoints[skillID] == nil then | |||
return 'ERROR: Failed to find Mastery Unlock data for '..skillName | |||
end | |||
local bonuses = SkillData.MasteryCheckpoints[skillID].bonuses | |||
local totalPoolXP = SkillData.MasteryPoolXP[skillID + 1] | |||
local result = '{|class="wikitable"\r\n!Pool %!!style="width:100px"|Pool XP!!Bonus' | |||
for i, bonus in Shared.skpairs(bonuses) do | |||
result = result..'\r\n|-' | |||
result = result..'\r\n|'..(MasteryCheckpoints[i] * 100)..'%||' | |||
result = result..Shared.formatnum(totalPoolXP * MasteryCheckpoints[i])..' xp||'..bonus | |||
end | |||
result = result..'\r\n|-\r\n!colspan="2"|Total Mastery Pool XP' | |||
result = result..'\r\n|'..Shared.formatnum(totalPoolXP) | |||
result = result..'\r\n|}' | |||
return result | |||
end | end | ||
function p._getFarmingTable(category) | function p._getFarmingTable(category) | ||
local seedList = {} | |||
if category == 'Allotment' or category == 'Herb' or category == 'Tree' then | |||
seedList = Items.getItems(function(item) return item.tier == category end) | |||
else | |||
return 'ERROR: Invalid farming category. Please choose Allotment, Herb, or Tree' | |||
end | |||
local result = '{|class="wikitable sortable stickyHeader"' | |||
result = result..'\r\n|- class="headerRow-0"' | |||
result = result..'\r\n!colspan=2|Seeds!!'..Icons.Icon({'Farming', type='skill', notext=true})..' Level' | |||
result = result..'!!XP!!Growth Time!!Seed Value' | |||
if category == 'Allotment' then | |||
result = result..'!!colspan="2"|Crop!!Crop Healing!!Crop Value' | |||
elseif category == 'Herb' then | |||
result = result..'!!colspan="2"|Herb!!Herb Value' | |||
elseif category == 'Tree' then | |||
result = result..'!!colspan="2"|Logs!!Log Value' | |||
end | |||
result = result..'!!Seed Sources' | |||
table.sort(seedList, function(a, b) return a.farmingLevel < b.farmingLevel end) | |||
for i, seed in pairs(seedList) do | |||
result = result..'\r\n|-' | |||
result = result..'\r\n|'..Icons.Icon({seed.name, type='item', size='50', notext=true})..'||[['..seed.name..']]' | |||
result = result..'||'..seed.farmingLevel..'||'..Shared.formatnum(seed.farmingXP) | |||
result = result..'||data-sort-value="'..seed.timeToGrow..'"|'..Shared.timeString(seed.timeToGrow, true) | |||
result = result..'||data-sort-value="'..seed.sellsFor..'"|'..Icons.GP(seed.sellsFor) | |||
local crop = Items.getItemByID(seed.grownItemID) | |||
result = result..'||'..Icons.Icon({crop.name, type='item', size='50', notext=true})..'||[['..crop.name..']]' | |||
if category == 'Allotment' then | |||
result = result..'||'..Icons.Icon({'Hitpoints', type='skill', notext=true})..' '..(crop.healsFor * 10) | |||
end | |||
result = result..'||data-sort-value="'..crop.sellsFor..'"|'..Icons.GP(crop.sellsFor) | |||
result = result..'||'..ItemSourceTables._getItemSources(seed) | |||
end | |||
result = result..'\r\n|}' | |||
return result | |||
end | end | ||
function p.getFarmingTable(frame) | function p.getFarmingTable(frame) | ||
local category = frame.args ~= nil and frame.args[1] or frame | |||
return p._getFarmingTable(category) | |||
end | end | ||
function p.getFarmingFoodTable(frame) | function p.getFarmingFoodTable(frame) | ||
local result = '{| class="wikitable sortable stickyHeader"' | |||
result = result..'\r\n|- class="headerRow-0"' | |||
result = result..'\r\n!colspan="2"|Crop!!'..Icons.Icon({"Farming", type="skill", notext=true})..' Level' | |||
result = result..'!!Healing!!Value' | |||
local itemArray = Items.getItems(function(item) return item.grownItemID ~= nil end) | |||
table.sort(itemArray, function(a, b) return a.farmingLevel < b.farmingLevel end) | |||
for i, item in Shared.skpairs(itemArray) do | |||
local crop = Items.getItemByID(item.grownItemID) | |||
if crop.healsFor ~= nil and crop.healsFor > 0 then | |||
result = result..'\r\n|-' | |||
result = result..'\r\n|'..Icons.Icon({crop.name, type='item', notext='true', size='50'})..'||[['..crop.name..']]' | |||
result = result..'||style="text-align:right;"|'..item.farmingLevel | |||
result = result..'||style="text-align:right" data-sort-value="'..crop.healsFor..'"|'..Icons.Icon({"Hitpoints", type="skill", notext=true})..' '..(crop.healsFor * 10) | |||
result = result..'||style="text-align:right" data-sort-value="'..crop.sellsFor..'"|'..Icons.GP(crop.sellsFor) | |||
end | |||
end | |||
result = result..'\r\n|}' | |||
return result | |||
end | end | ||
function p.getFarmingPlotTable(frame) | function p.getFarmingPlotTable(frame) | ||
local areaName = frame.args ~= nil and frame.args[1] or frame | |||
local patches = nil | |||
for i, area in Shared.skpairs(SkillData.Farming.Patches) do | |||
if area.areaName == areaName then | |||
patches = area.patches | |||
break | |||
end | |||
end | |||
if patches == nil then | |||
return "ERROR: Invalid area name.[[Category:Pages with script errors" | |||
end | |||
local result = '{|class="wikitable"' | |||
result = result..'\r\n!Plot!!'..Icons.Icon({'Farming', type='skill', notext=true})..' Level!!Cost' | |||
for i, patch in Shared.skpairs(patches) do | |||
result = result..'\r\n|-\r\n|'..i | |||
result = result..'||style="text-align:right;" data-sort-value="0"|'..patch.level | |||
if patch.cost == 0 then | |||
result = result..'||Free' | |||
else | |||
result = result..'||style="text-align:right;" data-sort-value="'..patch.cost..'"|'..Icons.GP(patch.cost) | |||
end | |||
end | |||
result = result..'\r\n|}' | |||
return result | |||
end | end | ||
function p.getSmithingTable(frame) | function p.getSmithingTable(frame) | ||
local tableType = frame.args ~= nil and frame.args[1] or frame | |||
local bar = nil | |||
if tableType ~= 'Smelting' then | |||
bar = Items.getItem(tableType) | |||
if bar == nil then | |||
return 'ERROR: Could not find an item named '..tableType..' to build a smithing table with' | |||
elseif bar.type ~= 'Bar' then | |||
return 'ERROR: '..tableType.." is not a bar and thus can't be used for smithing" | |||
end | |||
end | |||
local smithList = {} | |||
for i, item in pairs(ItemData.Items) do | |||
if item.smithingLevel ~= nil then | |||
if tableType == 'Smelting' then | |||
if item.type == 'Bar' then | |||
table.insert(smithList, item) | |||
end | |||
else | |||
for j, req in pairs(item.smithReq) do | |||
if req.id == bar.id then | |||
table.insert(smithList, item) | |||
end | |||
end | |||
end | |||
end | |||
end | |||
local result = '{|class="wikitable sortable stickyHeader"' | |||
result = result..'\r\n|-class="headerRow-0"' | |||
result = result..'\r\n!Item!!Name!!'..Icons.Icon({'Smithing', type='skill', notext=true})..' Level!!XP!!Value!!Ingredients' | |||
--Adding value/bar for things other than smelting | |||
if bar ~= nil then result = result..'!!Value/Bar' end | |||
table.sort(smithList, function(a, b) | |||
if a.smithingLevel ~= b.smithingLevel then | |||
return a.smithingLevel < b.smithingLevel | |||
else | |||
return a.name < b.name | |||
end end) | |||
for i, item in Shared.skpairs(smithList) do | |||
result = result..'\r\n|-' | |||
result = result..'\r\n|'..Icons.Icon({item.name, type='item', size='50', notext=true})..'||' | |||
local qty = item.smithingQty ~= nil and item.smithingQty or 1 | |||
if qty > 1 then | |||
result = result..item.smithingQty..'x ' | |||
end | |||
result = result..'[['..item.name..']]' | |||
result = result..'||data-sort-value="'..item.smithingLevel..'"|'..Icons._SkillReq('Smithing', item.smithingLevel) | |||
result = result..'||'..item.smithingXP | |||
local totalValue = item.sellsFor * qty | |||
result = result..'||data-sort-value="'..totalValue..'"|'..Icons.GP(item.sellsFor) | |||
if qty > 1 then | |||
result = result..' (x'..qty..')' | |||
end | |||
result = result..'||' | |||
local barQty = 0 | |||
for i, mat in Shared.skpairs(item.smithReq) do | |||
matItem = Items.getItemByID(mat.id) | |||
if i > 1 then result = result..', ' end | |||
result = result..Icons.Icon({matItem.name, type='item', qty=mat.qty, notext=true}) | |||
if bar ~= nil and mat.id == bar.id then | |||
barQty = mat.qty | |||
end | |||
end | |||
--Add the data for the value per bar | |||
if bar ~= nil then | |||
if barQty == 0 then | |||
result = result..'||data-sort-value="0"|N/A' | |||
else | |||
local barVal = totalValue / barQty | |||
result = result..'||data-sort-value="'..barVal..'"|'..Icons.GP(Shared.round(barVal, 1, 1)) | |||
end | |||
end | |||
end | |||
result = result..'\r\n|}' | |||
return result | |||
end | end | ||
function p.getFiremakingTable(frame) | function p.getFiremakingTable(frame) | ||
local resultPart = {} | |||
table.insert(resultPart, '{| class="wikitable sortable stickyHeader"') | |||
table.insert(resultPart, '\r\n|-class="headerRow-0"') | |||
table.insert(resultPart, '\r\n!colspan="2" rowspan="2"|Logs!!rowspan="2"|'..Icons.Icon({'Firemaking', type='skill', notext=true})..' Level') | |||
table.insert(resultPart, '!!rowspan="2"|Burn Time!!colspan="2"|Without Bonfire!!colspan="2"|With Bonfire!!rowspan="2"|Bonfire Bonus!!rowspan="2"|Bonfire Time') | |||
table.insert(resultPart, '\r\n|-class="headerRow-1"') | |||
table.insert(resultPart, '\r\n!XP!!XP/s!!XP!!XP/s') | |||
for i, logData in Shared.skpairs(SkillData.Firemaking) do | |||
local logs = Items.getItemByID(logData.logID) | |||
local name = logs.name | |||
local burnTime = logData.baseInterval / 1000 | |||
local bonfireTime = logData.baseBonfireInterval / 1000 | |||
local XPS = logData.baseXP / burnTime | |||
local XP_BF = logData.baseXP * (1 + logData.bonfireXPBonus / 100) | |||
local XPS_BF = XP_BF / burnTime | |||
table.insert(resultPart, '\r\n|-') | |||
table.insert(resultPart, '\r\n|data-sort-value="'..name..'"|'..Icons.Icon({name, type='item', size='50', notext=true})) | |||
table.insert(resultPart, '||[['..name..']]') | |||
table.insert(resultPart, '||style ="text-align: right;"|'..logData.levelRequired) | |||
table.insert(resultPart, '||style ="text-align: right;" data-sort-value="'..burnTime..'"|'..Shared.timeString(burnTime, true)) | |||
table.insert(resultPart, '||style ="text-align: right;"|'..logData.baseXP) | |||
table.insert(resultPart, '||style ="text-align: right;" data-sort-value="'..XPS..'"|'..Shared.round(XPS, 2, 2)) | |||
table.insert(resultPart, '||style ="text-align: right;"|'..Shared.round(XP_BF, 2, 0)) | |||
table.insert(resultPart, '||style ="text-align: right;" data-sort-value="'..XPS_BF..'"|'..Shared.round(XPS_BF, 2, 2)) | |||
table.insert(resultPart, '||style ="text-align: right;" data-sort-value="'..logData.bonfireXPBonus..'"|'..logData.bonfireXPBonus..'%') | |||
table.insert(resultPart, '||style ="text-align: right;" data-sort-value="'..bonfireTime..'"|'..Shared.timeString(bonfireTime, true)) | |||
end | |||
table.insert(resultPart, '\r\n|}') | |||
return table.concat(resultPart) | |||
end | end | ||
function p.getMasteryTokenTable() | function p.getMasteryTokenTable() | ||
local baseTokenChance = 18500 | |||
local masterySkills = {} | |||
-- Find all mastery tokens | |||
local masteryTokens = Items.getItems(function(item) return item.isToken ~= nil and item.skill ~= nil and item.isToken end) | |||
for i, item in pairs(masteryTokens) do | |||
local milestones = SkillData.Milestones[item.skill + 1] | |||
if milestones ~= nil then | |||
table.insert(masterySkills, {tokenRef = i, skillID = item.skill, milestoneCount = milestones}) | |||
end | |||
end | |||
table.sort(masterySkills, function(a, b) | |||
if a['milestoneCount'] == b['milestoneCount'] then | |||
return a['skillID'] < b['skillID'] | |||
else | |||
return a['milestoneCount'] > b['milestoneCount'] | |||
end | |||
end) | |||
-- Generate output table | |||
local resultPart = {} | |||
local CCI = Items.getItem('Clue Chasers Insignia') | |||
local CCIIcon = Icons.Icon({'Clue Chasers Insignia', type='item', notext=true}) | |||
if CCI == nil then return '' end | |||
table.insert(resultPart, '{| class="wikitable sortable"') | |||
table.insert(resultPart, '\r\n!rowspan="2"|Token!!rowspan="2"|Skill!!colspan="2"|Approximate Mastery Token Chance') | |||
table.insert(resultPart, '\r\n|-\r\n!Without ' .. CCIIcon .. '!!With ' .. CCIIcon) | |||
for i, m in ipairs(masterySkills) do | |||
local token = masteryTokens[m.tokenRef] | |||
local denom = math.floor(baseTokenChance / m['milestoneCount']) | |||
local denomCCI = math.floor(baseTokenChance / m['milestoneCount'] * (1 - CCI.increasedItemChance / 100)) | |||
table.insert(resultPart, '\r\n|-') | |||
table.insert(resultPart, '\r\n|style="text-align:center"|' .. Icons.Icon({token.name, type='item', size=50, notext=true})) | |||
table.insert(resultPart, '\r\n|' .. Icons.Icon({Constants.getSkillName(m['skillID']), type='skill'})) | |||
table.insert(resultPart, '\r\n|style="text-align:right" data-sort-value="' .. denom .. '"|1/' .. Shared.formatnum(denom)) | |||
table.insert(resultPart, '\r\n|style="text-align:right" data-sort-value="' .. denomCCI .. '"|1/' .. Shared.formatnum(denomCCI)) | |||
end | |||
table.insert(resultPart, '\r\n|}') | |||
return table.concat(resultPart) | |||
end | end | ||
function p.getSkillUnlockCostTable() | function p.getSkillUnlockCostTable() | ||
local returnPart = {} | |||
table.insert(returnPart, '{| class="wikitable stickyHeader"\r\n|- class="headerRow-0"\r\n!Unlock!!Cost!!Cumulative Cost') | |||
local accCost = 0 | |||
for i, cost in ipairs(SkillData.SkillUnlockCosts) do | |||
accCost = accCost + cost | |||
table.insert(returnPart, '|-') | |||
table.insert(returnPart, '|' .. i .. '||' .. Icons.GP(cost) .. '||' .. Icons.GP(accCost)) | |||
end | |||
table.insert(returnPart, '|}') | |||
return table.concat(returnPart, '\r\n') | |||
end | end | ||
return p | return p |
Revision as of 19:16, 8 December 2021
Data pulled from Module:GameData
Some skills have their own modules:
- Module:Magic for Magic
- Module:Prayer for Prayer
- Module:Skills/Agility for Agility
- Module:Skills/Summoning for Summoning
- Module:Skills/Gathering for Mining, Fishing, Woodcutting
- Module:Skills/Artisan for Smithing, Cooking, Herblore, etc.
Also be aware of:
- Module:Navboxes for navigation boxes appearing near the bottom of pages
--Some skills have their own modules:
--Module:Magic for Magic
--Module:Prayer for Prayer
--Module:Skills/Agility for Agility
--Module:Skills/Summoning for Summoning
--Module:Skills/Gathering for Mining, Fishing, Woodcutting
--Module:Skills/Artisan for Smithing, Cooking, Herblore, etc.
--Also be aware of:
--Module:Navboxes for navigation boxes appearing near the bottom of pages
local p = {}
local ItemData = mw.loadData('Module:Items/data')
local SkillData = mw.loadData('Module:Skills/data')
local Shared = require('Module:Shared')
local Constants = require('Module:Constants')
local Items = require('Module:Items')
local ItemSourceTables = require('Module:Items/SourceTables')
local Icons = require('Module:Icons')
local MasteryCheckpoints = {.1, .25, .5, .95}
function p.getMasteryUnlockTable(frame)
local skillName = frame.args ~= nil and frame.args[1] or frame
local skillID = Constants.getSkillID(skillName)
if skillID == nil then
return "ERROR: Failed to find a skill ID for "..skillName
end
local unlockTable = SkillData.MasteryUnlocks[skillID]
if unlockTable == nil then
return 'ERROR: Failed to find Mastery Unlock data for '..skillName
end
local result = '{|class="wikitable"\r\n!Level!!Unlock'
for i, unlock in Shared.skpairs(unlockTable) do
result = result..'\r\n|-'
result = result..'\r\n|'..unlock.level..'||'..unlock.unlock
end
result = result..'\r\n|}'
return result
end
function p.getMasteryCheckpointTable(frame)
local skillName = frame.args ~= nil and frame.args[1] or frame
local skillID = Constants.getSkillID(skillName)
if skillID == nil then
return "ERROR: Failed to find a skill ID for "..skillName
end
if SkillData.MasteryCheckpoints[skillID] == nil then
return 'ERROR: Failed to find Mastery Unlock data for '..skillName
end
local bonuses = SkillData.MasteryCheckpoints[skillID].bonuses
local totalPoolXP = SkillData.MasteryPoolXP[skillID + 1]
local result = '{|class="wikitable"\r\n!Pool %!!style="width:100px"|Pool XP!!Bonus'
for i, bonus in Shared.skpairs(bonuses) do
result = result..'\r\n|-'
result = result..'\r\n|'..(MasteryCheckpoints[i] * 100)..'%||'
result = result..Shared.formatnum(totalPoolXP * MasteryCheckpoints[i])..' xp||'..bonus
end
result = result..'\r\n|-\r\n!colspan="2"|Total Mastery Pool XP'
result = result..'\r\n|'..Shared.formatnum(totalPoolXP)
result = result..'\r\n|}'
return result
end
function p._getFarmingTable(category)
local seedList = {}
if category == 'Allotment' or category == 'Herb' or category == 'Tree' then
seedList = Items.getItems(function(item) return item.tier == category end)
else
return 'ERROR: Invalid farming category. Please choose Allotment, Herb, or Tree'
end
local result = '{|class="wikitable sortable stickyHeader"'
result = result..'\r\n|- class="headerRow-0"'
result = result..'\r\n!colspan=2|Seeds!!'..Icons.Icon({'Farming', type='skill', notext=true})..' Level'
result = result..'!!XP!!Growth Time!!Seed Value'
if category == 'Allotment' then
result = result..'!!colspan="2"|Crop!!Crop Healing!!Crop Value'
elseif category == 'Herb' then
result = result..'!!colspan="2"|Herb!!Herb Value'
elseif category == 'Tree' then
result = result..'!!colspan="2"|Logs!!Log Value'
end
result = result..'!!Seed Sources'
table.sort(seedList, function(a, b) return a.farmingLevel < b.farmingLevel end)
for i, seed in pairs(seedList) do
result = result..'\r\n|-'
result = result..'\r\n|'..Icons.Icon({seed.name, type='item', size='50', notext=true})..'||[['..seed.name..']]'
result = result..'||'..seed.farmingLevel..'||'..Shared.formatnum(seed.farmingXP)
result = result..'||data-sort-value="'..seed.timeToGrow..'"|'..Shared.timeString(seed.timeToGrow, true)
result = result..'||data-sort-value="'..seed.sellsFor..'"|'..Icons.GP(seed.sellsFor)
local crop = Items.getItemByID(seed.grownItemID)
result = result..'||'..Icons.Icon({crop.name, type='item', size='50', notext=true})..'||[['..crop.name..']]'
if category == 'Allotment' then
result = result..'||'..Icons.Icon({'Hitpoints', type='skill', notext=true})..' '..(crop.healsFor * 10)
end
result = result..'||data-sort-value="'..crop.sellsFor..'"|'..Icons.GP(crop.sellsFor)
result = result..'||'..ItemSourceTables._getItemSources(seed)
end
result = result..'\r\n|}'
return result
end
function p.getFarmingTable(frame)
local category = frame.args ~= nil and frame.args[1] or frame
return p._getFarmingTable(category)
end
function p.getFarmingFoodTable(frame)
local result = '{| class="wikitable sortable stickyHeader"'
result = result..'\r\n|- class="headerRow-0"'
result = result..'\r\n!colspan="2"|Crop!!'..Icons.Icon({"Farming", type="skill", notext=true})..' Level'
result = result..'!!Healing!!Value'
local itemArray = Items.getItems(function(item) return item.grownItemID ~= nil end)
table.sort(itemArray, function(a, b) return a.farmingLevel < b.farmingLevel end)
for i, item in Shared.skpairs(itemArray) do
local crop = Items.getItemByID(item.grownItemID)
if crop.healsFor ~= nil and crop.healsFor > 0 then
result = result..'\r\n|-'
result = result..'\r\n|'..Icons.Icon({crop.name, type='item', notext='true', size='50'})..'||[['..crop.name..']]'
result = result..'||style="text-align:right;"|'..item.farmingLevel
result = result..'||style="text-align:right" data-sort-value="'..crop.healsFor..'"|'..Icons.Icon({"Hitpoints", type="skill", notext=true})..' '..(crop.healsFor * 10)
result = result..'||style="text-align:right" data-sort-value="'..crop.sellsFor..'"|'..Icons.GP(crop.sellsFor)
end
end
result = result..'\r\n|}'
return result
end
function p.getFarmingPlotTable(frame)
local areaName = frame.args ~= nil and frame.args[1] or frame
local patches = nil
for i, area in Shared.skpairs(SkillData.Farming.Patches) do
if area.areaName == areaName then
patches = area.patches
break
end
end
if patches == nil then
return "ERROR: Invalid area name.[[Category:Pages with script errors"
end
local result = '{|class="wikitable"'
result = result..'\r\n!Plot!!'..Icons.Icon({'Farming', type='skill', notext=true})..' Level!!Cost'
for i, patch in Shared.skpairs(patches) do
result = result..'\r\n|-\r\n|'..i
result = result..'||style="text-align:right;" data-sort-value="0"|'..patch.level
if patch.cost == 0 then
result = result..'||Free'
else
result = result..'||style="text-align:right;" data-sort-value="'..patch.cost..'"|'..Icons.GP(patch.cost)
end
end
result = result..'\r\n|}'
return result
end
function p.getSmithingTable(frame)
local tableType = frame.args ~= nil and frame.args[1] or frame
local bar = nil
if tableType ~= 'Smelting' then
bar = Items.getItem(tableType)
if bar == nil then
return 'ERROR: Could not find an item named '..tableType..' to build a smithing table with'
elseif bar.type ~= 'Bar' then
return 'ERROR: '..tableType.." is not a bar and thus can't be used for smithing"
end
end
local smithList = {}
for i, item in pairs(ItemData.Items) do
if item.smithingLevel ~= nil then
if tableType == 'Smelting' then
if item.type == 'Bar' then
table.insert(smithList, item)
end
else
for j, req in pairs(item.smithReq) do
if req.id == bar.id then
table.insert(smithList, item)
end
end
end
end
end
local result = '{|class="wikitable sortable stickyHeader"'
result = result..'\r\n|-class="headerRow-0"'
result = result..'\r\n!Item!!Name!!'..Icons.Icon({'Smithing', type='skill', notext=true})..' Level!!XP!!Value!!Ingredients'
--Adding value/bar for things other than smelting
if bar ~= nil then result = result..'!!Value/Bar' end
table.sort(smithList, function(a, b)
if a.smithingLevel ~= b.smithingLevel then
return a.smithingLevel < b.smithingLevel
else
return a.name < b.name
end end)
for i, item in Shared.skpairs(smithList) do
result = result..'\r\n|-'
result = result..'\r\n|'..Icons.Icon({item.name, type='item', size='50', notext=true})..'||'
local qty = item.smithingQty ~= nil and item.smithingQty or 1
if qty > 1 then
result = result..item.smithingQty..'x '
end
result = result..'[['..item.name..']]'
result = result..'||data-sort-value="'..item.smithingLevel..'"|'..Icons._SkillReq('Smithing', item.smithingLevel)
result = result..'||'..item.smithingXP
local totalValue = item.sellsFor * qty
result = result..'||data-sort-value="'..totalValue..'"|'..Icons.GP(item.sellsFor)
if qty > 1 then
result = result..' (x'..qty..')'
end
result = result..'||'
local barQty = 0
for i, mat in Shared.skpairs(item.smithReq) do
matItem = Items.getItemByID(mat.id)
if i > 1 then result = result..', ' end
result = result..Icons.Icon({matItem.name, type='item', qty=mat.qty, notext=true})
if bar ~= nil and mat.id == bar.id then
barQty = mat.qty
end
end
--Add the data for the value per bar
if bar ~= nil then
if barQty == 0 then
result = result..'||data-sort-value="0"|N/A'
else
local barVal = totalValue / barQty
result = result..'||data-sort-value="'..barVal..'"|'..Icons.GP(Shared.round(barVal, 1, 1))
end
end
end
result = result..'\r\n|}'
return result
end
function p.getFiremakingTable(frame)
local resultPart = {}
table.insert(resultPart, '{| class="wikitable sortable stickyHeader"')
table.insert(resultPart, '\r\n|-class="headerRow-0"')
table.insert(resultPart, '\r\n!colspan="2" rowspan="2"|Logs!!rowspan="2"|'..Icons.Icon({'Firemaking', type='skill', notext=true})..' Level')
table.insert(resultPart, '!!rowspan="2"|Burn Time!!colspan="2"|Without Bonfire!!colspan="2"|With Bonfire!!rowspan="2"|Bonfire Bonus!!rowspan="2"|Bonfire Time')
table.insert(resultPart, '\r\n|-class="headerRow-1"')
table.insert(resultPart, '\r\n!XP!!XP/s!!XP!!XP/s')
for i, logData in Shared.skpairs(SkillData.Firemaking) do
local logs = Items.getItemByID(logData.logID)
local name = logs.name
local burnTime = logData.baseInterval / 1000
local bonfireTime = logData.baseBonfireInterval / 1000
local XPS = logData.baseXP / burnTime
local XP_BF = logData.baseXP * (1 + logData.bonfireXPBonus / 100)
local XPS_BF = XP_BF / burnTime
table.insert(resultPart, '\r\n|-')
table.insert(resultPart, '\r\n|data-sort-value="'..name..'"|'..Icons.Icon({name, type='item', size='50', notext=true}))
table.insert(resultPart, '||[['..name..']]')
table.insert(resultPart, '||style ="text-align: right;"|'..logData.levelRequired)
table.insert(resultPart, '||style ="text-align: right;" data-sort-value="'..burnTime..'"|'..Shared.timeString(burnTime, true))
table.insert(resultPart, '||style ="text-align: right;"|'..logData.baseXP)
table.insert(resultPart, '||style ="text-align: right;" data-sort-value="'..XPS..'"|'..Shared.round(XPS, 2, 2))
table.insert(resultPart, '||style ="text-align: right;"|'..Shared.round(XP_BF, 2, 0))
table.insert(resultPart, '||style ="text-align: right;" data-sort-value="'..XPS_BF..'"|'..Shared.round(XPS_BF, 2, 2))
table.insert(resultPart, '||style ="text-align: right;" data-sort-value="'..logData.bonfireXPBonus..'"|'..logData.bonfireXPBonus..'%')
table.insert(resultPart, '||style ="text-align: right;" data-sort-value="'..bonfireTime..'"|'..Shared.timeString(bonfireTime, true))
end
table.insert(resultPart, '\r\n|}')
return table.concat(resultPart)
end
function p.getMasteryTokenTable()
local baseTokenChance = 18500
local masterySkills = {}
-- Find all mastery tokens
local masteryTokens = Items.getItems(function(item) return item.isToken ~= nil and item.skill ~= nil and item.isToken end)
for i, item in pairs(masteryTokens) do
local milestones = SkillData.Milestones[item.skill + 1]
if milestones ~= nil then
table.insert(masterySkills, {tokenRef = i, skillID = item.skill, milestoneCount = milestones})
end
end
table.sort(masterySkills, function(a, b)
if a['milestoneCount'] == b['milestoneCount'] then
return a['skillID'] < b['skillID']
else
return a['milestoneCount'] > b['milestoneCount']
end
end)
-- Generate output table
local resultPart = {}
local CCI = Items.getItem('Clue Chasers Insignia')
local CCIIcon = Icons.Icon({'Clue Chasers Insignia', type='item', notext=true})
if CCI == nil then return '' end
table.insert(resultPart, '{| class="wikitable sortable"')
table.insert(resultPart, '\r\n!rowspan="2"|Token!!rowspan="2"|Skill!!colspan="2"|Approximate Mastery Token Chance')
table.insert(resultPart, '\r\n|-\r\n!Without ' .. CCIIcon .. '!!With ' .. CCIIcon)
for i, m in ipairs(masterySkills) do
local token = masteryTokens[m.tokenRef]
local denom = math.floor(baseTokenChance / m['milestoneCount'])
local denomCCI = math.floor(baseTokenChance / m['milestoneCount'] * (1 - CCI.increasedItemChance / 100))
table.insert(resultPart, '\r\n|-')
table.insert(resultPart, '\r\n|style="text-align:center"|' .. Icons.Icon({token.name, type='item', size=50, notext=true}))
table.insert(resultPart, '\r\n|' .. Icons.Icon({Constants.getSkillName(m['skillID']), type='skill'}))
table.insert(resultPart, '\r\n|style="text-align:right" data-sort-value="' .. denom .. '"|1/' .. Shared.formatnum(denom))
table.insert(resultPart, '\r\n|style="text-align:right" data-sort-value="' .. denomCCI .. '"|1/' .. Shared.formatnum(denomCCI))
end
table.insert(resultPart, '\r\n|}')
return table.concat(resultPart)
end
function p.getSkillUnlockCostTable()
local returnPart = {}
table.insert(returnPart, '{| class="wikitable stickyHeader"\r\n|- class="headerRow-0"\r\n!Unlock!!Cost!!Cumulative Cost')
local accCost = 0
for i, cost in ipairs(SkillData.SkillUnlockCosts) do
accCost = accCost + cost
table.insert(returnPart, '|-')
table.insert(returnPart, '|' .. i .. '||' .. Icons.GP(cost) .. '||' .. Icons.GP(accCost))
end
table.insert(returnPart, '|}')
return table.concat(returnPart, '\r\n')
end
return p