Module:Unit: Difference between revisions

From Heroes of Might and Magic: Olden Era Official Wiki
No edit summary
No edit summary
Line 68: Line 68:
         if arrayName and index and propName then
         if arrayName and index and propName then
             -- Convert from 1-based indexing (user-friendly) to 0-based indexing (JSON format)
             -- Convert from 1-based indexing (user-friendly) to 0-based indexing (JSON format)
             local arrayIndex = index - 1
             local actualIndex = index - 1
             -- Check if the array exists and is not nil
            local array = unit[arrayName]
             if unit[arrayName] == nil then
 
             -- Check if the array exists and is a table
             if array == nil then
                 return "Array '" .. arrayName .. "' not found for unit '" .. unitName .. "'"
                 return "Array '" .. arrayName .. "' not found for unit '" .. unitName .. "'"
             end
             end
            -- Check if the array is actually a table
 
             if type(unit[arrayName]) ~= "table" then
             if type(array) ~= "table" then
                 return "Property '" .. arrayName .. "' is not an array for unit '" .. unitName .. "'"
                 return "Property '" .. arrayName .. "' is not an array for unit '" .. unitName .. "'"
             end
             end
             -- Check if the array has the specified index
 
             if unit[arrayName][arrayIndex] ~= nil then
            local element = array[actualIndex]
                local arrayItem = unit[arrayName][arrayIndex]
 
                 if type(arrayItem) == "table" and arrayItem[propName] ~= nil then
             -- If element is not found at the converted index, it might mean that the array uses 1-based indexing
                     return tostring(arrayItem[propName])
            -- This can happen depending on how the JSON was parsed
             if element == nil then
                -- Try with 1-based indexing (standard Lua arrays)
                element = array[index]
                if element ~= nil then
                    -- Use 1-based indexing, so we don't subtract 1
                    actualIndex = index
                 end
            end
 
            -- Now check if we found an element
            if element ~= nil and type(element) == "table" then
                local value = element[propName]
                if value ~= nil then
                     return tostring(value)
                 else
                 else
                     return "Property '" .. propName .. "' not found in " .. arrayName .. "[" .. arrayIndex .. "] for unit '" .. unitName .. "'"
                     return "Property '" .. propName .. "' not found in " .. arrayName .. "[" .. actualIndex .. "] for unit '" .. unitName .. "'"
                 end
                 end
             else
             else
                 return "Array '" .. arrayName .. "' does not contain index " .. arrayIndex .. " for unit '" .. unitName .. "' (requested as " .. index .. " for user-friendly indexing)"
                 return "Array '" .. arrayName .. "' does not contain index " .. actualIndex .. " for unit '" .. unitName .. "' (requested as " .. index .. " for user-friendly indexing)"
             end
             end
         end
         end

Revision as of 18:15, 9 December 2025

Module for requesting characteristics of all existing units in Olden Era. Actual data is stored in Data:units.json.

For documentation page, see Module:Unit/doc.

Supported Commands

get

The module supports the main get command, through which you can retrieve individual unit attributes (listed below). The basic syntax of the command is:

