Module:HeroData/nav

From The Deadlock Wiki
Jump to navigation Jump to search

Overview

[edit source]

Generates hero navigation cards

Functions

[edit source]

get_hero_nav_cards

[edit source]

For Template:Hero Navbox on Heroes, individual hero pages like Abrams, and the home page.

Examples

[edit source]

First with debug_mode on, to help visualize what the output's source looks like.

{{#invoke:HeroData/nav|get_hero_nav_cards
|text_size=13
|card_size=88
|in_herolabs=false
|debug_mode=true
}}

{{Hero card2|heroName=Abrams|cardSize=88|textSize=13|isHeroLabs=false}}{{Hero card2|heroName=Apollo|cardSize=88|textSize=13|isHeroLabs=false}}{{Hero card2|heroName=Bebop|cardSize=88|textSize=13|isHeroLabs=false}}{{Hero card2|heroName=Billy|cardSize=88|textSize=13|isHeroLabs=false}}{{Hero card2|heroName=Calico|cardSize=88|textSize=13|isHeroLabs=false}}{{Hero card2|heroName=Celeste|cardSize=88|textSize=13|isHeroLabs=false}}{{Hero card2|heroName=The Doorman|cardSize=88|textSize=13|isHeroLabs=false}}{{Hero card2|heroName=Drifter|cardSize=88|textSize=13|isHeroLabs=false}}{{Hero card2|heroName=Dynamo|cardSize=88|textSize=13|isHeroLabs=false}}{{Hero card2|heroName=Graves|cardSize=88|textSize=13|isHeroLabs=false}}{{Hero card2|heroName=Grey Talon|cardSize=88|textSize=13|isHeroLabs=false}}{{Hero card2|heroName=Haze|cardSize=88|textSize=13|isHeroLabs=false}}{{Hero card2|heroName=Holliday|cardSize=88|textSize=13|isHeroLabs=false}}{{Hero card2|heroName=Infernus|cardSize=88|textSize=13|isHeroLabs=false}}{{Hero card2|heroName=Ivy|cardSize=88|textSize=13|isHeroLabs=false}}{{Hero card2|heroName=Kelvin|cardSize=88|textSize=13|isHeroLabs=false}}{{Hero card2|heroName=Lady Geist|cardSize=88|textSize=13|isHeroLabs=false}}{{Hero card2|heroName=Lash|cardSize=88|textSize=13|isHeroLabs=false}}{{Hero card2|heroName=McGinnis|cardSize=88|textSize=13|isHeroLabs=false}}{{Hero card2|heroName=Mina|cardSize=88|textSize=13|isHeroLabs=false}}{{Hero card2|heroName=Mirage|cardSize=88|textSize=13|isHeroLabs=false}}{{Hero card2|heroName=Mo & Krill|cardSize=88|textSize=13|isHeroLabs=false}}{{Hero card2|heroName=Paige|cardSize=88|textSize=13|isHeroLabs=false}}{{Hero card2|heroName=Paradox|cardSize=88|textSize=13|isHeroLabs=false}}{{Hero card2|heroName=Pocket|cardSize=88|textSize=13|isHeroLabs=false}}{{Hero card2|heroName=Rem|cardSize=88|textSize=13|isHeroLabs=false}}{{Hero card2|heroName=Seven|cardSize=88|textSize=13|isHeroLabs=false}}{{Hero card2|heroName=Shiv|cardSize=88|textSize=13|isHeroLabs=false}}{{Hero card2|heroName=Silver|cardSize=88|textSize=13|isHeroLabs=false}}{{Hero card2|heroName=Sinclair|cardSize=88|textSize=13|isHeroLabs=false}}{{Hero card2|heroName=Venator|cardSize=88|textSize=13|isHeroLabs=false}}{{Hero card2|heroName=Victor|cardSize=88|textSize=13|isHeroLabs=false}}{{Hero card2|heroName=Vindicta|cardSize=88|textSize=13|isHeroLabs=false}}{{Hero card2|heroName=Viscous|cardSize=88|textSize=13|isHeroLabs=false}}{{Hero card2|heroName=Vyper|cardSize=88|textSize=13|isHeroLabs=false}}{{Hero card2|heroName=Warden|cardSize=88|textSize=13|isHeroLabs=false}}{{Hero card2|heroName=Wraith|cardSize=88|textSize=13|isHeroLabs=false}}{{Hero card2|heroName=Yamato|cardSize=88|textSize=13|isHeroLabs=false}}

Now with debug_mode defaulted to false (off) to see actual visual output.

{{#invoke:HeroData/nav|get_hero_nav_cards
|text_size=13
|card_size=88
|in_herolabs=false
}}

Hero Labs

Abrams

Hero Labs

Apollo

Hero Labs

Bebop

Hero Labs

Billy

Hero Labs

Calico

Hero Labs

Celeste

Hero Labs

The Doorman

Hero Labs

Drifter

Hero Labs

Dynamo

