Module:Abilities/card: Difference between revisions

mNo edit summary
Added channel time attribute
 
(7 intermediate revisions by the same user not shown)
Line 36: Line 36:
end
end


--{{#invoke:AbilityData|get_ability_card|HERO_NAME|ABILITY_NUM|ADD_LINK|NOTES}}--
--{{#invoke:Abilities/card|get_ability_card|HERO_NAME|ABILITY_NUM|ADD_LINK|NOTES}}--
--Simply calls get_ability_card_from_key with the same parameters, but with key
-- Args:
--get_ability_card and invoke_get_ability_card_key will eventually be removed, and
--   HERO_NAME (required) - Name of the hero that is found in Data:HeroData.json under "Name"
--get_ability_card_from_key will be renamed to get_ability_card
--   ABILITY_NUM (required) - Selects ability at index 1 to 4
--both routes exist temporarily as current hero pages use get_ability_card via hero name
--   ADD_LINK - Add a hyperlink to the title to the associated page
--and im currently testing via hero_key on [[User:Sur/Abrams]]
--   NOTES - User note data to include in the footer of the ability card
--on the final version with fully automated pages, hero_key will be used.
--for now, hero_name can suffice
p.get_ability_card = function(frame)
p.get_ability_card = function(frame)
local hero_name = frame.args[1]
local hero_name = frame.args[1]
Line 51: Line 49:
local hero_key = get_hero_key(hero_name)
local hero_key = get_hero_key(hero_name)
if (hero_key == nil) then return 'Hero with name' .. hero_name .. 'not found' end
return p.get_ability_card_from_key(hero_key, ability_num, add_link, notes)
return build_ability_card(hero_key, ability_num, add_link, notes)
end
end


--from hero key*
-- Pulls data from Data:AbilityCards.json to populate Template:Ability card v2
--notes parameter will eventually be removed, as notes_source_page would be sufficient or could even be determined from within this function
function build_ability_card(hero_key, ability_num, add_link, notes, notes_source_page)
function p.get_ability_card_from_key(hero_key, ability_num, add_link, notes, notes_source_page)
if type(hero_key) == 'table' and hero_key.args then
local frame = hero_key
hero_key = frame.args[1]
ability_num = frame.args[2]
add_link = frame.args[3]
notes = frame.args[4]
notes_source_page = frame.args[5]
end
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  
if(ability == nil) then  
Line 79: Line 68:
if notes_source_page ~= nil and notes ~= "" then
if notes_source_page ~= nil and notes ~= "" then
--Notes comes from a /Notes page, and the notes are not blank
-- Notes comes from a /Notes page, and the notes are not blank
-- Confirm the notes source page exists, otherwise, don't display any notes
-- Confirm the notes source page exists, otherwise, don't display any notes
local title = mw.title.new(notes_source_page)
local title = mw.title.new(notes_source_page)
Line 87: Line 76:
end
end
return mw.getCurrentFrame():expandTemplate{
local frame = mw.getCurrentFrame()
title = "Ability card v2/Card",
args = {
hero_key = hero_key,
ability_num = ability_num,
name = ability_name_localized,
name_link = name_link,
icon = lang.get_string(ability.Key, 'en') .. '.png',
description = mw.getCurrentFrame():preprocess(lang.get_string(ability.DescKey)),
radius = ability.Radius and ability.Radius.Value,
radius_ss = get_attr_ss(ability.Radius),
range = ability.AbilityCastRange and ability.AbilityCastRange.Value,
range_ss = get_attr_ss(ability.AbilityCastRange),
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]),
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),
num_of_charges = ability.AbilityCharges and ability.AbilityCharges.Value,
notes = notes,
notes_source_page = notes_source_page
}
}
end
 
p.get_ability_card_test = 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 hero_key = get_hero_key(hero_name)
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_alt_boxes = get_alt_boxes(hero_key, ability_num, 1)
return get_ability_card_test(hero_key, ability_num, add_link, notes)
if #info1_alt_boxes > 6 then
end
error(#info1_alt_boxes .. ' alt boxes found, but only 6 are supported. Please update Module:Abilities/card and Template:Ability_card_v2')
 
-- Function for sandboxing workshopping potential update of entire ability card generation
function get_ability_card_test(hero_key, ability_num, add_link, notes, notes_source_page)
local ability = utils.get_ability_card_data(hero_key, ability_num)
if(ability == nil) then  
return 'Ability data not found for hero ' ..hero_key.. ' and num ' .. ability_num
end
end
local ability_name_localized = lang.get_string(ability.Key)
local info2_desc = get_info_desc(hero_key, ability_num, 2)
local name_link = nil
local info2_main_boxes = get_main_boxes(hero_key, ability_num, 2)
if add_link == 'true' then
local info2_alt_boxes = get_alt_boxes(hero_key, ability_num, 2)
name_link = ability_name_localized
end
if notes_source_page ~= nil and notes ~= "" then
if #info2_alt_boxes > 6 then
--Notes comes from a /Notes page, and the notes are not blank
error(#info2_alt_boxes .. ' alt boxes found, but only 6 are supported. Please update Module:Abilities/card and Template:Ability_card_v2')
-- Confirm the notes source page exists, otherwise, don't display any notes
local title = mw.title.new(notes_source_page)
if not (title and title.exists) then
notes = ""
end
end
end
local upgrades = get_upgrade_boxes(hero_key, ability_num)
return mw.getCurrentFrame():expandTemplate{
return frame:expandTemplate{
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,
-- Header info defined in various attributes
name = ability_name_localized,
name = ability_name_localized,
name_link = name_link,
name_link = name_link,
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)),
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),
radius_ss = get_attr_ss(ability.Radius),
Line 168: Line 121:
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,
-- Info section #1 defined in "Info1" attribute
info1_desc = info1_desc,
info1_mainbox1 = info1_main_boxes[1],
info1_mainbox2 = info1_main_boxes[2],
info1_mainbox3 = info1_main_boxes[3],
info1_altbox1 =  info1_alt_boxes[1],
info1_altbox2 =  info1_alt_boxes[2],
info1_altbox3 =  info1_alt_boxes[3],
info1_altbox4 =  info1_alt_boxes[4],
info1_altbox5 =  info1_alt_boxes[5],
info1_altbox6 =  info1_alt_boxes[6],
-- Info section #2 defined in "Info2" attribute
info2_desc = info2_desc,
info2_mainbox1 = info2_main_boxes[1],
info2_mainbox2 = info2_main_boxes[2],
info2_mainbox3 = info2_main_boxes[3],
info2_altbox1 =  info2_alt_boxes[1],
info2_altbox2 =  info2_alt_boxes[2],
info2_altbox3 =  info2_alt_boxes[3],
info2_altbox4 =  info2_alt_boxes[4],
info2_altbox5 =  info2_alt_boxes[5],
info2_altbox6 =  info2_alt_boxes[6],
-- Ability upgrades defined in "Upgrades" attribute
upgrade1 = upgrades[1],
upgrade2 = upgrades[2],
upgrade3 = upgrades[3],
-- User-created ability notes
notes = notes,
notes = notes,
notes_source_page = notes_source_page
notes_source_page = notes_source_page
}
}
}
}
end
end


Line 194: Line 178:
return commonutils.round_to_sig_fig(scale.Value, 3)
return commonutils.round_to_sig_fig(scale.Value, 3)
end
--for use from an ability page (ability pages are WIP), not hero pages
function p.write_ability_card_from_ability_key(frame)
local ability_key = frame.args[1]
if ability_key == nil then return "ability_key '" .. ability_key "' not provided" end
-- Determine the hero and ability number
local found_hero_key
local found_ability_num
for hero_key, card_data in pairs(data) do
if found_hero_key == nil or found_ability_num == nil then
for ability_num, ability_data in pairs(card_data) do
if ability_num ~= "Name" then
if ability_data['Key'] == ability_key then
found_hero_key = hero_key
found_ability_num = ability_num
break
end -- hero_key and ability_num found
end
end
end
end
if found_ability_num == nil or found_hero_key == nil then return "ability_key " .. ability_key .. " is not used by any heroes" end
-- Get notes for this ability
local notes_source_page_name = utils.get_notes_source_page_name(ability_key)
local notes_str = frame:preprocess("{{"..notes_source_page_name.."}}")
-- Create the ability card
return p.get_ability_card_from_key(found_hero_key, found_ability_num, true, notes_str, notes_source_page_name)
end
end


-- Get all info sections for specified ability
-- Get the description for an ability's info section
--{{#invoke:AbilityData|get_ability_card|HERO_KEY|ABILITY_NUM}}--
--{{#invoke:AbilityData|get_info_desc|HERO_KEY|ABILITY_NUM|INFO_SECTION_INDEX}}--
p.get_all_info_sections = function(frame)
p.get_info_desc = function(frame)
local hero_key = frame.args[1]
local hero_key = frame.args[1]
local ability_num = frame.args[2]
local ability_num = frame.args[2]
 
local info_section_num = frame.args[3]
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 "Ability Not Found" end
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 output_template = ''
if info_section.DescKey == nil then
for info_section_num=1, 10 do
return ''
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/Card/Info section",
args = {
hero_key = hero_key,
ability_num = ability_num,
info_section_num = info_section_num,
}
}
output_template = output_template .. info_template
end
end
return output_template
return frame:preprocess(lang.get_string(info_section.DescKey))
end
end


-- Get the description for an ability's info section
function get_info_desc(hero_key, ability_num, info_section_num)
--{{#invoke:AbilityData|get_info_desc|HERO_KEY|ABILITY_NUM|INFO_SECTION_INDEX}}--
p.get_info_desc = function(frame)
local hero_key = frame.args[1]
local ability_num = frame.args[2]
local info_section_num = frame.args[3]
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 "Ability Not Found" end
if(ability == nil) then return "Ability Not Found" end
Line 274: Line 213:
end
end
local frame = mw.getCurrentFrame()
return frame:preprocess(lang.get_string(info_section.DescKey))
return frame:preprocess(lang.get_string(info_section.DescKey))
end
end
 
--{{#invoke:AbilityData|get_info_main|HERO_KEY|ABILITY_NUM|INFO_SECTION_INDEX}}--
function get_main_boxes(hero_key, ability_num, info_section_num)
p.get_info_main = function(frame)
local hero_key = frame.args[1]
local ability_num = frame.args[2]
local info_section_num = frame.args[3]
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 "Ability Not Found" end
if(ability == nil) then return "Ability Not Found" end
Line 295: Line 230:
return ''
return ''
end
end
local frame = mw.getCurrentFrame()
local props = info_section.Main.Props
local props = info_section.Main.Props
-- Concatenate multiple section boxes into a single output template
local info_box_template = ''
local main_boxes = {}
for k, prop in pairs(props) do
for k, prop in pairs(props) do
-- Exclude 0 values
-- Exclude 0 values
if prop.Value and prop.Value ~= 0 then
if prop.Value and prop.Value ~= 0 then
local icon = get_icon(prop.Type)
local icon = get_icon(prop.Type)
local main_box = frame:expandTemplate{
section_box = frame:expandTemplate{
title = "Ability_card_v2/Card/MainBox",
title = "Ability_card_v2/Card/MainBox",
args = {
args = {
Line 318: Line 254:
}
}
}
}
info_box_template = info_box_template .. section_box .. '\n'
table.insert(main_boxes, main_box)
end
end
end
end
return info_box_template
return main_boxes
end
end


--{{#invoke:AbilityData|get_info_alt|HERO_KEY|ABILITY_NUM|INFO_SECTION_INDEX}}--
function get_alt_boxes(hero_key, ability_num, info_section_num)
p.get_info_alt = function(frame)
local hero_key = frame.args[1]
local ability_num = frame.args[2]
local info_section_num = frame.args[3]
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 "Ability Not Found" end
if(ability == nil) then return "Ability Not Found" end
Line 344: Line 275:
end
end
-- Concatenate multiple section boxes into a single output template
local frame = mw.getCurrentFrame()
local info_box_template = ''
local alt_boxes = {}
for k, prop in pairs(props) do
for k, prop in pairs(props) do
-- Some props don't have values, as those come from upgrades
-- Some props don't have values, as those come from upgrades
Line 351: Line 284:
if prop.Value and prop.Value ~= 0 then
if prop.Value and prop.Value ~= 0 then
local icon = get_icon(prop.Type)
local icon = get_icon(prop.Type)
section_box = frame:expandTemplate{
local alt_box = frame:expandTemplate{
title = "Ability_card_v2/Card/AltBox",
title = "Ability_card_v2/Card/AltBox",
args = {
args = {
Line 364: Line 297:
}
}
}
}
info_box_template = info_box_template .. section_box .. '\n'
table.insert(alt_boxes, alt_box)
end
end
end
end
return info_box_template
return alt_boxes
end
end


local UPGRADE_COST_MAP = {1, 2, 5}
local UPGRADE_COST_MAP = {1, 2, 5}
--{{#invoke:AbilityData|get_upgrades|HERO_KEY|ABILITY_NUM}}--
function get_upgrade_boxes(hero_key, ability_num)
p.get_upgrades = function(frame)
local hero_key = frame.args[1]
local ability_num = frame.args[2]
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 "Ability Not Found" end
if(ability == nil) then return "Ability Not Found" end
local frame = mw.getCurrentFrame()
local props = ability.Upgrades
local props = ability.Upgrades
-- Concatenate multiple section boxes into a single output template
local upgrade_boxes = {}
local upgrades_template = ''
for k, prop in pairs(props) do
for k, prop in pairs(props) do
local description = lang.get_string(prop.DescKey)
local description = lang.get_string(prop.DescKey)
Line 401: Line 332:
end
end
box = frame:expandTemplate{
local upgrade_box = frame:expandTemplate{
title = "Ability_card_v2/Card/UpgradeBox",
title = "Ability_card_v2/Card/UpgradeBox",
args = {
args = {
Line 411: Line 342:
}
}
}
}
upgrades_template = upgrades_template .. box .. '\n'
table.insert(upgrade_boxes, upgrade_box)
end
end
return upgrades_template
return upgrade_boxes
end
end


Line 460: Line 391:
end
end
return nil
return nil
end
--for use from an ability page (ability pages are WIP), not hero pages
function p.write_ability_card_from_ability_key(frame)
local ability_key = frame.args[1]
if ability_key == nil then return "ability_key '" .. ability_key "' not provided" end
-- Determine the hero and ability number
local found_hero_key
local found_ability_num
for hero_key, card_data in pairs(data) do
if found_hero_key == nil or found_ability_num == nil then
for ability_num, ability_data in pairs(card_data) do
if ability_num ~= "Name" then
if ability_data['Key'] == ability_key then
found_hero_key = hero_key
found_ability_num = ability_num
break
end -- hero_key and ability_num found
end
end
end
end
if found_ability_num == nil or found_hero_key == nil then return "ability_key " .. ability_key .. " is not used by any heroes" end
-- Get notes for this ability
local notes_source_page_name = utils.get_notes_source_page_name(ability_key)
local notes_str = frame:preprocess("{{"..notes_source_page_name.."}}")
-- Create the ability card
return p.get_ability_card_from_key(found_hero_key, found_ability_num, true, notes_str, notes_source_page_name)
end
--from hero key*
--notes parameter will eventually be removed, as notes_source_page would be sufficient or could even be determined from within this function
function p.get_ability_card_from_key(hero_key, ability_num, add_link, notes, notes_source_page)
if type(hero_key) == 'table' and hero_key.args then
local frame = hero_key
hero_key = frame.args[1]
ability_num = frame.args[2]
add_link = frame.args[3]
notes = frame.args[4]
notes_source_page = frame.args[5]
end
local ability = utils.get_ability_card_data(hero_key, ability_num)
if(ability == nil) then
return 'Ability data not found for hero ' ..hero_key.. ' and num ' .. ability_num
end
local ability_name_localized = lang.get_string(ability.Key)
local name_link = nil
if add_link == 'true' then
name_link = ability_name_localized
end
if notes_source_page ~= nil and notes ~= "" then
--Notes comes from a /Notes page, and the notes are not blank
-- Confirm the notes source page exists, otherwise, don't display any notes
local title = mw.title.new(notes_source_page)
if not (title and title.exists) then
notes = ""
end
end
return mw.getCurrentFrame():expandTemplate{
title = "Template:Ability card v2/Card",
args = {
hero_key = hero_key,
ability_num = ability_num,
name = ability_name_localized,
name_link = name_link,
icon = lang.get_string(ability.Key, 'en') .. '.png',
description = mw.getCurrentFrame():preprocess(lang.get_string(ability.DescKey)),
radius = ability.Radius and ability.Radius.Value,
radius_ss = get_attr_ss(ability.Radius),
range = ability.AbilityCastRange and ability.AbilityCastRange.Value,
range_ss = get_attr_ss(ability.AbilityCastRange),
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]),
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),
num_of_charges = ability.AbilityCharges and ability.AbilityCharges.Value,
notes = notes,
notes_source_page = notes_source_page
}
}
end
end


return p
return p