Module:HeroClassData

From Heroes of Might and Magic: Olden Era Official Wiki

This module allows for the dynamic extraction of all variables, combat growth coefficients, and translations for hero classes stored within the wiki's Cargo database (specifically from the HeroClass and Translation tables). It automatically handles localized fallback to English if a translation in the requested language is missing.

Basic Syntax

To fetch a data field, use the following syntax:

{{#invoke:HeroClassData|get|CLASS_ID|VARIABLE|LANGUAGE_CODE}}
  • CLASS_ID : The technical identifier of the hero class (e.g., might_dungeon, magic_undead).
  • VARIABLE : The keyword for the specific data field you want to display (see the list below).
  • LANGUAGE_CODE : (Optional) The localization code (e.g., en, fr, pl). Defaults to English (en).

---

Available Variables

📝 Text & Translations (Language-Dependent)

These variables query the Translation table using the type="hero_class" filter and dynamically adapt to the requested language code.

Variable Description Example Output (en)
name The localized name of the hero class. Overlord
description The localized official description, detailing mechanical behavior and class identity. Might Hero. Upon leveling up, most of the time gains Attack...

⚔️ Initial Attributes

The starting statistics given to any hero belonging to this class (queried from the HeroClass table).

Variable Description Value
offence Base Attack attribute. 2
defence Base Defense attribute. 2
spell_power Base Spell Power attribute. 2
intelligence Base Knowledge / Intelligence attribute. 1
luck Base Luck value. 0
morale Base Morale value. 0

📈 Stat Probability Growth (Leveling up)

Weights determining the percentage chance of a specific stat increasing upon reaching a new level.

Variable Description Example (might_dungeon)
roll_lvl1_attack % chance to gain Attack between levels 1 and 23. 30
roll_lvl1_defense % chance to gain Defense between levels 1 and 23. 35
roll_lvl1_power % chance to gain Spell Power between levels 1 and 23. 20
roll_lvl1_knowledge % chance to gain Knowledge between levels 1 and 23. 15
roll_lvl24_attack % chance to gain Attack at level 24 and above. 25
roll_lvl24_defense % chance to gain Defense at level 24 and above. 25
roll_lvl24_power % chance to gain Spell Power at level 24 and above. 25
roll_lvl24_knowledge % chance to gain Knowledge at level 24 and above. 25

⚙️ Technical Properties

Miscellaneous configuration variables mapped out in the class template definition.

Variable Description Example
faction The structural faction this class belongs to. dungeon
class_type The primary archetype profile. might or magic
native_biome The preferred battlefield and movement environment. Dirt
skills_roll_variant The table pointer determining skill weight probabilities. dungeon_might_skills_table
cost_gold Hiring fee required to purchase a hero of this class. 2500
enable_tactics Boolean indicating if the Tactics phase is enabled. yes / no

---

Practical Examples

Example 1: Fetching Localized Class Names

To display the French name of the Overlord class:

{{#invoke:HeroClassData|get|might_dungeon|name|fr}}

Output: Suzerain

Example 2: Building Template Integration

When listing a hero inside a dynamically generated row, use their underlying class_id to output their localized class text natively:

The hero belongs to the {{#invoke:HeroClassData|get|{{{class_id}}}|name|{{{lang|en}}}}} archetype.

local p = {}

-- Table de correspondance entre les noms usuels et les identifiants Cargo
local class_mapping = {
    ["herald"]      = "magic_demon",
    ["warlock"]     = "magic_dungeon",
    ["cleric"]      = "magic_human",
    ["druid"]       = "magic_nature",
    ["necromancer"] = "magic_undead",
    ["riftspeaker"] = "magic_unfrozen",
    ["enforcer"]    = "might_demon",
    ["overlord"]    = "dungeon_might",
    ["knight"]      = "might_human", 
    ["warden"]      = "might_nature",
    ["death knight"]= "might_undead",
    ["oathkeeper"]  = "might_unfrozen"
}

local function get_cargo_class_id(input_id)
    if not input_id then return "" end
    local clean_id = mw.text.trim(string.lower(input_id))
    return class_mapping[clean_id] or clean_id
end

-- ==========================================
-- NOUVELLE FONCTION : Génère le tableau complet en UNE SEULE requête !
-- Syntaxe : {{#invoke:HeroClassData|getStatsTable|NOM_CLASSE}}
-- ==========================================
function p.getStatsTable(frame)
    local args = frame.args[1] and frame.args or frame:getParent().args
    local class_id = get_cargo_class_id(args[1])
    
    if class_id == "" then return "Erreur : ID de classe manquant." end

    -- On demande TOUS les champs d'un coup (séparés par des virgules)
    local fields = "offence, roll_lvl1_attack, roll_lvl24_attack, defence, roll_lvl1_defense, roll_lvl24_defense, spell_power, roll_lvl1_power, roll_lvl24_power, intelligence, roll_lvl1_knowledge, roll_lvl24_knowledge"
    
    local queryOpts = { where = string.format('id="%s"', class_id) }
    local res = mw.ext.cargo.query('HeroClass', fields, queryOpts)

    -- Si Cargo ne trouve rien, on évite de faire planter la page
    if not res or not res[1] then 
        return "<!-- Données Cargo introuvables pour " .. class_id .. " -->" 
    end
    
    local data = res[1] -- Nos données sont ici, accessibles instantanément

    -- On reconstruit le tableau HTML proprement en Lua
    local html = {}
    table.insert(html, '{| class="wikitable" style="width:100%; border-collapse:collapse; margin-bottom:8px;"')
    table.insert(html, '! Carac. || Base || 1-12 || 13+')
    
    -- Ligne Attaque
    table.insert(html, '|-')
    table.insert(html, string.format('| [[File:Icon Stats Attack.png|24px]] Attaque || style="text-align:center;" | %s || style="text-align:center;" | %s || style="text-align:center;" | %s', data.offence or 0, data.roll_lvl1_attack or 0, data.roll_lvl24_attack or 0))
    
    -- Ligne Défense
    table.insert(html, '|-')
    table.insert(html, string.format('| [[File:Icon Stats Defence.png|24px]] Défense || style="text-align:center;" | %s || style="text-align:center;" | %s || style="text-align:center;" | %s', data.defence or 0, data.roll_lvl1_defense or 0, data.roll_lvl24_defense or 0))
    
    -- Ligne Puissance
    table.insert(html, '|-')
    table.insert(html, string.format('| [[File:Icon Stats Spellpower.png|24px]] Puissance des sorts || style="text-align:center;" | %s || style="text-align:center;" | %s || style="text-align:center;" | %s', data.spell_power or 0, data.roll_lvl1_power or 0, data.roll_lvl24_power or 0))
    
    -- Ligne Savoir
    table.insert(html, '|-')
    table.insert(html, string.format('| [[File:Icon Stats Inteligence.png|24px]] Savoir || style="text-align:center;" | %s || style="text-align:center;" | %s || style="text-align:center;" | %s', data.intelligence or 0, data.roll_lvl1_knowledge or 0, data.roll_lvl24_knowledge or 0))
    
    table.insert(html, '|}')

    -- On renvoie le bloc HTML complet
    return table.concat(html, "\n")
end

-- (L'ancienne fonction p.get reste en dessous pour ne rien casser ailleurs)
function p.get(frame)
    -- ... (garde ton ancienne fonction get ici) ...
end

return p