Module:HeroDataArrays: Difference between revisionsGive feedback
Jump to navigation
Jump to search
Gammaton32 (talk | contribs) No edit summary |
Updated to not have issues when stats are missing. |
||
| Line 33: | Line 33: | ||
local node = heroData -- start with the biggest node heroData, and | local node = heroData -- start with the biggest node heroData, and | ||
for k in string.gmatch(key, "([^>]+)") do -- iterate over each key, splitting on ">", | for k in string.gmatch(key, "([^>]+)") do -- iterate over each key, splitting on ">", | ||
if node[k] ~= nil then | if node and node[k] ~= nil then -- trying the key as a string e.g. "1", (Added 'node and' for safety) | ||
node = node[k] | node = node[k] | ||
elseif node and node[tonumber(k)] ~= nil then -- else using the key as numeric, (Added 'node and' for safety) | |||
node = node[tonumber(k)] | node = node[tonumber(k)] | ||
else -- If at any point the path breaks, the result is nil | |||
node = nil | |||
break | |||
end -- drilling down the JSON node after node | end -- drilling down the JSON node after node | ||
end | end | ||
| Line 51: | Line 54: | ||
p.heroHealthTable = function(frame) | p.heroHealthTable = function(frame) | ||
-- Pull data | -- Pull data | ||
heroHealthData = heroDataArray({"Name", "MaxHealth", "LevelScaling>MaxHealth"}) | local heroHealthData = heroDataArray({"Name", "MaxHealth", "LevelScaling>MaxHealth"}) | ||
-- Input table will be called a, output wikitable will be called z | -- Input table will be called a, output wikitable will be called z | ||
local z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n".. | |||
"|+ Hero Base Health Stats \n".. | "|+ Hero Base Health Stats \n".. | ||
"! Hero !! Starting !! Added per Boon !! At Max Boon \n" | "! Hero !! Starting !! Added per Boon !! At Max Boon \n" | ||
| Line 61: | Line 63: | ||
-- Iterate over heroes adding a new row to the wikitable for each | -- Iterate over heroes adding a new row to the wikitable for each | ||
for i,a in pairs(heroHealthData) do | for i,a in pairs(heroHealthData) do | ||
local maxHealth = a["MaxHealth"] or 0 | |||
local scalingHealth = a["LevelScaling>MaxHealth"] or 0 | |||
z = z.. | z = z.. | ||
"|- \n".. | "|- \n".. | ||
"| style=\"text-align:left;\" | ".. | "| style=\"text-align:left;\" | ".. | ||
frame:expandTemplate{title="PageRef", args={a["Name"]}}.. | frame:expandTemplate{title="PageRef", args={a["Name"]}}.. | ||
" || ".. | " || "..maxHealth.." || +"..scalingHealth.." || ".. | ||
tostring(roundValue(tonumber( | tostring(roundValue(tonumber(maxHealth) + tonumber(scalingHealth) * soul_unlock.get_max('PowerIncrease'))).." \n" | ||
end | end | ||
z = z.."|}" | z = z.."|}" | ||
return z | return z | ||
end | end | ||
p.heroRegenTable = function(frame) | p.heroRegenTable = function(frame) | ||
heroRegenData = heroDataArray({"Name", "BaseHealthRegen"}) | local heroRegenData = heroDataArray({"Name", "BaseHealthRegen"}) | ||
z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n".. | local z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n".. | ||
"|+ Hero Base Health Regen \n".. | "|+ Hero Base Health Regen \n".. | ||
"! Hero !! HP/s \n" | "! Hero !! HP/s \n" | ||
for i,a in pairs(heroRegenData) do | for i,a in pairs(heroRegenData) do | ||
local baseHealthRegen = a["BaseHealthRegen"] or 0 | |||
z = z.. | z = z.. | ||
"|- \n".. | "|- \n".. | ||
"| style=\"text-align:left;\" | ".. | "| style=\"text-align:left;\" | ".. | ||
frame:expandTemplate{title="PageRef", args={a["Name"]}}.. | frame:expandTemplate{title="PageRef", args={a["Name"]}}.. | ||
" || ".. | " || "..baseHealthRegen.." \n" | ||
end | end | ||
z = z.."|}" | z = z.."|}" | ||
| Line 94: | Line 97: | ||
p.heroDpsTable = function(frame) | p.heroDpsTable = function(frame) | ||
heroDpsData = heroDataArray({"Name","ReloadSingle","ReloadDelay","ReloadTime", | local heroDpsData = heroDataArray({"Name","ReloadSingle","ReloadDelay","ReloadTime", | ||
"ClipSize","RoundsPerSecond","BulletDamage","BulletsPerShot"}) | "ClipSize","RoundsPerSecond","BulletDamage","BulletsPerShot"}) | ||
z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n".. | local z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n".. | ||
"|+ Hero Base Damage \n".. | "|+ Hero Base Damage \n".. | ||
"! Hero !! Reload Delay (s) !! Reload Time (s) !! Ammo !! Bullets per sec !! Bullet Damage !! Bullets Per Shot \n" | "! Hero !! Reload Delay (s) !! Reload Time (s) !! Ammo !! Bullets per sec !! Bullet Damage !! Bullets Per Shot \n" | ||
for i,a in pairs(heroDpsData) do | for i,a in pairs(heroDpsData) do | ||
local | local reloadDelay = a["ReloadDelay"] or 0 | ||
local | local reloadTime = a["ReloadTime"] or 0 | ||
local | local clipSize = a["ClipSize"] or 0 | ||
local | local roundsPerSecond = a["RoundsPerSecond"] or 0 | ||
local | local bulletDamage = a["BulletDamage"] or 0 | ||
local | local bulletsPerShot = a["BulletsPerShot"] or 0 | ||
z = z.. | z = z.. | ||
"|- \n".. | "|- \n".. | ||
"| style=\"text-align:left;\" | ".. | "| style=\"text-align:left;\" | ".. | ||
frame:expandTemplate{title="PageRef", args={a["Name"]}}.. | frame:expandTemplate{title="PageRef", args={a["Name"]}}.. | ||
" || ".. | " || "..reloadDelay.." || "..reloadTime.." || "..clipSize.. | ||
" || ".. | " || "..roundsPerSecond.." || "..bulletDamage.." || "..bulletsPerShot.." \n" | ||
end | end | ||
z = z.."|}" | z = z.."|}" | ||
| Line 120: | Line 123: | ||
p.heroBulletSpeedTable = function(frame) | p.heroBulletSpeedTable = function(frame) | ||
heroBulletSpeedData = heroDataArray({"Name", "BulletSpeed"}) | local heroBulletSpeedData = heroDataArray({"Name", "BulletSpeed"}) | ||
z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n".. | local z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n".. | ||
"|+ Base Bullet Velocity \n".. | "|+ Base Bullet Velocity \n".. | ||
"! Hero !! m/s \n" | "! Hero !! m/s \n" | ||
for i,a in pairs(heroBulletSpeedData) do | for i,a in pairs(heroBulletSpeedData) do | ||
local | local bulletSpeed = a["BulletSpeed"] or 0 | ||
z = z.. | z = z.. | ||
"|- \n".. | "|- \n".. | ||
"| style=\"text-align:left;\" | ".. | "| style=\"text-align:left;\" | ".. | ||
frame:expandTemplate{title="PageRef", args={a["Name"]}}.. | frame:expandTemplate{title="PageRef", args={a["Name"]}}.. | ||
" || ".. | " || "..bulletSpeed.." \n" | ||
end | end | ||
z = z.."|}" | z = z.."|}" | ||
| Line 139: | Line 142: | ||
p.heroClipSizeTable = function(frame) | p.heroClipSizeTable = function(frame) | ||
heroClipSizeData = heroDataArray({"Name", "ClipSize"}) | local heroClipSizeData = heroDataArray({"Name", "ClipSize"}) | ||
z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n".. | local z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n".. | ||
"|+ Base Ammo Count \n".. | "|+ Base Ammo Count \n".. | ||
"! Hero !! Ammo \n" | "! Hero !! Ammo \n" | ||
for i,a in pairs(heroClipSizeData) do | for i,a in pairs(heroClipSizeData) do | ||
local | local clipSize = a["ClipSize"] or 0 | ||
z = z.. | z = z.. | ||
"|- \n".. | "|- \n".. | ||
"| style=\"text-align:left;\" | ".. | "| style=\"text-align:left;\" | ".. | ||
frame:expandTemplate{title="PageRef", args={a["Name"]}}.. | frame:expandTemplate{title="PageRef", args={a["Name"]}}.. | ||
" || ".. | " || "..clipSize.." \n" | ||
end | end | ||
z = z.."|}" | z = z.."|}" | ||
| Line 158: | Line 161: | ||
p.heroMoveSpeedTable = function(frame) | p.heroMoveSpeedTable = function(frame) | ||
heroMoveSpeedData = heroDataArray({"Name", "MoveSpeed"}) | local heroMoveSpeedData = heroDataArray({"Name", "MoveSpeed"}) | ||
z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n".. | local z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n".. | ||
"|+ Base Movement Speed \n".. | "|+ Base Movement Speed \n".. | ||
"! Hero !! m/s \n" | "! Hero !! m/s \n" | ||
for i,a in pairs(heroMoveSpeedData) do | for i,a in pairs(heroMoveSpeedData) do | ||
local moveSpeed = a["MoveSpeed"] or 0 | |||
z = z.. | z = z.. | ||
"|- \n".. | "|- \n".. | ||
"| style=\"text-align:left;\" | ".. | "| style=\"text-align:left;\" | ".. | ||
frame:expandTemplate{title="PageRef", args={a["Name"]}}.. | frame:expandTemplate{title="PageRef", args={a["Name"]}}.. | ||
" || ".. | " || "..moveSpeed.." \n" | ||
end | end | ||
z = z.."|}" | z = z.."|}" | ||
| Line 176: | Line 180: | ||
p.heroRoundsPerSecondTable = function(frame) | p.heroRoundsPerSecondTable = function(frame) | ||
heroRoundsPerSecondData = heroDataArray({"Name", "RoundsPerSecond"}) | local heroRoundsPerSecondData = heroDataArray({"Name", "RoundsPerSecond"}) | ||
z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n".. | local z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n".. | ||
"|+ Base Fire Rate \n".. | "|+ Base Fire Rate \n".. | ||
"! Hero !! Rounds/s \n" | "! Hero !! Rounds/s \n" | ||
for i,a in pairs(heroRoundsPerSecondData) do | for i,a in pairs(heroRoundsPerSecondData) do | ||
local | local roundsPerSecond = a["RoundsPerSecond"] or 0 | ||
z = z.. | z = z.. | ||
"|- \n".. | "|- \n".. | ||
"| style=\"text-align:left;\" | ".. | "| style=\"text-align:left;\" | ".. | ||
frame:expandTemplate{title="PageRef", args={a["Name"]}}.. | frame:expandTemplate{title="PageRef", args={a["Name"]}}.. | ||
" || ".. | " || "..roundsPerSecond.." \n" | ||
end | end | ||
z = z.."|}" | z = z.."|}" | ||
| Line 195: | Line 199: | ||
p.heroFalloffRangeTable = function(frame) | p.heroFalloffRangeTable = function(frame) | ||
heroFalloffRangeData = heroDataArray({"Name", "FalloffStartRange", "FalloffEndRange"}) | local heroFalloffRangeData = heroDataArray({"Name", "FalloffStartRange", "FalloffEndRange"}) | ||
z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n".. | local z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n".. | ||
"|+ Base Falloff Range \n".. | "|+ Base Falloff Range \n".. | ||
"! Hero !! Minimum Range (m) !! Maximum Range (m) \n" | "! Hero !! Minimum Range (m) !! Maximum Range (m) \n" | ||
for i,a in pairs(heroFalloffRangeData) do | for i,a in pairs(heroFalloffRangeData) do | ||
local | local falloffStartRange = a["FalloffStartRange"] or 0 | ||
local | local falloffEndRange = a["FalloffEndRange"] or 0 | ||
z = z.. | z = z.. | ||
"|- \n".. | "|- \n".. | ||
"| style=\"text-align:left;\" | ".. | "| style=\"text-align:left;\" | ".. | ||
frame:expandTemplate{title="PageRef", args={a["Name"]}}.. | frame:expandTemplate{title="PageRef", args={a["Name"]}}.. | ||
" || ".. | " || "..falloffStartRange.." || "..falloffEndRange.." \n" | ||
end | end | ||
z = z.."|}" | z = z.."|}" | ||
| Line 216: | Line 220: | ||
p.heroBulletDamageTable = function(frame) | p.heroBulletDamageTable = function(frame) | ||
-- Pull data | -- Pull data | ||
heroBulletDamageData = heroDataArray({"Name", "BulletDamage", "LevelScaling>BulletDamage"}) | local heroBulletDamageData = heroDataArray({"Name", "BulletDamage", "LevelScaling>BulletDamage"}) | ||
local z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n".. | |||
"|+ Hero Base Bullet Damage Stats \n".. | "|+ Hero Base Bullet Damage Stats \n".. | ||
"! Hero !! Starting !! Added per Boon !! At Max Boon \n" | "! Hero !! Starting !! Added per Boon !! At Max Boon \n" | ||
| Line 226: | Line 228: | ||
-- Iterate over heroes adding a new row to the wikitable for each | -- Iterate over heroes adding a new row to the wikitable for each | ||
for i,a in pairs(heroBulletDamageData) do | for i,a in pairs(heroBulletDamageData) do | ||
local BulletDamage = a["BulletDamage"] or 0 | -- FIX: Set default values of 0 if the data is nil to prevent arithmetic errors | ||
local bulletDamage = a["BulletDamage"] or 0 | |||
local scalingDamage = a["LevelScaling>BulletDamage"] or 0 | |||
z = z.. | z = z.. | ||
"|- \n".. | "|- \n".. | ||
"| style=\"text-align:left;\" | ".. | "| style=\"text-align:left;\" | ".. | ||
frame:expandTemplate{title="PageRef", args={a["Name"]}}.. | frame:expandTemplate{title="PageRef", args={a["Name"]}}.. | ||
" || ".. | -- Use the safe variables here | ||
tostring(roundValue(tonumber( | " || "..bulletDamage.." || +"..scalingDamage.." || ".. | ||
-- And use them in the calculation | |||
tostring(roundValue(tonumber(bulletDamage) + tonumber(scalingDamage) * soul_unlock.get_max('PowerIncrease'))).." \n" | |||
end | end | ||
z = z.."|}" | z = z.."|}" | ||
return z | return z | ||
end | end | ||
| Line 243: | Line 247: | ||
p.heroLightMeleeTable = function(frame) | p.heroLightMeleeTable = function(frame) | ||
-- Pull data | -- Pull data | ||
heroLightMeleeData = heroDataArray({"Name", "LightMeleeDamage", "LevelScaling>LightMeleeDamage"}) | local heroLightMeleeData = heroDataArray({"Name", "LightMeleeDamage", "LevelScaling>LightMeleeDamage"}) | ||
local z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n".. | |||
"|+ Hero Base Light Melee Stats \n".. | "|+ Hero Base Light Melee Stats \n".. | ||
"! Hero !! Starting !! Added per Boon !! At Max Boon \n" | "! Hero !! Starting !! Added per Boon !! At Max Boon \n" | ||
| Line 253: | Line 255: | ||
-- Iterate over heroes adding a new row to the wikitable for each | -- Iterate over heroes adding a new row to the wikitable for each | ||
for i,a in pairs(heroLightMeleeData) do | for i,a in pairs(heroLightMeleeData) do | ||
local lightMeleeDamage = a["LightMeleeDamage"] or 0 | |||
local scalingDamage = a["LevelScaling>LightMeleeDamage"] or 0 | |||
z = z.. | z = z.. | ||
"|- \n".. | "|- \n".. | ||
"| style=\"text-align:left;\" | ".. | "| style=\"text-align:left;\" | ".. | ||
frame:expandTemplate{title="PageRef", args={a["Name"]}}.. | frame:expandTemplate{title="PageRef", args={a["Name"]}}.. | ||
" || ".. | " || "..lightMeleeDamage.." || +"..scalingDamage.." || ".. | ||
tostring(roundValue(tonumber( | tostring(roundValue(tonumber(lightMeleeDamage) + tonumber(scalingDamage) * soul_unlock.get_max('PowerIncrease'))).." \n" | ||
end | end | ||
z = z.."|}" | z = z.."|}" | ||
return z | return z | ||
end | end | ||
| Line 269: | Line 271: | ||
p.heroHeavyMeleeTable = function(frame) | p.heroHeavyMeleeTable = function(frame) | ||
-- Pull data | -- Pull data | ||
heroHeavyMeleeData = heroDataArray({"Name", "HeavyMeleeDamage", "LevelScaling>HeavyMeleeDamage"}) | local heroHeavyMeleeData = heroDataArray({"Name", "HeavyMeleeDamage", "LevelScaling>HeavyMeleeDamage"}) | ||
local z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n".. | |||
"|+ Hero Base Heavy Melee Stats \n".. | "|+ Hero Base Heavy Melee Stats \n".. | ||
"! Hero !! Starting !! Added per Boon !! At Max Boon \n" | "! Hero !! Starting !! Added per Boon !! At Max Boon \n" | ||
| Line 279: | Line 279: | ||
-- Iterate over heroes adding a new row to the wikitable for each | -- Iterate over heroes adding a new row to the wikitable for each | ||
for i,a in pairs(heroHeavyMeleeData) do | for i,a in pairs(heroHeavyMeleeData) do | ||
local heavyMeleeDamage = a["HeavyMeleeDamage"] or 0 | |||
local scalingDamage = a["LevelScaling>HeavyMeleeDamage"] or 0 | |||
z = z.. | z = z.. | ||
"|- \n".. | "|- \n".. | ||
"| style=\"text-align:left;\" | ".. | "| style=\"text-align:left;\" | ".. | ||
frame:expandTemplate{title="PageRef", args={a["Name"]}}.. | frame:expandTemplate{title="PageRef", args={a["Name"]}}.. | ||
" || ".. | " || "..heavyMeleeDamage.." || +"..scalingDamage.." || ".. | ||
tostring(roundValue(tonumber( | tostring(roundValue(tonumber(heavyMeleeDamage) + tonumber(scalingDamage) * soul_unlock.get_max('PowerIncrease'))).." \n" | ||
end | end | ||
z = z.."|}" | z = z.."|}" | ||
return z | return z | ||
end | end | ||
p.heroStaminaTable = function(frame) | p.heroStaminaTable = function(frame) | ||
heroStaminaData = heroDataArray({"Name", "Stamina"}) | local heroStaminaData = heroDataArray({"Name", "Stamina"}) | ||
z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n".. | local z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n".. | ||
"|+ Hero Base Stamina Stats \n".. | "|+ Hero Base Stamina Stats \n".. | ||
"! Hero !! Stamina Bars \n" | "! Hero !! Stamina Bars \n" | ||
for i,a in pairs(heroStaminaData) do | for i,a in pairs(heroStaminaData) do | ||
local stamina = a["Stamina"] or 0 | |||
z = z.. | z = z.. | ||
"|- \n".. | "|- \n".. | ||
"| style=\"text-align:left;\" | ".. | "| style=\"text-align:left;\" | ".. | ||
frame:expandTemplate{title="PageRef", args={a["Name"]}}.. | frame:expandTemplate{title="PageRef", args={a["Name"]}}.. | ||
" || ".. | " || "..stamina.." \n" | ||
end | end | ||
z = z.."|}" | z = z.."|}" | ||
| Line 312: | Line 313: | ||
p.heroDashTable = function(frame) | p.heroDashTable = function(frame) | ||
heroDashData = heroDataArray({"Name", "GroundDashDuration"}) | local heroDashData = heroDataArray({"Name", "GroundDashDuration"}) | ||
z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n".. | local z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n".. | ||
"|+ Hero Base Dash Speed Stats \n".. | "|+ Hero Base Dash Speed Stats \n".. | ||
"! Hero !! Dash Speed \n" | "! Hero !! Dash Speed \n" | ||
for i,a in pairs(heroDashData) do | for i,a in pairs(heroDashData) do | ||
local | local groundDashDuration = a["GroundDashDuration"] or 0 | ||
z = z.. | z = z.. | ||
"|- \n".. | "|- \n".. | ||
"| style=\"text-align:left;\" | ".. | "| style=\"text-align:left;\" | ".. | ||
frame:expandTemplate{title="PageRef", args={a["Name"]}}.. | frame:expandTemplate{title="PageRef", args={a["Name"]}}.. | ||
" || ".. | " || "..groundDashDuration.."s \n" | ||
end | end | ||
z = z.."|}" | z = z.."|}" | ||
| Line 331: | Line 332: | ||
p.heroReloadTable = function(frame) | p.heroReloadTable = function(frame) | ||
heroReloadData = heroDataArray({"Name", "ReloadTime"}) | local heroReloadData = heroDataArray({"Name", "ReloadTime"}) | ||
z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n".. | local z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n".. | ||
"|+ Hero Base Reload Time Stats \n".. | "|+ Hero Base Reload Time Stats \n".. | ||
"! Hero !! Reload Time \n" | "! Hero !! Reload Time \n" | ||
for i,a in pairs(heroReloadData) do | for i,a in pairs(heroReloadData) do | ||
local | local reloadTime = a["ReloadTime"] or 0 | ||
z = z.. | z = z.. | ||
"|- \n".. | "|- \n".. | ||
"| style=\"text-align:left;\" | ".. | "| style=\"text-align:left;\" | ".. | ||
frame:expandTemplate{title="PageRef", args={a["Name"]}}.. | frame:expandTemplate{title="PageRef", args={a["Name"]}}.. | ||
" || ".. | " || "..reloadTime.."s \n" | ||
end | end | ||
z = z.."|}" | z = z.."|}" | ||
Revision as of 16:09, 26 August 2025
Overview
This module consists of one generic function, heroDataArray, and a series of functions that create specific wikitables using the output from heroDataArray.
local p = {};
local util_module = require('Module:Utilities')
local allHeroData = mw.loadJsonData("Data:HeroData.json")
local soul_unlock = require('Module:SoulUnlock')
local inGameHeroData = {}
-- Just get heroes that are playable
for i, heroData in pairs(allHeroData) do
if heroData["IsDisabled"] == false then
table.insert(inGameHeroData, heroData)
end
end
-- Helper function to round numeric values
local function roundValue(value)
if type(value) == "number" then
return util_module.round_to_sig_fig(value, 3)
end
return value
end
-- heroDataArray takes as argument a table of any length containing keys or
-- paths of keys in the HeroData JSON, e.g. {Name, MaxHealth, LevelScaling>Health}.
-- A path of keys should be specified as such, with the ">" character separating
-- subsequent keys.
local heroDataArray = function(args)
local outData = {}
for i, heroData in ipairs(inGameHeroData) do -- Iterate over each hero
local out = {} -- First creating a table to hold data
for j, key in pairs(args) do -- Iterate over each key:
if string.find(key, ">") ~= nil then -- If the key is actually a path of keys,
local node = heroData -- start with the biggest node heroData, and
for k in string.gmatch(key, "([^>]+)") do -- iterate over each key, splitting on ">",
if node and node[k] ~= nil then -- trying the key as a string e.g. "1", (Added 'node and' for safety)
node = node[k]
elseif node and node[tonumber(k)] ~= nil then -- else using the key as numeric, (Added 'node and' for safety)
node = node[tonumber(k)]
else -- If at any point the path breaks, the result is nil
node = nil
break
end -- drilling down the JSON node after node
end
out[key] = roundValue(node) -- until outputting the final node (rounded)
else
out[key] = roundValue(heroData[key]) -- or just grab the data if not a path (rounded)
end
end
outData[heroData["Name"]] = out -- Save data in the big table of heroes
end
return(outData)
end
p.heroHealthTable = function(frame)
-- Pull data
local heroHealthData = heroDataArray({"Name", "MaxHealth", "LevelScaling>MaxHealth"})
-- Input table will be called a, output wikitable will be called z
local z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n"..
"|+ Hero Base Health Stats \n"..
"! Hero !! Starting !! Added per Boon !! At Max Boon \n"
-- Iterate over heroes adding a new row to the wikitable for each
for i,a in pairs(heroHealthData) do
local maxHealth = a["MaxHealth"] or 0
local scalingHealth = a["LevelScaling>MaxHealth"] or 0
z = z..
"|- \n"..
"| style=\"text-align:left;\" | "..
frame:expandTemplate{title="PageRef", args={a["Name"]}}..
" || "..maxHealth.." || +"..scalingHealth.." || "..
tostring(roundValue(tonumber(maxHealth) + tonumber(scalingHealth) * soul_unlock.get_max('PowerIncrease'))).." \n"
end
z = z.."|}"
return z
end
p.heroRegenTable = function(frame)
local heroRegenData = heroDataArray({"Name", "BaseHealthRegen"})
local z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n"..
"|+ Hero Base Health Regen \n"..
"! Hero !! HP/s \n"
for i,a in pairs(heroRegenData) do
local baseHealthRegen = a["BaseHealthRegen"] or 0
z = z..
"|- \n"..
"| style=\"text-align:left;\" | "..
frame:expandTemplate{title="PageRef", args={a["Name"]}}..
" || "..baseHealthRegen.." \n"
end
z = z.."|}"
return z
end
p.heroDpsTable = function(frame)
local heroDpsData = heroDataArray({"Name","ReloadSingle","ReloadDelay","ReloadTime",
"ClipSize","RoundsPerSecond","BulletDamage","BulletsPerShot"})
local z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n"..
"|+ Hero Base Damage \n"..
"! Hero !! Reload Delay (s) !! Reload Time (s) !! Ammo !! Bullets per sec !! Bullet Damage !! Bullets Per Shot \n"
for i,a in pairs(heroDpsData) do
local reloadDelay = a["ReloadDelay"] or 0
local reloadTime = a["ReloadTime"] or 0
local clipSize = a["ClipSize"] or 0
local roundsPerSecond = a["RoundsPerSecond"] or 0
local bulletDamage = a["BulletDamage"] or 0
local bulletsPerShot = a["BulletsPerShot"] or 0
z = z..
"|- \n"..
"| style=\"text-align:left;\" | "..
frame:expandTemplate{title="PageRef", args={a["Name"]}}..
" || "..reloadDelay.." || "..reloadTime.." || "..clipSize..
" || "..roundsPerSecond.." || "..bulletDamage.." || "..bulletsPerShot.." \n"
end
z = z.."|}"
return z
end
p.heroBulletSpeedTable = function(frame)
local heroBulletSpeedData = heroDataArray({"Name", "BulletSpeed"})
local z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n"..
"|+ Base Bullet Velocity \n"..
"! Hero !! m/s \n"
for i,a in pairs(heroBulletSpeedData) do
local bulletSpeed = a["BulletSpeed"] or 0
z = z..
"|- \n"..
"| style=\"text-align:left;\" | "..
frame:expandTemplate{title="PageRef", args={a["Name"]}}..
" || "..bulletSpeed.." \n"
end
z = z.."|}"
return z
end
p.heroClipSizeTable = function(frame)
local heroClipSizeData = heroDataArray({"Name", "ClipSize"})
local z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n"..
"|+ Base Ammo Count \n"..
"! Hero !! Ammo \n"
for i,a in pairs(heroClipSizeData) do
local clipSize = a["ClipSize"] or 0
z = z..
"|- \n"..
"| style=\"text-align:left;\" | "..
frame:expandTemplate{title="PageRef", args={a["Name"]}}..
" || "..clipSize.." \n"
end
z = z.."|}"
return z
end
p.heroMoveSpeedTable = function(frame)
local heroMoveSpeedData = heroDataArray({"Name", "MoveSpeed"})
local z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n"..
"|+ Base Movement Speed \n"..
"! Hero !! m/s \n"
for i,a in pairs(heroMoveSpeedData) do
local moveSpeed = a["MoveSpeed"] or 0
z = z..
"|- \n"..
"| style=\"text-align:left;\" | "..
frame:expandTemplate{title="PageRef", args={a["Name"]}}..
" || "..moveSpeed.." \n"
end
z = z.."|}"
return z
end
p.heroRoundsPerSecondTable = function(frame)
local heroRoundsPerSecondData = heroDataArray({"Name", "RoundsPerSecond"})
local z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n"..
"|+ Base Fire Rate \n"..
"! Hero !! Rounds/s \n"
for i,a in pairs(heroRoundsPerSecondData) do
local roundsPerSecond = a["RoundsPerSecond"] or 0
z = z..
"|- \n"..
"| style=\"text-align:left;\" | "..
frame:expandTemplate{title="PageRef", args={a["Name"]}}..
" || "..roundsPerSecond.." \n"
end
z = z.."|}"
return z
end
p.heroFalloffRangeTable = function(frame)
local heroFalloffRangeData = heroDataArray({"Name", "FalloffStartRange", "FalloffEndRange"})
local z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n"..
"|+ Base Falloff Range \n"..
"! Hero !! Minimum Range (m) !! Maximum Range (m) \n"
for i,a in pairs(heroFalloffRangeData) do
local falloffStartRange = a["FalloffStartRange"] or 0
local falloffEndRange = a["FalloffEndRange"] or 0
z = z..
"|- \n"..
"| style=\"text-align:left;\" | "..
frame:expandTemplate{title="PageRef", args={a["Name"]}}..
" || "..falloffStartRange.." || "..falloffEndRange.." \n"
end
z = z.."|}"
return z
end
p.heroBulletDamageTable = function(frame)
-- Pull data
local heroBulletDamageData = heroDataArray({"Name", "BulletDamage", "LevelScaling>BulletDamage"})
local z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n"..
"|+ Hero Base Bullet Damage Stats \n"..
"! Hero !! Starting !! Added per Boon !! At Max Boon \n"
-- Iterate over heroes adding a new row to the wikitable for each
for i,a in pairs(heroBulletDamageData) do
-- FIX: Set default values of 0 if the data is nil to prevent arithmetic errors
local bulletDamage = a["BulletDamage"] or 0
local scalingDamage = a["LevelScaling>BulletDamage"] or 0
z = z..
"|- \n"..
"| style=\"text-align:left;\" | "..
frame:expandTemplate{title="PageRef", args={a["Name"]}}..
-- Use the safe variables here
" || "..bulletDamage.." || +"..scalingDamage.." || "..
-- And use them in the calculation
tostring(roundValue(tonumber(bulletDamage) + tonumber(scalingDamage) * soul_unlock.get_max('PowerIncrease'))).." \n"
end
z = z.."|}"
return z
end
p.heroLightMeleeTable = function(frame)
-- Pull data
local heroLightMeleeData = heroDataArray({"Name", "LightMeleeDamage", "LevelScaling>LightMeleeDamage"})
local z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n"..
"|+ Hero Base Light Melee Stats \n"..
"! Hero !! Starting !! Added per Boon !! At Max Boon \n"
-- Iterate over heroes adding a new row to the wikitable for each
for i,a in pairs(heroLightMeleeData) do
local lightMeleeDamage = a["LightMeleeDamage"] or 0
local scalingDamage = a["LevelScaling>LightMeleeDamage"] or 0
z = z..
"|- \n"..
"| style=\"text-align:left;\" | "..
frame:expandTemplate{title="PageRef", args={a["Name"]}}..
" || "..lightMeleeDamage.." || +"..scalingDamage.." || "..
tostring(roundValue(tonumber(lightMeleeDamage) + tonumber(scalingDamage) * soul_unlock.get_max('PowerIncrease'))).." \n"
end
z = z.."|}"
return z
end
p.heroHeavyMeleeTable = function(frame)
-- Pull data
local heroHeavyMeleeData = heroDataArray({"Name", "HeavyMeleeDamage", "LevelScaling>HeavyMeleeDamage"})
local z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n"..
"|+ Hero Base Heavy Melee Stats \n"..
"! Hero !! Starting !! Added per Boon !! At Max Boon \n"
-- Iterate over heroes adding a new row to the wikitable for each
for i,a in pairs(heroHeavyMeleeData) do
local heavyMeleeDamage = a["HeavyMeleeDamage"] or 0
local scalingDamage = a["LevelScaling>HeavyMeleeDamage"] or 0
z = z..
"|- \n"..
"| style=\"text-align:left;\" | "..
frame:expandTemplate{title="PageRef", args={a["Name"]}}..
" || "..heavyMeleeDamage.." || +"..scalingDamage.." || "..
tostring(roundValue(tonumber(heavyMeleeDamage) + tonumber(scalingDamage) * soul_unlock.get_max('PowerIncrease'))).." \n"
end
z = z.."|}"
return z
end
p.heroStaminaTable = function(frame)
local heroStaminaData = heroDataArray({"Name", "Stamina"})
local z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n"..
"|+ Hero Base Stamina Stats \n"..
"! Hero !! Stamina Bars \n"
for i,a in pairs(heroStaminaData) do
local stamina = a["Stamina"] or 0
z = z..
"|- \n"..
"| style=\"text-align:left;\" | "..
frame:expandTemplate{title="PageRef", args={a["Name"]}}..
" || "..stamina.." \n"
end
z = z.."|}"
return z
end
p.heroDashTable = function(frame)
local heroDashData = heroDataArray({"Name", "GroundDashDuration"})
local z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n"..
"|+ Hero Base Dash Speed Stats \n"..
"! Hero !! Dash Speed \n"
for i,a in pairs(heroDashData) do
local groundDashDuration = a["GroundDashDuration"] or 0
z = z..
"|- \n"..
"| style=\"text-align:left;\" | "..
frame:expandTemplate{title="PageRef", args={a["Name"]}}..
" || "..groundDashDuration.."s \n"
end
z = z.."|}"
return z
end
p.heroReloadTable = function(frame)
local heroReloadData = heroDataArray({"Name", "ReloadTime"})
local z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n"..
"|+ Hero Base Reload Time Stats \n"..
"! Hero !! Reload Time \n"
for i,a in pairs(heroReloadData) do
local reloadTime = a["ReloadTime"] or 0
z = z..
"|- \n"..
"| style=\"text-align:left;\" | "..
frame:expandTemplate{title="PageRef", args={a["Name"]}}..
" || "..reloadTime.."s \n"
end
z = z.."|}"
return z
end
return p