Editing Module:Sandbox/Vergir

Warning: You are not logged in. Once you make an edit, a temporary account will be created for you. Learn more. Log in or create an account to continue receiving notifications after this account expires, and to access other features.
The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then publish the changes below to finish undoing the edit.
Latest revision Your text
Line 1: Line 1:
-- Builds tables of hero base stats that scale with a given scaling type,
-- read from [[Data:HeroData.json]].
--
-- Each public function below renders one table. The shared work lives in
-- build_scaling_table(), so adding a table for another scaling type (Boons,
-- for instance) only takes a new wrapper naming its data key and caption.
--
-- {{#invoke:Sandbox/Vergir|write_spirit_scaling_table}}
local p = {}
local p = {}
local heroes_data      = mw.loadJsonData("Data:HeroData.json")
local attributes_data  = mw.loadJsonData("Data:AttributeData.json")
local util_module      = require('Module:Utilities')
local lang_module      = require('Module:Lang')
local dictionary_module = require('Module:Dictionary')
local hero_data_module  = require('Module:HeroData')
--------------------------------------------------------------------------------
-- Helpers
--------------------------------------------------------------------------------
-- next() ignores metamethods and mw.loadJsonData hands back proxy tables, so
-- keys always have to be collected through pairs() rather than tested with next().
local function sorted_keys(tbl)
local keys = {}
if (tbl == nil) then return keys end
for key in pairs(tbl) do table.insert(keys, key) end
table.sort(keys)
return keys
end
-- Comma or whitespace separated list to a set.
local function to_set(list)
local set = {}
if (list == nil) then return set end
for entry in string.gmatch(list, "[^,%s]+") do set[entry] = true end
return set
end
-- Localized name of a stat, resolved in three steps:
--  1. [[Data:AttributeData.json]] label -> Valve's own translation
--  2. [[Data:Dictionary]] entry, for stats Valve has no label for
--  3. the raw key, spaced out, with a missing-translation tooltip
local function stat_label(stat)
for _, category in pairs(attributes_data) do
local attribute = category[stat]
if (attribute ~= nil and attribute["label"] ~= nil) then
local localized = lang_module.get_string(attribute["label"])
if (localized ~= nil and localized ~= '') then return localized end
end
end
local translated = dictionary_module.translate(stat)
if (translated ~= nil and translated:sub(1, 5) ~= "Key '") then return translated end
return util_module.add_space_before_cap(stat) ..
mw.getCurrentFrame():expandTemplate{title = "MissingValveTranslationTooltip"}
end
-- Heroes are listed as they are read, so "The Doorman" sorts under D.
local function sort_name(hero_data, hero_key)
return (hero_data["Name"] or hero_key):gsub("^The ", "")
end
local function hero_icon(hero_key, hero_data)
return mw.getCurrentFrame():expandTemplate{
title = "HeroIcon",
args = {[1] = hero_data["Name"] or hero_key, l1 = lang_module.get_string(hero_key)},
}
end
-- "6.3 + x0.0084", or just the scaling for stats that have no base value
-- (percentage stats such as Fire Rate and the resistances).
local function scaling_cell(hero_data, stat, value, scaling_type)
local scaling_str = hero_data_module.write_scalar_str(value, scaling_type)
local base = hero_data_module.get_stat(hero_data, stat)
if (type(base) ~= "number") then return scaling_str end
return base .. ' + ' .. scaling_str
end
-- Every scaling a hero has of one type, minus the excluded stats and any
-- zeroes, ordered by localized stat name:
--  { { stat = , label = , value = }, ... }
local function hero_scalings(hero_data, scaling_key, excluded_stats)
local scalings = {}
local hero_scaling_data = hero_data[scaling_key]
for _, stat in ipairs(sorted_keys(hero_scaling_data)) do
local value = hero_scaling_data[stat]
if (not excluded_stats[stat] and type(value) == "number" and value ~= 0) then
table.insert(scalings, {stat = stat, label = stat_label(stat), value = value})
end
end
table.sort(scalings, function(a, b)
if (a.label == b.label) then return a.stat < b.stat end
return a.label < b.label
end)
return scalings
end
--------------------------------------------------------------------------------
-- Shared table builder
--------------------------------------------------------------------------------
-- options:
--  scaling_type: "Spirit" or "Level", picks both the <type>Scaling data key
--                and the scaling template ({{Ss}} or {{PI}})
--  caption_key:  [[Data:Dictionary]] key for the table caption
--  excluded_stats: set of stat keys to leave out
local function build_scaling_table(options)
local scaling_key = options.scaling_type .. "Scaling"
-- Collect the heroes that have anything left to show
local rows = {}
for _, hero_key in ipairs(sorted_keys(heroes_data)) do
local hero_data = heroes_data[hero_key]
if (not hero_data["InDevelopment"] and not hero_data["IsDisabled"]) then
local scalings = hero_scalings(hero_data, scaling_key, options.excluded_stats)
if (#scalings > 0) then
table.insert(rows, {
key = hero_key,
data = hero_data,
sort_name = sort_name(hero_data, hero_key),
scalings = scalings,
})
end
end
end
if (#rows == 0) then return '' end
table.sort(rows, function(a, b) return a.sort_name < b.sort_name end)
-- Build the table
local output = {
'{| class="wikitable"',
'|+ ' .. dictionary_module.translate(options.caption_key),
'! ' .. dictionary_module.translate("Hero"),
'! ' .. dictionary_module.translate("Stats"),
'! ' .. dictionary_module.translate("Scaling"),
}
for _, row in ipairs(rows) do
for index, scaling in ipairs(row.scalings) do
table.insert(output, '|-')
if (index == 1) then
local rowspan = ''
if (#row.scalings > 1) then rowspan = ' rowspan="' .. #row.scalings .. '" |' end
table.insert(output, '|' .. rowspan .. ' ' .. hero_icon(row.key, row.data))
end
table.insert(output, '| ' .. scaling.label)
table.insert(output, '| ' ..
scaling_cell(row.data, scaling.stat, scaling.value, options.scaling_type))
end
end
table.insert(output, '|}')
return table.concat(output, '\n')
end
--------------------------------------------------------------------------------
-- Wikitext entry points
--------------------------------------------------------------------------------
-- Hero base stats that scale with Spirit Power.
--{{#invoke:Sandbox/Vergir|write_spirit_scaling_table|exclude=}}
-- exclude: comma separated stat keys to leave out. Defaults to DPS and
--          SustainedDPS, which are both derived from stats already listed.
--          Pass an empty value to list every stat.
function p.write_spirit_scaling_table(frame)
local args = frame.args or {}
return build_scaling_table{
scaling_type = "Spirit",
caption_key = "HeroSpiritScalingCaption",
excluded_stats = to_set(args["exclude"] or "DPS,SustainedDPS"),
}
end
return p
return p
Please note that all contributions to The Deadlock Wiki are considered to be released under the Creative Commons Attribution-NonCommercial-ShareAlike (see Deadlock:Copyrights for details). If you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource. Do not submit copyrighted work without permission!
Cancel Editing help (opens in new window)
Preview page with this template

Page included on this page: