Module:Township: Difference between revisions

Fixed currencies not showing up in task list
(getBuildingBiomeTable: Add biome requirements to header rows)
(Fixed currencies not showing up in task list)
(16 intermediate revisions by 4 users not shown)
Line 2: Line 2:
local Icons = require('Module:Icons')
local Icons = require('Module:Icons')
local Items = require('Module:Items')
local Items = require('Module:Items')
local Monsters = require('Module:Monsters')
local Shop = require('Module:Shop')
local Shop = require('Module:Shop')
local GameData = require('Module:GameData')
local GameData = require('Module:GameData')
local Constants = require('Module:Constants')
local Modifiers = require('Module:Modifiers')
local Num = require('Module:Number')


local p = {}
local p = {}
Line 160: Line 162:
education = 'Education',
education = 'Education',
storage = 'Storage',
storage = 'Storage',
worship = 'Worship'
worship = 'Worship',
fortification = 'Fortification'
}
}
local resourceText = function(resName, resType, quantity)
local resourceText = function(resName, resType, quantity)
local elemClass = (quantity < 0 and 'text-negative') or 'text-positive'
local elemClass = (quantity < 0 and 'text-negative') or 'text-positive'
local resIcon = Icons.Icon({resName, type=resType, notext=true})
local resIcon = Icons.Icon({resName, type=resType, notext=true})
return resIcon .. '&nbsp;<span class="' .. elemClass .. '">' .. Shared.numStrWithSign(quantity) .. '</span>'
return resIcon .. '&nbsp;<span class="' .. elemClass .. '">' .. Num.numStrWithSign(quantity) .. '</span>'
end
end


Line 188: Line 191:
-- Modifiers
-- Modifiers
if includeMods and building.modifiers ~= nil then
if includeMods and building.modifiers ~= nil then
table.insert(resultPart, Constants.getModifiersText(building.modifiers))
table.insert(resultPart, Modifiers.getModifiersText(building.modifiers))
end
end


Line 255: Line 258:
end
end


-- Gets the Township level and population requirements for a tier
-- Gets the Township level or abyssalLevel, population and fortification requirements for a tier
-- Returns {population=X, level=X}
-- Returns {population=X, level=X} for non-abyssal tiers
function p._getTierRequirements(tier)
-- Returns {population=X, abyssalLevel=X, fortification=X} for abyssal tiers
return Township.populationForTier[tier]
function p._getTierRequirements(tier, abyssalTier)
local tierData = Township.populationForTier[tier]
if abyssalTier ~= nil then
local abyssalTierData = Shared.clone(Township.abyssalTierRequirements[abyssalTier + 1])
abyssalTierData.population = tierData.population
return abyssalTierData
else
return tierData
end
end
end


-- Returns a string containing the Township level and population requirements for a tier
-- Returns a string containing the Township level and population requirements for a tier
function p._getTierText(tier)
function p._getTierText(tier, abyssalTier)
local tierData = p._getTierRequirements(tier)
local realmID = (abyssalTier ~= nil and 'melvorItA:Abyssal' or 'melvorD:Melvor')
local tierData = p._getTierRequirements(tier, abyssalTier)
if tierData ~= nil then
if tierData ~= nil then
local tierText = Icons._SkillReq('Township', tierData.level, false)
local tierText = Icons._SkillReq('Township', tierData.abyssalLevel or tierData.level, false, realmID)
if tierData.population > 0 then
if tierData.population ~= nil and tierData.population > 0 then
tierText = tierText .. '<br/>' .. Icons.Icon({'Population', type='township', notext=true}) .. '&nbsp;' .. Shared.formatnum(tierData.population)
tierText = tierText .. '<br/>' .. Icons.Icon({'Population', type='township', notext=true}) .. '&nbsp;' .. Num.formatnum(tierData.population)
end
if tierData.fortification ~= nil and tierData.fortification > 0 then
tierText = tierText .. '<br/>' .. Icons.Icon({'Fortification', type='township', notext=true}) .. '&nbsp;' .. Num.formatnum(tierData.fortification) .. '%'
end
end
return tierText
return tierText
Line 278: Line 293:
local seasonReqs = {
local seasonReqs = {
["Nightfall"] = Icons.Icon({'Township%23Worship', 'Bane Worship', img='Statue of Bane', type='building'}),
["Nightfall"] = Icons.Icon({'Township%23Worship', 'Bane Worship', img='Statue of Bane', type='building'}),
["SolarEclipse"] = Icons.Icon({'Township%23Worship', 'The Herald Worship', img='Statue of The Herald', type='building'})
["SolarEclipse"] = Icons.Icon({'Township%23Worship', 'The Herald Worship', img='Statue of The Herald', type='building'}),
["Lemon"] = Icons.Icon({'Ancient_Relics', 'Ancient Relics', img='Ancient Relics'}),
["EternalDarkness"] = Icons.Icon({'Township%23Worship', 'Xon Worship', img='Statue of Xon', type='building'}),
}
}


