Editing Module:HeroDataGive feedback
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: | ||
local p = {}; | local p = {}; | ||
local heroes_data = mw.loadJsonData("Data:HeroData.json") | local heroes_data = mw.loadJsonData("Data:HeroData.json") | ||
local attributes_data = mw.loadJsonData("Data:AttributeData.json") | |||
local attribute_orders = mw.loadJsonData("Data:StatInfoboxOrder.json") | |||
local util_module = require('Module:Utilities') | local util_module = require('Module:Utilities') | ||
local lang_module = require('Module:Lang') | local lang_module = require('Module:Lang') | ||
local dictionary_module = require('Module:Dictionary') | |||
local attribute_module = require('Module:AttributeData') | |||
local | |||
-- returns the table of a specific item, used by external modules | -- returns the table of a specific item, used by external modules | ||
| Line 83: | Line 18: | ||
end | end | ||
-- | -- Returns an array of item tables that have the same properties | ||
-- @function get_similar_items | |||
-- @param {string} | |||
-- @return {array of tables} | |||
local function get_similar_items(property) | |||
local similarItems = {} | |||
for _, v in pairs(heroes_data) do | |||
if (v[property] ~= nil) then | |||
-- | table.insert(similarItems, v) | ||
function | |||
-- | |||
-- | |||
function | |||
local | |||
for _, | |||
if ( | |||
table.insert( | |||
end | end | ||
end | end | ||
return | return similarItems | ||
end | end | ||
-- | -- returns the key of the specified hero's english name | ||
function p.get_hero_key(frame) | |||
local hero_name_input = frame.args[1] -- Get the hero name from the template argument | |||
function p. | if not hero_name_input then | ||
return "Error: Hero name not specified." | |||
end | |||
-- | |||
end | |||
-- | hero_name_input = hero_name_input:lower() -- For case-independent search | ||
-- | -- Go through all the characters and look for a name match. | ||
for hero_key, hero_data in pairs(heroes_data) do | |||
if hero_data["Name"] then | |||
local current_hero_name = hero_data["Name"]:lower() | |||
if current_hero_name == hero_name_input then | |||
return hero_key -- Return the key if the name matches | |||
end | |||
end | |||
end | |||
end | |||
-- | return "Hero not found." -- If nothing is found | ||
end | end | ||
| Line 189: | Line 61: | ||
local sig_figs_or_localize = frame.args[3] | local sig_figs_or_localize = frame.args[3] | ||
local hero = | local hero = heroes_data[hero_name] | ||
if(hero == nil) then hero = p.get_json_item(hero_name) end | |||
if(hero == nil) then return "Hero Not Found" end | if(hero == nil) then return "Hero Not Found" end | ||
local var_value = | -- Check top-level first, then Weapon, then AltFire | ||
local var_value = hero[hero_stat_key] | |||
if var_value == nil and hero.Weapon then | |||
var_value = hero.Weapon[hero_stat_key] | |||
end | |||
if var_value == nil and hero.Weapon and hero.Weapon.AltFire then | |||
var_value = hero.Weapon.AltFire[hero_stat_key] | |||
end | |||
if(var_value == nil) then return 0 end | if(var_value == nil) then return 0 end | ||
| Line 215: | Line 96: | ||
local sig_figs_or_localize = frame.args[3] | local sig_figs_or_localize = frame.args[3] | ||
local hero = | local hero = heroes_data[hero_name] | ||
if(hero == nil) then hero = p.get_json_item(hero_name) end | |||
if(hero == nil) then return "Hero Not Found" end | if(hero == nil) then return "Hero Not Found" end | ||
| Line 242: | Line 124: | ||
local hero_name = frame.args[1] | local hero_name = frame.args[1] | ||
local var = frame.args[2] | local var = frame.args[2] | ||
local | local number_str = frame.args[3] | ||
local | local number_int = tonumber(number_str) | ||
local localize = frame.args[4] | |||
local hero = | local hero = heroes_data[hero_name] | ||
if(hero == nil) then hero = p.get_json_item(hero_name) end | |||
if(hero == nil) then return "Hero Not Found" end | if(hero == nil) then return "Hero Not Found" end | ||
local list = | -- Check top-level first, then Weapon, then AltFire | ||
local list = hero[var] | |||
if list == nil and hero.Weapon then | |||
list = hero.Weapon[var] | |||
end | |||
if list == nil and hero.Weapon and hero.Weapon.AltFire then | |||
list = hero.Weapon.AltFire[var] | |||
end | |||
if (list == nil) then return "" end | if (list == nil) then return "" end | ||
local element = list[number_int] | local element = list[number_int] | ||
if (element == nil) then return "" end | if (element == nil) then return "" end | ||
if | if localize=="true" then | ||
element = lang_module.get_string(element) | element = lang_module.get_string(element) | ||
end | end | ||
| Line 293: | Line 185: | ||
if (hero == nil) then return "Hero not found, must be unlocalized" end | if (hero == nil) then return "Hero not found, must be unlocalized" end | ||
local template_title = 'PageRef' | local template_title = 'PageRef' | ||
for i, item_key in ipairs(hero["RecommendedItems"] | for i, item_key in ipairs(hero["RecommendedItems"]) do | ||
template_args = {} | |||
template_args[1] = lang_module.get_string(item_key, 'en') | template_args[1] = lang_module.get_string(item_key, 'en') | ||
template_args['alt_name'] = localize(item_key, item_key) | template_args['alt_name'] = localize(item_key, item_key) | ||
| Line 302: | Line 194: | ||
return str | return str | ||
end | end | ||
--If the hero scales with the stat, it returns {{Ss|value}} or {{PI|value}}, else blank string | --If the hero scales with the stat, it returns {{Ss|value}} or {{PI|value}}, else blank string | ||
| Line 312: | Line 205: | ||
local no_template = frame.args["no_template"] | local no_template = frame.args["no_template"] | ||
local hero_data = | local hero_data = heroes_data[hero_key] | ||
if(hero_data == nil) then hero_data = p.get_json_item(hero_key) end | |||
if(hero_data == nil) then return "Hero not found." end | if(hero_data == nil) then return "Hero not found." end | ||
local | local scaling_data = hero_data[scaling_type .. "Scaling"] | ||
if scaling_data == nil then return "" end | |||
local scaling_value = scaling_data[hero_stat_key] | |||
if scaling_value == nil then return "" end | if scaling_value == nil then return "" end | ||
| Line 329: | Line 226: | ||
end | end | ||
if no_template == "true" then | local scaling_str = p.write_scalar_str(scaling_value, scaling_type) | ||
if no_template == "true" then | |||
return scaling_value | |||
else | |||
return scaling_str | |||
end | |||
end | end | ||
| Line 339: | Line 238: | ||
-- Returns "true" if found, nil if not (for #if templates) | -- Returns "true" if found, nil if not (for #if templates) | ||
p.hero_has_stat = function(frame) | p.hero_has_stat = function(frame) | ||
local hero_key = frame.args[1] | |||
local stat_key = frame.args[2] | |||
if (hero_key == nil) then return nil end | |||
local hero_data = heroes_data[hero_key] | |||
if (hero_data == nil) then hero_data = p.get_json_item(hero_key) end | |||
if (hero_data == nil) then return nil end | |||
-- 1. Check Base Value | |||
-- We allow 0 if it's explicitly set, but usually we filter 0 for hiding. | |||
-- However, for resists, 0 usually means "hide", so we check ~= 0. | |||
local val = hero_data[stat_key] | |||
if (val ~= nil and val ~= 0) then return "true" end | |||
-- 2. Check Level Scaling (Boons) | |||
if (hero_data["LevelScaling"] ~= nil and hero_data["LevelScaling"][stat_key] ~= nil and hero_data["LevelScaling"][stat_key] ~= 0) then | |||
return "true" | |||
end | |||
-- 3. Check Spirit Scaling | |||
if (hero_data["SpiritScaling"] ~= nil and hero_data["SpiritScaling"][stat_key] ~= nil and hero_data["SpiritScaling"][stat_key] ~= 0) then | |||
return "true" | |||
end | |||
return nil | |||
end | end | ||
| Line 402: | Line 290: | ||
return result | return result | ||
end | |||
-- Retrieve scaling value and type of a hero's given stat, if it has scaling, else return 0 | |||
function p.get_hero_scaling_data(hero_data, hero_stat_key) | |||
local scaling_type_full | |||
local scaling_data | |||
local scaling_value | |||
local scaling_types = {"Spirit", "Level"} | |||
local scaling_data_returned = {} | |||
for index, scaling_type in ipairs(scaling_types) do | |||
scaling_type_full = scaling_type .. "Scaling" | |||
scaling_data = hero_data[scaling_type_full] | |||
--If the scaling data exists | |||
if (scaling_data ~= nil) then | |||
scaling_value = scaling_data[hero_stat_key] | |||
--If the stat scales | |||
if (scaling_value ~= nil) then | |||
scaling_data_returned[scaling_value] = scaling_type | |||
end | |||
end | |||
end | |||
return scaling_data_returned | |||
end | |||
function localize(key, fallback) | |||
local result = lang_module.get_string(key) | |||
if (result == "") or (result == nil) then | |||
result = util_module.add_space_before_cap(fallback) .. mw.getCurrentFrame():expandTemplate{title="MissingValveTranslationTooltip"} | |||
end | |||
return result | |||
end | |||
-- Mapping from hero name to internal tag name | |||
local TAG_NAME_MAP = { | |||
["Abrams"] = "Abrams", | |||
["Bebop"] = "Bebop", | |||
["Billy"] = "Punkgoat", | |||
["Calico"] = "Nano", | |||
["The Doorman"] = "Doorman", | |||
["Drifter"] = "Drifter", | |||
["Dynamo"] = "Dynamo", | |||
["Apollo"] = "Fencer", | |||
["Graves"] = "Necro", | |||
["Grey Talon"] = "Orion", | |||
["Haze"] = "Haze", | |||
["Holliday"] = "Astro", | |||
["Infernus"] = "Inferno", | |||
["Ivy"] = "Tengu", | |||
["Kelvin"] = "Kelvin", | |||
["Lady Geist"] = "Geist", | |||
["Lash"] = "Lash", | |||
["McGinnis"] = "Engineer", | |||
["Mina"] = "VampireBat", | |||
["Mirage"] = "Mirage", | |||
["Mo & Krill"] = "Digger", | |||
["Paige"] = "Bookworm", | |||
["Paradox"] = "Chrono", | |||
["Celeste"] = "Unicorn", | |||
["Pocket"] = "Synth", | |||
["Rem"] = "Familiar", | |||
["Seven"] = "Gigawatt", | |||
["Shiv"] = "Shiv", | |||
["Silver"] = "Werewolf", | |||
["Silver (Transformed)"] = "Werewolf", | |||
["Sinclair"] = "Magician", | |||
["Venator"] = "Priest", | |||
["Victor"] = "Frank", | |||
["Vindicta"] = "Vindicta", | |||
["Viscous"] = "Viscous", | |||
["Vyper"] = "Viper", | |||
["Warden"] = "Warden", | |||
["Wraith"] = "Wraith", | |||
["Yamato"] = "Yamato", | |||
} | |||
-- Function to call hero tags based on name | |||
p.get_hero_tag = function (frame) | |||
local name = frame.args[1] | |||
local number = tonumber(frame.args[2]) | |||
-- Validate input | |||
if not name then | |||
return "Error: Missing name input." | |||
end | |||
if number ~= 1 and number ~= 2 and number ~= 3 then | |||
return string.format("Error: Invalid number '%s'. Must be 1, 2, or 3.", tostring(frame.args[2])) | |||
end | |||
local tagname = TAG_NAME_MAP[name] | |||
if not tagname then | |||
return string.format("Error: Unknown name '%s'.", name) | |||
end | |||
-- Build localization key | |||
local key = string.format("Citadel_%s_HeroTag_%d", tagname, number) | |||
-- Call Lang.get_string | |||
local result = lang_module.get_string(key) | |||
return result or ("[Missing string for key: " .. key .. "]") | |||
end | end | ||
| Line 412: | Line 405: | ||
[0.72] = {}, | [0.72] = {}, | ||
} | } | ||
local get_dash = function(hero) | |||
return hero.GroundDashDuration | |||
or (hero.Weapon and hero.Weapon.GroundDashDuration) | |||
or (hero.Weapon and hero.Weapon.AltFire and hero.Weapon.AltFire.GroundDashDuration) | |||
end | |||
-- Collect heroes | -- Collect heroes | ||
for hero_key, hero_data in pairs(heroes_data) do | for hero_key, hero_data in pairs(heroes_data) do | ||
if not hero_data.InDevelopment and not hero_data.IsDisabled then | if not hero_data.InDevelopment and not hero_data.IsDisabled then | ||
local dash = | local dash = get_dash(hero_data) | ||
if dash and buckets[dash] then | if dash and buckets[dash] then | ||
table.insert(buckets[dash], hero_data.Name or hero_key) | table.insert(buckets[dash], hero_data.Name or hero_key) | ||