Editing Module:Abilities-test/card

Jump to navigation Jump to search
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 4: Line 4:


local p = {}
local p = {}
local data = mw.loadJsonData("Data:AbilityCards.json")
local data = mw.loadJsonData("User:Saag/AbilityCards.json")


-- Maps attr type to an appropriate image and page link
-- Maps attr type to an appropriate image and page link
Line 12: Line 12:
bullet_armor_down = {img='Bullet_Armor.png', link='Damage_Resistance', color = 'NoColor'},
bullet_armor_down = {img='Bullet_Armor.png', link='Damage_Resistance', color = 'NoColor'},
cast = {img='AttributeIconMaxChargesIncrease.png', link=''},
cast = {img='AttributeIconMaxChargesIncrease.png', link=''},
charges = {img='AttributeIconMaxChargesIncrease.png', link='', color = 'Purple'},
charges = {img='AttributeIconMaxChargesIncrease.png', link=''},
damage = {img='Damage_heart.png', link='', color = 'NoColor'}, -- 'NoColor' will apply no icon color and use the original image
damage = {img='Damage_heart.png', link='', color = 'NoColor'}, -- 'NoColor' will apply no icon color and use the original image
bullet_damage = {img='Bullet_damage.png', link='Bullet_Damage', color = 'NoColor'},
bullet_damage = {img='Bullet_damage.png', link='Bullet_Damage', color = 'NoColor'},
Line 19: Line 19:
health = {img='Health.png', link='Health', color = 'Green'},
health = {img='Health.png', link='Health', color = 'Green'},
move_speed = {img='Move speed.png', link='Move Speed', color = 'Green'},
move_speed = {img='Move speed.png', link='Move Speed', color = 'Green'},
range = {img='CastRange.png', link='Ability_Range', color = 'Purple'},
range = {img='CastRange.png', link='Ability_Range'},
radius = {img='CastRange.png', link='Ability_Range', color = 'Purple'},
tech_armor_up = {img='Spirit_Armor.png', link='Damage_Resistance', color = 'NoColor'},
tech_armor_up = {img='Spirit_Armor.png', link='Damage_Resistance', color = 'NoColor'},
tech_damage = {img='AttributeIconTechShieldHealth.png', link='Spirit_Damage', color = 'NoColor',size = '12px'},
tech_damage = {img='AttributeIconTechShieldHealth.png', link='Spirit_Damage', color = 'NoColor',size = '12px'},
distance = {img='AttributeIconTechRange.png', link='Ability_Range'},
distance = {img='AttributeIconTechRange.png', link='Ability_Range'},
duration = {img='AttributeIconTechDuration.png', link='Ability Duration', color = 'Purple'},
duration = {img='AttributeIconTechDuration.png', link='Ability Duration'},
slow = {img='MoveSlow.png', link='', color = 'Purple'},
slow = {img='MoveSlow.png', link=''},
melee_damage = {img='Melee damage.png', link='Melee Damage'},
melee_damage = {img='Melee damage.png', link='Melee Damage'},
cooldown = {img='AttributeIconTechDuration.png', link='Ability Cooldown'},
cooldown = {img='AttributeIconTechDuration.png', link='Ability Cooldown'},
combat_barrier = {img='Barrier.png', link='Barrier', color = 'Green'},
combat_barrier = {img='Barrier.png', link='Barrier', color = 'Green'},
time = {img='AttributeIconTechDuration.png', link='Ability Duration', color = 'Purple'},
}
}


-- TODO - replace this with utils file
-- TODO - replace this with utils file
function utils.get_ability_card_data(hero_key, ability_num)
function get_ability_card_data(hero_key, ability_num)
if(hero_key == nil) then return nil end
if(hero_key == nil) then return nil end
return data[hero_key][tonumber(ability_num)]
return data[hero_key][tonumber(ability_num)]
Line 40: Line 38:


