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 3: | Line 3: | ||
local utils = require "Module:Abilities/utils" | local utils = require "Module:Abilities/utils" | ||
local Icon = require"Module:Abilities/icon" | local Icon = require"Module:Abilities/icon" | ||
local p = {} | local p = {} | ||
| Line 10: | Line 9: | ||
function get_hero_key(hero_name) | function get_hero_key(hero_name) | ||
if hero_name == | if not hero_name or hero_name == "" then return nil end | ||
-- if name starts with "hero_", use it directly as the key | -- if name starts with "hero_", use it directly as the key | ||
if string.sub(hero_name, 1, 5) == "hero_" then return hero_name end | if string.sub(hero_name, 1, 5) == "hero_" then return hero_name end | ||
local resource_lookup = mw.loadJsonData("Data:ResourceLookup.json") | local resource_lookup = mw.loadJsonData("Data:ResourceLookup.json") | ||
return | if not resource_lookup then return nil end | ||
local key = tostring(hero_name):lower() | |||
local entry = resource_lookup[key] | |||
if not entry then | |||
return nil | |||
end | |||
return entry.key | |||
end | end | ||
| Line 63: | Line 71: | ||
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 = Icon.getAttrIcon("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) | ||
| Line 103: | Line 130: | ||
channel_time_scale = get_attr_scale(ability.AbilityChannelTime), | channel_time_scale = get_attr_scale(ability.AbilityChannelTime), | ||
channel_time_scale_type = get_attr_scale_type(ability.AbilityChannelTime), | channel_time_scale_type = get_attr_scale_type(ability.AbilityChannelTime), | ||
radius = ability.Radius and ability.Radius.Value, | radius = ability.Radius and ability.Radius.Value, | ||
radius_scale = get_attr_scale(ability.Radius), | radius_scale = get_attr_scale(ability.Radius), | ||
radius_scale_type = get_attr_scale_type(ability.Radius), | radius_scale_type = get_attr_scale_type(ability.Radius), | ||
range = ability.AbilityCastRange and ability.AbilityCastRange.Value, | range = ability.AbilityCastRange and ability.AbilityCastRange.Value, | ||
range_scale = get_attr_scale(ability.AbilityCastRange), | range_scale = get_attr_scale(ability.AbilityCastRange), | ||
range_scale_type = get_attr_scale_type(ability.AbilityCastRange), | range_scale_type = get_attr_scale_type(ability.AbilityCastRange), | ||
duration = ability.AbilityDuration and ability.AbilityDuration.Value, | duration = ability.AbilityDuration and ability.AbilityDuration.Value, | ||
duration_scale = get_attr_scale(ability.AbilityDuration), | duration_scale = get_attr_scale(ability.AbilityDuration), | ||
duration_scale_type = get_attr_scale_type(ability.AbilityDuration), | duration_scale_type = get_attr_scale_type(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_scale = get_attr_scale(ability.AbilityCooldown), | cooldown_scale = get_attr_scale(ability.AbilityCooldown), | ||
cooldown_scale_type = get_attr_scale_type(ability.AbilityCooldown), | cooldown_scale_type = get_attr_scale_type(ability.AbilityCooldown), | ||
charge_cooldown = ability.AbilityCooldownBetweenCharge and ability.AbilityCooldownBetweenCharge.Value ~= -1 and ability.AbilityCooldownBetweenCharge.Value, | charge_cooldown = ability.AbilityCooldownBetweenCharge and ability.AbilityCooldownBetweenCharge.Value ~= -1 and ability.AbilityCooldownBetweenCharge.Value, | ||
charge_cooldown_scale = get_attr_scale(ability.AbilityCooldownBetweenCharge), | charge_cooldown_scale = get_attr_scale(ability.AbilityCooldownBetweenCharge), | ||
charge_cooldown_scale_type = get_attr_scale_type(ability.AbilityCooldownBetweenCharge), | charge_cooldown_scale_type = get_attr_scale_type(ability.AbilityCooldownBetweenCharge), | ||
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 | ||
| Line 195: | Line 216: | ||
end | end | ||
-- | -- Get spirit scaling of attribute, return nil if none is found | ||
function get_attr_scale(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 | ||
| Line 244: | Line 234: | ||
end | end | ||
function get_attr_scale_type(attr) | function get_attr_scale_type(attr) | ||
local scale = | if not attr then | ||
return nil | |||
end | |||
local scale = attr.Scale | |||
if not scale then | if not scale then | ||
return nil | return nil | ||
| Line 256: | Line 249: | ||
return scale.Type | return scale.Type | ||
end | end | ||
| Line 334: | Line 317: | ||
for k, prop in ipairs(props) do -- use ipairs for ordered iteration | for k, prop in ipairs(props) do -- use ipairs for ordered iteration | ||
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 | ||
if | if prop.Scale and prop.Scale.Type == 'melee' then | ||
local hero = get_hero_data(hero_key) | local hero = get_hero_data(hero_key) | ||
value = prop.Value + hero. | value = prop.Value + hero.LightMeleeDamage * prop.Scale.Value | ||
elseif | elseif prop.Scale and prop.Scale.Type == 'heavy_melee' then | ||
local hero = get_hero_data(hero_key) | local hero = get_hero_data(hero_key) | ||
value = hero. | value = prop.Value + hero.HeavyMeleeDamage * prop.Scale.Value | ||
end | end | ||
| Line 362: | Line 341: | ||
icon_color = icon and icon.color, | icon_color = icon and icon.color, | ||
icon_size = icon and icon.size, | icon_size = icon and 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, | ||
-- allow nil value here as some status effects don't have a value but should not be hidden | -- 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", | hide = value == 0 and "true" or "false", | ||
| Line 379: | Line 358: | ||
icon_color = icon and icon.color, | icon_color = icon and icon.color, | ||
icon_size = icon and icon.size, | icon_size = icon and 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, | ||
hide = (value == nil or value == 0) and "true" or "false", | hide = (value == nil or value == 0) and "true" or "false", | ||
} | } | ||
| Line 416: | Line 395: | ||
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 then | |||
local icon = Icon.getAttrIcon(prop.Type) | |||
local alt_box = frame:expandTemplate{ | |||
title = "Ability_card_v2/Card/AltBox", | |||
args = { | |||
key = prop.Key, | |||
value = prop.Value, | |||
icon = icon and icon.img, | |||
icon_link = icon and icon.link, | |||
icon_color = icon and icon.color, | |||
icon_size = icon and 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 = prop.Value == 0 and "true" or "false", | |||
} | |||
} | |||
table.insert(alt_boxes, alt_box) | |||
end | |||
end | |||
return alt_boxes | return alt_boxes | ||
| Line 452: | Line 422: | ||
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 471: | Line 431: | ||
local upgrade_boxes = {} | local upgrade_boxes = {} | ||
for k, upgrade in | for k, upgrade in pairs(upgrades) do | ||
local description = lang.get_string(upgrade.DescKey) | local description = lang.get_string(upgrade.DescKey) | ||
local desc_length = description and #description or 0 | |||
-- bypass some keys if they are mistakenly left in game files | -- bypass some keys if they are mistakenly left in game files | ||
| Line 492: | Line 453: | ||
end | end | ||
-- | -- Vary the font size based on the number of characters to prevent overflow | ||
local fontsize = '1rem' | |||
local | if desc_length > 30 and desc_length < 51 then | ||
fontsize = '0.9rem' | |||
elseif desc_length > 50 and desc_length < 71 then | |||
fontsize = '0.8rem' | |||
elseif desc_length > 70 then | |||
fontsize = '0.7rem' | |||
end | |||
local upgrade_box = frame:expandTemplate{ | local upgrade_box = frame:expandTemplate{ | ||
title = "Ability_card_v2/Card/UpgradeBox", | title = "Ability_card_v2/Card/UpgradeBox", | ||
| Line 508: | Line 468: | ||
index = k, | index = k, | ||
cost = UPGRADE_COST_MAP[k], | cost = UPGRADE_COST_MAP[k], | ||
description = | description = frame:preprocess(description), | ||
scale_value = | scale_value = upgrade.Scale and commonutils.round_to_sig_fig(upgrade.Scale.Value, 3), | ||
scale_type = | scale_type = upgrade.Scale and upgrade.Scale.Type, | ||
fontsize = fontsize | |||
fontsize = | |||
} | } | ||
} | } | ||
| Line 525: | Line 482: | ||
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 | local value | ||
if type(v) == 'table' then | |||
value = v.Value | |||
else | |||
value = v | |||
end | |||
local formatted_value = utils.format_value_with_prepost(k, value, frame) | |||
local attr_name = lang.get_string(k..'_label') | |||
local key = formatted_value .. '|' .. attr_name -- Unique identifier | |||
-- skip DescKey for the edge case where we are generating description instead of using localization files | |||
if k ~= 'DescKey' then | |||
-- Skip if this combination has already been added | |||
if not seen[key] then | |||
-- 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 | ||
return description | |||
return | |||
end | end | ||
| Line 668: | Line 599: | ||
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_scale = get_attr_scale(ability.Radius), | radius_scale = get_attr_scale(ability.Radius), | ||
radius_scale_type = get_attr_scale_type(ability.Radius), | radius_scale_type = get_attr_scale_type(ability.Radius), | ||
range = ability.AbilityCastRange and ability.AbilityCastRange.Value, | range = ability.AbilityCastRange and ability.AbilityCastRange.Value, | ||
range_scale = get_attr_scale(ability.AbilityCastRange), | range_scale = get_attr_scale(ability.AbilityCastRange), | ||
range_scale_type = get_attr_scale_type(ability.AbilityCastRange), | range_scale_type = get_attr_scale_type(ability.AbilityCastRange), | ||
duration = ability.AbilityDuration and ability.AbilityDuration.Value, | duration = ability.AbilityDuration and ability.AbilityDuration.Value, | ||
duration_scale = get_attr_scale(ability.AbilityDuration), | duration_scale = get_attr_scale(ability.AbilityDuration), | ||
duration_scale_type = get_attr_scale_type(ability.AbilityDuration), | duration_scale_type = get_attr_scale_type(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_scale = get_attr_scale(ability.AbilityCooldown), | cooldown_scale = get_attr_scale(ability.AbilityCooldown), | ||
cooldown_scale_type = get_attr_scale_type(ability.AbilityCooldown), | cooldown_scale_type = get_attr_scale_type(ability.AbilityCooldown), | ||
charge_cooldown = ability.AbilityCooldownBetweenCharge and ability.AbilityCooldownBetweenCharge.Value, | |||
charge_cooldown = ability.AbilityCooldownBetweenCharge | |||
charge_cooldown_scale = get_attr_scale(ability.AbilityCooldownBetweenCharge), | charge_cooldown_scale = get_attr_scale(ability.AbilityCooldownBetweenCharge), | ||
charge_cooldown_scale_type = get_attr_scale_type(ability.AbilityCooldownBetweenCharge), | charge_cooldown_scale_type = get_attr_scale_type(ability.AbilityCooldownBetweenCharge), | ||
num_of_charges = ability.AbilityCharges and ability.AbilityCharges.Value, | |||
num_of_charges = ability.AbilityCharges and ability.AbilityCharges.Value | notes = notes, | ||
notes_source_page = notes_source_page, | |||
} | } | ||
} | } | ||