Module:SkillChances

From Heroes of Might and Magic: Olden Era Official Wiki

Documentation for this module may be created at Module:SkillChances/doc

-- This module is intended as a supporting muscle for the SkillChances template.
local p = {}
local UtilQuery = require('Module:UtilQuery')
local FACTION = {
    humans = 'human', -- changed!
    necros = 'undead', -- changed!
    nature = 'nature',
    demons = 'demon', -- changed!
    unfrozen = 'unfrozen',
    dungeon = 'dungeon',
}

-- Displays a variable
------------------------------------------------------------------------------------------------------------------------
local function dump(target)
    return '<pre>' .. mw.dumpObject(target) .. '</pre>'
end

------------------------------------------------------------------------------------------------------------------------
local function collectChances()
    local result = UtilQuery.run([[
        tables =
            SkillRollWeight = S
        |where =
            S.table_id NOT LIKE 'arenaGame%%'
        |fields =
            S.table_id = table_id,
            S.band_kind = band_kind,
            S.skill_id = skill_id,
            S.weight = weight
        |limit = 1000
    ]])
    return result
end

------------------------------------------------------------------------------------------------------------------------
local function consolidateChances(chancesBulk)
    local chances = {}
    for _, row in ipairs(chancesBulk) do
        local tableId = row.table_id or ''
        local factionPlural, type = tableId:match('^([^_]+)_([^_]+)')
        local classId = type .. '_' .. FACTION[factionPlural]
        local entry = chances[classId]
        if not entry then
            chances[classId] = {
                default = {},
                magic_levels = {},
                signature_levels = {},
                level_20_mega = {},
            }
            entry = chances[classId]
        end
        local band_kind = row.band_kind or 'default'
        entry[band_kind][row.skill_id] = tonumber(row.weight)
    end
    return chances
end

------------------------------------------------------------------------------------------------------------------------
local function computeTotals(chances)
    local totals = {}
    for classId, info in pairs(chances) do
        totals[classId] = {
            default = 0,
            magic_levels = 0,
            signature_levels = 0,
            level_20_mega = 0,
        }
        for skillId, weight in pairs(info.default) do
            totals[classId].default = totals[classId].default + weight

            local magicWeight = info.magic_levels[skillId] or weight
            totals[classId].magic_levels = totals[classId].magic_levels + magicWeight

            local signatureWeight = info.signature_levels[skillId] or weight
            totals[classId].signature_levels = totals[classId].signature_levels + signatureWeight

            local l20Weight = info.level_20_mega[skillId] or weight
            totals[classId].level_20_mega = totals[classId].level_20_mega + l20Weight
        end
    end
    return totals
end

------------------------------------------------------------------------------------------------------------------------
local function formatRatio(a, b)
    if not a or not b then
        return ''
    end
    return string.format("%.2f", 100 * a / b) .. '%'
end

------------------------------------------------------------------------------------------------------------------------
local function formatChances(chances, totals, skillId)
    local lines = {}
    for classId, info in pairs(chances) do
        local parts = {}

        local main = info.default[skillId]
        local magic = info.magic_levels[skillId] or main
        local signature = info.signature_levels[skillId] or main
        local l20 = info.level_20_mega[skillId] or main

        local ts = totals[classId]
        table.insert(parts, formatRatio(main, ts.default))
        table.insert(parts, magic ~= main and formatRatio(magic, ts.magic_levels) or '')
        table.insert(parts, signature ~= main and formatRatio(signature, ts.signature_levels) or '')
        table.insert(parts, l20 ~= main and formatRatio(l20, ts.level_20_mega) or '')

        while #parts > 0 and parts[#parts] == '' do
            table.remove(parts)
        end

        table.insert(lines, '| ' .. classId .. ' = ' .. table.concat(parts, ','))
    end
    return table.concat(lines, '\n')
end

------------------------------------------------------------------------------------------------------------------------
function p.populate(frame)
    local lang = frame.args.lang
    local skillId = frame.args.id;

    local chancesBulk = collectChances();
    local chances = consolidateChances(chancesBulk);
    local totals = computeTotals(chances);
    local formattedChances = formatChances(chances, totals, skillId);
    --do return dump(formattedChances) end

    local cleanTitle = frame:getTitle():gsub('Module:', '')
    return frame:preprocess(mw.ustring.format([[
        {{%s/base
        | lang = %s
        | id = %s
        %s
        }}
    ]], cleanTitle, lang, skillId, formattedChances))
end

return p