function get_hero_key(hero_name)
function get_hero_key(hero_name)
if hero_name == nil then return nil end
-- if name starts with "hero_", use it directly as the key
if string.sub(hero_name, 1, 5) == "hero_" then return hero_name end
for i, hero in pairs(data) do
for i, hero in pairs(data) do
if hero["Name"] == hero_name then
if hero["Name"] == hero_name then
Line 73: Line 66:
-- Pulls data from Data:AbilityCards.json to populate Template:Ability card v2
-- Pulls data from Data:AbilityCards.json to populate Template:Ability card v2
function build_ability_card(hero_key, ability_num, add_link, notes, notes_source_page)
function build_ability_card(hero_key, ability_num, add_link, notes, notes_source_page)
local ability = utils.get_ability_card_data(hero_key, ability_num)
local ability = get_ability_card_data(hero_key, ability_num)
if(ability == nil) then  
if(ability == nil) then  
return 'Ability data not found for hero ' ..hero_key.. ' and num ' .. ability_num
return 'Ability data not found for hero ' ..hero_key.. ' and num ' .. ability_num
Line 153: Line 146:
icon = lang.get_string(ability.Key, 'en') .. '.png',
icon = lang.get_string(ability.Key, 'en') .. '.png',
channel_time = ability.Cast and ability.Cast.AbilityChannelTime and ability.Cast.AbilityChannelTime.Value ~= 9999 and ability.Cast.AbilityChannelTime.Value,
channel_time = ability.Cast and ability.Cast.AbilityChannelTime and ability.Cast.AbilityChannelTime.Value,
channel_time_ss = ability.Cast and get_attr_ss(ability.Cast.AbilityChannelTime),
channel_time_ss = ability.Cast and get_attr_ss(ability.Cast.AbilityChannelTime),
radius = ability.Radius and ability.Radius.Value,
radius = ability.Radius and ability.Radius.Value,
Line 164: Line 157:
cooldown =ability.AbilityCooldown and ability.AbilityCooldown.Value,
cooldown =ability.AbilityCooldown and ability.AbilityCooldown.Value,
cooldown_ss = get_attr_ss(ability.AbilityCooldown),
cooldown_ss = get_attr_ss(ability.AbilityCooldown),
charge_cooldown = ability.AbilityCooldownBetweenCharge and ability.AbilityCooldownBetweenCharge.Value ~= -1 and ability.AbilityCooldownBetweenCharge.Value,
charge_cooldown = ability.AbilityCooldownBetweenCharge and ability.AbilityCooldownBetweenCharge.Value,
charge_cooldown_ss = get_attr_ss(ability.AbilityCooldownBetweenCharge),
charge_cooldown_ss = get_attr_ss(ability.AbilityCooldownBetweenCharge),
num_of_charges = ability.AbilityCharges and ability.AbilityCharges.Value,
num_of_charges = ability.AbilityCharges and ability.AbilityCharges.Value,
Line 262: Line 255:
local info_section_num = frame.args[3]
local info_section_num = frame.args[3]
local ability = utils.get_ability_card_data(hero_key, ability_num)
local ability = get_ability_card_data(hero_key, ability_num)
if(ability == nil) then return {} end -- return empty table, not string
if(ability == nil) then return "Ability Not Found" end
local info_section = ability['Info'..info_section_num]
local info_section = ability['Info'..info_section_num]
Line 277: Line 270:


function get_info_desc(hero_key, ability_num, info_section_num)
function get_info_desc(hero_key, ability_num, info_section_num)
local ability = utils.get_ability_card_data(hero_key, ability_num)
local ability = get_ability_card_data(hero_key, ability_num)
if(ability == nil) then return "Ability Not Found" end
if(ability == nil) then return "Ability Not Found" end
local info_section = ability['Info'..info_section_num]
local info_section = ability['Info'..info_section_num]
Line 293: Line 286:


function get_main_boxes(hero_key, ability_num, info_section_num)
function get_main_boxes(hero_key, ability_num, info_section_num)
local ability = utils.get_ability_card_data(hero_key, ability_num)
local ability = get_ability_card_data(hero_key, ability_num)
if(ability == nil) then return "Ability Not Found" end
if(ability == nil) then return "Ability Not Found" end
Line 303: Line 296:
local main = info_section.Main
local main = info_section.Main
if main == nil then
if main == nil then
return {}
return ''
end
end
local frame = mw.getCurrentFrame()
local frame = mw.getCurrentFrame()
local props = {}
local props = info_section.Main.Props
if props == nil then
-- Start with the standard Props array
return ''
if main.Props then
for _, prop in ipairs(main.Props) do
table.insert(props, prop)
end
end
end
local main_boxes = {}
local main_boxes = {}
for k, prop in ipairs(props) do -- use ipairs for ordered iteration
for k, prop in pairs(props) do
local value = prop.Value
local value = prop.Value
-- If it scales with melee damage, set the value using the hero's base melee to match in game visuals
-- If it scales with melee damage, set the value using the hero's base melee to match in game visuals
Line 328: Line 316:
local icon = get_icon(prop.Type)
local icon = get_icon(prop.Type)
local main_box = frame:expandTemplate{
local main_box
title = "User:Saag/Sandbox/Ability_card_v2/Card/MainBox",
if prop.StatusEffect then
args = {
main_box = frame:expandTemplate{
title = prop.Title,
title = "User:Saag/Sandbox/Ability_card_v2/Card/StatusBox",
key = prop.Key,
args = {
value = value,
title = prop.Title,
icon = icon.img,
key = prop.Key,
icon_link = icon.link,
value = value,
icon_color = icon.color,
status_effect = prop.StatusEffect,
icon_size = icon.size,
icon = icon.img,
scale_value = prop.Scale and commonutils.round_to_sig_fig(prop.Scale.Value, 3),
icon_link = icon.link,
scale_type =  prop.Scale and prop.Scale.Type,
icon_color = icon.color,
hide = (value == nil or value == 0) and "true" or "false",
icon_size = icon.size,
scale_value = prop.Scale and commonutils.round_to_sig_fig(prop.Scale.Value, 3),
scale_type =  prop.Scale and prop.Scale.Type,
-- allow nil value here as some status effects don't have a value but should not be hidden
hide = value == 0 and "true" or "false",
}
}
}
else
}
main_box = frame:expandTemplate{
title = "User:Saag/Sandbox/Ability_card_v2/Card/MainBox",
args = {
title = prop.Title,
key = prop.Key,
value = value,
icon = icon.img,
icon_link = icon.link,
icon_color = icon.color,
icon_size = icon.size,
scale_value = prop.Scale and commonutils.round_to_sig_fig(prop.Scale.Value, 3),
scale_type =  prop.Scale and prop.Scale.Type,
hide = (value == nil or value == 0) and "true" or "false",
}
}
end
table.insert(main_boxes, main_box)
table.insert(main_boxes, main_box)
end
end
Line 379: Line 345:


function get_alt_boxes(hero_key, ability_num, info_section_num)
function get_alt_boxes(hero_key, ability_num, info_section_num)
local ability = utils.get_ability_card_data(hero_key, ability_num)
local ability = get_ability_card_data(hero_key, ability_num)
if(ability == nil) then return "Ability Not Found" end
if(ability == nil) then return "Ability Not Found" end
Line 424: Line 390:
local UPGRADE_COST_MAP = {1, 2, 5}
local UPGRADE_COST_MAP = {1, 2, 5}
function get_upgrade_boxes(hero_key, ability_num)
function get_upgrade_boxes(hero_key, ability_num)
local ability = utils.get_ability_card_data(hero_key, ability_num)
local ability = get_ability_card_data(hero_key, ability_num)
if(ability == nil) then return "Ability Not Found" end
if(ability == nil) then return "Ability Not Found" end
local frame = mw.getCurrentFrame()
local frame = mw.getCurrentFrame()


local upgrades = ability.Upgrades
local props = ability.Upgrades
local upgrade_boxes = {}
local upgrade_boxes = {}
for k, upgrade in pairs(upgrades) do
for k, prop in pairs(props) do
local description = lang.get_string(upgrade.DescKey)
local description = lang.get_string(prop.DescKey)
 