Hero Labs

Graves

Hero Labs

Grey Talon

Hero Labs

Haze

Hero Labs

Holliday

Hero Labs

Infernus

Hero Labs

Ivy

Hero Labs

Kelvin

Hero Labs

Lady Geist

Hero Labs

Lash

Hero Labs

McGinnis

Hero Labs

Mina

Hero Labs

Mirage

Hero Labs

Mo & Krill

Hero Labs

Paige

Hero Labs

Paradox

Hero Labs

Pocket

Hero Labs

Rem

Hero Labs

Seven

Hero Labs

Shiv

Hero Labs

Silver

Hero Labs

Sinclair

Hero Labs

Venator

Hero Labs

Victor

Hero Labs

Vindicta

Hero Labs

Viscous

Hero Labs

Vyper

Hero Labs

Warden

Hero Labs

Wraith

Hero Labs

Yamato

Parameters

[edit source]
  • text_size - Font size of the hero name
  • card_size - Size of the hero card
  • in_herolabs - Get hero labs heroes (there are none at the moment)
  • debug_mode - (OPTIONAL) Defaults to false. With true, the output is raw wikitext source that isn't processed, allowing to see more clearly what is ran.

debug_mode is the only optional parameter. All other parameters are required. Template:Hero card2 utilizes this with some default values, see there for suggested values.

get_hero_roster

[edit source]

For Template:Roster on Heroes, generate a list using Template:HeroRosterCard.

get_hero_bulletpoints

[edit source]

For navboxes such as Template:Quotes Navbox, generate a bulletpoint list of heroes.

Add the name of a subpage to link to specific subpages. It will still display only the hero name but link to the subpage instead.

Add variable "no_redlinks=true" to hide red links (non-existent pages).

Examples

[edit source]
{{#invoke:HeroData/nav|get_hero_bulletpoints}}

Abrams Apollo Bebop Billy Calico Celeste The Doorman Drifter Dynamo Graves Grey Talon Haze Holliday Infernus Ivy Kelvin Lady Geist Lash McGinnis Mina Mirage Mo & Krill Paige Paradox Pocket Rem Seven Shiv Silver Sinclair Venator Victor Vindicta Viscous Vyper Warden Wraith Yamato

To link to "/Movement" subpages:

{{#invoke:HeroData/nav|get_hero_bulletpoints|Movement}}

AbramsApolloBebopBillyCalicoCelesteThe DoormanDrifterDynamoGravesGrey TalonHazeHollidayInfernusIvyKelvinLady GeistLashMcGinnisMinaMirageMo & KrillPaigeParadoxPocketRemSevenShivSilverSinclairVenatorVictorVindictaViscousVyperWardenWraithYamato

Hide redlinks:

{{#invoke:HeroData/nav|get_hero_bulletpoints|Movement|no_redlinks=true}}

AbramsThe DoormanDrifterDynamoHazeHollidayInfernusIvyLashMo & KrillParadoxPocketSevenShivSinclairVindictaViscousWraithYamato


local p = {}
local heroes_data = mw.loadJsonData("Data:HeroData.json")
local hero_release_module = require('Module:HeroData/release')
local lang_module = require('Module:Lang')
local utilities = require('Module:Utilities')

-- 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)
    local text_size = frame.args['text_size']
    local card_size = frame.args['card_size']
    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('{{Hero card2|heroName=%s|cardSize=%s|textSize=%s|isHeroLabs=%s}}',
            hero.link, card_size, text_size, in_herolabs))
    end

    local ret = table.concat(parts)

    if debug_mode then
        return ret
    else
        return frame:preprocess(ret)
    end
end

-- for [[Template:Roster]]
function p.get_hero_roster(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('{{HeroRosterCard|name=%s|key=%s}}', hero.name, hero.key))
    end

    local ret = table.concat(parts)

    if debug_mode then
        return ret
    else
        return frame:preprocess(ret)
    end
end

-- for [[Template:Quotes Navbox]] etc.
p.get_hero_bulletpoints = function(frame)
    local subpage = frame.args['1']
    local in_herolabs = frame.args['in_herolabs'] or 'false'
    local debug_mode = frame.args['debug_mode'] == 'true'
    local no_redlinks = frame.args['no_redlinks'] == 'true'

    local heroes = get_heroes(in_herolabs)
    local parts = {}

    for _, hero in ipairs(heroes) do
        -- Lua optimization: clean ternary fallback for page_title assignment
        local page_title = subpage and (hero.link .. '/' .. subpage) or hero.name

        -- Skip redlinks entirely when enabled
        if not (no_redlinks and not utilities.page_exists(page_title)) then
            local item
            if subpage then
                item = string.format('{{PageRef|%s|alt_link=%s}}', hero.link, page_title)
            else
                item = string.format('{{HeroIcon|%s}}', hero.link)
            end
            table.insert(parts, item)
        end
    end

    local ret = table.concat(parts, ' &bull; ')

    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

return p