| Latest revision |
Your text |
| Line 5: |
Line 5: |
| local inGameHeroData = {} | | local inGameHeroData = {} |
|
| |
|
| -- Just get heroes that are playable and have a "name" in HeroData | | -- Just get heroes that are playable |
| for i, heroData in pairs(allHeroData) do | | for i, heroData in pairs(allHeroData) do |
| if heroData["InDevelopment"] == false then | | if heroData["InDevelopment"] == false then |
| if heroData["IsDisabled"] == false then | | if heroData["IsDisabled"] == false then |
| if heroData["Name"] ~= nil then
| |
| table.insert(inGameHeroData, heroData) | | table.insert(inGameHeroData, heroData) |
| end | | end |
| end
| |
| end
| |
| end
| |
|
| |
| -- Use sort name for edge cases like "The Doorman"
| |
| local function sortHeroes(rows)
| |
| local function getSortName(name)
| |
| return (name:gsub("^The ", ""))
| |
| end | | end |
|
| |
| table.sort(rows, function(a, b)
| |
| local nameA = getSortName(a.sortName or a.name or "")
| |
| local nameB = getSortName(b.sortName or b.name or "")
| |
| return nameA:lower() < nameB:lower()
| |
| end)
| |
| end | | end |
|
| |
|
| Line 35: |
Line 20: |
| end | | end |
| return value | | return value |
| end
| |
|
| |
| -- Round to 4 digits
| |
| local function roundValueFour(value)
| |
| if type(value) == "number" then
| |
| return util_module.round_to_sig_fig(value, 4)
| |
| end
| |
| return value
| |
| end
| |
|
| |
| -- Round to an integer (up to 2 digits)
| |
| local function roundValueInteger(value)
| |
| if type(value) == "number" then
| |
| return util_module.round_to_sig_fig(value, 2)
| |
| end
| |
| return value
| |
| end
| |
|
| |
| -- Generate tables from given properties
| |
| local function buildTable(frame, rows, tableDef, options)
| |
| options = options or {}
| |
| -- option to ignore heroes who don't have any of the given properties. true by default
| |
| local filterZero = options.filterZero or true
| |
|
| |
| local filteredRows = {}
| |
|
| |
| for _, r in ipairs(rows) do
| |
| local hasValue = not filterZero
| |
|
| |
| if filterZero then
| |
| for _, col in ipairs(tableDef.columns) do
| |
| if r[col.field] ~= 0 and r[col.field] ~= nil then
| |
| if r[col.field] ~= "+0" then
| |
| hasValue = true
| |
| break
| |
| end
| |
| end
| |
| end
| |
| end
| |
|
| |
| if hasValue then
| |
| table.insert(filteredRows, r)
| |
| end
| |
| end
| |
|
| |
| if #filteredRows == 0 then
| |
| return ""
| |
| end
| |
|
| |
| -- Build header
| |
| local header = ""
| |
| for _, col in ipairs(tableDef.columns) do
| |
| header = header .. " !! " .. col.label
| |
| end
| |
|
| |
| -- Start table
| |
| local t = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n" ..
| |
| "|+ " .. tableDef.title .. " \n" ..
| |
| "! Hero" .. header .. " \n"
| |
|
| |
| -- Rows
| |
| for _, r in ipairs(filteredRows) do
| |
| local cells = ""
| |
| for _, col in ipairs(tableDef.columns) do
| |
| cells = cells .. " || " .. (r[col.field] or 0)
| |
| end
| |
|
| |
| -- A row may carry an alternate sort key and a label suffix, used by
| |
| -- secondary fire rows so they stay underneath their hero's main row
| |
| local nameCell = "| style=\"text-align:left;\""
| |
| if r.sortName then
| |
| nameCell = nameCell .. " data-sort-value=\"" .. r.sortName .. "\""
| |
| end
| |
| nameCell = nameCell .. " | " ..
| |
| frame:expandTemplate{ title = "PageRef", args = { r.name } } ..
| |
| (r.nameSuffix or "")
| |
|
| |
| t = t ..
| |
| "|- \n" ..
| |
| nameCell ..
| |
| cells .. " \n"
| |
| end
| |
|
| |
| t = t .. "|}"
| |
|
| |
| return t
| |
| end | | end |
|
| |
|
| Line 159: |
Line 58: |
| local heroHealthData = heroDataArray({"Name", "MaxHealth", "LevelScaling>MaxHealth"}) | | local heroHealthData = heroDataArray({"Name", "MaxHealth", "LevelScaling>MaxHealth"}) |
|
| |
|
| local rows = {} | | -- Input table will be called a, output wikitable will be called z |
| for name, data in pairs(heroHealthData) do | | local z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n".. |
| table.insert(rows, { | | "|+ Hero Base Health Stats \n".. |
| name = name,
| | "! Hero !! Starting !! Added per Boon !! At Max Boon \n" |
| maxHealth = data["MaxHealth"] or 0,
| | |
| scalingHealth = "+" .. data["LevelScaling>MaxHealth"] or 0,
| | -- Iterate over heroes adding a new row to the wikitable for each |
| maxScalingHealth = (data["MaxHealth"] + data["LevelScaling>MaxHealth"] * soul_unlock.get_max("PowerIncrease")) or 0 | | 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 | | end |
| sortHeroes(rows)
| |
|
| |
| local tableDefs = {
| |
| {
| |
| title = "Base Health Stats",
| |
| columns = {
| |
| { label = "Starting", field = "maxHealth" },
| |
| { label = "Added per Boon", field = "scalingHealth" },
| |
| { label = "At Max Boon", field = "maxScalingHealth" },
| |
| }
| |
| }
| |
| }
| |
| | | |
| local output = {}
| | z = z.."|}" |
| for _, def in ipairs(tableDefs) do | | return z |
| local t = buildTable(frame, rows, def, def.options)
| |
| if t ~= "" then
| |
| table.insert(output, t)
| |
| end
| |
| end
| |
| | |
| return table.concat(output, "\n\n") | |
| end | | end |
|
| |
|
| p.heroRegenTable = function(frame) | | p.heroRegenTable = function(frame) |
| local heroRegenData = heroDataArray({"Name", "BaseHealthRegen", "SpiritScaling>BaseHealthRegen"}) | | local heroRegenData = heroDataArray({"Name", "BaseHealthRegen"}) |
| | | |
| local rows = {} | | local z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n".. |
| for name, data in pairs(heroRegenData) do
| | "|+ Hero Base Health Regen \n".. |
| table.insert(rows, {
| | "! Hero !! HP/s \n" |
| name = name,
| |
| baseHealthRegen = data["BaseHealthRegen"] or 0,
| |
| spiritHealthRegen = "+".. (data["SpiritScaling>BaseHealthRegen"] or 0),
| |
| })
| |
| end
| |
| sortHeroes(rows)
| |
| | |
| local tableDefs = {
| |
| { | |
| title = "Base Health Regen Stats",
| |
| columns = {
| |
| { label = "HP/s", field = "baseHealthRegen" },
| |
| { label = "Spirit Scaling", field = "spiritHealthRegen" }
| |
| }
| |
| }
| |
| }
| |
|
| |
|
| local output = {}
| | for i,a in pairs(heroRegenData) do |
| for _, def in ipairs(tableDefs) do | | local baseHealthRegen = a["BaseHealthRegen"] or 0 |
| local t = buildTable(frame, rows, def, def.options) | | z = z.. |
| if t ~= "" then | | "|- \n".. |
| table.insert(output, t) | | "| style=\"text-align:left;\" | ".. |
| end
| | frame:expandTemplate{title="PageRef", args={a["Name"]}}.. |
| | " || "..baseHealthRegen.." \n" |
| end | | end |
| | | z = z.."|}" |
| return table.concat(output, "\n\n") | | return z |
| end | | end |
|
| |
|
| p.heroDpsTable = function(frame) | | p.heroDpsTable = function(frame) |
| local heroDpsData = heroDataArray({"Name","Weapon>DPS","Weapon>ReloadSingle","Weapon>ReloadDelay","Weapon>ReloadTime", | | local heroDpsData = heroDataArray({"Name","ReloadSingle","ReloadDelay","ReloadTime", |
| "Weapon>ClipSize","Weapon>RoundsPerSecond","Weapon>BulletDamage","Weapon>BulletsPerShot","Weapon>AltFire>DPS", | | "ClipSize","RoundsPerSecond","BulletDamage","BulletsPerShot"}) |
| "Weapon>AltFire>AmmoConsumedPerShot","Weapon>AltFire>RoundsPerSecond","Weapon>AltFire>BulletDamage","Weapon>AltFire>BulletsPerShot"})
| |
| | | |
| local rows = {} | | local z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n".. |
| for name, data in pairs(heroDpsData) do
| | "|+ Hero Base Damage \n".. |
| table.insert(rows, {
| | "! Hero !! Reload Delay (s) !! Reload Time (s) !! Ammo !! Bullets per sec !! Bullet Damage !! Bullets Per Shot \n" |
| name = name,
| |
| DPS = data["Weapon>DPS"] or 0,
| |
| reloadDelay = data["Weapon>ReloadDelay"] or 0,
| |
| reloadTime = data["Weapon>ReloadTime"] or 0,
| |
| clipSize = data["Weapon>ClipSize"] or 0,
| |
| roundsPerSecond = data["Weapon>RoundsPerSecond"] or 0,
| |
| bulletDamage = data["Weapon>BulletDamage"] or 0,
| |
| bulletsPerShot = data["Weapon>BulletsPerShot"] or 0,
| |
| altDPS = data["Weapon>AltFire>DPS"] or 0,
| |
| altAmmoConsumedPerShot = data["Weapon>AltFire>AmmoConsumedPerShot"] or 0,
| |
| altRoundsPerSecond = data["Weapon>AltFire>RoundsPerSecond"] or 0,
| |
| altBulletDamage = data["Weapon>AltFire>BulletDamage"] or 0,
| |
| altBulletsPerShot = data["Weapon>AltFire>BulletsPerShot"] or 0
| |
| })
| |
| | | |
| local altBulletDamage = data["Weapon>AltFire>BulletDamage"]
| | for i,a in pairs(heroDpsData) do |
| local altDPS = data["Weapon>AltFire>DPS"]
| | local reloadDelay = a["ReloadDelay"] or 0 |
| local altRoundsPerSecond = data["Weapon>AltFire>RoundsPerSecond"]
| | local reloadTime = a["ReloadTime"] or 0 |
| local altBulletsPerShot = data["Weapon>AltFire>BulletsPerShot"]
| | local clipSize = a["ClipSize"] or 0 |
| if altBulletDamage and altBulletDamage ~= 0 then
| | local roundsPerSecond = a["RoundsPerSecond"] or 0 |
| table.insert(rows, {
| | local bulletDamage = a["BulletDamage"] or 0 |
| name = name,
| | local bulletsPerShot = a["BulletsPerShot"] or 0 |
| sortName = name .. " (alt fire)",
| | z = z.. |
| nameSuffix = " (alt fire)",
| | "|- \n".. |
| DPS = altDPS,
| | "| style=\"text-align:left;\" | ".. |
| reloadDelay = data["Weapon>ReloadDelay"] or 0,
| | frame:expandTemplate{title="PageRef", args={a["Name"]}}.. |
| reloadTime = data["Weapon>ReloadTime"] or 0,
| | " || "..reloadDelay.." || "..reloadTime.." || "..clipSize.. |
| clipSize = data["Weapon>ClipSize"] or 0,
| | " || "..roundsPerSecond.." || "..bulletDamage.." || "..bulletsPerShot.." \n" |
| roundsPerSecond = altRoundsPerSecond,
| |
| bulletDamage = altBulletDamage,
| |
| bulletsPerShot = altBulletsPerShot
| |
| })
| |
| end | |
| end
| |
| sortHeroes(rows)
| |
| | |
| local tableDefs = {
| |
| {
| |
| title = "Base Damage Stats", | |
| columns = { | |
| { label = "Damage per sec", field = "DPS" },
| |
| { label = "Reload Delay (s)", field = "reloadDelay" }, | |
| { label = "Reload Time (s)", field = "reloadTime" }, | |
| { label = "Ammo", field = "clipSize" },
| |
| { label = "Bullets per sec", field = "roundsPerSecond" }, | |
| { label = "Bullet Damage", field = "bulletDamage" },
| |
| { label = "Bullets Per Shot", field = "bulletsPerShot" },
| |
| }
| |
| }
| |
| }
| |
| | |
| local output = {}
| |
| for _, def in ipairs(tableDefs) do
| |
| local t = buildTable(frame, rows, def, def.options)
| |
| if t ~= "" then
| |
| table.insert(output, t)
| |
| end
| |
| end | | end |
| | | z = z.."|}" |
| return table.concat(output, "\n\n") | | return z |
| end | | end |
|
| |
|
| p.heroBulletSpeedTable = function(frame) | | p.heroBulletSpeedTable = function(frame) |
| local heroBulletSpeedData = heroDataArray({ | | local heroBulletSpeedData = heroDataArray({"Name", "BulletSpeed"}) |
| "Name",
| | |
| "Weapon>BulletSpeed", | | local z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n".. |
| "Weapon>AltFire>BulletSpeed" | | "|+ Base Bullet Velocity \n".. |
| })
| | "! Hero !! m/s \n" |
|
| |
|
| local rows = {}
| | for i,a in pairs(heroBulletSpeedData) do |
| for name, data in pairs(heroBulletSpeedData) do | | local bulletSpeed = a["BulletSpeed"] or 0 |
| table.insert(rows, {
| | z = z.. |
| name = name,
| | "|- \n".. |
| bulletSpeed = data["Weapon>BulletSpeed"] or 0,
| | "| style=\"text-align:left;\" | ".. |
| altBulletSpeed = data["Weapon>AltFire>BulletSpeed"] or 0 | | frame:expandTemplate{title="PageRef", args={a["Name"]}}.. |
| })
| | " || "..bulletSpeed.." \n" |
|
| |
| local altBulletSpeed = data["Weapon>AltFire>BulletSpeed"]
| |
| if altBulletSpeed and altBulletSpeed ~= 0 then
| |
| table.insert(rows, {
| |
| name = name, | |
| sortName = name .. " (alt fire)",
| |
| nameSuffix = " (alt fire)", | |
| bulletSpeed = altBulletSpeed
| |
| })
| |
| end
| |
| end | | end |
| | z = z.."|}" |
| | return z |
| | end |
|
| |
|
| sortHeroes(rows)
| | p.heroClipSizeTable = function(frame) |
| | | local heroClipSizeData = heroDataArray({"Name", "ClipSize"}) |
| local tableDefs = { | | |
| {
| | local z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n".. |
| title = "Base Bullet Velocity",
| | "|+ Base Ammo Count \n".. |
| columns = {
| | "! Hero !! Ammo \n" |
| { label = "m/s", field = "bulletSpeed" }
| |
| }
| |
| } | |
| }
| |
|
| |
|
| local output = {}
| | for i,a in pairs(heroClipSizeData) do |
| for _, def in ipairs(tableDefs) do | | local clipSize = a["ClipSize"] or 0 |
| local t = buildTable(frame, rows, def, def.options)
| | z = z.. |
| if t ~= "" then | | "|- \n".. |
| table.insert(output, t) | | "| style=\"text-align:left;\" | ".. |
| end
| | frame:expandTemplate{title="PageRef", args={a["Name"]}}.. |
| | " || "..clipSize.." \n" |
| end | | end |
| | | z = z.."|}" |
| return table.concat(output, "\n\n") | | return z |
| end | | end |
|
| |
|
| p.heroClipSizeTable = function(frame) | | p.heroMoveSpeedTable = function(frame) |
| local heroClipSizeData = heroDataArray({"Name", "Weapon>ClipSize","Weapon>BulletsPerBurst","Weapon>AltFire>AmmoConsumedPerShot","SpiritScaling>ClipSize"}) | | local heroMoveSpeedData = heroDataArray({"Name", "MoveSpeed"}) |
| | | |
| local rows = {} | | local z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n".. |
| for name, data in pairs(heroClipSizeData) do
| | "|+ Base Movement Speed \n".. |
| table.insert(rows, {
| | "! Hero !! m/s \n" |
| name = name,
| |
| clipSize = data["Weapon>ClipSize"] or 0,
| |
| spiritClipSize = "+".. (data["SpiritScaling>ClipSize"] or 0),
| |
| bulletsPerBurst = data["Weapon>BulletsPerBurst"] or 0,
| |
| burstClipSize = data["Weapon>ClipSize"] or 0 / data["Weapon>BulletsPerBurst"] or 0,
| |
| ammoConsumedPerShot = data["Weapon>AltFire>AmmoConsumedPerShot"] or 0
| |
| })
| |
|
| |
| local ammoConsumedPerShot = data["Weapon>AltFire>AmmoConsumedPerShot"]
| |
| if ammoConsumedPerShot and ammoConsumedPerShot ~= 0 then | |
| table.insert(rows, {
| |
| name = name,
| |
| sortName = name .. " (alt fire)",
| |
| nameSuffix = " (alt fire)",
| |
| bulletsPerBurst = ammoConsumedPerShot,
| |
| clipSize = data["Weapon>ClipSize"] or 0,
| |
| spiritClipSize = "+".. (data["SpiritScaling>ClipSize"] or 0),
| |
| })
| |
| end | |
| end
| |
|
| |
| sortHeroes(rows)
| |
| | |
| local tableDefs = {
| |
| {
| |
| title = "Base Ammo Count",
| |
| columns = {
| |
| { label = "Ammo", field = "clipSize" },
| |
| { label = "Ammo Per Shot", field = "bulletsPerBurst" },
| |
| { label = "Spirit Scaling", field = "spiritClipSize" },
| |
| }
| |
| }
| |
| }
| |
|
| |
|
| local output = {}
| | for i,a in pairs(heroMoveSpeedData) do |
| for _, def in ipairs(tableDefs) do | | local moveSpeed = a["MoveSpeed"] or 0 |
| local t = buildTable(frame, rows, def, def.options) | | z = z.. |
| if t ~= "" then | | "|- \n".. |
| table.insert(output, t) | | "| style=\"text-align:left;\" | ".. |
| end
| | frame:expandTemplate{title="PageRef", args={a["Name"]}}.. |
| | " || "..moveSpeed.." \n" |
| end | | end |
| | | z = z.."|}" |
| return table.concat(output, "\n\n") | | return z |
| end | | end |
|
| |
|
| p.heroRoundsPerSecondTable = function(frame) | | p.heroRoundsPerSecondTable = function(frame) |
| local heroRoundsPerSecondData = heroDataArray({"Name", "Weapon>RoundsPerSecond", "Weapon>AltFire>RoundsPerSecond", "SpiritScaling>RoundsPerSecond", "SpiritScaling>FireRate"}) | | local heroRoundsPerSecondData = heroDataArray({"Name", "RoundsPerSecond"}) |
| | | |
| local rows = {} | | local z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n".. |
| for name, data in pairs(heroRoundsPerSecondData) do
| | "|+ Base Fire Rate \n".. |
| table.insert(rows, {
| | "! Hero !! Rounds/s \n" |
| name = name,
| |
| roundsPerSecond = data["Weapon>RoundsPerSecond"] or 0,
| |
| altRoundsPerSecond = data["Weapon>AltFire>RoundsPerSecond"] or 0,
| |
| spiritRoundsPerSecond = "+".. (data["SpiritScaling>RoundsPerSecond"] or 0),
| |
| spiritFireRate = "+".. (data["SpiritScaling>FireRate"] or 0),
| |
| })
| |
|
| |
| local altRoundsPerSecond = data["Weapon>AltFire>RoundsPerSecond"]
| |
| if altRoundsPerSecond and altRoundsPerSecond ~= 0 then | |
| table.insert(rows, {
| |
| name = name,
| |
| sortName = name .. " (alt fire)",
| |
| nameSuffix = " (alt fire)",
| |
| roundsPerSecond = altRoundsPerSecond,
| |
| spiritRoundsPerSecond = "+".. (data["SpiritScaling>RoundsPerSecond"] or 0),
| |
| })
| |
| end | |
| end
| |
| sortHeroes(rows)
| |
| | |
| local tableDefs = {
| |
| {
| |
| title = "Base Fire Rate",
| |
| columns = {
| |
| { label = "Rounds/s", field = "roundsPerSecond" },
| |
| { label = "Spirit Scaling", field = "spiritRoundsPerSecond" },
| |
| }
| |
| }
| |
| }
| |
|
| |
|
| local output = {}
| | for i,a in pairs(heroRoundsPerSecondData) do |
| for _, def in ipairs(tableDefs) do | | local roundsPerSecond = a["RoundsPerSecond"] or 0 |
| local t = buildTable(frame, rows, def, def.options)
| | z = z.. |
| if t ~= "" then | | "|- \n".. |
| table.insert(output, t) | | "| style=\"text-align:left;\" | ".. |
| end
| | frame:expandTemplate{title="PageRef", args={a["Name"]}}.. |
| | " || "..roundsPerSecond.." \n" |
| end | | end |
| | | z = z.."|}" |
| return table.concat(output, "\n\n") | | return z |
| end | | end |
|
| |
|
| p.heroFalloffRangeTable = function(frame) | | p.heroFalloffRangeTable = function(frame) |
| local heroFalloffRangeData = heroDataArray({"Name", "Weapon>FalloffStartRange", "Weapon>FalloffEndRange", "Weapon>AltFire>FalloffStartRange", "Weapon>AltFire>FalloffEndRange", | | local heroFalloffRangeData = heroDataArray({"Name", "FalloffStartRange", "FalloffEndRange"}) |
| "Weapon>AltFire>ExplosionRadius", "Weapon>FalloffEndScale", "Weapon>AltFire>ExplosionDamageScaleAtMaxRadius",})
| |
|
| |
| local rows = {}
| |
| for name, data in pairs(heroFalloffRangeData) do
| |
| table.insert(rows, {
| |
| name = name,
| |
| falloffStartRange = data["Weapon>FalloffStartRange"] or 0,
| |
| falloffEndRange = data["Weapon>FalloffEndRange"] or 0,
| |
| falloffEndScale = -100 + (100 * (data["Weapon>FalloffEndScale"] or 0)),
| |
| altFalloffStartRange = data["Weapon>AltFire>FalloffStartRange"] or 0,
| |
| altFalloffEndRange = data["Weapon>AltFire>FalloffEndRange"] or 0,
| |
| altExplosionRadius = 0,
| |
| altExplosionEndScale = (100 * (data["Weapon>AltFire>ExplosionDamageScaleAtMaxRadius"] or 0))
| |
| })
| |
| | | |
| local altFalloffStartRange = data["Weapon>AltFire>FalloffStartRange"]
| | local z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n".. |
| local altFalloffEndRange = data["Weapon>AltFire>FalloffEndRange"]
| | "|+ Base Falloff Range \n".. |
| local altExplosionRadius = data["Weapon>AltFire>ExplosionRadius"] or 0
| | "! Hero !! Minimum Range (m) !! Maximum Range (m) \n" |
| local altExplosionEndScale = (100 * (data["Weapon>AltFire>ExplosionDamageScaleAtMaxRadius"] or 0))
| |
| if altFalloffStartRange and altFalloffStartRange ~= 0 then
| |
| table.insert(rows, {
| |
| name = name,
| |
| sortName = name .. " (alt fire)",
| |
| nameSuffix = " (alt fire)",
| |
| falloffStartRange = altFalloffStartRange,
| |
| falloffEndRange = altFalloffEndRange,
| |
| altExplosionRadius = data["Weapon>AltFire>ExplosionRadius"] or 0,
| |
| falloffEndScale = -100 + (100 * (data["Weapon>FalloffEndScale"] or 0))
| |
| })
| |
| end
| |
| end
| |
| sortHeroes(rows)
| |
| | |
| local tableDefs = {
| |
| {
| |
| title = "Base Falloff Range",
| |
| columns = {
| |
| { label = "Minimum Range (m)", field = "falloffStartRange" },
| |
| { label = "Maximum Range (m)", field = "falloffEndRange" },
| |
| { label = "Damage Falloff (%)", field = "falloffEndScale" },
| |
| { label = "Explosion Radius (m)", field = "altExplosionRadius" },
| |
| }
| |
| }
| |
| }
| |
|
| |
|
| local output = {}
| | for i,a in pairs(heroFalloffRangeData) do |
| for _, def in ipairs(tableDefs) do | | local falloffStartRange = a["FalloffStartRange"] or 0 |
| local t = buildTable(frame, rows, def, def.options)
| | local falloffEndRange = a["FalloffEndRange"] or 0 |
| if t ~= "" then | | z = z.. |
| table.insert(output, t) | | "|- \n".. |
| end
| | "| style=\"text-align:left;\" | ".. |
| | frame:expandTemplate{title="PageRef", args={a["Name"]}}.. |
| | " || "..falloffStartRange.." || "..falloffEndRange.." \n" |
| end | | end |
| | | z = z.."|}" |
| return table.concat(output, "\n\n") | | return z |
| end | | end |
|
| |
|
| p.heroBulletDamageTable = function(frame) | | p.heroBulletDamageTable = function(frame) |
| -- Pull data | | -- Pull data |
| local heroBulletDamageData = heroDataArray({"Name", "Weapon>BulletDamage", "LevelScaling>BulletDamage", "Weapon>AltFire>BulletDamage", "LevelScaling>BulletDamageAltFire", | | local heroBulletDamageData = heroDataArray({"Name", "BulletDamage", "LevelScaling>BulletDamage"}) |
| "SpiritScaling>BulletDamage", "Weapon>BulletsPerShot", "Weapon>BulletsPerBurst"})
| |
|
| |
|
| local rows = {} | | local z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n".. |
| for name, data in pairs(heroBulletDamageData) do
| | "|+ Hero Base Bullet Damage Stats \n".. |
| table.insert(rows, {
| | "! Hero !! Starting !! Added per Boon !! At Max Boon \n" |
| name = name,
| |
| bulletDamage = data["Weapon>BulletDamage"] or 0,
| |
| bulletDamagePerShot = ((data["Weapon>BulletDamage"] or 0) * (data["Weapon>BulletsPerShot"] or 0) * (data["Weapon>BulletsPerBurst"] or 0)),
| |
| scalingDamage = "+" .. data["LevelScaling>BulletDamage"] or 0,
| |
| maxScalingDamage = (roundValue(data["Weapon>BulletDamage"] + data["LevelScaling>BulletDamage"] * soul_unlock.get_max("PowerIncrease"))) or 0,
| |
| altBulletDamage = data["Weapon>AltFire>BulletDamage"] or 0,
| |
| spiritScalingDamage = "+" .. (data["SpiritScaling>BulletDamage"] or 0),
| |
| })
| |
|
| |
|
| -- Secondary fire is listed as its own row, right under the hero's main row
| | -- Iterate over heroes adding a new row to the wikitable for each |
| local altDamage = data["Weapon>AltFire>BulletDamage"]
| | for i,a in pairs(heroBulletDamageData) do |
| if altDamage and altDamage ~= 0 then
| | -- FIX: Set default values of 0 if the data is nil to prevent arithmetic errors |
| local altScaling = data["LevelScaling>BulletDamageAltFire"] or 0
| | local bulletDamage = a["BulletDamage"] or 0 |
| table.insert(rows, { | | local scalingDamage = a["LevelScaling>BulletDamage"] or 0 |
| name = name,
| | z = z.. |
| sortName = name .. " (alt fire)", | | "|- \n".. |
| nameSuffix = " (alt fire)",
| | "| style=\"text-align:left;\" | ".. |
| bulletDamage = altDamage, | | frame:expandTemplate{title="PageRef", args={a["Name"]}}.. |
| scalingDamage = "+" .. altScaling, | | -- Use the safe variables here |
| maxScalingDamage = roundValue(altDamage + altScaling * soul_unlock.get_max("PowerIncrease")), | | " || "..bulletDamage.." || +"..scalingDamage.." || ".. |
| spiritScalingDamage = "+0",
| | -- And use them in the calculation |
| })
| | tostring(roundValue(tonumber(bulletDamage) + tonumber(scalingDamage) * soul_unlock.get_max('PowerIncrease'))).." \n" |
| end
| |
| end | | end |
| sortHeroes(rows)
| |
|
| |
| local tableDefs = {
| |
| {
| |
| title = "Base Bullet Damage Stats",
| |
| columns = {
| |
| { label = "Starting", field = "bulletDamage" },
| |
| { label = "Added per Boon", field = "scalingDamage" },
| |
| { label = "At Max Boon", field = "maxScalingDamage" },
| |
| { label = "Spirit Scaling", field = "spiritScalingDamage" },
| |
| }
| |
| },
| |
| }
| |
|
| |
| local output = {}
| |
| for _, def in ipairs(tableDefs) do
| |
| local t = buildTable(frame, rows, def, def.options)
| |
| if t ~= "" then
| |
| table.insert(output, t)
| |
| end
| |
| end
| |
|
| |
| return table.concat(output, "\n\n")
| |
| end
| |
|
| |
| p.heroMeleeTable = function(frame)
| |
| -- Pull data
| |
| local heroMeleeData = heroDataArray({"Name", "LightMeleeDamage", "LevelScaling>LightMeleeDamage", "HeavyMeleeDamage", "LevelScaling>HeavyMeleeDamage", "SpiritScaling>HeavyMeleeDamage"})
| |
|
| |
| local rows = {}
| |
| for name, data in pairs(heroMeleeData) do
| |
| table.insert(rows, {
| |
| name = name,
| |
| lightMeleeDamage = data["LightMeleeDamage"] or 0,
| |
| lightScalingDamage = "+" .. data["LevelScaling>LightMeleeDamage"] or 0,
| |
| lightMaxScalingDamage = (roundValueFour(data["LightMeleeDamage"] + data["LevelScaling>LightMeleeDamage"] * soul_unlock.get_max("PowerIncrease"))) or 0,
| |
| heavyMeleeDamage = data["HeavyMeleeDamage"] or 0,
| |
| heavyScalingDamage = "+" .. data["LevelScaling>HeavyMeleeDamage"] or 0,
| |
| heavyMaxScalingDamage = (roundValueFour(data["HeavyMeleeDamage"] + data["LevelScaling>HeavyMeleeDamage"] * soul_unlock.get_max("PowerIncrease"))) or 0,
| |
| heavySpiritScalingDamage = "+" .. (data["SpiritScaling>HeavyMeleeDamage"] or 0),
| |
| })
| |
| end
| |
| sortHeroes(rows)
| |
|
| |
| local tableDefs = {
| |
| {
| |
| title = "Base Light & Heavy Melee Stats",
| |
| columns = {
| |
| { label = "Starting Light", field = "lightMeleeDamage" },
| |
| { label = "Added per Boon (L)", field = "lightScalingDamage" },
| |
| { label = "At Max Boon (L)", field = "lightMaxScalingDamage" },
| |
| { label = "Starting Heavy", field = "heavyMeleeDamage" },
| |
| { label = "Added per Boon (H)", field = "heavyScalingDamage" },
| |
| { label = "At Max Boon (H)", field = "heavyMaxScalingDamage" },
| |
| { label = "Spirit Scaling (H)", field = "heavySpiritScalingDamage" },
| |
|
| |
| }
| |
| }
| |
| }
| |
| | | |
| local output = {} | | z = z.."|}" |
| for _, def in ipairs(tableDefs) do
| | return z |
| local t = buildTable(frame, rows, def, def.options)
| |
| if t ~= "" then
| |
| table.insert(output, t)
| |
| end
| |
| end
| |
| | |
| return table.concat(output, "\n\n") | |
| end | | end |
|
| |
|
| Line 607: |
Line 251: |
| local heroLightMeleeData = heroDataArray({"Name", "LightMeleeDamage", "LevelScaling>LightMeleeDamage"}) | | local heroLightMeleeData = heroDataArray({"Name", "LightMeleeDamage", "LevelScaling>LightMeleeDamage"}) |
|
| |
|
| local rows = {} | | local z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n".. |
| for name, data in pairs(heroLightMeleeData) do | | "|+ Hero Base Light Melee Stats \n".. |
| table.insert(rows, { | | "! Hero !! Starting !! Added per Boon !! At Max Boon \n" |
| name = name,
| | |
| lightMeleeDamage = data["LightMeleeDamage"] or 0,
| | -- Iterate over heroes adding a new row to the wikitable for each |
| scalingDamage = "+" .. data["LevelScaling>LightMeleeDamage"] or 0,
| | for i,a in pairs(heroLightMeleeData) do |
| maxScalingDamage = (roundValueFour(data["LightMeleeDamage"] + data["LevelScaling>LightMeleeDamage"] * soul_unlock.get_max("PowerIncrease"))) or 0, | | 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 | | end |
| sortHeroes(rows)
| |
|
| |
| local tableDefs = {
| |
| {
| |
| title = "Base Light Melee Stats",
| |
| columns = {
| |
| { label = "Starting", field = "lightMeleeDamage" },
| |
| { label = "Added per Boon", field = "scalingDamage" },
| |
| { label = "At Max Boon", field = "maxScalingDamage" },
| |
| }
| |
| }
| |
| }
| |
| | | |
| local output = {} | | z = z.."|}" |
| for _, def in ipairs(tableDefs) do
| | return z |
| local t = buildTable(frame, rows, def, def.options)
| |
| if t ~= "" then
| |
| table.insert(output, t)
| |
| end
| |
| end
| |
| | |
| return table.concat(output, "\n\n") | |
| end | | end |
|
| |
|
| p.heroHeavyMeleeTable = function(frame) | | p.heroHeavyMeleeTable = function(frame) |
| -- Pull data | | -- Pull data |
| local heroHeavyMeleeData = heroDataArray({"Name", "HeavyMeleeDamage", "LevelScaling>HeavyMeleeDamage", "SpiritScaling>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 !! Starting !! Added per Boon !! At Max Boon \n" |
|
| |
|
| local rows = {} | | -- Iterate over heroes adding a new row to the wikitable for each |
| for name, data in pairs(heroHeavyMeleeData) do | | for i,a in pairs(heroHeavyMeleeData) do |
| table.insert(rows, { | | local heavyMeleeDamage = a["HeavyMeleeDamage"] or 0 |
| name = name,
| | local scalingDamage = a["LevelScaling>HeavyMeleeDamage"] or 0 |
| heavyMeleeDamage = data["HeavyMeleeDamage"] or 0,
| | z = z.. |
| scalingDamage = "+" .. data["LevelScaling>HeavyMeleeDamage"] or 0,
| | "|- \n".. |
| maxScalingDamage = (roundValueFour(data["HeavyMeleeDamage"] + data["LevelScaling>HeavyMeleeDamage"] * soul_unlock.get_max("PowerIncrease"))) or 0, | | "| style=\"text-align:left;\" | ".. |
| spiritScalingDamage = "+" .. (data["SpiritScaling>HeavyMeleeDamage"] or 0),
| | frame:expandTemplate{title="PageRef", args={a["Name"]}}.. |
| })
| | " || "..heavyMeleeDamage.." || +"..scalingDamage.." || ".. |
| | tostring(roundValue(tonumber(heavyMeleeDamage) + tonumber(scalingDamage) * soul_unlock.get_max('PowerIncrease'))).." \n" |
| end | | end |
| sortHeroes(rows)
| |
|
| |
| local tableDefs = {
| |
| {
| |
| title = "Base Heavy Melee Stats",
| |
| columns = {
| |
| { label = "Starting", field = "heavyMeleeDamage" },
| |
| { label = "Added per Boon", field = "scalingDamage" },
| |
| { label = "At Max Boon", field = "maxScalingDamage" },
| |
| { label = "Spirit Scaling", field = "spiritScalingDamage" },
| |
| }
| |
| }
| |
| }
| |
| | | |
| local output = {} | | z = z.."|}" |
| for _, def in ipairs(tableDefs) do
| | return z |
| local t = buildTable(frame, rows, def, def.options)
| |
| if t ~= "" then
| |
| table.insert(output, t)
| |
| end
| |
| end
| |
| | |
| return table.concat(output, "\n\n") | |
| end | | end |
|
| |
|
| p.heroStaminaTable = function(frame) | | p.heroStaminaTable = function(frame) |
| local heroStaminaData = heroDataArray({"Name", "Stamina", "StaminaCooldown"}) | | local heroStaminaData = heroDataArray({"Name", "Stamina"}) |
|
| |
|
| local rows = {} | | local z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n".. |
| for name, data in pairs(heroStaminaData) do
| | "|+ Hero Base Stamina Stats \n".. |
| table.insert(rows, {
| | "! Hero !! Stamina Bars \n" |
| name = name,
| |
| stamina = data["Stamina"] or 0,
| |
| staminaCooldown = data["StaminaCooldown"] or 0
| |
| }) | |
| end
| |
| sortHeroes(rows)
| |
|
| |
|
| local tableDefs = { | | for i,a in pairs(heroStaminaData) do |
| {
| | local stamina = a["Stamina"] or 0 |
| title = "Base Stamina Stats", | | z = z.. |
| columns = { | | "|- \n".. |
| { label = "Stamina Bars", field = "stamina" },
| | "| style=\"text-align:left;\" | ".. |
| { label = "Cooldown (s)", field = "staminaCooldown" }, | | frame:expandTemplate{title="PageRef", args={a["Name"]}}.. |
| }
| | " || "..stamina.." \n" |
| }
| |
| }
| |
|
| |
| local output = {}
| |
| for _, def in ipairs(tableDefs) do
| |
| local t = buildTable(frame, rows, def, def.options)
| |
| if t ~= "" then
| |
| table.insert(output, t)
| |
| end
| |
| end | | end |
| | | z = z.."|}" |
| return table.concat(output, "\n\n") | | return z |
| end | | end |
|
| |
|
| p.heroDashTable = function(frame) | | p.heroDashTable = function(frame) |
| local heroDashData = heroDataArray({"Name", "GroundDashSpeed", "GroundDashDuration", "AirDashSpeed", "AirDashDuration"}) | | local heroDashData = heroDataArray({"Name", "GroundDashDuration"}) |
|
| |
|
| local rows = {} | | local rows = {} |
| Line 720: |
Line 321: |
| table.insert(rows, { | | table.insert(rows, { |
| name = name, | | name = name, |
| dashSpeed = data["GroundDashSpeed"] or 0, | | duration = tonumber(data.GroundDashDuration) or 0 |
| dashDuration = data["GroundDashDuration"] or 0,
| |
| airDashSpeed = data["AirDashSpeed"] or 0,
| |
| airDashDuration = data["AirDashDuration"] or 0,
| |
| }) | | }) |
| end | | end |
| sortHeroes(rows) | | table.sort(rows, function(a, b) return a.name:lower() < b.name:lower() end) |
|
| | |
| local tableDefs = { | | local z = '{| class="wikitable sortable mw-collapsible" style="text-align:center"\n' .. |
| {
| | '|+ Hero Base Dash Speed Stats\n' .. |
| title = "Base Dash Speed Stats",
| | '! Hero !! Dash Speed (s)\n' |
| columns = {
| | for _, r in ipairs(rows) do |
| { label = "Dash Speed (m/s)", field = "dashSpeed" },
| | z = z .. '|-\n| style="text-align:left;" | ' .. |
| { label = "Dash Duration (s)", field = "dashDuration" },
| | frame:expandTemplate{title = 'PageRef', args = {r.name}} .. |
| { label = "Air Dash Speed (m/s)", field = "airDashSpeed" },
| | ' || ' .. r.duration .. '\n' |
| { label = "Air Dash Duration (s)", field = "airDashDuration" },
| |
| }
| |
| }
| |
| }
| |
|
| |
| local output = {}
| |
| for _, def in ipairs(tableDefs) do | |
| local t = buildTable(frame, rows, def, def.options) | |
| if t ~= "" then
| |
| table.insert(output, t)
| |
| end
| |
| end | | end |
| | | return z .. '|}' |
| return table.concat(output, "\n\n") | |
| end | | end |
|
| |
|
| p.heroReloadTable = function(frame) | | p.heroReloadTable = function(frame) |
| local heroReloadData = heroDataArray({"Name", "Weapon>ReloadTime"}) | | local heroReloadData = heroDataArray({"Name", "ReloadTime"}) |
|
| |
|
| | -- 1. collect rows |
| local rows = {} | | local rows = {} |
| for name, data in pairs(heroReloadData) do | | for name, data in pairs(heroReloadData) do |
| table.insert(rows, { | | table.insert(rows, { |
| name = name, | | name = name, |
| reloadTime = data["Weapon>ReloadTime"] or 0 | | reloadTime = tonumber(data.ReloadTime) or 0 |
| }) | | }) |
| end | | end |
|
| |
|
| sortHeroes(rows) | | -- 2. alphabetical by hero name |
| | table.sort(rows, function(a, b) return a.name:lower() < b.name:lower() end) |
|
| |
|
| local tableDefs = { | | -- 3. build table |
| {
| | local z = '{| class="wikitable sortable mw-collapsible" style="text-align:center"\n' .. |
| title = "Base Reload Time",
| | '|+ Hero Base Reload Time Stats\n' .. |
| columns = {
| | '! Hero !! Reload Time (s)\n' |
| { label = "Reload Time (s)", field = "reloadTime" },
| |
| }
| |
| }
| |
| }
| |
|
| |
| local output = {}
| |
| for _, def in ipairs(tableDefs) do
| |
| local t = buildTable(frame, rows, def, def.options)
| |
| if t ~= "" then
| |
| table.insert(output, t)
| |
| end
| |
| end
| |
|
| |
|
| return table.concat(output, "\n\n")
| | for _, r in ipairs(rows) do |
| end
| | z = z .. |
| | | '|-\n' .. |
| p.heroReloadDelayTable = function(frame)
| | '| style="text-align:left;" | ' .. |
| local heroReloadDelayData = heroDataArray({"Name", "Weapon>ReloadDelay"})
| | frame:expandTemplate{title = 'PageRef', args = {r.name}} .. |
| | | ' || ' .. r.reloadTime .. '\n' |
| local rows = {}
| |
| for name, data in pairs(heroReloadDelayData) do | |
| table.insert(rows, { | |
| name = name, | |
| reloadDelay = data["Weapon>ReloadDelay"] or 0 | |
| })
| |
| end
| |
| sortHeroes(rows)
| |
| | |
| local tableDefs = {
| |
| {
| |
| title = "Base Reload Delay",
| |
| columns = {
| |
| { label = "Reload Delay (s)", field = "reloadDelay" }
| |
| }
| |
| }
| |
| }
| |
| | |
| local output = {}
| |
| for _, def in ipairs(tableDefs) do
| |
| local t = buildTable(frame, rows, def, def.options)
| |
| if t ~= "" then
| |
| table.insert(output, t) | |
| end
| |
| end | | end |
| | | return z .. '|}' |
| return table.concat(output, "\n\n") | |
| end | | end |
|
| |
|
| p.heroMoveSpeedTable = function(frame) | | p.heroMoveSpeedTable = function(frame) |
| local heroMoveSpeedData = heroDataArray({"Name", "MaxMoveSpeed", "SprintSpeed", "Weapon>ShootMoveSpeed", "SpiritScaling>MaxMoveSpeed", "SpiritScaling>SprintSpeed"}) | | local heroMoveSpeedData = heroDataArray({"Name", "MaxMoveSpeed", "SprintSpeed"}) |
|
| |
|
| local rows = {} | | local z = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center\" \n".. |
| for name, data in pairs(heroMoveSpeedData) do
| | "|+ Hero Base Move Speed Stats \n".. |
| table.insert(rows, {
| | "! Hero !! Move Speed !! Sprint Speed !! Total Sprint Speed \n" |
| name = name,
| |
| moveSpeed = data["MaxMoveSpeed"] or 0,
| |
| sprintSpeed = data["SprintSpeed"] or 0,
| |
| totalSpeed = data["MaxMoveSpeed"] + data["SprintSpeed"] or 0,
| |
| shootSpeed = (data["Weapon>ShootMoveSpeed"] or 0) * 100,
| |
| totalShootingSpeed = roundValue((data["MaxMoveSpeed"] + data["SprintSpeed"] or 0) * (data["Weapon>ShootMoveSpeed"] or 0)),
| |
| spiritMoveSpeed = "+" .. (data["SpiritScaling>MaxMoveSpeed"] or 0),
| |
| spiritSprintSpeed = "+" .. (data["SpiritScaling>SprintSpeed"] or 0),
| |
| })
| |
| end
| |
| sortHeroes(rows)
| |
|
| |
|
| local tableDefs = { | | for i,a in pairs(heroMoveSpeedData) do |
| { | | local moveSpeed = a["MaxMoveSpeed"] or 0 |
| title = "Base Move Speed Stats",
| | local sprintSpeed = a["SprintSpeed"] or 0 |
| columns = {
| | z = z.. |
| { label = "Move Speed (m/s)", field = "moveSpeed" },
| | "|- \n".. |
| { label = "Sprint Speed (m/s)", field = "sprintSpeed" },
| | "| style=\"text-align:left;\" | ".. |
| { label = "Total Speed (m/s)", field = "totalSpeed" }, | | frame:expandTemplate{title="PageRef", args={a["Name"]}}.. |
| { label = "Shooting Speed (m/s)", field = "totalShootingSpeed" },
| | " || "..moveSpeed.." || "..sprintSpeed.." || "..tonumber(moveSpeed) + tonumber(sprintSpeed).." \n" |
| { label = "Shooting Mult (%)", field = "shootSpeed" },
| |
| { label = "MS Spirit Scaling", field = "spiritMoveSpeed" },
| |
| { label = "SS Spirit Scaling", field = "spiritSprintSpeed" },
| |
| }
| |
| }
| |
| }
| |
| | |
| local output = {}
| |
| for _, def in ipairs(tableDefs) do
| |
| local t = buildTable(frame, rows, def, def.options)
| |
| if t ~= "" then
| |
| table.insert(output, t)
| |
| end
| |
| end | | end |
| | | z = z.."|}" |
| return table.concat(output, "\n\n")
| | return z |
| end
| |
| | |
| p.heroDamageResistTable = function(frame)
| |
| local heroDamageResistData = heroDataArray({"Name", "BulletResist", "LevelScaling>BulletResist", "TechResist", "LevelScaling>TechResist", "MeleeResist", "CritDamageReceivedPercent",
| |
| "SpiritScaling>BulletResist", "SpiritScaling>TechResist",
| |
| })
| |
| | |
| local rows = {} | |
| for name, data in pairs(heroDamageResistData) do
| |
| table.insert(rows, {
| |
| name = name,
| |
| bulletResist = data["BulletResist"] or 0,
| |
| bulletResistScaling = "+".. (data["LevelScaling>BulletResist"] or 0),
| |
| bulletResistScalingMax = ((roundValue((data["BulletResist"] or 0) + (data["LevelScaling>BulletResist"] or 0) * soul_unlock.get_max("PowerIncrease"))) or 0),
| |
| bulletResistSpiritScaling = "+".. (data["SpiritScaling>BulletResist"] or 0),
| |
| spiritResist = data["TechResist"] or 0,
| |
| spiritResistScaling = "+".. (data["LevelScaling>TechResist"] or 0),
| |
| spiritResistScalingMax = ((roundValue((data["TechResist"] or 0) + (data["LevelScaling>TechResist"] or 0) * soul_unlock.get_max("PowerIncrease"))) or 0),
| |
| spiritResistSpiritScaling = "+".. (data["SpiritScaling>TechResist"] or 0),
| |
| meleeResist = data["MeleeResist"] or 0,
| |
| critReduction = data["CritDamageReceivedPercent"] or 0
| |
| })
| |
| end
| |
| sortHeroes(rows)
| |
| | |
| local tableDefs = {
| |
| {
| |
| title = "Base Bullet Resist Stats",
| |
| columns = {
| |
| { label = "Starting (%)", field = "bulletResist" },
| |
| { label = "Added per Boon (%)", field = "bulletResistScaling" },
| |
| { label = "At Max Boon (%)", field = "bulletResistScalingMax" },
| |
| { label = "Spirit Scaling (%)", field = "bulletResistSpiritScaling" },
| |
| }
| |
| },
| |
| {
| |
| title = "Base Spirit Resist Stats",
| |
| columns = {
| |
| { label = "Starting (%)", field = "spiritResist" },
| |
| { label = "Added per Boon (%)", field = "spiritResistScaling" },
| |
| { label = "At Max Boon (%)", field = "spiritResistScalingMax" },
| |
| { label = "Spirit Scaling (%)", field = "spiritResistSpiritScaling" },
| |
| }
| |
| },
| |
| {
| |
| title = "Base Melee Resist Stats",
| |
| columns = {
| |
| { label = "Melee Resist (%)", field = "meleeResist" },
| |
| }
| |
| },
| |
| {
| |
| title = "Base Crit Reduction Stats",
| |
| columns = {
| |
| { label = "Crit Reduction (%)", field = "critReduction" },
| |
| }
| |
| },
| |
| }
| |
| | |
| local output = {}
| |
| for _, def in ipairs(tableDefs) do
| |
| local t = buildTable(frame, rows, def, def.options)
| |
| if t ~= "" then
| |
| table.insert(output, t)
| |
| end
| |
| end
| |
| | |
| return table.concat(output, "\n\n") | |
| end
| |
| | |
| p.heroCritTable = function(frame)
| |
| local heroCritData = heroDataArray({"Name", "CritDamageBonusPercent"})
| |
| | |
| local rows = {}
| |
| for name, data in pairs(heroCritData) do
| |
| table.insert(rows, {
| |
| name = name,
| |
| critBonusScale = data["CritDamageBonusPercent"] or 0
| |
| })
| |
| end
| |
| sortHeroes(rows)
| |
| | |
| local tableDefs = {
| |
| {
| |
| title = "Base Crit Bonus Scale Stats",
| |
| columns = {
| |
| { label = "Crit Bonus Scale (%)", field = "critBonusScale" }
| |
| }
| |
| }
| |
| }
| |
| | |
| local output = {}
| |
| for _, def in ipairs(tableDefs) do
| |
| local t = buildTable(frame, rows, def, def.options)
| |
| if t ~= "" then
| |
| table.insert(output, t)
| |
| end
| |
| end
| |
| | |
| return table.concat(output, "\n\n")
| |
| end
| |
| | |
| p.heroSpiritTable = function(frame)
| |
| local heroSpiritData = heroDataArray({"Name", "LevelScaling>TechPower"})
| |
| | |
| local rows = {}
| |
| for name, data in pairs(heroSpiritData) do
| |
| table.insert(rows, {
| |
| name = name,
| |
| spiritScaling = "+".. data["LevelScaling>TechPower"] or 0,
| |
| maxSpiritScaling = (data["LevelScaling>TechPower"] * soul_unlock.get_max("PowerIncrease")) or 0,
| |
| })
| |
| end
| |
| sortHeroes(rows)
| |
| | |
| local tableDefs = {
| |
| {
| |
| title = "Spirit Scaling Stats",
| |
| columns = {
| |
| { label = "Spirit Per Boon", field = "spiritScaling" },
| |
| { label = "At Max Boon", field = "maxSpiritScaling" },
| |
| }
| |
| }
| |
| }
| |
| | |
| local output = {}
| |
| for _, def in ipairs(tableDefs) do
| |
| local t = buildTable(frame, rows, def, def.options)
| |
| if t ~= "" then
| |
| table.insert(output, t)
| |
| end
| |
| end
| |
| | |
| return table.concat(output, "\n\n")
| |
| end
| |
| | |
| p.heroGravityTable = function(frame)
| |
| local heroGravityData = heroDataArray({"Name", "GravityChange"})
| |
| | |
| local rows = {}
| |
| for name, data in pairs(heroGravityData) do
| |
| table.insert(rows, {
| |
| name = name,
| |
| gravityScale = (data["GravityChange"] or 0),
| |
| })
| |
| end
| |
| sortHeroes(rows)
| |
| | |
| local tableDefs = {
| |
| {
| |
| title = "Base Gravity Scale Stats",
| |
| columns = {
| |
| { label = "Gravity Scale (%)", field = "gravityScale" },
| |
| }
| |
| }
| |
| }
| |
| | |
| local output = {}
| |
| for _, def in ipairs(tableDefs) do
| |
| local t = buildTable(frame, rows, def, def.options)
| |
| if t ~= "" then
| |
| table.insert(output, t)
| |
| end
| |
| end
| |
| | |
| return table.concat(output, "\n\n")
| |
| end
| |
| | |
| p.bulletGravityTable = function(frame)
| |
| local heroGravityData = heroDataArray({"Name", "Weapon>BulletGravityScale", "Weapon>AltFire>BulletGravityScale"})
| |
| | |
| local rows = {}
| |
| for name, data in pairs(heroGravityData) do
| |
| table.insert(rows, {
| |
| name = name,
| |
| gravityScale = (data["Weapon>BulletGravityScale"] or 0),
| |
| altGravityScale = (data["Weapon>AltFire>BulletGravityScale"] or 0),
| |
| })
| |
| end
| |
| sortHeroes(rows)
| |
| | |
| local tableDefs = {
| |
| {
| |
| title = "Base Bullet Gravity Scale Stats",
| |
| columns = {
| |
| { label = "Gravity Scale", field = "gravityScale" },
| |
| }
| |
| },
| |
| {
| |
| title = "Base Alt-fire Bullet Gravity Scale Stats",
| |
| columns = {
| |
| { label = "Gravity Scale", field = "altGravityScale" },
| |
| }
| |
| }
| |
| }
| |
| | |
| local output = {}
| |
| for _, def in ipairs(tableDefs) do
| |
| local t = buildTable(frame, rows, def, def.options)
| |
| if t ~= "" then
| |
| table.insert(output, t)
| |
| end
| |
| end
| |
| | |
| return table.concat(output, "\n\n")
| |
| end
| |
| | |
| p.bulletRadiusTable = function(frame)
| |
| local heroBulletRadiusData = heroDataArray({"Name", "Weapon>BulletRadius", "Weapon>AltFire>BulletRadius"})
| |
| | |
| local rows = {}
| |
| for name, data in pairs(heroBulletRadiusData) do
| |
| table.insert(rows, {
| |
| name = name,
| |
| bulletRadius = (data["Weapon>BulletRadius"] or 0) * 100,
| |
| bulletRadiusInches = roundValueInteger((data["Weapon>BulletRadius"] or 0) * 100 * 0.394),
| |
| altBulletRadius = (data["Weapon>AltFire>BulletRadius"] or 0) * 100,
| |
| altBulletRadiusInches = roundValueInteger((data["Weapon>AltFire>BulletRadius"] or 0) * 100 * 0.394),
| |
| })
| |
|
| |
| local altBulletRadius = (data["Weapon>AltFire>BulletRadius"] or 0) * 100
| |
| local altBulletRadiusInches = roundValueInteger((data["Weapon>AltFire>BulletRadius"] or 0) * 100 * 0.394)
| |
| if altBulletRadius and altBulletRadius ~= 0 then
| |
| table.insert(rows, {
| |
| name = name,
| |
| sortName = name .. " (alt fire)",
| |
| nameSuffix = " (alt fire)",
| |
| bulletRadius = altBulletRadius,
| |
| bulletRadiusInches = altBulletRadiusInches
| |
| })
| |
| end
| |
| end
| |
| sortHeroes(rows)
| |
| | |
| local tableDefs = {
| |
| {
| |
| title = "Base Bullet Radius Stats",
| |
| columns = {
| |
| { label = "Bullet Radius (cm)", field = "bulletRadius" },
| |
| { label = "Bullet Radius (in)", field = "bulletRadiusInches" },
| |
| }
| |
| }
| |
| }
| |
| | |
| local output = {}
| |
| for _, def in ipairs(tableDefs) do
| |
| local t = buildTable(frame, rows, def, def.options)
| |
| if t ~= "" then
| |
| table.insert(output, t)
| |
| end
| |
| end
| |
| | |
| return table.concat(output, "\n\n")
| |
| end | | end |
|
| |
|
| return p | | return p |