Line 299: Line 316:
table.insert(resultPart, '<br/>Requires ' .. reqs)
table.insert(resultPart, '<br/>Requires ' .. reqs)
end
end
table.insert(resultPart, '\n| ' .. Constants.getModifiersText(season.modifiers))
table.insert(resultPart, '\n| ' .. Modifiers.getModifiersText(season.modifiers))
end
end
table.insert(resultPart, '\n|}')
table.insert(resultPart, '\n|}')
Line 311: Line 328:
table.insert(resultPart, '{| class="wikitable sortable stickyHeader"')
table.insert(resultPart, '{| class="wikitable sortable stickyHeader"')
table.insert(resultPart, '\n|- class="headerRow-0"')
table.insert(resultPart, '\n|- class="headerRow-0"')
table.insert(resultPart, '\n!rowspan="2" colspan="2"| Biome\n!colspan="2"| Requirements')
table.insert(resultPart, '\n!rowspan="2" colspan="2"| Biome\n!colspan="3"| Requirements')
table.insert(resultPart, '\n|- class="headerRow-1"')
table.insert(resultPart, '\n|- class="headerRow-1"')
table.insert(resultPart, '\n! ' .. Icons.Icon({'Township', 'Level', type='skill', nolink=true}))
table.insert(resultPart, '\n! ' .. Icons.Icon({'Township', 'Level', type='skill', nolink=true}))
table.insert(resultPart, '\n! ' .. Icons.Icon({'Township', 'Population', img='Population', type='township', section='Population' }))
table.insert(resultPart, '\n! ' .. Icons.Icon({'Township', 'Population', img='Population', type='township', section='Population' }))
table.insert(resultPart, '\n! ' .. Icons.Icon({'Township', 'Forification', img='Fortification', type='township', section='Fortification' }))


for i, biome in ipairs(Township.biomes) do
for i, biome in ipairs(Township.biomes) do
local reqs = p._getTierRequirements(biome.tier)
local reqs = p._getTierRequirements(biome.tier, biome.abyssalTier)
local fortification = reqs.fortification or 0
table.insert(resultPart, '\n|-\n|class="table-img"| ' .. Icons.Icon({biome.name, type='biome', size=50, nolink=true, notext=true}))
table.insert(resultPart, '\n|-\n|class="table-img"| ' .. Icons.Icon({biome.name, type='biome', size=50, nolink=true, notext=true}))
table.insert(resultPart, '\n| ' .. biome.name)
table.insert(resultPart, '\n| ' .. biome.name)
table.insert(resultPart, '\n|style="text-align:right"| ' .. reqs.level)
table.insert(resultPart, '\n|style="text-align:right"| ' .. (reqs.abyssalLevel or reqs.level))
table.insert(resultPart, '\n|style="text-align:right" data-sort-value="' .. reqs.population .. '"| ' .. Shared.formatnum(reqs.population))
table.insert(resultPart, '\n|style="text-align:right" data-sort-value="' .. reqs.population .. '"| ' .. Num.formatnum(reqs.population))
table.insert(resultPart, '\n|style="text-align:right" data-sort-value="' .. fortification .. '"| ' .. Num.formatnum(fortification))
end
end
table.insert(resultPart, '\n|}')
table.insert(resultPart, '\n|}')
Line 331: Line 351:
-- Skips upgraded buildings
-- Skips upgraded buildings
function p.getBuildingBiomeTable(frame)
function p.getBuildingBiomeTable(frame)
-- Setup the table
local tbl = mw.html.create('table')
local ret = {}
:addClass('wikitable sortable stickyHeader')
table.insert(ret, '{| class="wikitable sortable stickyHeader" style="text-align:center"')
:css('text-align', 'center')
 
local header = mw.html.create('tr'):addClass('headerRow-0')
local level = mw.html.create('tr'):addClass('sorttop')
local pop = mw.html.create('tr'):addClass('sorttop')
local fort = mw.html.create('tr'):addClass('sorttop')


-- Generate the table header, one column per biome
header:tag('th')
local biomeRows = {
:css('z-index', '2')
['head'] = { '\n|- class="headerRow-0"\n! Building' },
:wikitext('Building')
['level'] = { '\n|- class="sorttop"\n! ' .. Icons.Icon({'Township', 'Level', type='skill', nolink=true}) },
level:tag('th')
['pop'] = { '\n|- class="sorttop"\n! ' .. Icons.Icon({'Township', 'Population', img='Population', type='township', section='Population' }) }
:wikitext(Icons.Icon({'Township', 'Level', type='skill', nolink=true}))
}
pop:tag('th')
:wikitext(Icons.Icon({'Township', 'Population', img='Population', type='township', section='Population' }))
fort:tag('th')
:wikitext(Icons.Icon({'Township', 'Fortification', img='Fortification', type='township', section='Fortification' }))
for _, biome in ipairs(Township.biomes) do
for _, biome in ipairs(Township.biomes) do
local reqs = p._getTierRequirements(biome.tier)
local reqs = p._getTierRequirements(biome.tier, biome.abyssalTier)
table.insert(biomeRows.head,  '\n! ' .. Icons.Icon({biome.name, type='biome', notext=true, nolink=true}) .. '<br/>' .. biome.name)
header:tag('th')
table.insert(biomeRows.level, '\n| ' .. Shared.formatnum(reqs.level))
:wikitext(Icons.Icon({biome.name, type='biome', notext=true, nolink=true}).. '<br/>' .. biome.name)
table.insert(biomeRows.pop, '\n| ' .. Shared.formatnum(reqs.population))
level:tag('td')
:wikitext(Num.formatnum((reqs.abyssalLevel or reqs.level)))
pop:tag('td')
:wikitext(Num.formatnum(reqs.population))
fort:tag('td')
:wikitext(Num.formatnum((reqs.fortification or 0)))
end
end
table.insert(ret, table.concat(biomeRows.head))
table.insert(ret, table.concat(biomeRows.level))
tbl:node(header)
table.insert(ret, table.concat(biomeRows.pop))
tbl:node(level)
biomeRows = nil
tbl:node(pop)
tbl:node(fort)


for _, _building in ipairs(p._sortedBuildings(false)) do
for _, _building in ipairs(p._sortedBuildings(false)) do
Line 364: Line 399:
end
end


-- Build the row
local trow = tbl:tag('tr')
table.insert(ret, '\n|-')
trow:tag('th')
table.insert(ret, '\n!data-sort-value="' .. building.name .. '" style="text-align:left"| ' .. Icons.Icon({building.name, type='building'}))
:css('text-align', 'left')
:attr('data-sort-value', building.name)
:wikitext(Icons.Icon({building.name, type='building'}))
 
for _, biome in ipairs(Township.biomes) do
for _, biome in ipairs(Township.biomes) do
if buildingBiomes[biome.id] then
if buildingBiomes[biome.id] then
-- Buildable
trow:tag('td')
table.insert(ret, '\n|class="table-positive"| ✓')
:addClass('table-positive')
:wikitext('✓')
else
else
-- Invalid biome
trow:tag('td')
table.insert(ret, '\n|style="border:0px"|')
end
end
end
end
end
end
end
end
table.insert(ret, '\n|}')


