Difference between revisions of "Module:WeaponData"

From Zero-K
Jump to navigation Jump to search
m (Undo revision 9292 by Histidine (talk))
Tag: Undo
(Undo revision 9322 by Histidine (talk))
Tag: Undo
(9 intermediate revisions by the same user not shown)
Line 3: Line 3:
 
local weaponData = mw.loadData('Module:WeaponData/data')
 
local weaponData = mw.loadData('Module:WeaponData/data')
  
local function writeTemplateLine(key, value)
+
local function addCustomLabel(templateArgs, key, value, index)
if not key or not value then
 
return ""
 
end
 
local str = ""
 
str = str .. "| " .. key .. " = " .. value
 
return str
 
end
 
 
 
-- args: key in a key-value pair (nil if not a pair); value to display; number of extra rows used in the infobox thus far; infobox string thus far
 
-- return values: appended string, number of rows (now incremented by one), infobox string with new text appended
 
local function writeCustomDataLine(key, value, count, currentStr)
 
currentStr = currentStr or ''
 
count = count + 1
 
local append = ""
 
 
 
if key then
 
if key then
append = writeTemplateLine("customlabel"..count, key) .. writeTemplateLine("customdata"..count, value)
+
templateArgs["customlabel"..index] = key
 +
templateArgs["customdata"..index] = value
 
else
 
else
append = writeTemplateLine("special"..count, value)
+
templateArgs["special"..index] = value
 
end
 
end
currentStr = currentStr .. append
+
index = index + 1
return append, count, currentStr
 
 
end
 
end
  
 
function weapon.getData(frame)
 
function weapon.getData(frame)
 
if not frame then return '' end
 
if not frame then return '' end
local weaponDefName = frame.args[1]
+
local weaponDefName = frame.args.defname or frame.args[1] or "<no name specified>"
 
local wd = weaponData[weaponDefName]
 
local wd = weaponData[weaponDefName]
 
if not (wd) then return 'weapondef ' .. weaponDefName .. ' not found' end
 
if not (wd) then return 'weapondef ' .. weaponDefName .. ' not found' end
local property = frame.args[2]
+
local property = (frame.args.defname == nil) and frame.args[2] or frame.args[1]
 
local result = wd[property]
 
local result = wd[property]
 
if not result then result = '' end
 
if not result then result = '' end
Line 39: Line 24:
 
end
 
end
  
function weapon.printInfobox(frame)
+
local function addSpecialDataToTemplate(templateArgs, wd)
local weaponDefName = frame.args[1]
+
local num = 1
local expanded = frame.args[2]
+
for index, entry in ipairs(wd.extraData or {}) do
if not (weaponData[weaponDefName]) then return 'weapondef ' .. weaponDefName .. ' not found' end
 
if expanded then return frame:expandTemplate({title = "User:Histidine/Autoinfobox zkweapon", args = {defname=weaponDefName}})
 
else return [[{{User:Histidine/Autoinfobox zkweapon
 
|defname=]]..weaponDefName..[[}}]] end
 
end
 
 
 
function weapon.printInfoboxCustomRows(frame)
 
local weaponDefName = frame.args[1]
 
local expanded = frame.args[2]
 
local wd = weaponData[weaponDefName]
 
if not wd then return 'weapondef ' .. weaponDefName .. ' not found' end
 
if not wd.extraData then return '' end
 
 
local str = ''
 
local count = 0
 
for index, entry in ipairs(wd.extraData) do
 
local append = ''
 
 
if type(entry) == 'table' then
 
if type(entry) == 'table' then
 
if entry.type == 'shielddrain' then
 
if entry.type == 'shielddrain' then
append, count, str = writeCustomDataLine("Shield drain (HP/shot)", entry.drain, count, str)
+
addCustomLabel(templateArgs, "Shield drain (HP/shot)", entry.drain, num)
 
elseif entry.type == 'needs_link' then
 
elseif entry.type == 'needs_link' then
append, count, str = writeCustomDataLine("Grid needed", entry.power, count, str)
+
addCustomLabel(templateArgs, "Grid needed", entry.power, num)
 
elseif entry.type == 'spawn' then
 
