Module:SkillArtifacts: Difference between revisions

From Heroes of Might and Magic: Olden Era Official Wiki
No edit summary
No edit summary
Line 151: Line 151:
     if skillId == '' then return 'You must provide a skill id!' end
     if skillId == '' then return 'You must provide a skill id!' end
     --lang = 'en'
     --lang = 'en'
     skillId = 'skill_diplomacy'
     --skillId = 'skill_diplomacy'


     -- Cargo
     -- Cargo

Revision as of 20:20, 9 June 2026

This module lists the artifacts that mention a specific skill. Additionally, it applies hyperlinks to words that exactly match skill names.

Usage

1. English:

Input: {{#invoke:SkillArtifacts|display | lang=en | skill=skill_diplomacy}}

Output: Cannot resolve skill!


2. Japanese:

Input: {{#invoke:SkillArtifacts|display | lang=ja | skill=skill_diplomacy}}

Output: Cannot resolve skill!


-- Usage: {{#invoke:SkillArtifacts|display|lang=en|skill=skill_assault}}
local p = {}
local SkillsOverview = require("Module:SkillsOverview")
local PATCH_NAME = {
    ['Summon Avatar'] = 'Summon Avatar (Skill)',
}

------------------------------------------------------------------------------------------------------------------------
-- Debugs 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)
    local url = PATCH_NAME[nameEn] or nameEn
    if lang ~= 'en' then
        url = url .. '/' .. lang
    end
    return url
end

------------------------------------------------------------------------------------------------------------------------
--
------------------------------------------------------------------------------------------------------------------------
local function queryArtifacts(lang)
    -- fields:
    local fields = {}
    table.insert(fields, 'Artifact.id = id');
    table.insert(fields, 'Artifact.icon = icon');
    table.insert(fields, 'Translation.name = name');
    table.insert(fields, 'Translation.description = description');
    table.insert(fields, 'Translation.language = language');

    -- where:
    local where = {}
    table.insert(where, '(Translation.language = "en" OR Translation.language = "' .. lang .. '")')

    -- query:
    return mw.ext.cargo.query('Artifact, Translation', table.concat(fields, ','), {
        join = 'Artifact.id = Translation.target_id',
        where = table.concat(where, ' AND '),
        limit = 1000
    })
end

------------------------------------------------------------------------------------------------------------------------
-- Folds all artifact results from Cargo into a compacted table
------------------------------------------------------------------------------------------------------------------------
local function consolidateArtifacts(artifactsResult, lang)
    local hub = {}
    for _, row in ipairs(artifactsResult) do
        local id = row.id
        hub[id] = hub[id] or { id = id }
        local entry = hub[id]
        if row.language == lang then
            entry.name = row.name or ''
            entry.description = row.description or ''
            entry.icon = row.icon or ''
        end
        if row.language == 'en' then
            entry.descriptionEn = row.description or ''
        end
    end
    return hub
end

------------------------------------------------------------------------------------------------------------------------
--
------------------------------------------------------------------------------------------------------------------------
local function linkifyDescription(description, allSkills, lang)
    for _, group in ipairs(allSkills) do
        local url = getUrl(group.nameEn, lang)
        description = mw.ustring.gsub(description, '(' .. group.name .. ')', '[[' .. url .. '|' .. '%1]]')
    end
    return description
end

------------------------------------------------------------------------------------------------------------------------
--
------------------------------------------------------------------------------------------------------------------------
local function highlightCurrentSkill(description, name)
    local spanMarkup = '<span style="color:peru">' .. name .. '</span>'
    description = mw.ustring.gsub(description, '%[%[[^%]]*' .. name .. '%]%]', spanMarkup)
    return description
end

------------------------------------------------------------------------------------------------------------------------
--
------------------------------------------------------------------------------------------------------------------------
local function findRelatedArtifacts(artifacts, skill, allSkills, lang)
    local related = {}
    for _, artifact in pairs(artifacts) do
        if artifact.descriptionEn:match(skill.nameEn) then
            -- We found an artifact that mentions our target skill by name
            local description = linkifyDescription(artifact.description, allSkills, lang)
            description = highlightCurrentSkill(description, skill.name)
            table.insert(related, {
                name = artifact.name,
                description = description,
                icon = artifact.icon,
            })
        end
    end
    return related
end

------------------------------------------------------------------------------------------------------------------------
--
------------------------------------------------------------------------------------------------------------------------
local function renderArtifacts(artifacts)
    local root = mw.html.create()
    for _, artifact in ipairs(artifacts) do
        local container = root:tag('div'):css('display', 'flex'):css('margin-bottom', '8px')

        -- Left
        local icon = '[[File:' .. artifact.icon .. '.png|64px|link=]]'
        container:tag('div'):css('flex-shrink', 0):wikitext(icon)

        -- Right
        local content = "'''" .. artifact.name .. "'''<br>" .. artifact.description
        container:tag('div'):css('flex-grow', 1):css('padding', '8px 0 0 6px'):wikitext(content)
    end
    return tostring(root)
end

------------------------------------------------------------------------------------------------------------------------
--
------------------------------------------------------------------------------------------------------------------------
local function findSkill(allSkills, skillId)
    for _, group in ipairs(allSkills) do
        if group.id == skillId then
            return group
        end
    end
end

------------------------------------------------------------------------------------------------------------------------
-- Main public function
------------------------------------------------------------------------------------------------------------------------
function p.display(frame)
    --if 1 then return dump(frame) end

    -- Args
    local args = frame.args
    local lang = args.lang or 'en'
    local skillId = args.skill or ''
    if skillId == '' then return 'You must provide a skill id!' end
    --lang = 'en'
    --skillId = 'skill_diplomacy'

    -- Cargo
    local allSkills = SkillsOverview.getSkillsFromCargo(lang)
    local skill = findSkill(allSkills, skillId)
    if not skill then return 'Cannot resolve skill!' end
    local artifactsResult = queryArtifacts(lang)
    local artifactsHub = consolidateArtifacts(artifactsResult, lang)

    -- Main computation
    local artifacts = findRelatedArtifacts(artifactsHub, skill, allSkills, lang)
    --if 1 then return dump(artifacts) end
    if #artifacts == 0 then return "''No results''" end

    -- Output
    local markup = renderArtifacts(artifacts)
    return markup
end

return p