Module:Sandbox/Aurelain/ArtifactsOverview
From Heroes of Might and Magic: Olden Era Official Wiki
This module renders a giant table with all artifacts. Scroll artifacts are consolidated into 3 generic scroll artifacts (normal, enchanted and mythic). Campaign artifacts are excluded.
A hyper parameter is supported. For more information, see Module:UtilHyper/doc.
Usage
Input: {{#invoke:Sandbox/Aurelain/ArtifactsOverview|display | lang=en | hyper=Attack=Hero_Basics#Attributes}}
Output:
| Artifact🗯️ | description | ||
|---|---|---|---|
| Ambassador's Sash | Ambassador's Sash | ||
| Diplomatic Gifts | Diplomatic Gifts | ||
| Ancient Idol | Ancient Idol | ||
| Armor of Wonder | Armor of Wonder | ||
| Celestial Sash of Bliss | Celestial Sash of Bliss | ||
| Helm of Heavenly Enlightenment | Helm of Heavenly Enlightenment | ||
| Lion's Shield of Courage | Lion's Shield of Courage | ||
| Sandals of the Saint | Sandals of the Saint | ||
| Sword of Judgement | Sword of Judgement | ||
| Banner of Six Winds | Banner of Six Winds | ||
| Chitinous Shield | Chitinous Shield | ||
| Demon Claw | Demon Claw | ||
| Beelzebub's Boon | Beelzebub's Boon | ||
| Heartbeat | Heartbeat | ||
| Boreoloth's Tail | Boreoloth's Tail | ||
| Boreoloth's Hand | Boreoloth's Hand | ||
| Boreoloth's Head | Boreoloth's Head | ||
| Boreoloth's Heart | Boreoloth's Heart | ||
| Caduceus | Caduceus | ||
| Deck of Spells | Deck of Spells | ||
| Daylight Tome | Daylight Tome | ||
| Nightshade Tome | Nightshade Tome | ||
| Primal Tome | Primal Tome | ||
| Arcane Tome | Arcane Tome | ||
| Chain Link | Chain Link | ||
| Chain Mail | Chain Mail | ||
| Robe of Enlightenment | Robe of Enlightenment | ||
| Crown of the Supreme Magi | Crown of the Supreme Magi | ||
| Demonic Heart | Demonic Heart | ||
| Brass Knuckles | Brass Knuckles | ||
| Buckler | Buckler | ||
| Rapier | Rapier | ||
| Eagle Armor | Eagle Armor | ||
| Flask of Oblivion | Flask of Oblivion | ||
| Lifeblood Fae | Lifeblood Fae | ||
| Ring of Life | Ring of Life | ||
| Enchanted Magic Scroll | Enchanted Magic Scroll | ||
| Endless Bag | Endless Bag | ||
| Crescent Dagger | Crescent Dagger | ||
| Magic Slippers | Magic Slippers | ||
| Seven Eyes | Seven Eyes | ||
| Vortex Robe | Vortex Robe | ||
| Excalibur | Excalibur | ||
| Fallen Angel Wings | Fallen Angel Wings | ||
| Fine Wand | Fine Wand | ||
| Flag of Truce | Flag of Truce | ||
| Garotte | Garotte | ||
| Automated Antimagic Shield | Automated Antimagic Shield | ||
| Crimson Resonance Controller | Crimson Resonance Controller | ||
| Emerald Resonance Controller | Emerald Resonance Controller | ||
| Protective Belt | Protective Belt | ||
| Golden Goose Egg | Golden Goose Egg | ||
| Head Torch | Head Torch | ||
| Holy Sigil of Eridore | Holy Sigil of Eridore | ||
| Holy Sigil of Insara | Holy Sigil of Insara | ||
| Holy Sigil of Mearea | Holy Sigil of Mearea | ||
| Holy Sigil of Quix | Holy Sigil of Quix | ||
| Holy Sigil of Roph | Holy Sigil of Roph | ||
| Holy Sigil of The Second Man | Holy Sigil of The Second Man | ||
| Holy Sigil of The Seven Magi | Holy Sigil of The Seven Magi | ||
| Holy Sigil of Uurdt | Holy Sigil of Uurdt | ||
| Pelagic Hourglass | Pelagic Hourglass | ||
| Fancy Mask | Fancy Mask | ||
| Music Sheet | Music Sheet | ||
| Singing Pan-Pipe | Singing Pan-Pipe | ||
| Keeper's Amulet | Keeper's Amulet | ||
| Keeper's Ring | Keeper's Ring | ||
| Armet | Armet | ||
| Drum of War | Drum of War | ||
| Lance | Lance | ||
| Misericorde | Misericorde | ||
| Plate Armor | Plate Armor | ||
| Legion's Leg | Legion's Leg | ||
| Light-and-Shade Cloak | Light-and-Shade Cloak | ||
| Quivering Quiver | Quivering Quiver | ||
| Shroomwood Bow | Shroomwood Bow | ||
| Lord's Ring | Lord's Ring | ||
| Magic Key Ring | Magic Key Ring | ||
| Magic Scroll | Magic Scroll | ||
| Golden Moth | Golden Moth | ||
| Golden Pig | Golden Pig | ||
| Skull of Milos | Skull of Milos | ||
| Monster Head | Monster Head | ||
| Mythic Magic Scroll | Mythic Magic Scroll | ||
| Ogre's Club of Havoc | Ogre's Club of Havoc | ||
| Omencaller | Omencaller | ||
| Orb of Destruction | Orb of Destruction | ||
| Orb of Inhibition | Orb of Inhibition | ||
| Fish-to-the-Face | Fish-to-the-Face | ||
| Last Coin | Last Coin | ||
| Rags | Rags | ||
| Rope Belt | Rope Belt | ||
| Straw Hat | Straw Hat | ||
| Wooden Ring | Wooden Ring | ||
| Pole Star | Pole Star | ||
| Crown of Dragontooth | Crown of Dragontooth | ||
| Dragon Scale Armor | Dragon Scale Armor | ||
| Dragon Scale Shield | Dragon Scale Shield | ||
| Dragon Wing Tabard | Dragon Wing Tabard | ||
| Dragonbone Greaves | Dragonbone Greaves | ||
| Quiet Eye of a Dragon | Quiet Eye of a Dragon | ||
| Red Dragon Flame Tongue | Red Dragon Flame Tongue | ||
| Slithering Sash | Slithering Sash | ||
| Orb of Dawn | Orb of Dawn | ||
| Orb of Eternity | Orb of Eternity | ||
| Orb of Twilight | Orb of Twilight | ||
| Primordial Orb | Primordial Orb | ||
| Ring of Neutrality | Ring of Neutrality | ||
| Liquid Silence | Liquid Silence | ||
| Amelchia's Law | Amelchia's Law | ||
| Truthmaker | Truthmaker | ||
| Truthseeker | Truthseeker | ||
| Runestone Shards | Runestone Shards | ||
| Scholar's Amulet | Scholar's Amulet | ||
| Scholar's Tiara | Scholar's Tiara | ||
| Seal of Silence | Seal of Silence | ||
| Seven-League Boots | Seven-League Boots | ||
| Shackles of War | Shackles of War | ||
| Bone Boots | Bone Boots | ||
| Ribcage Armor | Ribcage Armor | ||
| Dark Hatchet | Dark Hatchet | ||
| Second Shade | Second Shade | ||
| Clenching Ring | Clenching Ring | ||
| Sirin Mask | Sirin Mask | ||
| Iridescent Cloak | Iridescent Cloak | ||
| Shaman Staff | Shaman Staff | ||
| Shoddy Shield | Shoddy Shield | ||
| Sixth Finger | Sixth Finger | ||
| Soulless Sash | Soulless Sash | ||
| Soulcaller Ring | Soulcaller Ring | ||
| Spellbinder's Hat | Spellbinder's Hat | ||
| Spells in Bottles | Spells in Bottles | ||
| Spyglass | Spyglass | ||
| Swamp Boots | Swamp Boots | ||
| Tactical Guide | Tactical Guide | ||
| Shield of the Rampaging Ogre | Shield of the Rampaging Ogre | ||
| Mirror Tiara | Mirror Tiara | ||
| Magic Mirror | Magic Mirror | ||
| Shard of Serenity | Shard of Serenity | ||
| Tunic of the Cyclops King | Tunic of the Cyclops King | ||
| Two-faced Mask | Two-faced Mask | ||
| Tabar Signet-Ring | Tabar Signet-Ring | ||
| Ukh Signet | Ukh Signet | ||
| Voodoo Doll | Voodoo Doll | ||
| Backpack | Backpack | ||
| Boots of Travel | Boots of Travel | ||
| Warlord Boots | Warlord Boots | ||
| Warrior's Belt | Warrior's Belt | ||
| Warrior's Amulet | Warrior's Amulet | ||
| Wizard's Cloak | Wizard's Cloak | ||
| Wizard's Amulet | Wizard's Amulet | ||
-- Usage: {{#invoke:ArtifactsOverview|display | lang=en}}
local p = {}
local f = mw.ustring.format
-- Note: The right side is just a fallback, it will seldom be used.
local TRANSLATION_IDS = {
wiki_none = 'None',
wiki_artifact = 'Artifact'
}
-- 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
-- Retrieves the text for some specific ids from Cargo Translations.
------------------------------------------------------------------------------------------------------------------------
local function translateIds(ids, lang, extra)
-- Key list
local list = {}
for key, _ in pairs(ids) do
list[#list + 1] = key
end
local idListString = '"' .. table.concat(list, '", "') .. '"'
-- Cargo
local where = {}
table.insert(where, 'target_id IN (' .. idListString .. ')')
table.insert(where, 'language = "' .. lang .. '"')
if extra then
table.insert(where, extra)
end
local results = mw.ext.cargo.query('Translation', 'target_id, name', {
where = table.concat(where, ' AND '),
limit = 100
})
-- Dictionary
local dictionary = mw.clone(ids)
for key, value in pairs(dictionary) do
dictionary[key] = value .. '🗯️'
end
for _, row in ipairs(results) do
local name = row['name']
if name and name ~= '' then
dictionary[row['target_id']] = name
end
end
return dictionary
end
-- Converts a dictionary into a linear array
------------------------------------------------------------------------------------------------------------------------
local function flatten(hub)
local list = {}
for _, entry in pairs(hub) do
list[#list + 1] = entry
end
return list
end
-- Interrogates the main Cargo table
------------------------------------------------------------------------------------------------------------------------
local function queryMain(lang)
-- fields:
local fields = {}
table.insert(fields, 'A.id = id');
table.insert(fields, 'T.language = language');
table.insert(fields, 'T.name = name');
table.insert(fields, 'T.description = description');
-- where:
local where = {}
table.insert(where, 'A.id NOT LIKE "campaign_%"')
table.insert(where, 'T.type = "artifact"')
table.insert(where, '(T.language = "en" OR T.language = "' .. lang .. '")')
-- query:
return mw.ext.cargo.query('Artifact=A, Translation=T', table.concat(fields, ','), {
join = 'A.id = T.target_id',
where = table.concat(where, ' AND '),
limit = 500
})
end
-- Folds magic scrolls into 3 artifacts (normal, enchanted and mythic):
------------------------------------------------------------------------------------------------------------------------
local function consolidateScrolls(lang, results)
local hub = {}
for _, row in ipairs(results) do
local id = row.id
if id:find('magic_scroll') then
if id:find('mythic') then
id = 'mythic_scroll_box_artifact'
else
if id:find('enchanted') then
id = 'enchanted_magic_scroll_artifact'
else
id = 'magic_scroll_artifact'
end
end
local entry = hub[id]
if not entry then
entry = {}
entry.id = id or ''
entry.spells = {}
hub[id] = entry
end
if row.language == lang then
entry.name = row.name or ''
entry.description = row.name or ''
end
if row.language == 'en' then
entry.nameEn = row.name or ''
local spellId = row.id:gsub('.*artifact_', '')
table.insert(entry.spells, spellId)
end
end
end
return hub
end
-- Folds all Cargo results into a single dictionary:
------------------------------------------------------------------------------------------------------------------------
local function consolidate(lang, results)
local hub = consolidateScrolls(lang, results)
for _, row in ipairs(results) do
local id = row.id
if not id:find('magic_scroll') then
local entry = hub[id]
if not entry then
entry = {}
entry.id = id or ''
hub[id] = entry
end
if row.language == lang then
entry.name = row.name or ''
entry.description = row.name or ''
end
if row.language == 'en' then
entry.nameEn = row.name or ''
end
end
end
return hub
end
------------------------------------------------------------------------------------------------------------------------
local function sortList(a, b)
return a.id < b.id
end
-- Boilerplate for the header cells
------------------------------------------------------------------------------------------------------------------------
local function addTh(tr, text)
return tr:tag('th'):wikitext(text)
end
-- Boilerplate for the body cells
------------------------------------------------------------------------------------------------------------------------
local function addTd(tr, content)
if type(content) == "string" then
return tr:tag('td'):wikitext(content)
else
return tr:tag('td'):node(content)
end
end
-- Boilerplate for the separator rows
------------------------------------------------------------------------------------------------------------------------
local function addSeparator(htmlTable, className, content)
htmlTable:tag('tr')
:addClass('separator')
:addClass(className)
:tag('td'):attr('data-sort-value', ''):attr('colspan', 100):wikitext(content):done()
end
------------------------------------------------------------------------------------------------------------------------
local function createHeader(htmlTable, words)
local tr = htmlTable:tag('tr')
--addTh(tr, 'id')
addTh(tr, words.wiki_artifact):attr('colspan', 2)
addTh(tr, 'description'):attr('colspan', 2)
end
------------------------------------------------------------------------------------------------------------------------
local function renderIcon(id, nameEn, lang)
local url = getUrl(nameEn, lang)
return f('[[File:%s.png|64px|link=%s]]', id, url)
end
------------------------------------------------------------------------------------------------------------------------
local function renderName(name, nameEn, lang)
local url = getUrl(nameEn, lang)
return f('[[%s|%s]]', url, name)
end
------------------------------------------------------------------------------------------------------------------------
local function createBody(htmlTable, list, lang)
local currentType = list[1].param1
local currentFaction = list[1].faction
for _, item in ipairs(list) do
-- separators
if item.faction ~= currentFaction then
currentFaction = item.faction
currentType = item.class_type
addSeparator(htmlTable, 'separator-large', '')
elseif item.class_type ~= currentType then
currentType = item.class_type
addSeparator(htmlTable, 'separator-tiny', '')
end
local tr = htmlTable:tag('tr'):addClass('artifact')
--addTd(tr, item.id)
addTd(tr, renderIcon(item.id, item.nameEn, lang))
addTd(tr, renderName(item.name, item.nameEn, lang))
addTd(tr, item.description)
end
end
-- M A I N
------------------------------------------------------------------------------------------------------------------------
function p.display(frame)
--do return dump(frame) end
-- Args
local args = frame.args
local lang = args.lang ~= '' and args.lang or 'en'
--lang = 'ja'
-- Language
local words = translateIds(TRANSLATION_IDS, lang)
-- Cargo
local results = queryMain(lang)
local hub = consolidate(lang, results)
local list = flatten(hub);
if #list == 0 then return words.wiki_none end
-- Various manipulations
table.sort(list, sortList)
-- Table
local htmlTable = mw.html.create('table')
htmlTable:addClass('wikitable sortable')
createHeader(htmlTable, words)
createBody(htmlTable, list, lang)
-- Output
local styleTag = frame:extensionTag('templatestyles', '', { src = frame:getTitle() .. '/styles.css' })
return '<div class="artifacts-overview">' .. styleTag .. tostring(htmlTable) .. '</div>'
end
return p


