Module:SkillData

From Heroes of Might and Magic: Olden Era Official Wiki

This module allows for the dynamic extraction of variables, asset icons, descriptions, and tiered scaling mechanics for main skills, sub-skills, and individual skill levels stored within the wiki's Cargo database. 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:SkillData|get|SKILL_ID|VARIABLE|LANGUAGE_CODE|FORCE_TYPE}}
  • SKILL_ID : The technical identifier of the capability (e.g., skill_faction_dungeon, sub_skill_faction_dungeon_1).
  • 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, de). Defaults to English (en).
  • FORCE_TYPE : (Optional) Overrides automated row-type resolution. Accepts skill, sub_skill, or skill_level.

---

Available Variables

📝 Text & Translations (Language-Dependent)

These variables query the Translation table and dynamically adapt to the requested language code. The module automatically deduces whether the ID points to a root skill, sub-skill, or level row.

Variable Description Example Output (en)
name The full display name of the skill/sub-skill/tier. Triumvirate's Strength
description The official technical capability behavior text, ratios, and battle modifiers. Once per round, the hero can activate one of the three Stances...

🎨 Assets & Layout Data

Technical data parameters queried directly from SkillDef, SkillLevelDef, or SubSkillDef records.

Variable Description Example Values / Output
icon The visual icon asset name string. Forced automatic Title Case formatting applies natively. Skill_Faction_Dungeon_1_Icon
skill_type Classification type assigned to the asset root. Faction, Might, Magic
max_level Maximum mastery tier achievable for a main skill root. 3
offered_sub_skills Comma-separated list of dependent sub-skill paths unlocked at specific tiers. sub_skill_faction_dungeon_1,sub_skill_faction_dungeon_2

---

Practical Examples

Example 1: Printing Localized Root Skill Data

To display the French translated title and performance behavior of a specific faction mechanics path:

=== {{#invoke:SkillData|get|skill_faction_dungeon|name|fr}} ===
{{#invoke:SkillData|get|skill_faction_dungeon|description|fr}}

Output:

Force du Triumvirat

Une fois par tour, le héros peut activer l’une des trois Postures en combat. La Posture active confère au héros un bonus de +2 à l’attribut correspondant.

Example 2: Dynamic Row Icon Assembly

To build a clean image list utilizing automated title capitalization rules on asset returns:

[[File:{{#invoke:SkillData|get|sub_skill_faction_dungeon_1|icon}}.png|28px]] '''{{#invoke:SkillData|get|sub_skill_faction_dungeon_1|name|{{{lang|en}}}}}'''

Output: Generates a layout rendering the formatted File:Sub_Skill_Faction_Dungeon_1_Icon.png element next to its corresponding localized title string.


local p = {}

-- Fonction locale pour formater automatiquement les icônes (Optionnel, calqué sur la demande précédente)
local function capitalize(str)
    if not str then return "" end
    local capitalized = str:gsub("(%a)([%w]*)", function(first, rest)
        return first:upper() .. rest:lower()
    end)
    return capitalized
end

-- Fonction principale pour récupérer une donnée liée aux compétences
-- Syntaxe : {{#invoke:SkillData|get|ID_SKILL|CHAMP|LANGUE|TYPE_FORCE}}
function p.get(frame)
    local args = frame.args[1] and frame.args or frame:getParent().args
    local skill_id = args[1]
    local field = args[2]
    local lang = args[3] or 'en'
    local force_type = args[4] -- Optionnel : pour forcer le type de traduction ('skill', 'sub_skill', 'skill_level')

    if not skill_id or not field then
        return "Erreur : ID de compétence ou champ manquant."
    end

    -- 1. Gestion des champs textuels traduits (name, description)
    if field == 'name' or field == 'description' then
        -- Détection automatique du type de traduction requis basé sur le préfixe de l'ID
        local translation_type = force_type or "skill"
        if not force_type then
            if string.sub(skill_id, 1, 9) == "sub_skill" then
                translation_type = "sub_skill"
            elseif string.find(skill_id, "_L%d+$") or string.find(skill_id, "_level") then
                -- Gestion alternative si les ID de niveau se finissent par _L1, _L2 ou contiennent level
                translation_type = "skill_level"
            end
        end

        local queryOpts = {
            where = string.format('target_id="%s" AND language="%s" AND type="%s"', skill_id, lang, translation_type)
        }
        
        local res = mw.ext.cargo.query('Translation', field, queryOpts)

        if res and res[1] and res[1][field] then
            return res[1][field]
        else
            -- Système de secours (fallback) vers l'anglais
            if lang ~= 'en' then
                local fallbackOpts = {
                    where = string.format('target_id="%s" AND language="en" AND type="%s"', skill_id, translation_type)
                }
                local fallbackRes = mw.ext.cargo.query('Translation', field, fallbackOpts)
                if fallbackRes and fallbackRes[1] and fallbackRes[1][field] then
                    return fallbackRes[1][field]
                end
            end
            return "" 
        end
    end

    -- 2. Gestion des données brutes (Recherche croisée dans Skill, SkillLevel ou SubSkill selon l'ID)
    local tableName = "Skill"
    if string.sub(skill_id, 1, 9) == "sub_skill" then
        tableName = "SubSkill"
    elseif string.find(skill_id, "_L%d+$") then
        tableName = "SkillLevel"
    end

    local skillOpts = {
        where = string.format('id="%s"', skill_id)
    }
    local skillRes = mw.ext.cargo.query(tableName, field, skillOpts)

    if skillRes and skillRes[1] and skillRes[1][field] then
        local value = skillRes[1][field]
        if field == 'icon' then
            return capitalize(value)
        end
        return value
    end

    return ""
end

return p