Module:WeaponData

From Zero-K
Revision as of 20:45, 11 May 2024 by Histidine (talk | contribs) (Undo revision 9322 by Histidine (talk))
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
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