|
|
(13 intermediate revisions by 2 users not shown) |
Line 1: |
Line 1: |
| local lang = require "Module:Lang" | | local data = mw.loadJsonData("Data:AbilityCards.json") |
| local utils = require "Module:Utilities"
| |
|
| |
|
| local p = {} | | local p = {} |
| local data = mw.loadJsonData("Data:AbilityCards.json")
| |
|
| |
| -- Maps attr type to an appropriate image and page link
| |
| -- Optional icon size, otherwise will be defaulted on the template
| |
| local ATTR_TYPE_ICON_MAP = {
| |
| bullet_armor_up = {img='Bullet_Armor.png', link='Damage_Resistance'},
| |
| bullet_armor_down = {img='Bullet_armor_down.png', link='Damage_Resistance', size='23px'},
| |
| cast = {img='AttributeIconMaxChargesIncrease.png', link=''},
| |
| charges = {img='AttributeIconMaxChargesIncrease.png', link=''},
| |
| damage = {img='Damage_heart.png', link='', color = 'NoColor'}, -- 'NoColor' will apply no icon color and use the original image
| |
| bullet_damage = {img='Damage.png', link='Bullet_Damage', color = 'Brown'},
| |
| fire_rate = {img='Fire Rate.png', link='Fire_Rate'},
| |
| healing = {img='Health regen.png', link='Health_Regen'},
| |
| health = {img='Extra Health.png', link='Health'},
| |
| move_speed = {img='Move speed.png', link='Move Speed'},
| |
| range = {img='CastRange.png', link='Ability_Range'},
| |
| tech_armor_up = {img='Spirit_Armor.png', link='Damage_Resistance'},
| |
| tech_damage = {img='AttributeIconTechShieldHealth.png', link='Spirit_Damage', color = 'Purple',size = '12px'},
| |
| distance = {img='AttributeIconTechRange.png', link='Ability_Range'},
| |
| duration = {img='AttributeIconTechDuration.png', link='Ability Duration'},
| |
| slow = {img='MoveSlow.png', link=''}
| |
| }
| |
|
| |
|
| -- returns the table of a specific item | | -- returns the table of a specific item |
| function get_ability(hero_name, ability_num) | | function get_ability(hero_key, ability_num) |
| local hero_key = get_hero_key(hero_name) | | local ui_data = data[hero_key] |
| if(hero_key == nil) then return "Hero Not Found" end
| | if(ui_data == nil) then return "Hero Not Found" end |
| return data[hero_key][tonumber(ability_num)]
| | return ui_data[tonumber(ability_num)] |
| end
| |
| | |
| function get_hero_key(hero_name)
| |
| for i, hero in pairs(data) do | |
| if hero["Name"] == hero_name then
| |
| return i
| |
| end
| |
| end
| |
| return nil
| |
| end
| |
| | |
| --{{#invoke:AbilityData|get_ability_card|HERO_NAME|ABILITY_NUM|ADD_LINK|NOTES}}--
| |
| p.get_ability_card = function(frame)
| |
| local hero_name = frame.args[1]
| |
| local ability_num = frame.args[2]
| |
| local add_link = frame.args[3]
| |
| local notes = frame.args[4]
| |
| | |
| local ability = get_ability(hero_name, ability_num)
| |
| if(ability == nil) then
| |
| return 'Ability data not found for hero ' ..hero_name.. ' and num ' .. ability_num
| |
| end
| |
|
| |
| local name_link = nil
| |
| if add_link == 'true' then
| |
| name_link = string.format("%s#(%s)_%s", hero_name, ability_num, ability.Name)
| |
| end
| |
|
| |
| return frame:expandTemplate{
| |
| title = "Ability card v2",
| |
| args = {
| |
| hero_name = hero_name,
| |
| ability_num = ability_num,
| |
| name = lang._get_string(ability.Key),
| |
| name_link = name_link,
| |
| icon = lang._get_string(ability.Key, 'en') .. '.png',
| |
| description = frame:preprocess(lang._get_string(ability.DescKey)),
| |
| radius = ability.Radius and ability.Radius.Value,
| |
| range = ability.AbilityCastRange and ability.AbilityCastRange.Value,
| |
| duration = ability.AbilityDuration and ability.AbilityDuration.Value,
| |
| -- ability_width = format_value_with_prepost(width_key, ability[width_key]),
| |
| cooldown =ability.AbilityCooldown and ability.AbilityCooldown.Value,
| |
| charge_cooldown = ability.AbilityCooldownBetweenCharge and ability.AbilityCooldownBetweenCharge.Value,
| |
| num_of_charges = ability.AbilityCharges and ability.AbilityCharges.Value,
| |
| notes = notes
| |
| }
| |
| }
| |
| end
| |
| | |
| -- Get all info sections for specified ability
| |
| --{{#invoke:AbilityData|get_ability_card|HERO_NAME|ABILITY_NUM}}--
| |
| p.get_all_info_sections = function(frame)
| |
| local hero_name = frame.args[1]
| |
| local ability_num = frame.args[2]
| |
| | |
| local ability = get_ability(hero_name, ability_num)
| |
| if(ability == nil) then return "Ability Not Found" end
| |
|
| |
| local output_template = ''
| |
| for info_section_num=1, 10 do
| |
| local info_section = ability['Info'..info_section_num]
| |
| -- some abilities have no info sections
| |
| if info_section == nil then break end
| |
| local info_template = frame:expandTemplate{
| |
| title = "Ability_card_v2/Info section",
| |
| args = {
| |
| hero_name = hero_name,
| |
| ability_num = ability_num,
| |
| info_section_num = info_section_num,
| |
| info_section_num
| |
| }
| |
| }
| |
| output_template = output_template .. info_template
| |
| end
| |
|
| |
| return output_template | |
| end
| |
| | |
| -- Get the description for an ability's info section
| |
| --{{#invoke:AbilityData|get_info_desc|HERO_NAME|ABILITY_NUM|INFO_SECTION_INDEX}}--
| |
| p.get_info_desc = function(frame)
| |
| local hero_name = frame.args[1]
| |
| local ability_num = frame.args[2]
| |
| local info_section_num = frame.args[3]
| |
|
| |
| local ability = get_ability(hero_name, ability_num)
| |
| if(ability == nil) then return "Ability Not Found" end
| |
| local info_section = ability['Info'..info_section_num]
| |
|
| |
| -- some abilities have no info sections
| |
| if info_section == nil then return '' end
| |
|
| |
| if info_section.DescKey == nil then
| |
| return ''
| |
| end
| |
|
| |
| return frame:preprocess(lang._get_string(info_section.DescKey))
| |
| end
| |
|
| |
| --{{#invoke:AbilityData|get_info_main|HERO_NAME|ABILITY_NUM|INFO_SECTION_INDEX}}--
| |
| p.get_info_main = function(frame)
| |
| local hero_name = frame.args[1]
| |
| local ability_num = frame.args[2]
| |
| local info_section_num = frame.args[3]
| |
|
| |
| local ability = get_ability(hero_name, ability_num)
| |
| if(ability == nil) then return "Ability Not Found" end
| |
|
| |
| local info_section = ability['Info'..info_section_num]
| |
|
| |
| -- some abilities have no info sections
| |
| if info_section == nil then return '' end
| |
|
| |
| local main = info_section.Main
| |
| if main == nil then
| |
| return ''
| |
| end
| |
|
| |
| local props = info_section.Main.Props
| |
| -- Concatenate multiple section boxes into a single output template
| |
| local info_box_template = ''
| |
| for k, prop in pairs(props) do
| |
| -- Exclude 0 values
| |
| if prop.Value and prop.Value ~= 0 then
| |
| local icon = get_icon(prop.Type)
| |
|
| |
| section_box = frame:expandTemplate{
| |
| title = "Ability_card_v2/MainBox",
| |
| args = {
| |
| title = prop.Title,
| |
| key = prop.Key,
| |
| value = prop.Value,
| |
| icon = icon.img,
| |
| icon_link = icon.link,
| |
| icon_color = icon.color,
| |
| icon_size = icon.size,
| |
| scale_value = prop.Scale and utils.round_to_sig_fig(prop.Scale.Value, 3),
| |
| scale_type = prop.Scale and prop.Scale.Type
| |
| }
| |
| }
| |
| info_box_template = info_box_template .. section_box .. '\n'
| |
| end
| |
| end
| |
|
| |
| return info_box_template
| |
| end
| |
| | |
| --{{#invoke:AbilityData|get_info_alt|HERO_NAME|ABILITY_NUM|INFO_SECTION_INDEX}}--
| |
| p.get_info_alt = function(frame)
| |
| local hero_name = frame.args[1]
| |
| local ability_num = frame.args[2]
| |
| local info_section_num = frame.args[3]
| |
|
| |
| local ability = get_ability(hero_name, ability_num)
| |
| if(ability == nil) then return "Ability Not Found" end
| |
|
| |
| local info_section = ability['Info'..info_section_num]
| |
|
| |
| -- some abilities have no info sections
| |
| if info_section == nil then return '' end
| |
|
| |
| local props = info_section.Alt
| |
| if props == nil then
| |
| return ''
| |
| end
| |
|
| |
| -- Concatenate multiple section boxes into a single output template
| |
| local info_box_template = ''
| |
| for k, prop in pairs(props) do
| |
| -- Some props don't have values, as those come from upgrades
| |
| -- For now, we will ignore these and only show data for the base ability
| |
| if prop.Value and prop.Value ~= 0 then
| |
| local icon = get_icon(prop.Type)
| |
| section_box = frame:expandTemplate{
| |
| title = "Ability_card_v2/AltBox",
| |
| args = {
| |
| key = prop.Key,
| |
| value = prop.Value,
| |
| icon = icon.img,
| |
| icon_link = icon.link,
| |
| icon_color = icon.color,
| |
| icon_size = icon.size,
| |
| scale_value = prop.Scale and utils.round_to_sig_fig(prop.Scale.Value, 3),
| |
| scale_type = prop.Scale and prop.Scale.Type
| |
| }
| |
| }
| |
| info_box_template = info_box_template .. section_box .. '\n'
| |
| end
| |
| end
| |
|
| |
| return info_box_template
| |
| end
| |
| | |
| local UPGRADE_COST_MAP = {1, 2, 5}
| |
| --{{#invoke:AbilityData|get_upgrades|HERO_NAME|ABILITY_NUM}}--
| |
| p.get_upgrades = function(frame)
| |
| local hero_name = frame.args[1]
| |
| local ability_num = frame.args[2]
| |
| local ability = get_ability(hero_name, ability_num)
| |
| if(ability == nil) then return "Ability Not Found" end
| |
|
| |
| local props = ability.Upgrades
| |
|
| |
| -- Concatenate multiple section boxes into a single output template
| |
| local upgrades_template = ''
| |
| for k, prop in pairs(props) do
| |
| local description = lang._get_string(prop.DescKey)
| |
|
| |
| -- Generate a description if there is no localized string
| |
| if description == nil then
| |
| description = create_description(prop, frame)
| |
| end
| |
|
| |
| -- Vary the font size based on the number of characters to prevent overflow
| |
| local fontsize = '1rem'
| |
| if #description > 60 and #description < 71 then
| |
| fontsize = '0.95rem'
| |
| elseif #description > 70 and #description < 91 then
| |
| fontsize = '0.875rem'
| |
| elseif #description > 90 then
| |
| fontsize = '0.8rem'
| |
| end
| |
|
| |
| box = frame:expandTemplate{
| |
| title = "Ability_card_v2/UpgradeBox",
| |
| args = {
| |
| cost = UPGRADE_COST_MAP[k],
| |
| description = frame:preprocess(description),
| |
| scale_value = prop.Scale and utils.round_to_sig_fig(prop.Scale.Value, 3),
| |
| scale_type = prop.Scale and prop.Scale.Type,
| |
| fontsize = fontsize
| |
| }
| |
| }
| |
| upgrades_template = upgrades_template .. box .. '\n'
| |
| end
| |
|
| |
| return upgrades_template
| |
| end
| |
| | |
| function create_description(prop, frame)
| |
| local description = ''
| |
| for k, v in pairs(prop) do
| |
| local formatted_value = format_value_with_prepost(k, v, frame)
| |
| local attr_name = lang._get_string(k..'_label')
| |
| description = description .. string.format('%s %s', formatted_value, attr_name)
| |
| end
| |
|
| |
| return description
| |
| end
| |
| | |
| function get_icon(attr_type)
| |
| local mappedAttr = ATTR_TYPE_ICON_MAP[attr_type]
| |
| local img = 'GenericProperty.png'
| |
| local link = ''
| |
| local size = nil
| |
| local color = 'Grey'
| |
| if mappedAttr then
| |
| img = mappedAttr.img
| |
| link = mappedAttr.link
| |
| size = mappedAttr.size
| |
| color = mappedAttr.color or color
| |
| end
| |
|
| |
| return {img=img, link=link, color=color, size=size}
| |
| end | | end |
|
| |
|
Line 305: |
Line 18: |
| if(ability == nil) then return "Ability Not Found" end | | if(ability == nil) then return "Ability Not Found" end |
| return ability.Name | | return ability.Name |
| end
| |
|
| |
| -- Add prefix and postfix labels to a value. Eg. "32" -> "32s"
| |
| function format_value_with_prepost(key, value, frame)
| |
| if (value == nil) then return nil end
| |
|
| |
| local prefix = lang._get_string(string.format("%s_prefix",key))
| |
| local postfix = lang._get_string(string.format("%s_postfix",key))
| |
|
| |
| -- Default pre/post fix to empty string, as they may not exist
| |
| if (prefix == nil) then prefix = '' end
| |
| if (postfix == nil) then postfix = '' end
| |
|
| |
| -- If string ends with 'm', then set the postfix to 'm' and remove it
| |
| if utils.string_endswith(tostring(value), 'm') then
| |
| value = tonumber(value:sub(1, -2))
| |
| postfix = 'm'
| |
| end
| |
|
| |
| if (prefix == '{s:sign}') then
| |
| if value < 0 then
| |
| prefix = '-'
| |
| else
| |
| prefix = '+'
| |
| end
| |
| -- if no prefix on positive value, add a '+'
| |
| else
| |
| if value > 0 then
| |
| prefix = '+'
| |
| end
| |
| end
| |
|
| |
| value_and_uom = frame:expandTemplate{
| |
| title = 'Template:ValueAndUom',
| |
| args = {
| |
| prefix..value,
| |
| postfix,
| |
| uom_style = 'font-size: 12px;'
| |
| }
| |
| }
| |
|
| |
| return value_and_uom
| |
| end | | end |
|
| |
|
Line 372: |
Line 43: |
| end | | end |
| end | | end |
| | |
| | return nil |
| end | | end |
|
| |
|
Line 384: |
Line 57: |
| | | |
| local hyperlink = ability_to_hyperlink(ability_name) | | local hyperlink = ability_to_hyperlink(ability_name) |
| | if (hyperlink == nil) then return "Ability " .. ability_name .. " not found" end |
| | | |
| local icon = "[[File:" .. ability_name .. ".png|link=" .. hyperlink .. "|" .. size .. "px]]" | | local icon = "[[File:" .. ability_name .. ".png|link=" .. hyperlink .. "|" .. size .. "px]]" |
Line 391: |
Line 65: |
| | | |
| return icon .. " " .. link | | return icon .. " " .. link |
| end
| |
|
| |
| function find_width_key(ability)
| |
| for key, value in pairs(ability) do
| |
| if type(key) == "string" and key:sub(-5) == "Width" then
| |
| return key
| |
| end
| |
| end
| |
| return nil
| |
| end
| |
|
| |
| function string_in_list(str, list)
| |
| for _, value in ipairs(list) do
| |
| if value == str then
| |
| return true
| |
| end
| |
| end
| |
| return false
| |
| end | | end |
|
| |
|
| return p | | return p |