return table.concat(ret)
return tostring(tbl)
end
end


Line 396: Line 433:
table.insert(resultPart, '{| class="wikitable sortable stickyHeader"')
table.insert(resultPart, '{| class="wikitable sortable stickyHeader"')
table.insert(resultPart, '\n|- class="headerRow-0"')
table.insert(resultPart, '\n|- class="headerRow-0"')
table.insert(resultPart, '\n!colspan="2"|Building\n!Requirements\n!Type\n!Max Built')
table.insert(resultPart, '\n!colspan="2"|Building\n!Requirements\n!Max Built')
table.insert(resultPart, '\n!Biomes\n!Cost\n!Provides')
table.insert(resultPart, '\n!Biomes\n!Cost\n!Provides')


Line 414: Line 451:
table.insert(resultPart, '\n|class="table-img"' .. rowSpan .. '| ' .. Icons.Icon({buildingName, type='building', notext=true, size=50}))
table.insert(resultPart, '\n|class="table-img"' .. rowSpan .. '| ' .. Icons.Icon({buildingName, type='building', notext=true, size=50}))
table.insert(resultPart, '\n' .. rowSpanOnly .. '| ' .. Icons.getExpansionIcon(building.id) .. Icons.Icon({buildingName, type='building', noicon=true}))
table.insert(resultPart, '\n' .. rowSpanOnly .. '| ' .. Icons.getExpansionIcon(building.id) .. Icons.Icon({buildingName, type='building', noicon=true}))
table.insert(resultPart, '\n|' .. 'data-sort-value="' .. building.tier .. '"' .. rowSpan .. '| ' .. (p._getTierText(building.tier) or ''))
table.insert(resultPart, '\n|' .. 'data-sort-value="' .. building.tier .. '"' .. rowSpan .. '| ' .. (p._getTierText(building.tier, building.abyssalTier) or ''))
table.insert(resultPart, '\n' .. rowSpanOnly .. '| ' .. building.type)
table.insert(resultPart, '\n|style="text-align:right"' .. rowSpan .. '| ' .. building.maxUpgrades)
table.insert(resultPart, '\n|style="text-align:right"' .. rowSpan .. '| ' .. building.maxUpgrades)
firstRow = false
firstRow = false
Line 426: Line 462:
local providesText = p._getBuildingBenefitText(building, biomeID)
local providesText = p._getBuildingBenefitText(building, biomeID)
if building.modifiers ~= nil then
if building.modifiers ~= nil then
local modText = Constants.getModifiersText(building.modifiers)
local modText = Modifiers.getModifiersText(building.modifiers)
if providesText == nil then
if providesText == nil then
providesText = modText
providesText = modText
Line 457: Line 493:
if itemDesc == nil then
if itemDesc == nil then
if item.modifiers ~= nil then
if item.modifiers ~= nil then
itemDesc = Constants.getModifiersText(item.modifiers, false, true)
itemDesc = Modifiers.getModifiersText(item.modifiers, false, true)
else
else
itemDesc = ''
itemDesc = ''
Line 480: Line 516:
function p.getWorshipTable()
function p.getWorshipTable()
local function getCheckpointCell(checkpoint)
local function getCheckpointCell(checkpoint)
return '\n|-\n!' .. checkpoint .. '%<br/>' .. Shared.formatnum(checkpoint * Township.maxWorship / 100) .. '/' .. Shared.formatnum(Township.maxWorship)
return '\n|-\n!' .. checkpoint .. '%<br/>' .. Num.formatnum(checkpoint * Township.maxWorship / 100) .. '/' .. Num.formatnum(Township.maxWorship)
end
end


Line 520: Line 556:
table.insert(ret, getCheckpointCell(0))
table.insert(ret, getCheckpointCell(0))
for _, worship in ipairs(worships) do
for _, worship in ipairs(worships) do
table.insert(ret, '\n| ' .. Constants.getModifiersText(worship.modifiers))
table.insert(ret, '\n| ' .. Modifiers.getModifiersText(worship.modifiers))
end
end


