Module:HeroClassDataParser

From Heroes of Might and Magic: Olden Era Official Wiki
Revision as of 20:59, 23 May 2026 by akesha.taladim (talk | contribs) (Undo revision 19653 by 76561198256426587 (talk))

HeroClassDataParser Module Documentation

This module provides accessors for **hero class data** stored in `Data:HeroClassData.json`. It allows retrieving stats, skill chances, subclasses, and generating formatted stats boxes for display on the wiki.

Data is **cached on first access** for improved performance.

Functions

getStat(frame)

Retrieves the base value of a stat for a given hero class.

Usage
{{#invoke:HeroClassDataParser|getStat|Knight|attack}}
Parameters
  • frame.args[1] – string: hero class name
  • frame.args[2] – string: stat key (`attack`, `defence`, `power`, `knowledge`)
Returns
  • string: stat value, or empty string if not found

---

getPre12(frame)

Retrieves the "pre-12" roll value for a stat.

Usage
{{#invoke:HeroClassDataParser|getPre12|Knight|attack}}
Parameters
  • frame.args[1] – hero class name
  • frame.args[2] – stat key
Returns
  • string: value of statRollPre12 or empty string

---

getPost12(frame)

Retrieves the "post-12" roll value for a stat.

Usage
{{#invoke:HeroClassDataParser|getPost12|Knight|attack}}
Parameters
  • frame.args[1] – hero class name
  • frame.args[2] – stat key
Returns
  • string: value of statRollPost12 or empty string

---

getSkillChance(frame)

Retrieves the chance of learning a secondary skill for a class.

Usage
{{#invoke:HeroClassDataParser|getSkillChance|Knight|leadershipSkill}}
Parameters
  • frame.args[1] – hero class name
  • frame.args[2] – skill key
Returns
  • string: skill chance, or empty string

---

getSubclassName(frame)

Returns the name of a subclass for a class.

Usage
{{#invoke:HeroClassDataParser|getSubclassName|Necromancer|1}}
Parameters
  • frame.args[1] – hero class name
  • frame.args[2] – number/string: subclass index or name
Returns
  • string: subclass name, or empty string

---

getSubclassEffect(frame)

Returns the effect description of a subclass.

Usage
{{#invoke:HeroClassDataParser|getSubclassEffect|Necromancer|1}}
Parameters
  • frame.args[1] – hero class name
  • frame.args[2] – number/string: subclass index or name
Returns
  • string: effect description, or empty string

---

getSubclassSkill(frame)

Returns a specific skill of a subclass.

Usage
{{#invoke:HeroClassDataParser|getSubclassSkill|Necromancer|Soulweaver|2}}
Parameters
  • frame.args[1] – hero class name
  • frame.args[2] – string/number: subclass name or index
  • frame.args[3] – number: skill index (1-based)
Returns
  • string: skill name, or empty string

---

statsBox(frame)

Generates an HTML snippet displaying the class's main stats with icons.

Usage
{{#invoke:HeroClassDataParser|statsBox|Knight}}
Parameters
  • frame.args[1] – hero class name
Returns
  • string: HTML of a vertical stats box

---

Internal Functions

  • getHeroClassData() – Loads and caches the hero class JSON data from `Data:HeroClassData.json`.
  • findHeroClass(className) – Finds and returns the class table by name.

local p = {}

local heroClassDataCache = nil
local function getHeroClassData()
    if not heroClassDataCache then
        local content = mw.title.new('Data:HeroClassData.json'):getContent() or '{}'
        heroClassDataCache = mw.text.jsonDecode(content)
    end
    return heroClassDataCache
end

local function findHeroClass(className)
    local json = getHeroClassData()
    if not json or not json.heroClasses then return nil end
    for _, class in ipairs(json.heroClasses) do
        if class.name == className then
            return class
        end
    end
    return nil
end
-- Additional functions for class/stat/skill lookup

function p.getStat(frame)
    local cls = findHeroClass(frame.args[1])
    local stat = frame.args[2]
    return cls and cls[stat] or ''
end

function p.getPre12(frame)
    local cls = findHeroClass(frame.args[1])
    local stat = frame.args[2]
    return cls and cls[stat .. 'RollPre12'] or ''
end

function p.getPost12(frame)
    local cls = findHeroClass(frame.args[1])
    local stat = frame.args[2]
    return cls and cls[stat .. 'RollPost12'] or ''
end

function p.getSkillChance(frame)
    local cls = findHeroClass(frame.args[1])
    local skill = frame.args[2]
    return cls and cls[skill] or ''
end

function p.getSubclassName(frame)
    local cls = findHeroClass(frame.args[1])
    local subParam = frame.args[2]
    if not cls or not cls.subclasses then return '' end
    local keys = {}
    for k in pairs(cls.subclasses) do table.insert(keys, k) end
    local idx = tonumber(subParam)
    if idx and keys[idx] then
        return keys[idx]
    end
    return ''
end

function p.getSubclassEffect(frame)
    local cls = findHeroClass(frame.args[1])
    local subParam = frame.args[2]
    if not cls or not cls.subclasses then return '' end
    local subclassName = subParam
    if tonumber(subParam) then
        local keys = {}
        for k in pairs(cls.subclasses) do table.insert(keys, k) end
        subclassName = keys[tonumber(subParam)]
    end
    return cls.subclasses[subclassName] and cls.subclasses[subclassName].effect or ''
end

function p.getSubclassSkill(frame)
    local cls = findHeroClass(frame.args[1])
    local subParam = frame.args[2]
    local idx = tonumber(frame.args[3])
    if not cls or not cls.subclasses or not idx then return '' end
    local subclassName = subParam
    if tonumber(subParam) then
        local keys = {}
        for k in pairs(cls.subclasses) do table.insert(keys, k) end
        subclassName = keys[tonumber(subParam)]
    end
    local skills = cls.subclasses[subclassName] and cls.subclasses[subclassName].skills or nil
    return skills and skills[idx] or ''
end

function p.statsBox(frame)
    local class = frame.args[1]
    local cls = findHeroClass(class)
    if not cls then return 'Unknown class: ' .. tostring(class) end

    -- small helper to stringify values
    local function val(v) return tostring(v or '-') end

    local icons = {
        '[[File:Icon Stats Attack.png|28px]]',
        '[[File:Icon Stats Defence.png|28px]]',
        '[[File:Icon Stats Spellpower.png|28px]]',
        '[[File:Icon Stats Inteligence.png|28px]]',
    }

    local values = { val(cls.attack), val(cls.defence), val(cls.power), val(cls.knowledge) }

    local html = '<div class="stats-vertical" style="display:flex; gap:8px; justify-content:space-between; align-items:center; width:100%;">'
    for i=1,4 do
        html = html .. string.format('<div style="flex:1; text-align:center;"><div style="font-weight:bold;">%s</div><div style="margin-top:6px;">%s</div></div>', values[i], icons[i])
    end
    html = html .. '</div>'

    return html
end

return p