Module:WeaponData

From Zero-K
Revision as of 04:12, 11 May 2024 by Histidine (talk | contribs) (There has to be a better way to test this stuff)
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 writeTemplateLine(key, value)
	if not key or not value then
		return ""
	end
	local str = "\n"
	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 ''
	local append = ""
	if key then
		append = writeTemplateLine("customlabel"..count, key) .. writeTemplateLine("customdata"..count, value)
	else
		append = writeTemplateLine("special"..count, value)
	end
	currentStr = currentStr .. append
	count = count + 1
	return append, count, currentStr
end


function weapon.getData(frame)
	if not frame then return '' end
    local weaponDefName = frame.args[1]
    local wd = weaponData[weaponDefName]
    if not (wd) then return 'weapondef ' .. weaponDefName .. ' not found' end
    local property = frame.args[2]
    local result = wd[property]
    if not result then result = '' end
    return frame:preprocess(result) or ''
end

function weapon.printInfobox(frame)
	local weaponDefName = frame.args[1]
    if not (weaponData[weaponDefName]) then return 'weapondef ' .. weaponDefName .. ' not found' end
	return [[{{User:Histidine/Autoinfobox zkweapon
|defname=]]..weaponDefName..[[}}]]
end

function weapon.printInfoboxCustomRows(frame)
	local weaponDefName = frame.args[1]
    local wd = weaponData[weaponDefName]
    if not wd then return 'weapondef ' .. weaponDefName .. ' not found' end
    if not wd.extraData then return 'foobar' end
	
	local str = ''
	local count = 1
	for i=1, #wd.extraData do
		local entry = wd.extraData[i]
		local append = ''
		if type(entry) == 'table' then
			if entry.type == 'shielddrain' then
				append, count, str = writeCustomDataLine("Shield drain (HP/shot)", entry.drain, count, str)				
			elseif entry.type == 'needs_link' then
				append, count, str = writeCustomDataLine("Grid needed", entry.power, count, str)				
			elseif entry.type == 'spawn' then
				append, count, str = writeCustomDataLine("Spawns Unit", "[[" .. entry.name .. "]]", count, str)
				append, count, str = writeCustomDataLine("Spawn Life (s)", entry.expire, count, str)				
			elseif entry.type == 'areadamage' then			
				local typeName = entry.grav and "Gravity Well" or "Ground Burn"
				if not grav then
					append, count, str = writeCustomDataLine(typeName .. " DPS", entry.dps, count, str)
				end
				append, count, str = writeCustomDataLine(typeName .. " radius (elmo)", entry.radius, count, str)
				append, count, str = writeCustomDataLine(typeName .. " duration (s)", entry.duration, count, str)
				
			elseif entry.type == 'stockpile' then
				append, count, str = writeCustomDataLine("Stockpile time (s)", entry.time, count, str)
				if (entry.cost) then
					append, count, str = writeCustomDataLine("Stockpile cost (M)", entry.cost, count, str)
				end
			end
		else
			if entry == 'hitscan' then
				append, count, str = writeCustomDataLine(nil, "Instantly hits", count, str)
			elseif entry == 'ignoreshield' then
				append, count, str = writeCustomDataLine(nil, "Ignores shields", count, str)
			elseif entry == 'smoothsground' then
				append, count, str = writeCustomDataLine(nil, "Smooths ground", count, str)
			elseif entry == 'hightraj' then
				append, count, str = writeCustomDataLine(nil, "High trajectory", count, str)
			elseif entry == 'trajtoggle' then
				append, count, str = writeCustomDataLine(nil, "Trajectory toggle", count, str)
			elseif entry == 'watercapable' then
				append, count, str = writeCustomDataLine(nil, "Water capable", count, str)
			elseif entry == 'friendlyfire' then
				append, count, str = writeCustomDataLine(nil, "Potential friendly fire", count, str)
			elseif entry == 'nofriendlyfire' then
				append, count, str = writeCustomDataLine(nil, "No friendly fire", count, str)
			elseif entry == 'nogroundcollide' then
				append, count, str = writeCustomDataLine(nil, "Passes through ground", count, str)
			elseif entry == 'piercing' then
				append, count, str = writeCustomDataLine(nil, "Damage increase vs large units", count, str)
			elseif entry == 'damagefalloff' then
				append, count, str = writeCustomDataLine(nil, "Damage falls off with range", count, str)
			elseif entry == 'inaccuratevsmoving' then
				append, count, str = writeCustomDataLine(nil, "Inaccuracy vs moving targets", count, str)
			elseif entry == 'interceptedbyantinuke' then
				append, count, str = writeCustomDataLine(nil, "Can be shot down by antinukes", count, str)
			end
		end
	end
	return frame:preprocess(str) or ''
end

return weapon