Editing Module:Abilities/cardGive 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 2: | Line 2: | ||
local commonutils = require "Module:Utilities" | local commonutils = require "Module:Utilities" | ||
local utils = require "Module:Abilities/utils" | local utils = require "Module:Abilities/utils" | ||
local p = {} | local p = {} | ||
local data = mw.loadJsonData("Data:AbilityCards.json") | local data = mw.loadJsonData("Data:AbilityCards.json") | ||
-- Maps attr type to an appropriate image and page link | |||
-- Optional icon size, will be defaulted on the template | |||
local ATTR_TYPE_ICON_MAP = { | |||
bullet_armor_up = {img='Bullet_Armor.png', link='Damage_Resistance', color = 'Brown'}, | |||
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', color = 'Brown'}, | |||
healing = {img='Health regen.png', link='Health_Regen', color = 'Green'}, | |||
health = {img='Health.png', link='Health', color = 'Green'}, | |||
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', color = 'Purple'}, | |||
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=''}, | |||
melee_damage = {img='Melee damage.png', link='Melee Damage'}, | |||
cooldown = {img='AttributeIconTechDuration.png', link='Ability Cooldown'}, | |||
combat_barrier = {img='Barrier.png', link='Barrier', color = 'Green'}, | |||
} | |||
function get_hero_key(hero_name) | 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 | |||
return | |||
end | end | ||
| Line 63: | Line 83: | ||
local info1_desc = get_info_desc(hero_key, ability_num, 1) | local info1_desc = get_info_desc(hero_key, ability_num, 1) | ||
local info1_main_boxes = get_main_boxes(hero_key, ability_num, 1) | local info1_main_boxes = get_main_boxes(hero_key, ability_num, 1) | ||
-- Inject Hex Duration only for Rabbit Hex | |||
if ability.Key == "ability_magician_animalhexarea" | |||
and ability.Other | |||
and ability.Other.HexDuration | |||
and ability.Other.HexDuration.Value then | |||
local icon = get_icon("duration") | |||
table.insert(info1_main_boxes, 1, | |||
frame:expandTemplate{ | |||
title = "Ability_card_v2/Card/MainBox", | |||
args = { | |||
key = "HexDuration", | |||
value = ability.Other.HexDuration.Value, | |||
icon = icon.img, | |||
icon_link = icon.link, | |||
icon_color = icon.color, | |||
} | |||
}) | |||
end | |||
local info1_alt_boxes = get_alt_boxes(hero_key, ability_num, 1) | local info1_alt_boxes = get_alt_boxes(hero_key, ability_num, 1) | ||
if #info1_alt_boxes > | if #info1_alt_boxes > 6 then | ||
error(#info1_alt_boxes .. ' alt boxes found, but only | error(#info1_alt_boxes .. ' alt boxes found, but only 6 are supported. Please update Module:Abilities/card and Template:Ability_card_v2') | ||
end | end | ||
| Line 74: | Line 113: | ||
local info2_alt_boxes = get_alt_boxes(hero_key, ability_num, 2) | local info2_alt_boxes = get_alt_boxes(hero_key, ability_num, 2) | ||
if #info2_alt_boxes > | if #info2_alt_boxes > 6 then | ||
error(#info2_alt_boxes .. ' alt boxes found, but only | error(#info2_alt_boxes .. ' alt boxes found, but only 6 are supported. Please update Module:Abilities/card and Template:Ability_card_v2') | ||
end | end | ||
| Line 82: | Line 121: | ||
local info3_alt_boxes = get_alt_boxes(hero_key, ability_num, 3) | local info3_alt_boxes = get_alt_boxes(hero_key, ability_num, 3) | ||
if #info3_alt_boxes > | if #info3_alt_boxes > 6 then | ||
error(#info3_alt_boxes .. ' alt boxes found, but only | error(#info3_alt_boxes .. ' alt boxes found, but only 6 are supported. Please update Module:Abilities/card and Template:Ability_card_v2') | ||
end | end | ||
| Line 91: | Line 130: | ||
title = "Ability_card_v2/Card", | title = "Ability_card_v2/Card", | ||
args = { | args = { | ||
hero_key = hero_key, | hero_key = hero_key, | ||
ability_num = ability_num, | ability_num = ability_num, | ||
| Line 100: | Line 138: | ||
icon = lang.get_string(ability.Key, 'en') .. '.png', | icon = lang.get_string(ability.Key, 'en') .. '.png', | ||
channel_time = ability. | 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), | |||
radius = ability.Radius and ability.Radius.Value, | radius = ability.Radius and ability.Radius.Value, | ||
radius_ss = get_attr_ss(ability.Radius), | |||
range = ability.AbilityCastRange and ability.AbilityCastRange.Value, | range = ability.AbilityCastRange and ability.AbilityCastRange.Value, | ||
range_ss = get_attr_ss(ability.AbilityCastRange), | |||
duration = ability.AbilityDuration and ability.AbilityDuration.Value, | duration = ability.AbilityDuration and ability.AbilityDuration.Value, | ||
duration_ss = get_attr_ss(ability.AbilityDuration), | |||
-- ability_width = format_value_with_prepost(width_key, ability[width_key]), | -- ability_width = format_value_with_prepost(width_key, ability[width_key]), | ||
cooldown =ability.AbilityCooldown and ability.AbilityCooldown.Value, | cooldown =ability.AbilityCooldown and ability.AbilityCooldown.Value, | ||
cooldown_ss = get_attr_ss(ability.AbilityCooldown), | |||
charge_cooldown = ability.AbilityCooldownBetweenCharge and ability.AbilityCooldownBetweenCharge.Value, | |||
charge_cooldown_ss = get_attr_ss(ability.AbilityCooldownBetweenCharge), | |||
charge_cooldown = ability.AbilityCooldownBetweenCharge and ability.AbilityCooldownBetweenCharge.Value | num_of_charges = ability.AbilityCharges and ability.AbilityCharges.Value, | ||
num_of_charges = ability.AbilityCharges and ability.AbilityCharges.Value | |||
-- Info section #1 defined in "Info1" attribute | -- Info section #1 defined in "Info1" attribute | ||
info1_desc = info1_desc, | info1_desc = info1_desc, | ||
info1_mainbox1 = info1_main_boxes[1], | info1_mainbox1 = info1_main_boxes[1], | ||
info1_mainbox2 = info1_main_boxes[2], | info1_mainbox2 = info1_main_boxes[2], | ||
info1_mainbox3 = info1_main_boxes[3], | info1_mainbox3 = info1_main_boxes[3], | ||
info1_altbox1 = info1_alt_boxes[1], | info1_altbox1 = info1_alt_boxes[1], | ||
info1_altbox2 = info1_alt_boxes[2], | info1_altbox2 = info1_alt_boxes[2], | ||
| Line 141: | Line 164: | ||
info1_altbox5 = info1_alt_boxes[5], | info1_altbox5 = info1_alt_boxes[5], | ||
info1_altbox6 = info1_alt_boxes[6], | info1_altbox6 = info1_alt_boxes[6], | ||
-- Info section #2 defined in "Info2" attribute | -- Info section #2 defined in "Info2" attribute | ||
info2_desc = info2_desc, | info2_desc = info2_desc, | ||
info2_mainbox1 = info2_main_boxes[1], | info2_mainbox1 = info2_main_boxes[1], | ||
info2_mainbox2 = info2_main_boxes[2], | info2_mainbox2 = info2_main_boxes[2], | ||
info2_mainbox3 = info2_main_boxes[3], | info2_mainbox3 = info2_main_boxes[3], | ||
info2_altbox1 = info2_alt_boxes[1], | info2_altbox1 = info2_alt_boxes[1], | ||
info2_altbox2 = info2_alt_boxes[2], | info2_altbox2 = info2_alt_boxes[2], | ||
| Line 157: | Line 176: | ||
info2_altbox5 = info2_alt_boxes[5], | info2_altbox5 = info2_alt_boxes[5], | ||
info2_altbox6 = info2_alt_boxes[6], | info2_altbox6 = info2_alt_boxes[6], | ||
-- Info section #3 defined in "Info3" attribute | -- Info section #3 defined in "Info3" attribute | ||
info3_desc = info3_desc, | info3_desc = info3_desc, | ||
info3_mainbox1 = info3_main_boxes[1], | info3_mainbox1 = info3_main_boxes[1], | ||
info3_mainbox2 = info3_main_boxes[2], | info3_mainbox2 = info3_main_boxes[2], | ||
info3_mainbox3 = info3_main_boxes[3], | info3_mainbox3 = info3_main_boxes[3], | ||
info3_altbox1 = info3_alt_boxes[1], | info3_altbox1 = info3_alt_boxes[1], | ||
info3_altbox2 = info3_alt_boxes[2], | info3_altbox2 = info3_alt_boxes[2], | ||
| Line 173: | Line 188: | ||
info3_altbox5 = info3_alt_boxes[5], | info3_altbox5 = info3_alt_boxes[5], | ||
info3_altbox6 = info3_alt_boxes[6], | info3_altbox6 = info3_alt_boxes[6], | ||
-- Ability upgrades defined in "Upgrades" attribute | -- Ability upgrades defined in "Upgrades" attribute | ||
upgrade1 = upgrades[1], | upgrade1 = upgrades[1], | ||
| Line 187: | Line 201: | ||
end | end | ||
-- Get spirit scaling of attribute, return nil if none is found | |||
function get_attr_ss(attr) | |||
if not attr then | |||
return nil | |||
-- | |||
if not attr then | |||
return nil | |||
end | end | ||
local scale = attr.Scale | local scale = attr.Scale | ||
if not scale then | if not scale then | ||
return nil | return nil | ||
end | end | ||
if scale. | if scale.Type ~= 'spirit' then | ||
return nil | return nil | ||
end | end | ||
| Line 255: | Line 220: | ||
end | end | ||
return | return commonutils.round_to_sig_fig(scale.Value, 3) | ||
end | end | ||
| Line 276: | Line 231: | ||
local ability = utils.get_ability_card_data(hero_key, ability_num) | local ability = utils.get_ability_card_data(hero_key, ability_num) | ||
if(ability == nil) then return | 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 316: | Line 271: | ||
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 | ||
local main_boxes = {} | local main_boxes = {} | ||
for k, prop in | for k, prop in pairs(props) do | ||
-- Exclude 0 values | |||
if prop.Value and prop.Value ~= 0 then | |||
-- | local icon = get_icon(prop.Type) | ||
if | local main_box = frame:expandTemplate{ | ||
title = "Ability_card_v2/Card/MainBox", | title = "Ability_card_v2/Card/MainBox", | ||
args = { | args = { | ||
title = prop.Title, | title = prop.Title, | ||
key = prop.Key, | key = prop.Key, | ||
value = | value = prop.Value, | ||
icon = | icon = icon.img, | ||
icon_link = | icon_link = icon.link, | ||
icon_color = | icon_color = icon.color, | ||
icon_size = | icon_size = icon.size, | ||
scale_value = | scale_value = prop.Scale and commonutils.round_to_sig_fig(prop.Scale.Value, 3), | ||
scale_type = | scale_type = prop.Scale and prop.Scale.Type | ||
} | } | ||
} | } | ||
table.insert(main_boxes, main_box) | |||
end | end | ||
end | end | ||
return main_boxes | return main_boxes | ||
end | end | ||
| Line 416: | Line 322: | ||
local alt_boxes = {} | local alt_boxes = {} | ||
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) | |||
local alt_box = frame:expandTemplate{ | |||
title = "Ability_card_v2/Card/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 commonutils.round_to_sig_fig(prop.Scale.Value, 3), | |||
scale_type = prop.Scale and prop.Scale.Type | |||
} | |||
} | |||
table.insert(alt_boxes, alt_box) | |||
end | |||
end | |||
return alt_boxes | return alt_boxes | ||
| Line 452: | Line 348: | ||
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 = utils.get_ability_card_data(hero_key, ability_num) | ||
| Line 468: | Line 354: | ||
local frame = mw.getCurrentFrame() | local frame = mw.getCurrentFrame() | ||
local | local props = ability.Upgrades | ||
local upgrade_boxes = {} | local upgrade_boxes = {} | ||
for k, | for k, prop in pairs(props) do | ||
local description = lang.get_string( | local description = lang.get_string(prop.DescKey) | ||
-- Generate a description if there is no localized string | -- Generate a description if there is no localized string | ||
if (description == nil or description == '' | if (description == nil or description == '') then | ||
description = create_description( | description = create_description(prop, frame) | ||
end | end | ||
-- | -- Vary the font size based on the number of characters to prevent overflow | ||
local fontsize = '1rem' | |||
local | 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 | |||
local upgrade_box = frame:expandTemplate{ | local upgrade_box = frame:expandTemplate{ | ||
title = "Ability_card_v2/Card/UpgradeBox", | title = "Ability_card_v2/Card/UpgradeBox", | ||
args = { | args = { | ||
cost = UPGRADE_COST_MAP[k], | |||
description = frame:preprocess(description), | |||
scale_value = prop.Scale and commonutils.round_to_sig_fig(prop.Scale.Value, 3), | |||
scale_type = prop.Scale and prop.Scale.Type, | |||
fontsize = fontsize | |||
} | } | ||
} | } | ||
| Line 522: | Line 390: | ||
return upgrade_boxes | return upgrade_boxes | ||
end | end | ||
function create_description(prop, frame) | function create_description(prop, frame) | ||
local | local description = '' | ||
local | local first = true | ||
local seen = {} | local seen = {} -- Set to track added combinations | ||
for k, v in pairs(prop) do | for k, v in pairs(prop) do | ||
if | |||
if type(v) ~= 'table' then | |||
local formatted_value = utils.format_value_with_prepost(k, v, frame) | |||
local | local attr_name = lang.get_string(k..'_label') | ||
local | local key = formatted_value .. '|' .. attr_name -- Unique identifier | ||
-- | -- Skip if this combination has already been added | ||
if | if not seen[key] then | ||
if not | -- Add line break if this is not the first item | ||
if not first then | |||
description = description .. '<br>' | |||
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 | ||
end | end | ||
return description | |||
end | |||
p.get_attr_icon = function(frame) | |||
local attr_type = frame.args[1] | |||
local icon = get_icon(attr_type) | |||
return string.format('[[File:%s|%s|18px|link=%s]]', icon.img or '', icon.size or '', icon.link or '') | |||
end | |||
function get_icon(attr_type) | |||
local mappedAttr = ATTR_TYPE_ICON_MAP[attr_type] | |||
local img = 'GenericProperty.png' | |||
local link = '' | |||
local size = '' | |||
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 660: | Line 518: | ||
return mw.getCurrentFrame():expandTemplate{ | return mw.getCurrentFrame():expandTemplate{ | ||
title = "Ability card v2/Card", | title = "Template:Ability card v2/Card", | ||
args = { | args = { | ||
hero_key = hero_key, | hero_key = hero_key, | ||
| Line 668: | Line 526: | ||
icon = lang.get_string(ability.Key, 'en') .. '.png', | icon = lang.get_string(ability.Key, 'en') .. '.png', | ||
description = mw.getCurrentFrame():preprocess(lang.get_string(ability.DescKey)), | description = mw.getCurrentFrame():preprocess(lang.get_string(ability.DescKey)), | ||
radius = ability.Radius and ability.Radius.Value, | radius = ability.Radius and ability.Radius.Value, | ||
radius_ss = get_attr_ss(ability.Radius), | |||
range = ability.AbilityCastRange and ability.AbilityCastRange.Value, | range = ability.AbilityCastRange and ability.AbilityCastRange.Value, | ||
range_ss = get_attr_ss(ability.AbilityCastRange), | |||
duration = ability.AbilityDuration and ability.AbilityDuration.Value, | duration = ability.AbilityDuration and ability.AbilityDuration.Value, | ||
duration_ss = get_attr_ss(ability.AbilityDuration), | |||
-- ability_width = format_value_with_prepost(width_key, ability[width_key]), | -- ability_width = format_value_with_prepost(width_key, ability[width_key]), | ||
cooldown =ability.AbilityCooldown and ability.AbilityCooldown.Value, | cooldown =ability.AbilityCooldown and ability.AbilityCooldown.Value, | ||
cooldown_ss = get_attr_ss(ability.AbilityCooldown), | |||
charge_cooldown = ability.AbilityCooldownBetweenCharge and ability.AbilityCooldownBetweenCharge.Value, | |||
charge_cooldown_ss = get_attr_ss(ability.AbilityCooldownBetweenCharge), | |||
charge_cooldown = ability.AbilityCooldownBetweenCharge | num_of_charges = ability.AbilityCharges and ability.AbilityCharges.Value, | ||
notes = notes, | |||
notes_source_page = notes_source_page | |||
num_of_charges = ability.AbilityCharges and ability.AbilityCharges.Value | |||
} | } | ||
} | } | ||