Module:UnitInfobox: Difference between revisions
From Heroes of Might and Magic: Olden Era Official Wiki
No edit summary |
No edit summary |
||
| (38 intermediate revisions by the same user not shown) | |||
| Line 6: | Line 6: | ||
local function dump(target) | local function dump(target) | ||
return '<pre>' .. mw.dumpObject(target) .. '</pre>' | return '<pre>' .. mw.dumpObject(target) .. '</pre>' | ||
end | |||
-- Spawns a safe robotic url from an English name, fit for adding it before the visible name | |||
------------------------------------------------------------------------------------------------------------------------ | |||
local function getUrl(nameEn, lang) | |||
if not nameEn then | |||
return '' | |||
end | |||
local url = nameEn | |||
if lang ~= 'en' then | |||
url = url .. '/' .. lang | |||
end | |||
return url | |||
end | end | ||
| Line 36: | Line 49: | ||
end | end | ||
end | end | ||
return mw.ext.cargo.query(tables, fields, options) | local success, result = pcall(function() | ||
return mw.ext.cargo.query(tables, fields, options) | |||
end) | |||
return success and result or {} | |||
end | |||
------------------------------------------------------------------------------------------------------------------------ | |||
local function getBaseId(unitId) | |||
return unitId:gsub('_alt$', ''):gsub('_upg$', '') | |||
end | end | ||
------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------ | ||
local function getEnglishBaseUnitName(unitId) | local function getEnglishBaseUnitName(unitId) | ||
local baseId = unitId | local baseId = getBaseId(unitId) | ||
local table = runQuery([[ | local table = runQuery([[ | ||
tables = | tables = | ||
| Line 49: | Line 70: | ||
U.id = T.target_id | U.id = T.target_id | ||
| where = | | where = | ||
U.id = | U.id = "%s" | ||
AND T.language = 'en' | AND T.language = 'en' | ||
AND T.type = 'unit' | AND T.type = 'unit' | ||
| Line 57: | Line 78: | ||
1 | 1 | ||
]], baseId); | ]], baseId); | ||
return (table[1] or {name = ''}).name | |||
end | end | ||
------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------ | ||
function p. | function p.findGrowth(frame) | ||
local unitId = frame.args.id | local unitId = frame.args.id | ||
local baseId = getBaseId(unitId) | |||
local table = runQuery([[ | |||
tables = | |||
MapObject = M | |||
| where = | |||
M.units_hire_sid = '%s' | |||
| fields = | |||
M.units_weekly = units_weekly | |||
| limit = | |||
1 | |||
]], baseId); | |||
local growth = (table[1] or { units_weekly = '' }).units_weekly | |||
return growth; | |||
end | |||
------------------------------------------------------------------------------------------------------------------------ | |||
local function findTownBuilding(unitId, lang) | |||
local baseId = getBaseId(unitId) | |||
local table = runQuery([[ | |||
tables = | |||
Building = B, | |||
Translation = T, | |||
Translation = E, | |||
| join on = | |||
B.id = T.target_id, | |||
B.id = E.target_id | |||
| where = | |||
B.units_hire_sid = "%s" | |||
AND T.language = "%s" | |||
AND E.language = 'en' | |||
| fields = | |||
T.name = name, | |||
E.name = name_en | |||
| limit = | |||
2 | |||
]], baseId, lang); | |||
if #table ~= 2 then | |||
return nil | |||
end | |||
local level = unitId == baseId and 1 or 2 | |||
return { | |||
name_en = table[1].name_en, -- we need the English name of the base! | |||
name = table[level].name | |||
} | |||
end | |||
------------------------------------------------------------------------------------------------------------------------ | |||
local function findExternalDwelling(unitId, lang, isBank) | |||
local nameEn = getEnglishBaseUnitName(unitId) | local nameEn = getEnglishBaseUnitName(unitId) | ||
nameEn = nameEn:gsub('man$', 'men') -- fix 'Swordmen' and 'Crossbowmen' | nameEn = nameEn:gsub('man$', 'men') -- fix 'Swordmen' and 'Crossbowmen' | ||
nameEn = nameEn:gsub(' of', 's of') -- fix 'Sentinels of Glory' | nameEn = nameEn:gsub(' of', 's of') -- fix 'Sentinels of Glory' | ||
nameEn = nameEn:gsub('Waurms', 'Waurmos') | nameEn = nameEn:gsub('Waurms', 'Waurmos') | ||
-- Note: Currently (2026-07-16), the banks are not present in Cargo | |||
local prefix = isBank == 1 and 'Defeat its guard to obtain' or 'You can recruit' | |||
local table = runQuery([[ | local table = runQuery([[ | ||
tables = | tables = | ||
Translation = T | Translation = E, | ||
Translation = T, | |||
| join on = | |||
E.target_id = T.target_id | |||
| where = | | where = | ||
E.type = 'map_object' | |||
AND | AND E.language = 'en' | ||
AND | AND E.description LIKE "%s %s%%" | ||
AND T.type = 'map_object' | |||
AND T.language = "%s" | |||
| fields = | | fields = | ||
T. | E.name = name_en, | ||
T.name = name | |||
| limit = | | limit = | ||
1 | 1 | ||
]], nameEn); | ]], prefix, nameEn, lang); | ||
if #table ~= 1 then | |||
local | return nil | ||
return | end | ||
return table[1] | |||
end | |||
------------------------------------------------------------------------------------------------------------------------ | |||
function p.findDwelling(frame) | |||
local unitId = frame.args.id | |||
local lang = frame.args.lang | |||
local names = findTownBuilding(unitId, lang) | |||
if not names then | |||
names = findExternalDwelling(unitId, lang, 0) | |||
end | |||
if not names then | |||
return '' | |||
end | |||
return '[[' .. getUrl(names.name_en, lang) .. '|' .. names.name .. ']]' | |||
end | end | ||
------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------ | ||
function p. | function p.findSpecialistId(frame) | ||
local unitId = frame.args.id | local unitId = frame.args.id | ||
local nameEn = getEnglishBaseUnitName(unitId) | local nameEn = getEnglishBaseUnitName(unitId) | ||
local nameEnWithSmartApostrophe = nameEn:gsub("'", '’') | |||
local table = runQuery([[ | local table = runQuery([[ | ||
tables = | tables = | ||
| Line 95: | Line 189: | ||
T.type = 'hero_specialization' | T.type = 'hero_specialization' | ||
AND T.language = 'en' | AND T.language = 'en' | ||
AND T.description LIKE | AND (T.description LIKE "%s growth in your cities increases by%%" OR | ||
T.description LIKE "%s growth in your cities increases by%%") | |||
| fields = | | fields = | ||
T.target_id = target_id | T.target_id = target_id | ||
| limit = | | limit = | ||
1 | 1 | ||
]], nameEn); | ]], nameEn, nameEnWithSmartApostrophe); | ||
local | local specialist = (table[1] or {target_id = ''}).target_id | ||
specialist = specialist:gsub('_specialization', '') | specialist = specialist:gsub('_specialization', '') | ||
return specialist | return specialist | ||
end | |||
------------------------------------------------------------------------------------------------------------------------ | |||
function p.findBank(frame) | |||
return '' | |||
end | |||
------------------------------------------------------------------------------------------------------------------------ | |||
function p.simplifyName(frame) | |||
return (mw.ustring.gsub(frame.args.name, "[^%a]", "")) | |||
end | end | ||
return p | return p | ||
Latest revision as of 08:50, 20 July 2026
Documentation for this module may be created at Module:UnitInfobox/doc
-- This module is intended as a supporting muscle for the UnitInfobox template.
local p = {}
-- Displays a variable
------------------------------------------------------------------------------------------------------------------------
local function dump(target)
return '<pre>' .. mw.dumpObject(target) .. '</pre>'
end
-- Spawns a safe robotic url from an English name, fit for adding it before the visible name
------------------------------------------------------------------------------------------------------------------------
local function getUrl(nameEn, lang)
if not nameEn then
return ''
end
local url = nameEn
if lang ~= 'en' then
url = url .. '/' .. lang
end
return url
end
-- Parses and runs a Cargo query from wiki-like syntax
------------------------------------------------------------------------------------------------------------------------
local function runQuery(query, ...)
query = string.gsub(query, "%-%-.-\n", "") -- remove "comments"
query = select('#', ...) > 0 and mw.ustring.format(query, ...) or query
query = mw.text.trim(query)
local tables = ''
local fields = ''
local options = {}
for part in query:gmatch('[^|]+') do
local key, val = part:match('^%s*([^=]+)%s*=%s*(.-)%s*$')
if key and val then
key = mw.text.trim(key):lower()
val = mw.text.trim(val)
val = val:gsub('%s', ' ')
if key == 'tables' then
tables = val
elseif key == 'fields' then
fields = val
elseif key == 'limit' then
options[key] = tonumber(val) or val
elseif key == 'join on' then
options['join'] = val
else
options[key] = val
end
end
end
local success, result = pcall(function()
return mw.ext.cargo.query(tables, fields, options)
end)
return success and result or {}
end
------------------------------------------------------------------------------------------------------------------------
local function getBaseId(unitId)
return unitId:gsub('_alt$', ''):gsub('_upg$', '')
end
------------------------------------------------------------------------------------------------------------------------
local function getEnglishBaseUnitName(unitId)
local baseId = getBaseId(unitId)
local table = runQuery([[
tables =
Unit = U,
Translation = T
| join on =
U.id = T.target_id
| where =
U.id = "%s"
AND T.language = 'en'
AND T.type = 'unit'
| fields =
T.name = name
| limit =
1
]], baseId);
return (table[1] or {name = ''}).name
end
------------------------------------------------------------------------------------------------------------------------
function p.findGrowth(frame)
local unitId = frame.args.id
local baseId = getBaseId(unitId)
local table = runQuery([[
tables =
MapObject = M
| where =
M.units_hire_sid = '%s'
| fields =
M.units_weekly = units_weekly
| limit =
1
]], baseId);
local growth = (table[1] or { units_weekly = '' }).units_weekly
return growth;
end
------------------------------------------------------------------------------------------------------------------------
local function findTownBuilding(unitId, lang)
local baseId = getBaseId(unitId)
local table = runQuery([[
tables =
Building = B,
Translation = T,
Translation = E,
| join on =
B.id = T.target_id,
B.id = E.target_id
| where =
B.units_hire_sid = "%s"
AND T.language = "%s"
AND E.language = 'en'
| fields =
T.name = name,
E.name = name_en
| limit =
2
]], baseId, lang);
if #table ~= 2 then
return nil
end
local level = unitId == baseId and 1 or 2
return {
name_en = table[1].name_en, -- we need the English name of the base!
name = table[level].name
}
end
------------------------------------------------------------------------------------------------------------------------
local function findExternalDwelling(unitId, lang, isBank)
local nameEn = getEnglishBaseUnitName(unitId)
nameEn = nameEn:gsub('man$', 'men') -- fix 'Swordmen' and 'Crossbowmen'
nameEn = nameEn:gsub(' of', 's of') -- fix 'Sentinels of Glory'
nameEn = nameEn:gsub('Waurms', 'Waurmos')
-- Note: Currently (2026-07-16), the banks are not present in Cargo
local prefix = isBank == 1 and 'Defeat its guard to obtain' or 'You can recruit'
local table = runQuery([[
tables =
Translation = E,
Translation = T,
| join on =
E.target_id = T.target_id
| where =
E.type = 'map_object'
AND E.language = 'en'
AND E.description LIKE "%s %s%%"
AND T.type = 'map_object'
AND T.language = "%s"
| fields =
E.name = name_en,
T.name = name
| limit =
1
]], prefix, nameEn, lang);
if #table ~= 1 then
return nil
end
return table[1]
end
------------------------------------------------------------------------------------------------------------------------
function p.findDwelling(frame)
local unitId = frame.args.id
local lang = frame.args.lang
local names = findTownBuilding(unitId, lang)
if not names then
names = findExternalDwelling(unitId, lang, 0)
end
if not names then
return ''
end
return '[[' .. getUrl(names.name_en, lang) .. '|' .. names.name .. ']]'
end
------------------------------------------------------------------------------------------------------------------------
function p.findSpecialistId(frame)
local unitId = frame.args.id
local nameEn = getEnglishBaseUnitName(unitId)
local nameEnWithSmartApostrophe = nameEn:gsub("'", '’')
local table = runQuery([[
tables =
Translation = T
| where =
T.type = 'hero_specialization'
AND T.language = 'en'
AND (T.description LIKE "%s growth in your cities increases by%%" OR
T.description LIKE "%s growth in your cities increases by%%")
| fields =
T.target_id = target_id
| limit =
1
]], nameEn, nameEnWithSmartApostrophe);
local specialist = (table[1] or {target_id = ''}).target_id
specialist = specialist:gsub('_specialization', '')
return specialist
end
------------------------------------------------------------------------------------------------------------------------
function p.findBank(frame)
return ''
end
------------------------------------------------------------------------------------------------------------------------
function p.simplifyName(frame)
return (mw.ustring.gsub(frame.args.name, "[^%a]", ""))
end
return p


