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 = require("Module:Icon/attr") | |||
-- List of scaling type attributes | |||
local scalingTypes = { | |||
["spirit"] = { class = "spirit", icon = "[[File:Spirit scaling.png|link=Spirit Power#Spirit Power Scaling|{{{icon_size|40px}}}]]" }, | |||
["duration"] = { class = "spirit", icon = "[[File:Spirit scaling.png|link=Spirit Power#Spirit Power Scaling|{{{icon_size|40px}}}]]" }, | |||
["stats_count"] = { class = "spirit", icon = "[[File:Spirit scaling.png|link=Spirit Power#Spirit Power Scaling|{{{icon_size|40px}}}]]" }, | |||
["weapon_power"] = { class = "weapon", icon = "[[File:Weapon scaling.png|link=Weapon Damage#Weapon Damage Scaling|{{{icon_size|40px}}}]]" }, | |||
["weapon_damage_increase"] = { class = "weapon", icon = "[[File:Weapon scaling.png|link=Weapon Damage#Weapon Damage Scaling|{{{icon_size|40px}}}]]" }, | |||
["melee"] = { class = "weapon", icon = "[[File:Melee scaling.png|link=Melee Damage#Abilities|{{{icon_size|40px}}}]]" }, | |||
["heavy_melee"] = { class = "weapon", icon = "[[File:Melee scaling.png|link=Melee Damage#Abilities|{{{icon_size|40px}}}]]" }, | |||
["power_increase"] = { class = "boon", icon = "[[File:Boon scaling.png|link=Boon|{{{icon_size|25px}}}]]" }, | |||
} | |||
-- List of get scaling attribute | |||
function p.get_scalar(frame) | |||
local args = frame.args | |||
local scaling = args[1] -- first parameter | |||
local attribute = args[2] -- second parameter | |||
local scaling = scalingTypes[scaling] | |||
if scaling then | |||
return scaling[attribute] or "" | |||
else | |||
return "{{Tooltip|?|Missing scaling type in Module:Abilities/card}}" | |||
end | |||
return "" | |||
end | |||
function get_hero_key(hero_name) | function get_hero_key(hero_name) | ||
| Line 63: | Line 94: | ||
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) | ||
| Line 103: | Line 153: | ||
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 239: | ||
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 257: | ||
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 272: | ||
return scale.Type | return scale.Type | ||
end | end | ||
| Line 334: | Line 340: | ||
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.LightMeleeDamage * | 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 = prop.Value + hero.HeavyMeleeDamage * | value = prop.Value + hero.HeavyMeleeDamage * prop.Scale.Value | ||
end | end | ||
local icon = | local icon = get_icon(prop.Type) | ||
local main_box | local main_box | ||
| Line 362: | Line 364: | ||
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 381: | ||
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 418: | ||
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 = get_icon(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 445: | ||
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 454: | ||
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 476: | ||
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 491: | ||
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 505: | ||
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 | |||
end | |||
p.get_attr_icon = function(frame) | |||
local attr_type = frame.args[1] | |||
local icon = get_icon(attr_type) | |||
if icon == nil then | |||
return '' | |||
end | |||
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 = nil | |||
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 | |||
if img == nil then | |||
return nil | |||
end | |||
return {img=img, link=link, color=color, size=size} | |||
end | end | ||
| Line 668: | Line 654: | ||
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, | |||
} | } | ||
} | } | ||