Line 527: Line 563:
table.insert(ret, getCheckpointCell(checkpoint))
table.insert(ret, getCheckpointCell(checkpoint))
for _, worship in ipairs(worships) do
for _, worship in ipairs(worships) do
table.insert(ret, '\n| ' .. Constants.getModifiersText(worship.checkpoints[i]))
table.insert(ret, '\n| ' .. Modifiers.getModifiersText(worship.checkpoints[i]))
end
end
end
end


-- Total sum
-- Total sum
-- TODO Needs fixing, no function currently for aggregating modifiers
--[==[
table.insert(ret, '\n|-\n!Total')
table.insert(ret, '\n|-\n!Total')
for _, worship in ipairs(worships) do
for _, worship in ipairs(worships) do
Line 550: Line 588:
end
end
end
end
table.insert(ret, '\n|' .. Constants.getModifiersText(modifiers))
table.insert(ret, '\n|' .. Modifiers.getModifiersText(modifiers))
end
end
--]==]
table.insert(ret, '\n|}')
table.insert(ret, '\n|}')


Line 574: Line 613:
-- ID
-- ID
table.insert(ret, '\n|-\n| <b>Building ID:</b> ' .. building.id)
table.insert(ret, '\n|-\n| <b>Building ID:</b> ' .. building.id)
-- Type
table.insert(ret, '\n|-\n| <b>Type:</b> ' .. building.type)
-- Tier
-- Tier
local tier = p._getTierText(building.tier)
local tier = p._getTierText(building.tier, building.abyssalTier)
table.insert(ret, '\n|-\n| <b>Requirements:</b><br/>' .. tier)
table.insert(ret, '\n|-\n| <b>Requirements:</b><br/>' .. tier)


Line 623: Line 660:
-- Maximum built
-- Maximum built
local biomeCount = Shared.tableCount(building.biomes)
local biomeCount = Shared.tableCount(building.biomes)
local maxText = Shared.formatnum(building.maxUpgrades)
local maxText = Num.formatnum(building.maxUpgrades)
if biomeCount > 1 then
if biomeCount > 1 then
maxText = maxText .. ' per biome, ' .. Shared.formatnum(biomeCount * building.maxUpgrades) .. ' total'
maxText = maxText .. ' per biome, ' .. Num.formatnum(biomeCount * building.maxUpgrades) .. ' total'
end
end
table.insert(ret, '\n|-\n| <b>Maximum Built:</b><br/>' .. maxText)
table.insert(ret, '\n|-\n| <b>Maximum Built:</b><br/>' .. maxText)
Line 694: Line 731:
table.insert(ret, '\n|-\n!colspan="2"| Requirements')
table.insert(ret, '\n|-\n!colspan="2"| Requirements')
for _, building in ipairs(buildingList) do
for _, building in ipairs(buildingList) do
table.insert(ret, '\n|' .. p._getTierText(building.tier))
table.insert(ret, '\n|' .. p._getTierText(building.tier, building.abyssalTier))
end
end


Line 760: Line 797:
-- Requirements
-- Requirements
table.insert(ret, '\n|')
table.insert(ret, '\n|')
local requirements = {}
-- Determines order of requirements output
for _, item in ipairs(task.goals.items) do
local reqOrder = {
local itemname = GameData.getEntityByID('items', item.id).name
["items"] = 10,
table.insert(requirements, Shared.formatnum(item.quantity)..' '..Icons.Icon({itemname, type='item'}))
["monsters"] = 20,
["monsterWithItems"] = 30,
["skillXP"] = 40,
["buildings"] = 50,
["numPOIs"] = 60,
["numRefinements"] = 70
}
local reqTextPart = {}
 
