570
edits
(getFiremakingTable: Fix reference to non-existent attribute) |
(Adjusted the appearance of the Lesser Relics table) |
||
(27 intermediate revisions by 3 users not shown) | |||
Line 15: | Line 15: | ||
local p = {} | local p = {} | ||
local Shared = require('Module:Shared') | local Shared = require('Module:Shared') | ||
Line 24: | Line 22: | ||
local Items = require('Module:Items') | local Items = require('Module:Items') | ||
local Icons = require('Module:Icons') | local Icons = require('Module:Icons') | ||
-- Given a skill ID, returns the key for that skill's recipe data. | |||
-- If the skill has no recipes (e.g. is a combat skill) then the | |||
-- return value is nil | |||
function p.getSkillRecipeKey(skillID) | |||
-- Convert skillID to local ID if not already | |||
local ns, localSkillID = GameData.getLocalID(skillID) | |||
local recipeIDs = { | |||
["Woodcutting"] = 'trees', | |||
["Fishing"] = 'fish', | |||
["Firemaking"] = 'logs', | |||
["Mining"] = 'rockData', | |||
["Thieving"] = 'npcs', | |||
["Agility"] = 'obstacles', | |||
["Cooking"] = 'recipes', | |||
["Smithing"] = 'recipes', | |||
["Farming"] = 'recipes', | |||
["Summoning"] = 'recipes', | |||
["Fletching"] = 'recipes', | |||
["Crafting"] = 'recipes', | |||
["Runecrafting"] = 'recipes', | |||
["Herblore"] = 'recipes', | |||
["Astrology"] = 'recipes' | |||
} | |||
return recipeIDs[localSkillID] | |||
end | |||
-- Given a skill ID & recipe, returns the skill level requirement for | |||
-- that recipe. If the level could not be determined, then the return | |||
-- value is nil | |||
function p.getRecipeLevel(skillID, recipe) | |||
-- Convert skillID to local ID if not already | |||
local ns, localSkillID = GameData.getLocalID(skillID) | |||
if localSkillID == 'Agility' then | |||
-- For Agility, level is derived from obstacle category | |||
if recipe.category ~= nil then | |||
-- Obstacle | |||
return SkillData.Agility.obstacleUnlockLevels[recipe.category+1] | |||
else | |||
-- Pillar | |||
local nsR, localRecipeID = GameData.getLocalID(recipe.id) | |||
if localRecipeID ~= nil then | |||
if string.find(localRecipeID, '^Pillar') ~= nil then | |||
return 99 | |||
elseif string.find(localRecipeID, '^ElitePillar') ~= nil then | |||
return 120 | |||
end | |||
end | |||
end | |||
else | |||
-- For all other skills, the recipe should have a level property | |||
return recipe.level | |||
end | |||
end | |||
-- Thieving | -- Thieving | ||
Line 70: | Line 122: | ||
local npc = p.getThievingNPC(npcName) | local npc = p.getThievingNPC(npcName) | ||
if npc == nil then | if npc == nil then | ||
return | return Shared.printError('Invalid Thieving NPC ' .. npcName) | ||
end | end | ||
Line 85: | Line 137: | ||
for j, drop in pairs(area.uniqueDrops) do | for j, drop in pairs(area.uniqueDrops) do | ||
if drop.id == itemID then | if drop.id == itemID then | ||
for k, npcID in | for k, npcID in ipairs(area.npcIDs) do | ||
areaNPCs[npcID] = drop.quantity | areaNPCs[npcID] = { qty = drop.quantity, area = area } | ||
end | end | ||
break | break | ||
Line 106: | Line 158: | ||
end | end | ||
if dropWt > 0 then | if dropWt > 0 then | ||
table.insert(resultArray, {npc = npc.name, minQty = dropQty.min, maxQty = dropQty.max, wt = dropWt * SkillData.Thieving.itemChance, totalWt = totalWt * 100, level = npc.level}) | table.insert(resultArray, {npc = npc.name, minQty = dropQty.min, maxQty = dropQty.max, wt = dropWt * SkillData.Thieving.itemChance, totalWt = totalWt * 100, level = npc.level, npcID = npc.id, type = 'npc'}) | ||
end | end | ||
--Chance of -1 on unique drops is to indicate variable chance | --Chance of -1 on unique drops is to indicate variable chance | ||
if npc.uniqueDrop ~= nil and npc.uniqueDrop.id == itemID then | if npc.uniqueDrop ~= nil and npc.uniqueDrop.id == itemID then | ||
table.insert(resultArray, {npc = npc.name, minQty = npc.uniqueDrop.quantity, maxQty = npc.uniqueDrop.quantity, wt = -1, totalWt = -1, level = npc.level}) | table.insert(resultArray, {npc = npc.name, minQty = npc.uniqueDrop.quantity, maxQty = npc.uniqueDrop.quantity, wt = -1, totalWt = -1, level = npc.level, npcID = npc.id, type = 'npcUnique'}) | ||
end | end | ||
local areaNPC = areaNPCs[npc.id] | |||
table.insert(resultArray, {npc = npc.name, minQty = | if areaNPC ~= nil then | ||
table.insert(resultArray, {npc = npc.name, minQty = areaNPC.qty, maxQty = areaNPC.qty, wt = SkillData.Thieving.baseAreaUniqueChance, totalWt = 100, level = npc.level, npcID = npc.id, area = areaNPC.area, type = 'areaUnique'}) | |||
end | end | ||
end | end | ||
Line 122: | Line 175: | ||
if drop.itemID == itemID then | if drop.itemID == itemID then | ||
if drop.npcs == nil then | if drop.npcs == nil then | ||
table.insert(resultArray, {npc = 'all', minQty = 1, maxQty = 1, wt = 1, totalWt = Shared.round2(1/(drop.chance/100), 0), level = 1}) | table.insert(resultArray, {npc = 'all', minQty = 1, maxQty = 1, wt = 1, totalWt = Shared.round2(1/(drop.chance/100), 0), level = 1, npcID = itemID, type = 'generalRare'}) | ||
else | else | ||
for j, npcID in ipairs(drop.npcs) do | for j, npcID in ipairs(drop.npcs) do | ||
local npc = p.getThievingNPCByID(npcID) | local npc = p.getThievingNPCByID(npcID) | ||
if npc ~= nil then | if npc ~= nil then | ||
table.insert(resultArray, {npc = npc.name, minQty = 1, maxQty = 1, wt = 1, totalWt = Shared.round2(1/(drop.chance/100), 0), level = npc.level}) | table.insert(resultArray, {npc = npc.name, minQty = 1, maxQty = 1, wt = 1, totalWt = Shared.round2(1/(drop.chance/100), 0), level = npc.level, npcID = npc.id, type = 'generalRare'}) | ||
end | end | ||
end | end | ||
Line 187: | Line 240: | ||
table.insert(modTypes, 'uniqueModifiers') | table.insert(modTypes, 'uniqueModifiers') | ||
end | end | ||
local masteryReq = { | |||
['standardModifiers'] = { 1, 40, 80 }, | |||
['uniqueModifiers'] = { 20, 60, 99 } | |||
} | |||
local modArray = {} | local modArray = {} | ||
local isSkillMod = {} | local isSkillMod = {} | ||
--Adding a Group Number to hold together different bonuses from the same modifier [Falterfire 22/10/27] | |||
local groupNum = 0 | |||
for _, modType in ipairs(modTypes) do | for _, modType in ipairs(modTypes) do | ||
for i, modTypeData in ipairs(cons[modType]) do | for i, modTypeData in ipairs(cons[modType]) do | ||
groupNum = masteryReq[modType][i] | |||
local modVal = nil | local modVal = nil | ||
if modValue ~= nil then | if modValue ~= nil then | ||
Line 200: | Line 260: | ||
end | end | ||
for j, modifier in ipairs(modTypeData.modifiers) do | for j, modifier in ipairs(modTypeData.modifiers) do | ||
local modEntry = (modifier.skill ~= nil and {modifier.skill, modVal}) or modVal | local modEntry = (modifier.skill ~= nil and { skillID = modifier.skill, value = modVal }) or modVal | ||
addToArray(modArray, {modifier.key, modEntry}) | addToArray(modArray, {modifier.key, modEntry, group = groupNum}) | ||
end | end | ||
end | end | ||
Line 210: | Line 270: | ||
for i, modDefn in ipairs(modArray) do | for i, modDefn in ipairs(modArray) do | ||
local modName, modVal = modDefn[1], modDefn[2] | local modName, modVal = modDefn[1], modDefn[2] | ||
local isSkill = type(modVal) == 'table' and | local isSkill = type(modVal) == 'table' and modVal.skillID ~= nil | ||
if modArrayKV[modName] == nil then | if modArrayKV[modName] == nil then | ||
modArrayKV[modName] = (isSkill and { modVal } or modVal) | modArrayKV[modName] = (isSkill and { modVal } or modVal) | ||
Line 230: | Line 290: | ||
local skillID = Constants.getSkillID(skillName) | local skillID = Constants.getSkillID(skillName) | ||
if skillID == nil then | if skillID == nil then | ||
return | return Shared.printError('Failed to find a skill ID for ' .. skillName) | ||
end | end | ||
local unlockTable = SkillData[ | local _, localSkillID = GameData.getLocalID(skillID) | ||
-- Clone so that we can sort by level | |||
local unlockTable = Shared.clone(SkillData[localSkillID].masteryLevelUnlocks) | |||
if unlockTable == nil then | if unlockTable == nil then | ||
return ' | return Shared.printError('Failed to find Mastery Unlock data for ' .. skillName) | ||
end | end | ||
table.sort(unlockTable, function(a, b) return (a.level == b.level and a.descriptionID < b.descriptionID) or a.level < b.level end) | |||
local result = '{|class="wikitable"\r\n!Level!!Unlock' | local result = '{|class="wikitable"\r\n!Level!!Unlock' | ||
Line 251: | Line 314: | ||
local skillID = Constants.getSkillID(skillName) | local skillID = Constants.getSkillID(skillName) | ||
if skillID == nil then | if skillID == nil then | ||
return | return Shared.printError('Failed to find a skill ID for ' .. skillName) | ||
end | end | ||
local checkpoints = SkillData[ | local _, localSkillID = GameData.getLocalID(skillID) | ||
local checkpoints = SkillData[localSkillID].masteryCheckpoints | |||
if checkpoints == nil then | if checkpoints == nil then | ||
return ' | return Shared.printError('Failed to find Mastery Unlock data for ' .. skillName) | ||
end | end | ||
local totalPoolXP = SkillData[ | local totalPoolXP = SkillData[localSkillID].baseMasteryPoolCap | ||
local checkpointPct = GameData.rawData.masteryCheckpoints | |||
local result = '{|class="wikitable"\r\n!Pool %!!style="width:100px"|Pool XP!!Bonus' | local result = '{|class="wikitable"\r\n!Pool %!!style="width:100px"|Pool XP!!Bonus' | ||
for i, checkpointDesc in ipairs(checkpoints) do | for i, checkpointDesc in ipairs(checkpoints) do | ||
result = result..'\r\n|-' | result = result..'\r\n|-' | ||
result = result..'\r\n|'.. | result = result..'\r\n|'..checkpointPct[i]..'%||' | ||
result = result..Shared.formatnum(math.floor(totalPoolXP * | result = result..Shared.formatnum(math.floor(totalPoolXP * checkpointPct[i] / 100))..' xp||'..checkpointDesc | ||
end | end | ||
result = result..'\r\n|-\r\n!colspan="2"|Total Mastery Pool XP' | result = result..'\r\n|-\r\n!colspan="2"|Total Mastery Pool XP' | ||
Line 273: | Line 338: | ||
function p.getMasteryTokenTable() | function p.getMasteryTokenTable() | ||
-- Defines which skill levels should be included within the output | |||
local skillLevels = { | |||
{ | |||
["id"] = 'Base', | |||
["level"] = 99, | |||
["description"] = '[[Full Version|Base Game]] (Level 99)' | |||
}, { | |||
["id"] = 'TotH', | |||
["level"] = 120, | |||
["description"] = Icons.TotH() .. ' [[Throne of the Herald Expansion|Throne of the Herald]] (Level 120)' | |||
} | |||
} | |||
local baseTokenChance = 18500 | local baseTokenChance = 18500 | ||
local | local masteryActionCount = {} | ||
local CCI = Items.getItemByID( | local CCI_ID = 'melvorD:Clue_Chasers_Insignia' | ||
if CCI == nil then return '' end | local CCI = Items.getItemByID(CCI_ID) | ||
if CCI == nil then | |||
return Shared.printError('Failed to find item with ID ' .. CCI_ID) | |||
end | |||
-- | -- Iterate over each skill with mastery, determining the number of | ||
-- mastery actions for each | |||
for skillLocalID, skill in pairs(SkillData) do | for skillLocalID, skill in pairs(SkillData) do | ||
if skill.masteryTokenID ~= nil then | if skill.masteryTokenID ~= nil then | ||
table.insert( | local actCount = { ["skill"] = skill } | ||
for i, levelDef in ipairs(skillLevels) do | |||
actCount[levelDef.id] = 0 | |||
end | |||
local recipeKey = p.getSkillRecipeKey(skillLocalID) | |||
if recipeKey ~= nil then | |||
local recipeData = skill[recipeKey] | |||
for i, recipe in ipairs(recipeData) do | |||
if recipe.noMastery == nil or not recipe.noMastery then | |||
local skillLevel = p.getRecipeLevel(skillLocalID, recipe) | |||
if skillLevel ~= nil then | |||
for j, levelDef in ipairs(skillLevels) do | |||
if skillLevel <= levelDef.level then | |||
actCount[levelDef.id] = actCount[levelDef.id] + 1 | |||
end | |||
end | |||
end | |||
end | |||
end | |||
end | |||
table.insert(masteryActionCount, actCount) | |||
end | end | ||
end | end | ||
table.sort( | |||
local firstID = skillLevels[1].id | |||
table.sort(masteryActionCount, | |||
function(a, b) | function(a, b) | ||
if a | if a[firstID] == b[firstID] then | ||
return a.name < b.name | return a.skill.name < b.skill.name | ||
else | else | ||
return a | return a[firstID] > b[firstID] | ||
end | end | ||
end) | end) | ||
-- Generate output table | -- Generate output table | ||
local resultPart = {} | local resultPart = {} | ||
local CCIIcon = Icons.Icon({CCI.name, type='item', notext=true}) | local CCIIcon = Icons.Icon({CCI.name, type='item', notext=true}) | ||
local columnPairs = Shared.tableCount(skillLevels) | |||
-- Generate header | |||
table.insert(resultPart, '{| class="wikitable sortable"') | table.insert(resultPart, '{| class="wikitable sortable"') | ||
table.insert(resultPart, ' | table.insert(resultPart, '\n!rowspan="3"|Token!!rowspan="3"|Skill!!colspan="' .. columnPairs * 2 .. '"|Approximate Mastery Token Chance') | ||
table.insert(resultPart, '\ | table.insert(resultPart, '\n|-') | ||
for i, levelDef in ipairs(skillLevels) do | |||
table.insert(resultPart, '\n!colspan="2"| ' .. levelDef.description) | |||
end | |||
table.insert(resultPart, '\n|-' .. string.rep('\n!Without ' .. CCIIcon .. '\n!With ' .. CCIIcon, columnPairs)) | |||
for i, | for i, rowData in ipairs(masteryActionCount) do | ||
local token = Items.getItemByID(skill.masteryTokenID) | local token = Items.getItemByID(rowData.skill.masteryTokenID) | ||
table.insert(resultPart, '\n|-') | |||
table.insert(resultPart, '\n|style="text-align:center"|' .. Icons.Icon({token.name, type='item', size=50, notext=true})) | |||
table.insert(resultPart, '\n|' .. Icons.Icon({rowData.skill.name, type='skill'})) | |||
for j, levelDef in ipairs(skillLevels) do | |||
local actCount = rowData[levelDef.id] | |||
local denom, denomCCI = 0, 0 | |||
if actCount > 0 then | |||
denom = math.floor(baseTokenChance / actCount) | |||
denomCCI = Shared.round(baseTokenChance / (actCount * (1 + CCI.modifiers.increasedOffItemChance / 100)), 0, 0) | |||
end | |||
table.insert(resultPart, '\n|style="text-align:right" data-sort-value="' .. denom .. '"|1/' .. Shared.formatnum(denom)) | |||
table.insert(resultPart, '\n|style="text-align:right" data-sort-value="' .. denomCCI .. '"|1/' .. Shared.formatnum(denomCCI)) | |||
end | |||
end | end | ||
table.insert(resultPart, ' | table.insert(resultPart, '\n|}') | ||
return table.concat(resultPart) | return table.concat(resultPart) | ||
Line 321: | Line 437: | ||
local advMode = GameData.getEntityByID('gamemodes', 'melvorF:Adventure') | local advMode = GameData.getEntityByID('gamemodes', 'melvorF:Adventure') | ||
if advMode ~= nil then | if advMode ~= nil then | ||
local unlockCount = Shared.tableCount(GameData.skillData) - Shared.tableCount(advMode.startingSkills) | |||
local costLength = Shared.tableCount(advMode.skillUnlockCost) | |||
local returnPart = {} | local returnPart = {} | ||
table.insert(returnPart, '{| class="wikitable stickyHeader"\r\n|- class="headerRow-0"\r\n!Unlock!!Cost!!Cumulative Cost') | table.insert(returnPart, '{| class="wikitable stickyHeader"\r\n|- class="headerRow-0"\r\n!Unlock!!Cost!!Cumulative Cost') | ||
local accCost = 0 | local accCost = 0 | ||
for i, cost | for i = 1, unlockCount, 1 do | ||
local cost = advMode.skillUnlockCost[math.min(i, costLength)] | |||
accCost = accCost + cost | accCost = accCost + cost | ||
table.insert(returnPart, '|-') | table.insert(returnPart, '|-') | ||
Line 334: | Line 453: | ||
return table.concat(returnPart, '\r\n') | return table.concat(returnPart, '\r\n') | ||
end | end | ||
end | end | ||
Line 440: | Line 471: | ||
local XPS = logData.baseExperience / burnTime | local XPS = logData.baseExperience / burnTime | ||
local XP_BF = logData.baseExperience * (1 + logData.bonfireXPBonus / 100) | local XP_BF = logData.baseExperience * (1 + logData.bonfireXPBonus / 100) | ||
local XPS_BF = XP_BF / burnTime | local XPS_BF = Shared.round(XP_BF / burnTime, 2, 2) | ||
XP_BF = Shared.round(XP_BF, 2, 0) | |||
table.insert(resultPart, '\r\n|-') | 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, '\r\n|data-sort-value="'..name..'"|'..Icons.Icon({name, type='item', size='50', notext=true})) | ||
table.insert(resultPart, '|| | table.insert(resultPart, '||'..Icons.getExpansionIcon(logs.id)..Icons.Icon({name, type='item', noicon=true})) | ||
table.insert(resultPart, '||style ="text-align: right;"|'..logData.level) | table.insert(resultPart, '||style ="text-align: right;"|'..logData.level) | ||
table.insert(resultPart, '||style ="text-align: right;" data-sort-value="'..burnTime..'"|'..Shared.timeString(burnTime, true)) | table.insert(resultPart, '||style ="text-align: right;" data-sort-value="'..burnTime..'"|'..Shared.timeString(burnTime, true)) | ||
table.insert(resultPart, '||style ="text-align: right;"|'..logData.baseExperience) | table.insert(resultPart, '||style ="text-align: right;" data-sort-value="' .. logData.baseExperience .. '"| ' .. Shared.formatnum(logData.baseExperience)) | ||
table.insert(resultPart, '||style ="text-align: right;" data-sort-value="'..XPS..'"|'..Shared.round(XPS, 2, 2)) | table.insert(resultPart, '||style ="text-align: right;" data-sort-value="'..XPS..'"|'..Shared.formatnum(Shared.round(XPS, 2, 2))) | ||
table.insert(resultPart, '||style ="text-align: right;"|'..Shared. | table.insert(resultPart, '||style ="text-align: right;" data-sort-value="' .. XP_BF .. '"| ' .. Shared.formatnum(XP_BF)) | ||
table.insert(resultPart, '||style ="text-align: right;" data-sort-value="'..XPS_BF..'"|'..Shared. | table.insert(resultPart, '||style ="text-align: right;" data-sort-value="'..XPS_BF..'"|'..Shared.formatnum(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="'..logData.bonfireXPBonus..'"|'..logData.bonfireXPBonus..'%') | ||
table.insert(resultPart, '||style ="text-align: right;" data-sort-value="'..bonfireTime..'"|'..Shared.timeString(bonfireTime, true)) | table.insert(resultPart, '||style ="text-align: right;" data-sort-value="'..bonfireTime..'"|'..Shared.timeString(bonfireTime, true)) | ||
Line 457: | Line 489: | ||
table.insert(resultPart, '\r\n|}') | table.insert(resultPart, '\r\n|}') | ||
return table.concat(resultPart) | return table.concat(resultPart) | ||
end | |||
function p.getAncientRelicsTable(frame) | |||
local skillName = frame.args ~= nil and frame.args[1] or frame | |||
local skillID = nil | |||
if skillName ~= nil and skillName ~= '' then | |||
skillID = Constants.getSkillID(skillName) | |||
if skillID == nil then | |||
return Shared.printError('Failed to find a skill ID for ' .. skillName) | |||
end | |||
end | |||
local resultPart = {} | |||
table.insert(resultPart, '{| class="wikitable sortable stickyHeader lighttable"') | |||
table.insert(resultPart, '\n|-class="headerRow-0"') | |||
table.insert(resultPart, '\n|-\n!colspan="2"|Skill\n!Relic\n!Modifiers') | |||
local relics = GameData.getEntities('ancientRelics', | |||
function(relic) | |||
return skillID == nil or relic.skillID == skillID | |||
end) | |||
table.sort(relics, | |||
function (a, b) | |||
local skillNameA, skillNameB = Constants.getSkillName(a.skillID), Constants.getSkillName(b.skillID) | |||
if skillNameA == skillNameB then | |||
-- Order by numbers at the end of relic IDs | |||
-- Relics have a 'number' property, but this appears to contain duplicates | |||
return string.sub(a.id, string.len(a.id)) < string.sub(b.id, string.len(b.id)) | |||
else | |||
return skillNameA < skillNameB | |||
end | |||
end) | |||
local function appendSkillRows(resultTable, rowTable, relicCount, skillID) | |||
local skillName = Constants.getSkillName(skillID) | |||
table.insert(resultTable, '\n|-\n|rowspan="' .. relicCount .. '"| ' .. Icons.Icon({skillName, type='skill', notext=true, size=50})) | |||
table.insert(resultTable, '\n|rowspan="' .. relicCount .. '"| ' .. Icons.Icon({skillName, type='skill', noicon=true})) | |||
table.insert(resultTable, table.concat(rowTable)) | |||
end | |||
local skillRelicCount, currentSkillID, tablePart = 0, nil, {} | |||
for i, relic in ipairs(relics) do | |||
if currentSkillID == nil then | |||
currentSkillID = relic.skillID | |||
elseif relic.skillID ~= currentSkillID then | |||
appendSkillRows(resultPart, tablePart, skillRelicCount, currentSkillID) | |||
tablePart = {} | |||
currentSkillID = relic.skillID | |||
skillRelicCount = 0 | |||
end | |||
skillRelicCount = skillRelicCount + 1 | |||
if skillRelicCount > 1 then | |||
table.insert(tablePart, '\n|-') | |||
end | |||
table.insert(tablePart, '\n| ' .. skillRelicCount .. '\n| ' .. Constants.getModifiersText(relic.modifiers)) | |||
end | |||
appendSkillRows(resultPart, tablePart, skillRelicCount, currentSkillID) | |||
table.insert(resultPart, '\n|}') | |||
return table.concat(resultPart) | |||
end | |||
function p.getLesserRelicsTable(frame) | |||
local lesserRelics = {} | |||
-- Iterate over each skill with a global rare drop then check | |||
-- if the skill has a Lesser Relic drop | |||
for skillLocalID, skill in pairs(SkillData) do | |||
if skill.rareDrops ~= nil then | |||
for i, drops in pairs(skill.rareDrops) do | |||
if string.match(drops.itemID, '_Lesser_Relic') then | |||
table.insert(lesserRelics, Items.getItemByID(drops.itemID)) | |||
end | |||
end | |||
end | |||
end | |||
table.sort(lesserRelics, function(a, b) return a.name < b.name end) | |||
-- Create the Table | |||
local resultTable = mw.html.create('table') | |||
resultTable:addClass('wikitable sortable') | |||
resultTable:tag('tr'):addClass('headerRow-0') | |||
:tag('th'):wikitext('Icon') | |||
:tag('th'):wikitext('Lesser Relic') | |||
:tag('th'):wikitext('Modifiers') | |||
for _, relic in ipairs(lesserRelics) do | |||
local tr = mw.html.create('tr') | |||
tr:tag('td'):wikitext(Icons.Icon({relic.name, type='item', size='50', notext=true})) | |||
tr:tag('td'):wikitext(Icons.Icon({relic.name, type='item', noicon=true})) | |||
tr:tag('td'):wikitext(Constants.getModifiersText(relic.modifiers)) | |||
resultTable:node(tr) | |||
end | |||
return resultTable | |||
end | end | ||
return p | return p |
edits