elseif entry.type == 'spawn' then
append, count, str = writeCustomDataLine("Spawns Unit", "[[" .. entry.name .. "]]", count, str)
+
addCustomLabel(templateArgs, "Spawns Unit", "[[" .. entry.name .. "]]", num)
append, count, str = writeCustomDataLine("Spawn Life (s)", entry.expire, count, str)
+
addCustomLabel(templateArgs, "Spawn Life (s)", entry.expire, num)
 
elseif entry.type == 'areadamage' then
 
elseif entry.type == 'areadamage' then
 
local typeName = entry.grav and "Gravity Well" or "Ground Burn"
 
local typeName = entry.grav and "Gravity Well" or "Ground Burn"
 
if not grav then
 
if not grav then
append, count, str = writeCustomDataLine(typeName .. " DPS", entry.dps, count, str)
+
addCustomLabel(templateArgs, typeName .. " DPS", entry.dps, num)
 
end
 
end
append, count, str = writeCustomDataLine(typeName .. " radius (elmo)", entry.radius, count, str)
+
addCustomLabel(templateArgs, typeName .. " radius (elmo)", entry.radius, num)
append, count, str = writeCustomDataLine(typeName .. " duration (s)", entry.duration, count, str)
+
addCustomLabel(templateArgs, typeName .. " duration (s)", entry.duration, num)
  
 
elseif entry.type == 'stockpile' then
 
elseif entry.type == 'stockpile' then
append, count, str = writeCustomDataLine("Stockpile time (s)", entry.time, count, str)
+
addCustomLabel(templateArgs, "Stockpile time (s)", entry.time, num)
 
if (entry.cost) then
 
if (entry.cost) then
append, count, str = writeCustomDataLine("Stockpile cost (M)", entry.cost, count, str)
+
addCustomLabel(templateArgs, "Stockpile cost (M)", entry.cost, num)
 
end
 
end
else
 
append, count, str = writeCustomDataLine("Invalid table data", entry.type, count, str)
 
 
end
 
end
 
else
 
else
 
if entry == 'hitscan' then
 
if entry == 'hitscan' then
append, count, str = writeCustomDataLine(nil, "Instantly hits", count, str)
+
addCustomLabel(templateArgs, nil, "Instantly hits", num)
 
elseif entry == 'ignoreshield' then
 
elseif entry == 'ignoreshield' then
append, count, str = writeCustomDataLine(nil, "Ignores shields", count, str)
+
addCustomLabel(templateArgs, nil, "Ignores shields", num)
 
elseif entry == 'smoothsground' then
 
elseif entry == 'smoothsground' then
append, count, str = writeCustomDataLine(nil, "Smooths ground", count, str)
+
addCustomLabel(templateArgs, nil, "Smooths ground", num)
 
elseif entry == 'hightraj' then
 
elseif entry == 'hightraj' then
append, count, str = writeCustomDataLine(nil, "High trajectory", count, str)
+
addCustomLabel(templateArgs, nil, "High trajectory", num)
 
elseif entry == 'trajtoggle' then
 
elseif entry == 'trajtoggle' then
append, count, str = writeCustomDataLine(nil, "Trajectory toggle", count, str)
+
addCustomLabel(templateArgs, nil, "Trajectory toggle", num)
 
elseif entry == 'watercapable' then
 
elseif entry == 'watercapable' then
append, count, str = writeCustomDataLine(nil, "Water capable", count, str)
+
addCustomLabel(templateArgs, nil, "Water capable", num)
 
elseif entry == 'friendlyfire' then
 
elseif entry == 'friendlyfire' then
append, count, str = writeCustomDataLine(nil, "Potential friendly fire", count, str)
+
addCustomLabel(templateArgs, nil, "Potential friendly fire", num)
 
elseif entry == 'nofriendlyfire' then
 
elseif entry == 'nofriendlyfire' then
append, count, str = writeCustomDataLine(nil, "No friendly fire", count, str)
+
addCustomLabel(templateArgs, nil, "No friendly fire", num)
 
elseif entry == 'nogroundcollide' then
 
elseif entry == 'nogroundcollide' then
append, count, str = writeCustomDataLine(nil, "Passes through ground", count, str)
+
addCustomLabel(templateArgs, nil, "Passes through ground", num)
 
elseif entry == 'piercing' then
 
elseif entry == 'piercing' then
append, count, str = writeCustomDataLine(nil, "Damage increase vs large units", count, str)
+
addCustomLabel(templateArgs, nil, "Damage increase vs large units", num)
 
