Difference between revisions of "Module:WeaponData"

From Zero-K
Jump to navigation Jump to search
(Custom data handling)
Line 3: Line 3:
 
local weaponData = mw.loadData('Module:WeaponData/data')
 
local weaponData = mw.loadData('Module:WeaponData/data')
  
local function getMiscStatsTable(weaponDefName)
+
local function writeTemplateLine(key, value)
local wd = weaponData[weaponDefName]
+
if not key or not value then
if not wd then return nil end
+
return ""
if not wd.miscstats then return nil end
+
end
+
local str = "\n"
local tbl = {}
+
str = str .. "| " .. key .. " = " .. value
for index, tag in ipairs(wd.miscstats) do
+
return str
tbl[tag] = true
+
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, indents) .. writeTemplateLine("customdata"..count, value, indents)
 +
else
 +
append = writeTemplateLine("special"..count, value, indents)
 
end
 
end
return tbl
+
currentStr = currentStr .. append
 +
count = count + 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[1]
     if not (weaponData[weaponDefName]) then return 'weapondef ' .. weaponDefName .. ' not found' end
+
     local wd = weaponData[weaponDefName]
 +
    if not (wd) then return 'weapondef ' .. weaponDefName .. ' not found' end
 
     local property = frame.args[2]
 
     local property = frame.args[2]
     local result = weaponData[weaponDefName][property]
+
     local result = wd[property]
 
     if not result then result = '' end
 
     if not result then result = '' end
 
     return frame:preprocess(result) or ''
 
     return frame:preprocess(result) or ''
Line 32: Line 46:
 
end
 
end
  
function weapon.hasTag(frame)
+
function weapon.printCustomTraits(frame)
if not frame then return '' end
+
local weaponDefName = frame.args[1]
    local weaponDefName = frame.args[1]
+
     local wd = weaponData[weaponDefName]
     if not (weaponData[weaponDefName]) then return 'weapondef ' .. weaponDefName .. ' not found' end
+
    if not wd then return 'weapondef ' .. weaponDefName .. ' not found' end
     local tag = frame.args[2]
+
     if not wd.extraData then return '' end
 
 
local miscStats = getMiscStatsTable(weaponDefName)
+
local str = ''
if not miscStats then return false end
+
local count = 1
return miscStats[tag]
+
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
 +
 +
count = count + 1
 +
end
 
end
 
end
  
 
return weapon
 
return weapon

Revision as of 03:39, 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 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, indents) .. writeTemplateLine("customdata"..count, value, indents)
	else
		append = writeTemplateLine("special"..count, value, indents)
	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.printCustomTraits(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 '' 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
		
		count = count + 1
	end
end

return weapon