Module:WeaponData

From Zero-K
Revision as of 01:32, 18 May 2024 by Histidine (talk | contribs) (Fix special data handling of multiple rows)
Jump to navigation Jump to search
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
	return index
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
				num = addCustomLabel(templateArgs, "Shield drain (HP/shot)", entry.drain, num)
			elseif entry.type == 'needs_link' then
				num = addCustomLabel(templateArgs, "Grid needed", entry.power, num)
			elseif entry.type == 'spawn' then
				num = addCustomLabel(templateArgs, "Spawns Unit", "[[" .. entry.name .. "]]", num)
				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
					num = addCustomLabel(templateArgs, typeName .. " DPS", entry.dps, num)
				end
				num = addCustomLabel(templateArgs, typeName .. " radius (elmo)", entry.radius, num)
				num = addCustomLabel(templateArgs, typeName .. " duration (s)", entry.duration, num)

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