local function getItemText(itemID)
local item = Items.getItemByID(itemID)
if item == nil then
return Shared.printError('Unknown item: ' .. (itemID or 'nil'))
else
return Icons.Icon({item.name, type='item'})
end
end
end
for _, monster in ipairs(task.goals.monsters) do
local function getMonsterText(monsterID)
local monstername = GameData.getEntityByID('monsters', monster.id).name
local monster = Monsters.getMonsterByID(monsterID)
table.insert(requirements, Shared.formatnum(monster.quantity)..' '..Icons.Icon({monstername, type='monster'}))
if monster == nil then
return Shared.printError('Unknown monster: ' .. (monsterID or 'nil'))
else
return Icons.Icon({Monsters.getMonsterName(monster), type='monster'})
end
end
end
if type(task.goals.monsterWithItems) == 'table' then
 
for _, monWithItem in ipairs(task.goals.monsterWithItems) do
for goalType, goalData in pairs(task.goals) do
local monsterName = GameData.getEntityByID('monsters', monWithItem.monsterID).name
local typeOrder = reqOrder[goalType] or 0
local itemsText = {}
local goalText = nil
for i, itemID in ipairs(monWithItem.itemIDs) do
if type(goalData) == 'table' then
local itemName = GameData.getEntityByID('items', itemID).name
-- Goal data is a table
table.insert(itemsText, Icons.Icon({itemName, type='item'}))
for goalIdx, goalObj in ipairs(goalData) do
if goalType == 'items' then
goalText = Num.formatnum(goalObj.quantity) .. ' ' .. getItemText(goalObj.id)
elseif goalType == 'monsters' then
goalText = Num.formatnum(goalObj.quantity) .. ' ' .. getMonsterText(goalObj.id)
elseif goalType == 'monsterWithItems' then
local itemsText = {}
for i, itemID in ipairs(goalObj.itemIDs) do
table.insert(itemsText, getItemText(itemID))
end
goalText = Num.formatnum(goalObj.quantity) .. ' ' .. getMonsterText(goalObj.monsterID) .. ' with ' .. table.concat(itemsText, ', ') .. ' equipped'
elseif goalType == 'skillXP' then
local skillName = GameData.getSkillData(goalObj.id).name
goalText = Num.formatnum(goalObj.quantity) .. ' ' .. Icons.Icon({skillName, type='skill'}) .. ' XP'
elseif goalType == 'buildings' then
local buildingName = p._GetBuildingByID(goalObj.id).name
goalText = Num.formatnum(goalObj.quantity) .. ' ' .. Icons.Icon({buildingName, type='building'})
elseif goalType == 'numPOIs' then
local mapName = GameData.getEntityByID(GameData.skillData.Cartography.worldMaps, goalObj.worldMapID).name
goalText = 'Discover ' .. Num.formatnum(goalObj.quantity) .. ' Points of Interest in ' .. Icons.Icon({'Cartography', type='skill'}) .. ' world map of ' .. mapName
else
goalText = Shared.printError('Unknown goal type: ' .. (goalType or 'nil'))
end
table.insert(reqTextPart, {
["goalOrder"] = typeOrder,
["subOrder"] = goalIdx,
["text"] = goalText
})
end
else
-- Goal data is another value of some type
if goalType == 'numRefinements' then
goalText = 'Refine dig site maps in ' .. Icons.Icon({'Cartography', type='skill'}) .. ' ' .. Num.formatnum(goalData) .. ' times'
else
goalText = Shared.printError('Unknown goal type: ' .. (goalType or 'nil'))
end
end
table.insert(requirements, Shared.formatnum(monWithItem.quantity) .. ' ' .. Icons.Icon({monsterName, type='monster'}) .. ' with ' .. table.concat(itemsText, ', ') .. ' equipped')
table.insert(reqTextPart, {
["goalOrder"] = typeOrder,
["subOrder"] = 0,
["text"] = goalText
})
end
end
end
end
for _, skill in ipairs(task.goals.skillXP) do
 