{{#invoke:Unit|get|Unit Name|Property Name}}
Name Description Example Result
name Unit name (localized)
{{#invoke:Unit|get|Angel|name}}
Property 'name' not found for unit 'Angel'
Base name Name of un-upgraded unit (localized)
{{#invoke:Unit|get|Apotheosis|baseName}}
Property 'baseName' not found for unit 'Apotheosis'
First Upgrade Name of upgraded unit (localized)
{{#invoke:Unit|get|Angel|upgradeName}}
Property 'upgradeName' not found for unit 'Angel'
Second Upgrade Name of alt. upgraded unit (localized)
{{#invoke:Unit|get|Angel|altUpgradeName}}
Property 'altUpgradeName' not found for unit 'Angel'
Image name Name without spaces and apostrophes, suitable for wiki file names
{{#invoke:Unit|get|Sun's Aegis|imageName}}
Property 'imageName' not found for unit 'Sun's Aegis'
description Narrative description (localized with data substitutions)
{{#invoke:Unit|get|Angel|description}}
Property 'description' not found for unit 'Angel'
faction Unit faction
{{#invoke:Unit|get|Angel|faction}}
human
tier Unit tier
{{#invoke:Unit|get|Angel|tier}}
7
id Unit ID
{{#invoke:Unit|get|Angel|id}}
angel
nativeBiome Native biome
{{#invoke:Unit|get|Angel|nativeBiome}}
Grass
cost Hiring cost
{{#invoke:Unit|get|Angel|cost}}
Property 'cost' not found for unit 'Angel'
cost.gold
cost.resource
Access to specific property in unitCost object
{{#invoke:Unit|get|Angel|cost.gold}}
{{#invoke:Unit|get|Angel|cost.gemstones}}
Property 'cost.gold' not found for unit 'Angel'
Property 'cost.gemstones' not found for unit 'Angel'
upgradeCost Upgrade cost
{{#invoke:Unit|get|Archangel|upgradeCost}}
Property 'upgradeCost' not found for unit 'Archangel'
weeklyIncrement Base weekly increment from main building
{{#invoke:Unit|get|Angel|weeklyIncrement}}
1
expBonus Experience gained when defeating the unit
{{#invoke:Unit|get|Angel|expBonus}}
366
squadValue Squad value of the unit (used for army composition calculations)
{{#invoke:Unit|get|Angel|squadValue}}
3660
hp Maximum health
{{#invoke:Unit|get|Angel|hp}}
225
offence Offence parameter
{{#invoke:Unit|get|Angel|offence}}
30
defence Defence parameter
{{#invoke:Unit|get|Angel|defence}}
30
damageMin Minimum damage dealt
{{#invoke:Unit|get|Angel|damageMin}}
50
damageMax Maximum damage dealt
{{#invoke:Unit|get|Angel|damageMax}}
75
moral Default morale
{{#invoke:Unit|get|Angel|moral}}
0
moralMin Minimum morale value
{{#invoke:Unit|get|Angel|moralMin}}
-3
moralMax Maximum morale value
{{#invoke:Unit|get|Angel|moralMax}}
3
luck Default luck
{{#invoke:Unit|get|Angel|luck}}
0
luckMin Minimum luck value
{{#invoke:Unit|get|Angel|luckMin}}
-3
luckMax Maximum luck value
{{#invoke:Unit|get|Angel|luckMax}}
3
initiative Initiative
{{#invoke:Unit|get|Angel|initiative}}
8
speed Speed
{{#invoke:Unit|get|Angel|speed}}
4
moveType Movement type (fly or teleport)
{{#invoke:Unit|get|Angel|moveType}}
fly
baseClass.name Base class name (localized)
{{#invoke:Unit|get|Angel|baseClass.name|ru}}
Property 'baseClass.name' not found for unit 'Angel'
baseClass.description Base class description (localized)
{{#invoke:Unit|get|Angel|baseClass.description}}
Property 'baseClass.description' not found for unit 'Angel'
baseClass.icon Base class icon filename
{{#invoke:Unit|get|Angel|baseClass.icon}} or [[File:{{#invoke:Unit|get|Angel|baseClass.icon}}|50px]]
Property 'baseClass.icon' not found for unit 'Angel' - File:Property 'baseClass.icon' not found for unit 'Angel'

Active Abilities

To access specific active ability properties, use the format: abilities.index.property

Name Description Example Result
abilities.1.name Ability name (localized)
{{#invoke:Unit|get|Flaming Phoenix|abilities.1.name|ru}}
Awaken: Fire II
abilities.1.description Ability main description (localized with data substitutions)
{{#invoke:Unit|get|Flaming Phoenix|abilities.1.description|ru}}
Property 'description' not found in abilities[1] for unit 'Flaming Phoenix'
abilities.1.infoDescription Additional ability information (localized)
{{#invoke:Unit|get|Flaming Phoenix|abilities.1.infoDescription|ru}}
ability_no_turn
abilities.1.excaptionInTooltip Ability restrictions or exceptions (localized)
{{#invoke:Unit|get|Cultist|abilities.1.excaptionInTooltip|ru}}
description_effect_magic_creature_undead_construct_immunities
abilities.1.abilityType Type of ability (localized)
{{#invoke:Unit|get|Flaming Phoenix|abilities.1.abilityType|ru}}
Ability_type_special
abilities.1.ability_tier Ability rank or tier
{{#invoke:Unit|get|Flaming Phoenix|abilities.1.ability_tier|ru}}
6
abilities.1.energyLevel Energy required for ability activation
{{#invoke:Unit|get|Flaming Phoenix|abilities.1.energyLevel|ru}}
3
abilities.1.icon Ability icon filename
{{#invoke:Unit|get|Flaming Phoenix|abilities.1.icon|ru}}
Phoenix_ability_2.png

Passive Abilities

To access specific passive ability properties, use the format: passives.index.property

Name Description Example Result
passives.1.name Passive ability name (localized)
{{#invoke:Unit|get|Giant Toad|passives.1.name}}
Melee Attack
passives.1.description Passive ability description (localized with data substitutions)
{{#invoke:Unit|get|Giant Toad|passives.1.description}}
Property 'description' not found in passives[1] for unit 'Giant Toad'
passives.1.excaptionInTooltip Passive ability restrictions or exceptions (localized)
{{#invoke:Unit|get|Giant Toad|passives.1.excaptionInTooltip}}
Property 'excaptionInTooltip' not found in passives[1] for unit 'Giant Toad'
passives.1.icon Passive ability icon filename
{{#invoke:Unit|get|Giant Toad|passives.1.icon}}
Base passive melee attack.png

Alternative Attacks

To access specific alternative attack properties, use the format: alternativeAttacks.index.property

Name Description Example Result
alternativeAttacks.1.name Alternative attack name (localized)
{{#invoke:Unit|get|Infiltrator|alternativeAttacks.1.name}}
Fighting Style: Hit and Run
alternativeAttacks.1.description Alternative attack description (localized with data substitutions)
{{#invoke:Unit|get|Infiltrator|alternativeAttacks.1.description}}
Property 'description' not found in alternativeAttacks[1] for unit 'Infiltrator'
alternativeAttacks.1.abilityType Type of alternative attack (localized)
{{#invoke:Unit|get|Infiltrator|alternativeAttacks.1.abilityType}}
Ability_type_attack_alt
alternativeAttacks.1.infoDescription Additional alternative attack information (localized)
{{#invoke:Unit|get|Infiltrator|alternativeAttacks.1.infoDescription}}
ability_no_energy
alternativeAttacks.1.icon Alternative attack icon filename
{{#invoke:Unit|get|Infiltrator|alternativeAttacks.1.icon}}
Assassin_ability_1.png
alternativeAttacks.1.ability_tier Alternative attack rank or tier
{{#invoke:Unit|get|Infiltrator|alternativeAttacks.1.ability_tier}}
1

Localization Support

The module supports localization in multiple languages. You can specify the language as an optional third parameter:

{{#invoke:Unit|get|Unit Name|Property Name|Language Code}}

For example:

  • {{#invoke:Unit|get|Angel|name|pl}}
    Property 'name' not found for unit 'Angel' - Polish
  • {{#invoke:Unit|get|Angel|name|ru}}
    Property 'name' not found for unit 'Angel' - Russian

local Unit = {}

-- Cache for data
local dataCache = nil

-- Load localization module
local LangStrings = require("Module:LocGetString")

-- Function to load JSON data from wiki page
local function loadJson(title)
    local page = mw.title.new(title)
    local content = page and page:getContent() or ""
    if content == "" then return {} end
    local ok, data = pcall(mw.text.jsonDecode, content)
    if not ok then return {} end
    return data
end

-- Load unit data from unitdata_work.json
local function loadUnits()
    if dataCache then return dataCache end
    dataCache = {}

    -- Load main JSON file (in real wiki, JSON data needs to be placed on this page)
    local units = loadJson("Data:units.json") -- or another suitable name for wiki page

    -- Copy data to cache
    for name, unit in pairs(units) do
        dataCache[name] = unit
    end

    return dataCache
end

-- Function to get unit property
function Unit.get(frame)
    local args = frame.args
    local unitName = args[1] or args.unit or ""
    local property = args[2] or args.property or ""
    local lang = args[3] or args.lang or "en"  -- Get language parameter, default to 'en'

    unitName = mw.text.trim(unitName or "")
    property = mw.text.trim(property or "")
    lang = mw.text.trim(lang or "en")

    if unitName == "" then
        return "Unit name not specified"
    end

    if property == "" then
        return "Property not specified"
    end

    -- Load unit data
    local units = loadUnits()

    -- Check if unit exists in data
    local unit = units[unitName]
    if not unit then
        return "Unit '" .. unitName .. "' not found"
    end

    -- Check if property is in format "arrayName.index.propertyName" (for accessing arrays)
    local arrayAccess = string.match(property, "^(.+)%.(%d+)%.(.+)$")
    if arrayAccess then
        local arrayName, indexStr, propName = string.match(property, "^(.+)%.(%d+)%.(.+)$")
        local index = tonumber(indexStr)
        if arrayName and index and propName then
            -- Convert from 1-based indexing (user-friendly) to 0-based indexing (JSON format)
            local actualIndex = index - 1
            local array = unit[arrayName]

            -- Check if the array exists and is a table
            if array == nil then
                return "Array '" .. arrayName .. "' not found for unit '" .. unitName .. "'"
            end

            if type(array) ~= "table" then
                return "Property '" .. arrayName .. "' is not an array for unit '" .. unitName .. "'"
            end

            local element = array[actualIndex]

            -- If element is not found at the converted index, it might mean that the array uses 1-based indexing
            -- This can happen depending on how the JSON was parsed
            if element == nil then
                -- Try with 1-based indexing (standard Lua arrays)
                element = array[index]
                if element ~= nil then
                    -- Use 1-based indexing, so we don't subtract 1
                    actualIndex = index
                end
            end

            -- Now check if we found an element
            if element ~= nil and type(element) == "table" then
                local value = element[propName]
                if value ~= nil then
                    return tostring(value)
                else
                    return "Property '" .. propName .. "' not found in " .. arrayName .. "[" .. actualIndex .. "] for unit '" .. unitName .. "'"
                end
            else
                return "Array '" .. arrayName .. "' does not contain index " .. actualIndex .. " for unit '" .. unitName .. "' (requested as " .. index .. " for user-friendly indexing)"
            end
        end
    end

    -- First check if property exists in main unit object
    if unit[property] ~= nil then
        return tostring(unit[property])
    end

    -- Then check if property exists in stats
    if unit.stats and unit.stats[property] ~= nil then
        return tostring(unit.stats[property])
    end

    -- If property not found
    return "Property '" .. property .. "' not found for unit '" .. unitName .. "'"
end

return Unit