Module:Spawn table
Jump to navigation
Jump to search
Documentation for this module may be created at Module:Spawn table/doc
local p = {}
local i18n = {
processArgsModule = 'Module:ProcessArgs',
entityLinkTemplate = 'EntityLink',
mobColumn = 'Mob',
chanceColumn = mw.getCurrentFrame():expandTemplate{title='Tooltip', args={'Spawn weight', 'Weight relative to other spawn entries in the category'}},
groupSizeColumn = mw.getCurrentFrame():expandTemplate{title='Tooltip', args={'Group size', 'Number of mobs the game tries to spawn per attempt'}},
chargeColumn = mw.getCurrentFrame():expandTemplate{title='Tooltip', args={'Charge', 'Charge generated by the mob' }},
budgetColumn = mw.getCurrentFrame():expandTemplate{title='Tooltip', args={'Budget', 'Maximum charge potential allowing spawning'}},
spawnCostNote = 'When spawning a mob with a budget, take the sum of the charge of each existing mob divided by the distance to that mob. If the total times the new mob\'s charge is greater than the new mob\'s budget, the spawn fails. See [[Spawn#Spawn costs]] for details.'
}
local spawnData = {} -- contains mob spawn info
local groupArgs = {
['creature'] = 'Creature category',
['passive'] = 'Creature category', --Deprecated
['monster'] = 'Monster category',
['hostile'] = 'Monster category', --Deprecated
['ambient'] = 'Ambient category',
['axolotl'] = 'Axolotl category',
['watercreature'] = 'Water creature category',
['cavecreature'] = 'Cave creature category',
['underground'] = 'Underground water creature category',
['waterambient'] = 'Water ambient category',
['misc'] = 'Misc category'
}
local hasNotes = false
local hasSpawnCost = false
-- parses input arguments into spawnData table
local function parseInput(args)
for argName in pairs(groupArgs) do
local groupArg = args[argName]
if groupArg then
local currentGroup = {}
local totalWeight = 0
currentGroup.mobs = {}
groupArg = groupArg .. '\n' -- allow last line to be matched like the rest
-- parse input of group parameter
for line in mw.ustring.gmatch(groupArg, '[^\r\n]+[\r\n]') do -- split on newline
local parsedLine = {}
for key, value in mw.ustring.gmatch(line, '([%a]+)%s*=%s*(.-)%s*[,\r\n]') do
if value ~= '' then
parsedLine[key:lower()] = value
end
end
parsedLine.note = mw.ustring.match(line, 'note=%s*(.-)%s*[\r\n]')
local currentMob = {}
-- convert weight to number; becomes nil if conversion fails
if parsedLine.weight then
weightNum = tonumber(parsedLine.weight)
-- if converted to number successfully
if weightNum then
currentMob.weight = weightNum
totalWeight = totalWeight + weightNum
end
end
if parsedLine.size then
currentMob.size = parsedLine.size
end
if parsedLine.charge then
hasSpawnCost = true
currentMob.charge = parsedLine.charge
end
if parsedLine.budget then
hasSpawnCost = true
currentMob.budget = parsedLine.budget
end
if parsedLine.note then
hasNotes = true
currentMob.note = parsedLine.note
end
if parsedLine.notename then
currentMob.notename = parsedLine.notename
end
if parsedLine.mob then
currentMob.mob = parsedLine.mob
table.insert(currentGroup.mobs, currentMob)
end
end
currentGroup.totalWeight = totalWeight
spawnData[argName] = currentGroup
end
end
end
-- takes root <table> html object and adds table body using info in spawnData
local function addTableBody(tableRoot, numberOfColumns)
local frame = mw.getCurrentFrame()
local groupNumber = 1
for groupArg, groupTable in pairs(spawnData) do
local groupHeader = mw.html.create('tr')
groupHeader:tag('th')
:attr('colspan', numberOfColumns)
:wikitext(groupArgs[groupArg])
tableRoot:node(groupHeader)
for _, mobData in ipairs(groupTable.mobs) do
local tableRow = mw.html.create('tr')
local mobCellText = frame:expandTemplate{title=i18n.entityLinkTemplate, args={mobData.mob}}
if mobData.note then
mobCellText = mobCellText .. frame:extensionTag{name='ref', content=mobData.note, args={name=mobData.mob:lower(), group='note'}}
elseif mobData.notename then
mobCellText = mobCellText .. frame:extensionTag{name='ref', args={name=mobData.notename:lower(), group='note'}}
end
tableRow:tag('th')
:css('text-align', 'left')
:css('font-weight', 'normal')
:wikitext(mobCellText)
-- Simplify weights for pools with single entries to avoid confusion from e.g. 10/10 and 25/25
local weightText = '1'
if mobData.weight ~= groupTable.totalWeight then
weightText = '<sup>' .. mobData.weight .. '</sup>⁄<sub>' .. groupTable.totalWeight .. '</sub>'
end
tableRow:tag('td')
:css('text-align', 'center')
:wikitext(weightText)
tableRow:tag('td')
:css('text-align', 'center')
:wikitext(mobData.size)
if hasSpawnCost then
tableRow:tag('td')
:css('text-align', 'center')
:wikitext(mobData.charge)
tableRow:tag('td')
:css('text-align', 'center')
:wikitext(mobData.budget)
end
tableRoot:node(tableRow)
end
end
end
-- function called from template
function p.mobSpawnTable(frame)
local args = frame
if frame == mw.getCurrentFrame() then
args = require(i18n.processArgsModule).merge( true )
else
frame = mw.getCurrentFrame()
end
parseInput(args)
local columns = {i18n.mobColumn, i18n.chanceColumn, i18n.groupSizeColumn}
local tableRoot = mw.html.create('table'):attr('class', 'wikitable')
local titleStr = args.title
if hasSpawnCost then
hasNotes = true
table.insert( columns, i18n.chargeColumn .. frame:extensionTag{name='ref', content=i18n.spawnCostNote, args={name='spawn-cost', group='note'}} )
table.insert( columns, i18n.budgetColumn .. frame:extensionTag{name='ref', args={name='spawn-cost', group='note'}} )
end
if titleStr then
tableRoot
:tag('caption')
:wikitext(titleStr)
end
local colHeaders = mw.html.create('tr')
for _, value in pairs(columns) do
colHeaders:tag('th'):wikitext(value)
end
tableRoot:node(colHeaders)
addTableBody(tableRoot, #columns)
local outputWikitext = tostring(tableRoot)
if hasNotes then
outputWikitext = outputWikitext .. '\n\n' .. frame:extensionTag{name='references', args={group='note'}}
end
return outputWikitext
end
return p