Module:Township: Difference between revisions

Fix township building sticky header and add cell borders
(Fix monster lookup)
(Fix township building sticky header and add cell borders)
 
(2 intermediate revisions by 2 users not shown)
Line 6: Line 6:
local GameData = require('Module:GameData')
local GameData = require('Module:GameData')
local Constants = require('Module:Constants')
local Constants = require('Module:Constants')
local Num = require('Module:Number')


local p = {}
local p = {}
Line 276: Line 277:
-- Generates a table of all seasons, their type/requirements, and modifiers
-- Generates a table of all seasons, their type/requirements, and modifiers
function p.getSeasonTable(frame)
function p.getSeasonTable(frame)
-- Exclude Easter egg seasons
local hideSeasons = {
'melvorAoD:Lemon'
}
-- Manual data specifying the worship requirement for those rare seasons
-- Manual data specifying the worship requirement for those rare seasons
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'})
}
}


Line 295: Line 293:


for i, season in ipairs(seasons) do
for i, season in ipairs(seasons) do
if not Shared.contains(hideSeasons, season.id) then
local ns, localSeasonID = Shared.getLocalID(season.id)
local ns, localSeasonID = Shared.getLocalID(season.id)
local reqs = seasonReqs[localSeasonID]
local reqs = seasonReqs[localSeasonID]
table.insert(resultPart, '\n|-')
table.insert(resultPart, '\n|-')
table.insert(resultPart, '\n|class="table-img"| ' .. Icons.Icon({season.name, type='township', size=50, nolink=true, notext=true}))
table.insert(resultPart, '\n|class="table-img"| ' .. Icons.Icon({season.name, type='township', size=50, nolink=true, notext=true}))
table.insert(resultPart, '\n| ' .. Icons.Icon({season.name, type='township', nolink=true, noicon=true}))
table.insert(resultPart, '\n| ' .. Icons.Icon({season.name, type='township', nolink=true, noicon=true}))
table.insert(resultPart, '\n| ' .. (season.order <= 3 and 'Regular' or 'Rare'))
table.insert(resultPart, '\n| ' .. (season.order <= 3 and 'Regular' or 'Rare'))
if reqs ~= nil then
if reqs ~= nil then
table.insert(resultPart, '<br/>Requires ' .. reqs)
table.insert(resultPart, '<br/>Requires ' .. reqs)
end
table.insert(resultPart, '\n| ' .. Constants.getModifiersText(season.modifiers))
end
end
table.insert(resultPart, '\n| ' .. Constants.getModifiersText(season.modifiers))
end
end
table.insert(resultPart, '\n|}')
table.insert(resultPart, '\n|}')
Line 338: Line 334:
-- 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')


-- 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' }))
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)
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.level))
pop:tag('td')
:wikitext(Num.formatnum(reqs.population))
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)


for _, _building in ipairs(p._sortedBuildings(false)) do
for _, _building in ipairs(p._sortedBuildings(false)) do
Line 371: Line 376:
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 764: Line 771:
-- 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 = Monsters.getMonsterName(Monsters.getMonsterByID(monster.id))
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 = Shared.formatnum(goalObj.quantity) .. ' ' .. getItemText(goalObj.id)
elseif goalType == 'monsters' then
goalText = Shared.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 = Shared.formatnum(goalObj.quantity) .. ' ' .. getMonsterText(goalObj.monsterID) .. ' with ' .. table.concat(itemsText, ', ') .. ' equipped'
elseif goalType == 'skillXP' then
local skillName = GameData.getSkillData(goalObj.id).name
goalText = Shared.formatnum(goalObj.quantity) .. ' ' .. Icons.Icon({skillName, type='skill'}) .. ' XP'
elseif goalType == 'buildings' then
local buildingName = p._GetBuildingByID(goalObj.id).name
goalText = Shared.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 ' .. Shared.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'}) .. ' ' .. Shared.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 853: Line 924:
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')
1,029

edits