elseif entry == 'damagefalloff' then
 
elseif entry == 'damagefalloff' then
append, count, str = writeCustomDataLine(nil, "Damage falls off with range", count, str)
+
addCustomLabel(templateArgs, nil, "Damage falls off with range", num)
 
elseif entry == 'inaccuratevsmoving' then
 
elseif entry == 'inaccuratevsmoving' then
append, count, str = writeCustomDataLine(nil, "Inaccuracy vs moving targets", count, str)
+
addCustomLabel(templateArgs, nil, "Inaccuracy vs moving targets", num)
 
elseif entry == 'interceptedbyantinuke' then
 
elseif entry == 'interceptedbyantinuke' then
append, count, str = writeCustomDataLine(nil, "Can be shot down by antinukes", count, str)
+
addCustomLabel(templateArgs, nil, "Can be shot down by antinukes", num)
else
 
append, count, str = writeCustomDataLine("Invalid tag data", entry, count, str)
 
 
end
 
end
 
end
 
end
 
end
 
end
return expanded and frame:preprocess(str) or str
+
end
 +
 
 +
function weapon.getInfoboxTemplate(frame)
 +
local args = frame.args
 +
local tbl = {title = "Infobox zkweapon", args = {}}
 +
local w = tbl.args
 +
local defName = args.defname or args[1] or "<no name specified>"
 +
local wd = weaponData[defName]
 +
if not (wd) then return 'weapondef ' .. defName .. ' not found' end
 +
 +
addSpecialDataToTemplate(w, wd)
 +
 +
for key, value in pairs(wd) do
 +
w[key] = args[key] or value
 +
end
 +
w.extraData = nil
 +
if (w.count and w.count > 1) then
 +
w.name = w.name .. " x " .. w.count
 +
end
 +
if (w.projectiles and w.projectiles > 1) then
 +
local append = " x " ..  w.projectiles
 +
if w.damage then w.damage = w.damage .. append end
 +
if w.empdamage then w.empdamage = w.empdamage .. append end
 +
if w.slowdamage then w.slowdamage = w.slowdamage .. append end
 +
if w.disarmdamage then w.disarmdamage = w.disarmdamage .. append end
 +
if w.shielddamage then w.shielddamage = w.shielddamage .. append end
 +
end
 +
 +
return tbl
 +
end
 +
 
 +
function weapon.printInfobox(frame)
 +
return frame:expandTemplate(weapon.getInfoboxTemplate(frame))
 
end
 
end
  
 
return weapon
 
return weapon

Revision as of 21:45, 11 May 2024

Documentation

This module is used to autogenerate the weapon infoboxes contained in unit infoboxes, by drawing data from Module:WeaponData/data. The intent is to ease updating of unit infoboxes on the wiki; ideally, only the one data page needing to be changed every release. The concept is taken from e.g. the Combat Card Data module on the Library of Ruina Wiki.

Unlike Module:UnitData, there is no template for this module. If it is desired to generate a weapon infobox outside its unit infobox, the module should be invoked directly, e.g.:

