Module:Unit: Difference between revisions
From Heroes of Might and Magic: Olden Era Official Wiki
No edit summary |
No edit summary |
||
| Line 202: | Line 202: | ||
local baseClass = unit["baseClass"] | local baseClass = unit["baseClass"] | ||
if baseClass == nil then | if baseClass == nil then | ||
return "baseClass not found | return "" -- Return empty string if baseClass not found | ||
end | end | ||
if type(baseClass) ~= "table" then | if type(baseClass) ~= "table" then | ||
return "baseClass is not | return "" -- Return empty string if baseClass is not a table | ||
end | end | ||
| Line 226: | Line 226: | ||
return getLocalizedDescription(baseClass, lang) | return getLocalizedDescription(baseClass, lang) | ||
else | else | ||
return " | return "" -- Return empty string if property not found in baseClass | ||
end | end | ||
end | end | ||
| Line 236: | Line 236: | ||
local unitCost = unit["unitCost"] | local unitCost = unit["unitCost"] | ||
if unitCost == nil then | if unitCost == nil then | ||
return "unitCost not found | return "" -- Return empty string if unitCost not found | ||
end | end | ||
if type(unitCost) ~= "table" then | if type(unitCost) ~= "table" then | ||
return "unitCost is not | return "" -- Return empty string if unitCost is not a table | ||
end | end | ||
| Line 249: | Line 249: | ||
return tostring(value) | return tostring(value) | ||
else | else | ||
return " | return "" -- Return empty string if property not found in unitCost | ||
end | end | ||
end | end | ||
| Line 269: | Line 269: | ||
-- If property not found | -- If property not found | ||
return " | return "" | ||
end | end | ||
return Unit | return Unit | ||
Revision as of 22:33, 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}}
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}}
|
Пробуждение. Огонь II |
| abilities.1.description | Ability main description (localized with data substitutions) | {{#invoke:Unit|get|Flaming Phoenix|abilities.1.description|ru}}
|
Получает +1 к скорости и инициативе, +25 к здоровью и всегда наносит максимальный урон. Позволяет использовать остальные способности. Применяется один раз за бой и действует до конца боя. |
| abilities.1.infoDescription | Additional ability information (localized) | {{#invoke:Unit|get|Flaming Phoenix|abilities.1.infoDescription|ru}}
|
Не завершает ход. |
| abilities.1.excaptionInTooltip | Ability restrictions or exceptions (localized) | {{#invoke:Unit|get|Cultist|abilities.1.excaptionInTooltip|ru}}
|
Не действует на магических существ, нежить и конструкты |
| abilities.1.abilityType | Type of ability (localized) | {{#invoke:Unit|get|Flaming Phoenix|abilities.1.abilityType|ru}}
|
Особая способность |
| 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}}
|
Can only attack adjacent enemies. Provokes counterattacks. |
| passives.1.excaptionInTooltip | Passive ability restrictions or exceptions (localized) | {{#invoke:Unit|get|Giant Toad|passives.1.excaptionInTooltip}}
|
|
| 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}}
|
This creature will return to its original position after attacking, but deal –50% Damage. |
| alternativeAttacks.1.abilityType | Type of alternative attack (localized) | {{#invoke:Unit|get|Infiltrator|alternativeAttacks.1.abilityType}}
|
Alternative Attack |
| alternativeAttacks.1.infoDescription | Additional alternative attack information (localized) | {{#invoke:Unit|get|Infiltrator|alternativeAttacks.1.infoDescription}}
|
Does not spend Focus Charges. |
| 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}}Anioł - Polish{{#invoke:Unit|get|Angel|name|ru}}Ангел - 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 localized text
local function getLocalizedText(sid, lang, returnEmptyIfMissing)
if sid and sid ~= "" then
local result = LangStrings.getText({args = {sid = sid, lang = lang}})
return result
else
if returnEmptyIfMissing then
return ""
else
return sid -- Return the original value if no sid
end
end
end
-- Function to get localized description with data substitutions
local function getLocalizedDescription(item, lang)
if not item or not item.sid_desc then
return ""
end
local text = LangStrings.getText({ args = { sid = item.sid_desc, lang = lang } }) or ""
local data = item.data or {}
local replacements = {}
-- If there are data_sid, localize each element and substitute data
if item.data_sid and type(item.data_sid) == "table" then
for i, sid in ipairs(item.data_sid) do
if sid and sid ~= "" then
local part = LangStrings.getText({ args = { sid = sid, lang = lang } }) or ""
if part ~= "" then
-- If data[i] is a table (array of values)
if type(data[i]) == "table" then
-- Replace placeholders {0}, {1}, {2}, etc. with data from data[i]
part = part:gsub("{(%d+)}", function(n)
local idx = tonumber(n) + 1 -- +1 because Lua indices start with 1
local val = data[i][idx]
return val ~= nil and tostring(val) or "{" .. n .. "}"
end)
replacements[i] = part
else
-- If data[i] is a single value, replace only {0}
part = part:gsub("{0}", tostring(data[i]))
replacements[i] = part
end
end
elseif data[i] ~= nil then
replacements[i] = tostring(data[i])
end
end
-- Add remaining elements from data that are not in data_sid
for i = #item.data_sid + 1, #data do
if data[i] ~= nil then
replacements[i] = tostring(data[i])
end
end
else
-- If no data_sid, use data directly
for i, val in ipairs(data) do
replacements[i] = tostring(val)
end
end
-- Substitute replacements in the base text
text = text:gsub("{(%d+)}", function(n)
local idx = tonumber(n) + 1
local val = replacements[idx]
return val or "{" .. n .. "}"
end)
return text
end
-- Function to get unit name using localization
local function getUnitName(unit, lang)
local id = unit.id or ""
if id ~= "" then
return getLocalizedText(id .. "_name", lang, false)
else
return unit.name or "No name"
end
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
-- If property is 'name', return localized name
if property == "name" then
return getUnitName(unit, lang)
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
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
-- Use 1-based indexing as per Lua convention
local element = array[index]
-- Now check if we found an element
if element ~= nil and type(element) == "table" then
local value = element[propName]
-- Special handling for 'name' property - use localization if sid_name exists (higher priority)
if propName == "name" and element["sid_name"] then
return getLocalizedText(element["sid_name"], lang, false)
elseif value ~= nil then
-- Handle special localized fields that should return empty string if missing
if propName == "abilityType" or propName == "excaptionInTooltip" or propName == "infoDescription" then
return getLocalizedText(value, lang, true)
else
return tostring(value)
end
else
-- If property is 'description', return localized description with data substitutions
if propName == "description" and element["sid_desc"] then
return getLocalizedDescription(element, lang)
else
return "" -- Return empty string if property not found
end
end
else
return "Array '" .. arrayName .. "' does not contain index " .. index .. " for unit '" .. unitName .. "'"
end
end
end
-- Check if property is in format "baseClass.propertyName" (for accessing baseClass object)
local baseClassAccess = string.match(property, "^baseClass%.(.+)$")
if baseClassAccess then
local baseClass = unit["baseClass"]
if baseClass == nil then
return "" -- Return empty string if baseClass not found
end
if type(baseClass) ~= "table" then
return "" -- Return empty string if baseClass is not a table
end
local propName = baseClassAccess
local value = baseClass[propName]
-- Special handling for 'name' property - use localization if sid_name exists (higher priority)
if propName == "name" and baseClass["sid_name"] then
return getLocalizedText(baseClass["sid_name"], lang, false)
elseif value ~= nil then
-- Handle special localized fields that should return empty string if missing
if propName == "abilityType" or propName == "excaptionInTooltip" or propName == "infoDescription" then
return getLocalizedText(value, lang, true)
else
return tostring(value)
end
else
-- If property is 'description', return localized description with data substitutions
if propName == "description" and baseClass["sid_desc"] then
return getLocalizedDescription(baseClass, lang)
else
return "" -- Return empty string if property not found in baseClass
end
end
end
-- Check if property is in format "cost.propertyName" (for accessing unitCost object)
local costAccess = string.match(property, "^cost%.(.+)$")
if costAccess then
local unitCost = unit["unitCost"]
if unitCost == nil then
return "" -- Return empty string if unitCost not found
end
if type(unitCost) ~= "table" then
return "" -- Return empty string if unitCost is not a table
end
local propName = costAccess
local value = unitCost[propName]
if value ~= nil then
return tostring(value)
else
return "" -- Return empty string if property not found in unitCost
end
end
-- First check if property exists in main unit object
if unit[property] ~= nil then
-- Special handling for 'name' property - use localization if sid_name exists (higher priority)
if property == "name" and unit["sid_name"] then
return getLocalizedText(unit["sid_name"], lang, false)
else
return tostring(unit[property])
end
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 ""
end
return Unit