local skillname = GameData.getSkillData(skill.id).name
table.sort(reqTextPart,
table.insert(requirements, Shared.formatnum(skill.quantity)..' '..Icons.Icon({skillname, type='skill'})..' XP')
function(a, b)
end
if a.goalOrder == b.goalOrder then
for _, building in ipairs(task.goals.buildings) do
return a.subOrder < b.subOrder
local buildingname = p._GetBuildingByID(building.id).name
else
table.insert(requirements, Shared.formatnum(building.quantity)..' '..Icons.Icon({buildingname, type='building'}))
return a.goalOrder < b.goalOrder
end
end
)
 
local requirements = {}
for i, req in ipairs(reqTextPart) do
table.insert(requirements, req.text)
end
end
-- We don't check tasks.requirements (so far it's only used to enumerate the Tutorial tasks so you only see 1 at a time)
-- We don't check tasks.requirements (so far it's only used to enumerate the Tutorial tasks so you only see 1 at a time)
Line 794: Line 895:
local rewards = {}
local rewards = {}
local rewardsVariableQty = {}
local rewardsVariableQty = {}
if task.rewards.gp > 0 and not isDailyTask then
if task.rewards.currencies ~= nil then
table.insert(rewards, Icons.GP(task.rewards.gp))
for _, currReward in ipairs(task.rewards.currencies) do
end
if isDailyTask and currReward.id ~= 'melvorD:GP' then
if task.rewards.slayerCoins > 0 then
table.insert(rewardsVariableQty, Icons._Currency(currReward.id))
if isDailyTask then
elseif not isDailyTask then
table.insert(rewardsVariableQty, Icons.SC())
table.insert(rewards, Icons._Currency(currReward.id, currReward.quantity))
else
end
table.insert(rewards, Icons.SC(task.rewards.slayerCoins))
end
end
end
end
for _, item in ipairs(task.rewards.items) do
for _, item in ipairs(task.rewards.items) do
local itemname = GameData.getEntityByID('items', item.id).name
local itemname = GameData.getEntityByID('items', item.id).name
table.insert(rewards, Shared.formatnum(item.quantity)..' '..Icons.Icon({itemname, type='item'}))
table.insert(rewards, Num.formatnum(item.quantity)..' '..Icons.Icon({itemname, type='item'}))
end
end
for _, skill in ipairs(task.rewards.skillXP) do
for _, skill in ipairs(task.rewards.skillXP) do
if not (isDailyTask and skill.id == 'melvorD:Township') then
if not (isDailyTask and skill.id == 'melvorD:Township') then
local skillname = GameData.getSkillData(skill.id).name
local skillname = GameData.getSkillData(skill.id).name
table.insert(rewards, Shared.formatnum(skill.quantity)..' '..Icons.Icon({skillname, type='skill'})..' XP')
table.insert(rewards, Num.formatnum(skill.quantity)..' '..Icons.Icon({skillname, type='skill'})..' XP')
end
end
end
end
for _, townshipResource in ipairs(task.rewards.townshipResources) do
for _, townshipResource in ipairs(task.rewards.townshipResources) do
local resourcename = p._getResourceByID(townshipResource.id).name
local resourcename = p._getResourceByID(townshipResource.id).name
table.insert(rewards, Shared.formatnum(townshipResource.quantity)..' '..Icons.Icon({resourcename, type='resource'}))
table.insert(rewards, Num.formatnum(townshipResource.quantity)..' '..Icons.Icon({resourcename, type='resource'}))
end
end
if not Shared.tableIsEmpty(rewardsVariableQty) then
if not Shared.tableIsEmpty(rewardsVariableQty) then
Line 834: Line 934:
function p.getTaskTable(frame)
function p.getTaskTable(frame)
local category = frame.args ~= nil and frame.args[1] or frame
local category = frame.args ~= nil and frame.args[1] or frame
local categoryData = GameData.getEntityByID(Township.taskCategories, category)
local categoryData = GameData.getEntityByName(Township.taskCategories, category)
local taskData, categoryName, isDailyTask = nil, nil, false
local taskData, categoryName, isDailyTask = nil, nil, false
if category == 'Daily' then
if category == 'Daily' then
Line 849: Line 949:
local taskcount = 0
local taskcount = 0
local ret = {}
local ret = {}
table.insert(ret, '{| class="wikitable lighttable" style="text-align:left"')
table.insert(ret, '{| class="wikitable lighttable stickyHeader" style="text-align:left"')
table.insert(ret, '\n|- class="headerRow-0"')
table.insert(ret, '\n!Task')
table.insert(ret, '\n!Task')
table.insert(ret, '\n!Requirements')
table.insert(ret, '\n!Requirements')
table.insert(ret, '\n!Rewards')
table.insert(ret, '\n!Rewards')
if isDailyTask then
if isDailyTask then
table.insert(ret, '<br/>(In addition to [[Township#Casual Tasks|Variable]] ' .. Icons.GP() .. ' & ' .. Icons.Icon({'Township', type='skill', notext=true}) .. ' XP)')
table.insert(ret, '<br/>(In addition to [[Township#Casual Tasks|Variable]] ' .. Icons._Currency('melvorD:GP') .. ' & ' .. Icons.Icon({'Township', type='skill', notext=true}) .. ' XP)')
end
end
if isDailyTask then
if isDailyTask then
Line 862: Line 963:
for _, task in ipairs(taskData) do
for _, task in ipairs(taskData) do
-- Filter out other categories
-- Filter out other categories
if task.category == category then
local categoryID, categoryNS, categoryLocalID = '', '', ''
if categoryData ~= nil then
categoryID = categoryData.id
categoryNS, categoryLocalID = Shared.getLocalID(categoryID)
end
if isDailyTask or task.category == categoryID or task.category == categoryLocalID then
taskcount = taskcount + 1
taskcount = taskcount + 1
local title = categoryName .. ' ' .. taskcount
local title = categoryName .. ' ' .. taskcount
Line 882: Line 988:
if referenceType == 'dungeon' then
if referenceType == 'dungeon' then
-- We get the tasks associated with all monsters in the dungeon
-- We get the tasks associated with all monsters in the dungeon
local monsters = GameData.getEntityByName('dungeons', referenceName).monsterIDs
local area = nil
local areaTypes = {'dungeons', 'abyssDepths'}
for _, areaType in ipairs(areaTypes) do
area = GameData.getEntityByName(areaType, referenceName)
if area ~= nil then
break
end
end
local monsters = area.monsterIDs
for _, monster in ipairs(monsters) do
for _, monster in ipairs(monsters) do
IDs[monster] = true
IDs[monster] = true
Line 891: Line 1,005:
end
end
if referenceType == 'monster' then
if referenceType == 'monster' then
IDs[GameData.getEntityByName('monsters', referenceName).id] = true
IDs[Monsters.getMonster(referenceName).id] = true
end
end
return IDs
return IDs
Line 918: Line 1,032:
return referenceIDs[entry.id] ~= nil
return referenceIDs[entry.id] ~= nil
end
end
for _, searchTable in ipairs(GetSearchTables(task)) do
for _, searchTable in pairs(GetSearchTables(task)) do -- ipairs won't work if first table is nil
-- Check to see if the table contains any of the IDs in referenceIDs
-- Check to see if the table contains any of the IDs in referenceIDs
if searchTable[1] ~= nil then -- Make sure table is not empty
if searchTable[1] ~= nil then -- Make sure table is not empty
Line 942: Line 1,056:
table.insert(ret, '\n!Rewards')
table.insert(ret, '\n!Rewards')
for _, task in ipairs(tasks) do
for _, task in ipairs(tasks) do
local categoryname = GameData.getEntityByID(Township.taskCategories, task.category).name
-- Some categories have a local ID, resolve this before looking up the task category
local taskNS, taskLocalID = Shared.getLocalID(task.id)
local catID = Shared.getNamespacedID(taskNS,  task.category)
local categoryname = GameData.getEntityByID(Township.taskCategories, catID).name
local title = '[[Township/Tasks#'..categoryname..'|'..categoryname..']]'
local title = '[[Township/Tasks#'..categoryname..'|'..categoryname..']]'
table.insert(ret, p._getTaskRow(title, task, false))
table.insert(ret, p._getTaskRow(title, task, false))