Module:Spawn table
Jump to navigation
Jump to search
This module implements Template:Spawn table.
Dependencies[edit source]
[view] [edit] [history] [refresh]The above documentation is transcluded from Module:Spawn table/doc.
require('strict')
local p = {}
local pageTitle = mw.title.getCurrentTitle()
local pageTitleString = pageTitle.fullText
local namespace = pageTitle.nsText
local function tooltip(text, title)
return tostring(mw.html.create('span')
:addClass('explain')
:attr('title', title)
:wikitext(text)
:allDone())
end
local i18n = {
processArgsModule = 'Module:ProcessArgs',
mobColumn = 'Mob',
chanceColumn = tooltip('Spawn weight', 'Weight relative to other spawn entries in the category'),
groupSizeColumn = tooltip('Group size', 'Number of mobs the game tries to spawn per attempt'),
chargeColumn = tooltip('Charge', 'Charge generated by the mob'),
budgetColumn = tooltip('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 [[Mob spawning#Spawn costs|Mob spawning § Spawn costs]] for details.',
-- SMW properties
smwSubnamePrefix = "SPAWN",
smwSpawnedMob = "Spawned mob",
smwSpawnedIn = "Spawned in",
smwEdition = "Edition",
smwCategory = "Category",
smwWeight = "Weight",
smwTotalWeight = "Total weight",
smwSize = "Size",
smwNote = "Note",
smwNoteName = "Note name",
smwSpawnJSON = "Spawn JSON"
}
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',
['underground'] = 'Underground water creature category',
['waterambient'] = 'Water ambient category',
['misc'] = 'Misc category'
}
-- [[Template:Spawn row]]
function p.main(frame)
local args = frame
if frame == mw.getCurrentFrame() then
args = require(i18n.processArgsModule).merge( true )
else
frame = mw.getCurrentFrame()
end
local data = {
mob = args.name or args[1],
weight = args.weight,
size = args.size,
charge = args.charge,
budget = args.budget,
note = args.note,
notename = args.notename
}
return mw.text.jsonEncode(data)
end
-- parses input arguments into spawnData table
local function parseInput(args)
local spawnData = {}
spawnData.notes = {}
for argName in pairs(groupArgs) do
if args[argName] and args[argName] ~= "" then
local group = {}
group.category = argName
group.mobs = {}
group.totalWeight = 0
-- parse input of group parameter
for line in mw.text.gsplit(args[argName], '\n') do -- split on newline
local parsed = mw.text.jsonDecode(line)
if parsed.weight and tonumber(parsed.weight) then
parsed.weight = tonumber(parsed.weight)
group.totalWeight = group.totalWeight + parsed.weight
end
if parsed.charge or parsed.budget then
spawnData.hasSpawnCost = true
end
if parsed.note or parsed.notename then
spawnData.hasNotes = true
if not parsed.notename then
parsed.notename = parsed.mob
end
if parsed.note and parsed.notename then
spawnData.notes[parsed.notename] = parsed.note
end
end
if parsed.mob then
table.insert(group.mobs, parsed)
end
end
table.insert(spawnData, group)
-- Put data into SMW
local onMain = false
if (namespace == '' or namespace == mw.site.namespaces[4].name) then
onMain = true
end
if onMain and not args.ignoreusage then
for _, data in ipairs(group.mobs) do
local origMob = data.mob
:gsub("Warm ", "")
:gsub("Cold ", "")
:gsub("Ashen ", "")
:gsub("Black ", "")
:gsub("Chestnut ", "")
:gsub("Pale ", "")
:gsub("Rusty ", "")
:gsub("Snowy ", "")
:gsub("Spotted ", "")
:gsub("Striped ", "")
:gsub("Woods ", "")
local smw_sub = {}
local smwSpawnedIn = pageTitleString
local subname = i18n.smwSubnamePrefix .. '_' .. origMob
local smw_json = {
[i18n.smwSpawnedMob] = data.mob,
[i18n.smwSpawnedIn] = smwSpawnedIn,
[i18n.smwEdition] = (args.edition or 'java'):lower(),
[i18n.smwCategory] = groupArgs[argName]:gsub(' category', ''),
[i18n.smwWeight] = data.weight,
[i18n.smwTotalWeight] = group.totalWeight,
[i18n.smwSize] = data.size,
[i18n.smwNote] = data.note or spawnData.notes[data.notename],
[i18n.smwNoteName] = data.notename
}
local smw_sub = { -- the actual SMW sub-object
[i18n.smwSpawnedMob] = origMob,
[i18n.smwSpawnedIn] = smwSpawnedIn,
[i18n.smwSpawnJSON] = mw.text.jsonEncode(smw_json)
}
mw.smw.subobject(smw_sub, subname)
end
end
end
end
return spawnData
end
local function addTableBody(spawnData, colspan)
local ret = mw.html.create()
for _, groupTable in ipairs(spawnData) do
ret:tag('tr')
:tag('th')
:attr('colspan', colspan)
:wikitext(groupArgs[groupTable.category])
:done()
:done()
for _, mobData in ipairs(groupTable.mobs) do
ret:tag('tr')
local mobCellText = require('Module:SpriteFile').link{name = 'EntitySprite', mobData.mob}
if mobData.note or mobData.notename then
mobCellText = mobCellText .. mw.getCurrentFrame():extensionTag{name='ref', content=mobData.note, args={name=mobData.notename or mobData.mob, group='note'}}
end
ret:tag('th')
:css('text-align', 'left')
:css('font-weight', 'normal')
:wikitext(mobCellText)
:done()
-- 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
ret:tag('td')
:css('text-align', 'center')
:wikitext(weightText)
:done()
:tag('td')
:css('text-align', 'center')
:wikitext((mobData.size:gsub('-', '–')))
:done()
if spawnData.hasSpawnCost then
ret:tag('td')
:css('text-align', 'center')
:wikitext(mobData.charge)
:done()
:tag('td')
:css('text-align', 'center')
:wikitext(mobData.budget)
:done()
end
ret:done()
end
end
return ret
end
-- [[Template:Spawn table]]
function p.mobSpawnTable(frame)
local args = frame
if frame == mw.getCurrentFrame() then
args = require(i18n.processArgsModule).merge( true )
else
frame = mw.getCurrentFrame()
end
local spawnData = parseInput(args)
local columns = {i18n.mobColumn, i18n.chanceColumn, i18n.groupSizeColumn}
local tableRoot = mw.html.create('table')
:addClass('wikitable')
if spawnData.hasSpawnCost then
spawnData.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
local titleStr = args.title
if args.edition then
local editionStr = string.format("'''''[[%s Edition]]'''''", (args.edition or ''):lower() == 'bedrock' and 'Bedrock' or 'Java')
if titleStr then
titleStr = titleStr .. ' in ' .. editionStr
else
titleStr = 'In ' .. editionStr
end
end
if titleStr then
tableRoot:tag('caption')
:wikitext(titleStr)
:done()
end
tableRoot:tag('tr')
for _, value in ipairs(columns) do
tableRoot:tag('th')
:wikitext(value)
:done()
end
tableRoot:done()
:node(addTableBody(spawnData, #columns))
:allDone()
local refs = ''
if spawnData.hasNotes then
refs = '\n\n' .. frame:extensionTag{name='references', args={group='note'}}
end
return tostring(tableRoot) .. refs .. require('Module:NiceJSON').wrap(spawnData, 'pre', 'spawntable-json')
end
return p