-- bypass some keys if they are mistakenly left in game files
local IGNORE_DESC_KEYS = {'citadel_ability_hornet_snipe_t3_desc', 'ability_fencer_ultimate_t3_desc'}
-- Generate a description if there is no localized string
-- Generate a description if there is no localized string
if (description == nil or description == '' or commonutils.contains(IGNORE_DESC_KEYS, upgrade.DescKey)) then
if (description == nil or description == '') then
description = create_description(upgrade, frame)
description = create_description(prop, frame)
else
-- Replace embedded value placeholders with just the base value
-- Pattern: {'Value': X, 'Scale': {...}} -> X
description = description:gsub("{'Value':%s*([%d%.%-]+),%s*'Scale':%s*{[^}]+}}", function(value)
return commonutils.round_to_sig_fig(tonumber(value), 3)
end)
-- Pattern: {'Value': X} -> X
description = description:gsub("{'Value':%s*([%d%.%-]+)}", function(value)
return commonutils.round_to_sig_fig(tonumber(value), 3)
end)
end
end
Line 466: Line 419:
title = "User:Saag/Sandbox/Ability_card_v2/Card/UpgradeBox",
title = "User:Saag/Sandbox/Ability_card_v2/Card/UpgradeBox",
args = {
args = {
index = k,
  cost = UPGRADE_COST_MAP[k],
cost = UPGRADE_COST_MAP[k],
  description = frame:preprocess(description),
description = frame:preprocess(description),
  scale_value = prop.Scale and commonutils.round_to_sig_fig(prop.Scale.Value, 3),
scale_value = upgrade.Scale and commonutils.round_to_sig_fig(upgrade.Scale.Value, 3),
  scale_type =  prop.Scale and prop.Scale.Type,
scale_type =  upgrade.Scale and upgrade.Scale.Type,
  fontsize = fontsize
fontsize = fontsize
}
}
}
}
Line 479: Line 431:
return upgrade_boxes
return upgrade_boxes
end
end


function create_description(prop, frame)
function create_description(prop, frame)
Line 487: Line 438:


     for k, v in pairs(prop) do
     for k, v in pairs(prop) do
     local value
    
         if type(v) == 'table' then
         if type(v) ~= 'table' then
        value = v.Value
            local formatted_value = utils.format_value_with_prepost(k, v, frame)
        else
            local attr_name = lang.get_string(k..'_label')
        value = v
            local key = formatted_value .. '|' .. attr_name  -- Unique identifier
    end
 
   
            -- Skip if this combination has already been added
        local formatted_value = utils.format_value_with_prepost(k, value, frame)
            if not seen[key] then
        local attr_name = lang.get_string(k..'_label')
            -- Add line break if this is not the first item
        local key = formatted_value .. '|' .. attr_name  -- Unique identifier
                if not first then
                  description = description .. '<br>'
-- skip DescKey for the edge case where we are generating description instead of using localization files
                end
if k ~= 'DescKey' then
 
        -- Skip if this combination has already been added
            description = description .. string.format('%s %s', formatted_value, attr_name)
        if not seen[key] then
            first = false
        -- Add line break if this is not the first item
            seen[key] = true  -- Mark this combination as added
            if not first then
           
              description = description .. '<br>'
            end
            end
        end
        description = description .. string.format('%s %s', formatted_value, attr_name)
        first = false
        seen[key] = true  -- Mark this combination as added
         end
         end
     end
     end
Line 535: Line 480:
size = mappedAttr.size
size = mappedAttr.size
color = mappedAttr.color or color
color = mappedAttr.color or color
end
end
return {img=img, link=link, color=color, size=size}
return {img=img, link=link, color=color, size=size}
Line 593: Line 538:
end
end
local ability = utils.get_ability_card_data(hero_key, ability_num)
local ability = get_ability_card_data(hero_key, ability_num)
if(ability == nil) then  
if(ability == nil) then  
return 'Ability data not found for hero ' ..hero_key.. ' and num ' .. ability_num
return 'Ability data not found for hero ' ..hero_key.. ' and num ' .. ability_num
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: