Module:HeroData/nav: Difference between revisions

Sur (talk | contribs)
m parameterize text size and card size
3D model function
 
(42 intermediate revisions by 8 users not shown)
Line 1: Line 1:
local p = {}
local p = {}
local heroes_data = mw.loadJsonData("Data:HeroData.json")
local heroes_data = mw.loadJsonData("Data:HeroData.json")
local hero_release_module = require('Module:HeroData/release')
local lang_module = require('Module:Lang')
local lang_module = require('Module:Lang')
local utilities = require('Module:Utilities')


-- for [[Template:Hero Navbox]] on /Heroes, i.e. {{Hero Card Nav|Hero=Abrams}} {{Hero Card Nav|Hero=Bebop}}
-- Cache to store results of get_heroes if called multiple times in one page render
local heroes_cache = {}
 
-- Shared helper function
local function get_heroes(in_herolabs)
    -- Return cached result if it exists
    if heroes_cache[in_herolabs] then
        return heroes_cache[in_herolabs]
    end
 
    local heroes = {}
 
    for hero_key, hero_data in pairs(heroes_data) do
        -- hero_werewolf_transformed is consolidated in Silver's page
        if hero_data["Name"] ~= nil and hero_key ~= 'hero_werewolf_transformed' then
 
            local this_hero_status = hero_release_module.get_hero_release_status(hero_key)
 
            if ((in_herolabs == 'true' and this_hero_status == 'HeroLabs') or
                (in_herolabs == 'false' and this_hero_status == 'Released')) then
 
                local is_recommended = hero_data['IsRecommended'] or false
 
                --- Create a sort key for each hero to ensure correct alphabetical ordering.
                local hero_name = lang_module.get_string(hero_key, nil, 'en')
                local sort_key_to_find = hero_key .. '_sort'
                local potential_sort_key = lang_module.get_string(sort_key_to_find, nil, 'en')
 
                local sort_key
                -- Detect translation failure if the returned string contains the original search key
                if string.find(potential_sort_key, sort_key_to_find, 1, true) then
                    sort_key = hero_name
                else
                    sort_key = potential_sort_key
                end
 
                -- NOTE: Check if lang_module.get_string(hero_key, 'en') returns the same value as hero_name.
                -- If the second argument defaults to nil natively, you can optimize further by setting: link = hero_name
                local hero_link = lang_module.get_string(hero_key, 'en')
 
                -- Store reusable hero data
                local hero = {
                    key = hero_key,
                    name = hero_name,
                    sort_key = sort_key,
                    link = hero_link,
                    recommended = tostring(is_recommended)
                }
 
                table.insert(heroes, hero)
            end
        end
    end
 
    -- Sort heroes
    table.sort(heroes, function(a, b)
        return a.sort_key < b.sort_key
    end)
 
    heroes_cache[in_herolabs] = heroes
    return heroes
end
 
-- for [[Template:Deadlock_Wiki/Heroes]]
function p.get_hero_nav_cards(frame)
function p.get_hero_nav_cards(frame)
local current_or_upcoming = frame.args[1]
    local text_size = frame.args['text_size']
if current_or_upcoming ~= 'Current' and current_or_upcoming ~= 'Upcoming' then
    local card_size = frame.args['card_size']
return 'First parameter must be Current or Upcoming'
    local in_herolabs = frame.args['in_herolabs'] or 'false'
end
    local debug_mode = frame.args['debug_mode'] == 'true'
 
local heroes = {}
    local heroes = get_heroes(in_herolabs)
for hero_key, hero_data in pairs(heroes_data) do
    local parts = {}
if hero_data["Name"] ~= nil and hero_data["IsDisabled"] == false then
 
if (hero_data["InDevelopment"] == false and current_or_upcoming == 'Current' or hero_data["InDevelopment"] == true and current_or_upcoming == 'Upcoming') then
    for _, hero in ipairs(heroes) do
table.insert(heroes, lang_module.get_string(hero_key))
        table.insert(parts, string.format('{{Hero card2|heroName=%s|cardSize=%s|textSize=%s|isHeroLabs=%s}}',
end
            hero.link, card_size, text_size, in_herolabs))
end
    end
end
 
    local ret = table.concat(parts)
--Order list alphabetically
 
table.sort(heroes) --O(nlogn)
    if debug_mode then
        return ret
--Add each item to output
    else
local ret = ''
        return frame:preprocess(ret)
for index, hero_name in ipairs(heroes) do
    end
ret = ret .. '{{Hero Card Nav|Hero=' .. hero_name .. '}} '
end
--Remove the last space
ret = string.sub(ret, 1, -(string.len(' '))-1)
return frame:preprocess(ret)
end
end


-- for [[Template:Deadlock_Wiki/Heroes]] on home page, i.e. [[Template:Hero card2]]
-- for [[Template:Roster]]
function p.get_hero_nav_cards_homepage(frame)
function p.get_hero_roster(frame)
--true or false
    local in_herolabs = frame.args['in_herolabs'] or 'false'
local in_herolabs = frame.args[1]
    local debug_mode = frame.args['debug_mode'] == 'true'
local text_size = frame.args[2]
local card_size = frame.args[3]


if in_herolabs ~= 'true' and in_herolabs ~= 'false' then
    local heroes = get_heroes(in_herolabs)
return 'in_herolabs must be either true or false as the first unnamed parameter'
    local parts = {}
end
 
if text_size == nil then text_size = 20 end
    for _, hero in ipairs(heroes) do
if card_size == nil then card_size = 132 end
        table.insert(parts, string.format('{{HeroRosterCard|name=%s|key=%s}}', hero.name, hero.key))
    end
--Iterate heroes
 
local heroes = {}
    local ret = table.concat(parts)
for hero_key, hero_data in pairs(heroes_data) do
 
if hero_data["Name"] ~= nil then
    if debug_mode then
-- if herolabs is requested, only needs to have herolabs=true
        return ret
-- otherwise, needs to be not disabled, in development, nd herolabs is nil or false
    else
if ((in_herolabs == 'true' and hero_data['InHeroLabs']) or
        return frame:preprocess(ret)
(in_herolabs == 'false' and not hero_data['IsDisabled'] and not hero_data['InDevelopment'] and (hero_data['InHeroLabs'] == nil or not hero_data['InHeroLabs']))) then
    end
end
local is_recommended = hero_data['Recommended']
 
if is_recommended == nil then
-- for [[Template:Quotes Navbox]] etc.
is_recommended = false
p.get_hero_bulletpoints = function(frame)
end
    local subpage = frame.args['1']
    local in_herolabs = frame.args['in_herolabs'] or 'false'
local hero_str = lang_module.get_string(hero_key) .. '|recommended=' .. tostring(is_recommended)
    local debug_mode = frame.args['debug_mode'] == 'true'
    local no_redlinks = frame.args['no_redlinks'] == 'true'
table.insert(heroes, hero_str)
 
end
    local heroes = get_heroes(in_herolabs)
end
    local parts = {}
end
 
    for _, hero in ipairs(heroes) do
--Order list alphabetically
        -- Lua optimization: clean ternary fallback for page_title assignment
table.sort(heroes) --O(nlogn)
        local page_title = subpage and (hero.link .. '/' .. subpage) or hero.name
 
--Add each item to output
        -- Skip redlinks entirely when enabled
local ret = ''
        if not (no_redlinks and not utilities.page_exists(page_title)) then
for index, hero_name in ipairs(heroes) do
            local item
ret = ret .. '{{Hero_card2|name=' .. hero_name
            if subpage then
ret = ret .. '|text_size=' .. text_size
                item = string.format('{{PageRef|%s|alt_link=%s}}', hero.link, page_title)
ret = ret .. '|herolabs=' .. in_herolabs
            else
ret = ret .. '|card_size=' .. card_size
                item = string.format('{{HeroIcon|%s}}', hero.link)
ret = ret .. '}} '
            end
end
            table.insert(parts, item)
        end
--Remove the last space
    end
ret = string.sub(ret, 1, -(string.len(' '))-1)
 
    local ret = table.concat(parts, ' &bull; ')
return frame:preprocess(ret)
 
    if debug_mode then
        return ret
    else
        return frame:preprocess(ret)
    end
end
 
-- for image galleries
p.get_hero_gallery = function(frame)
    local file_name = frame.args['1'] or ''
    local description = frame.args['2'] or ''
    local in_herolabs = frame.args['in_herolabs'] or 'false'
    local debug_mode = frame.args['debug_mode'] == 'true'
 
    local heroes = get_heroes(in_herolabs)
    local parts = {}
 
    for _, hero in ipairs(heroes) do
        table.insert(parts, string.format('File:%s%s|%s%s\n', hero.link, file_name, hero.name, description))
    end
   
    local ret = '<gallery>\n' .. table.concat(parts) .. '</gallery>'
 
    if debug_mode then
        return ret
    else
        return frame:preprocess(ret)
    end
end
 
-- Generate 3D model gallery
function p.get_hero_models(frame)
    local in_herolabs = frame.args['in_herolabs'] or 'false'
    local debug_mode = frame.args['debug_mode'] == 'true'
 
    local heroes = get_heroes(in_herolabs)
    local parts = {}
 
    for _, hero in ipairs(heroes) do
        table.insert(parts, string.format('{{3D Model|%s}}', hero.name))
    end
 
    local ret = table.concat(parts)
 
    if debug_mode then
        return ret
    else
        return frame:preprocess(ret)
    end
end
end
return p
return p