{{#invoke:WeaponData|printInfobox|defname=striderdetriment_gauss|name=Name override}}

Data page

Module:WeaponData/data is a central store of data used by Module:WeaponData to automatically populate weapon infoboxes.

The page is a Lua table written to the local file temp/weaponStats.lua by the Wiki Data Export (dbg_wiki_export.lua) widget in Zero-K. This widget should be run once each update and the data page on the wiki replaced accordingly. It should not be necessary to edit the data manually.


local getArgs = require('Module:Arguments').getArgs
local weapon = {}
local weaponData = mw.loadData('Module:WeaponData/data')

local function addCustomLabel(templateArgs, key, value, index)
	if key then
		templateArgs["customlabel"..index] = key
		templateArgs["customdata"..index] = value
	else
		templateArgs["special"..index] = value
	end
	index = index + 1
end

function weapon.getData(frame)
	if not frame then return '' end
	local weaponDefName = frame.args.defname or frame.args[1] or "<no name specified>"
	local wd = weaponData[weaponDefName]
	if not (wd) then return 'weapondef ' .. weaponDefName .. ' not found' end
	local property = (frame.args.defname == nil) and frame.args[2] or frame.args[1]
	local result = wd[property]
	if not result then result = '' end
	return result
end

local function addSpecialDataToTemplate(templateArgs, wd)
	local num = 1
	for index, entry in ipairs(wd.extraData or {}) do
		if type(entry) == 'table' then
			if entry.type == 'shielddrain' then
				addCustomLabel(templateArgs, "Shield drain (HP/shot)", entry.drain, num)
			elseif entry.type == 'needs_link' then
				addCustomLabel(templateArgs, "Grid needed", entry.power, num)
			elseif entry.type == 'spawn' then
				addCustomLabel(templateArgs, "Spawns Unit", "[[" .. entry.name .. "]]", num)
				addCustomLabel(templateArgs, "Spawn Life (s)", entry.expire, num)
			elseif entry.type == 'areadamage' then			
				local typeName = entry.grav and "Gravity Well" or "Ground Burn"
				if not grav then
					addCustomLabel(templateArgs, typeName .. " DPS", entry.dps, num)
				end
				addCustomLabel(templateArgs, typeName .. " radius (elmo)", entry.radius, num)
				addCustomLabel(templateArgs, typeName .. " duration (s)", entry.duration, num)

			elseif entry.type == 'stockpile' then
				addCustomLabel(templateArgs, "Stockpile time (s)", entry.time, num)
				if (entry.cost) then
					addCustomLabel(templateArgs, "Stockpile cost (M)", entry.cost, num)
				end
			end
		else
			if entry == 'hitscan' then
				addCustomLabel(templateArgs, nil, "Instantly hits", num)
			elseif entry == 'ignoreshield' then
				addCustomLabel(templateArgs, nil, "Ignores shields", num)
			elseif entry == 'smoothsground' then
				addCustomLabel(templateArgs, nil, "Smooths ground", num)
			elseif entry == 'hightraj' then
				addCustomLabel(templateArgs, nil, "High trajectory", num)
			elseif entry == 'trajtoggle' then
				addCustomLabel(templateArgs, nil, "Trajectory toggle", num)
			elseif entry == 'watercapable' then
				addCustomLabel(templateArgs, nil, "Water capable", num)
			elseif entry == 'friendlyfire' then
				addCustomLabel(templateArgs, nil, "Potential friendly fire", num)
			elseif entry == 'nofriendlyfire' then
				addCustomLabel(templateArgs, nil, "No friendly fire", num)
			elseif entry == 'nogroundcollide' then
				addCustomLabel(templateArgs, nil, "Passes through ground", num)
			elseif entry == 'piercing' then
				addCustomLabel(templateArgs, nil, "Damage increase vs large units", num)
			elseif entry == 'damagefalloff' then
				addCustomLabel(templateArgs, nil, "Damage falls off with range", num)
			elseif entry == 'inaccuratevsmoving' then
				addCustomLabel(templateArgs, nil, "Inaccuracy vs moving targets", num)
			elseif entry == 'interceptedbyantinuke' then
				addCustomLabel(templateArgs, nil, "Can be shot down by antinukes", num)
			end
		end
	end
end

function weapon.getInfoboxTemplate(frame)
	local args = frame.args
	local tbl = {title = "Infobox zkweapon", args = {}}
	local w = tbl.args
	local defName = args.defname or args[1] or "<no name specified>"
	local wd = weaponData[defName]
	if not (wd) then return 'weapondef ' .. defName .. ' not found' end
	
	addSpecialDataToTemplate(w, wd)
	
	for key, value in pairs(wd) do
		w[key] = args[key] or value
	end
	w.extraData = nil
	if (w.count and w.count > 1) then
		w.name = w.name .. " x " .. w.count	
	end
	if (w.projectiles and w.projectiles > 1) then
		local append = " x " ..  w.projectiles
		if w.damage then w.damage = w.damage .. append end
		if w.empdamage then w.empdamage = w.empdamage .. append end
		if w.slowdamage then w.slowdamage = w.slowdamage .. append end
		if w.disarmdamage then w.disarmdamage = w.disarmdamage .. append end
		if w.shielddamage then w.shielddamage = w.shielddamage .. append end
	end
	
	return tbl
end

function weapon.printInfobox(frame)
	return frame:expandTemplate(weapon.getInfoboxTemplate(frame))
end

return weapon