Module:Traits

From Elwiki
Revision as of 18:52, 14 January 2023 by Ritsu (talk | contribs)

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

-- pystart
require('Module:CommonFunctions')
local getArgs = require('Module:Arguments').getArgs
local p = {}

-- Main process
function p.main(frame)
    local args = getArgs(frame);

    -- Argument init
    local traits = args[3] or args.traits
    if (traits == nil) then
        traits = '-, -'
    end
    traits = split(traits);
    for k, v in ipairs(traits) do
        traits[k] = trim(v)
    end
    local skill = args[2] or args.skill
    local default_multiplier = 100

    -- Dictionary for headers
    local prop = {'MP Usage', 'Cooldown', 'Duration', 'MP Recovery', 'Max Hits'}

    local prop_short = {'mp', 'cd', 'duration', 'mp_recovery', 'hits', 'chance'}

    local STR = {
        LIGHT = 'Light',
        CRITICAL = 'Critical',
        REVERSED = 'Reversed',
        HEAVY = 'Heavy',
        HASTE = 'Haste',
        REGEN1 = 'Regenerating (1)',
        REGEN2 = 'Regenerating (2)',
        KB1 = 'Killing Blow (1)',
        KB2 = 'Killing Blow (2)',
        RUTHLESS = 'Ruthless',
        POWERFUL = 'Powerful',
        USEFUL = 'Useful',
        SEC = ' Seconds',
        MP = ' MP'
    }

    local details = {{STR.LIGHT, STR.CRITICAL, STR.REVERSED},
                     {STR.HEAVY, STR.HASTE, STR.REGEN2, STR.RUTHLESS, STR.POWERFUL, STR.REVERSED}, {STR.KB1},
                     {STR.REGEN1}, {STR.USEFUL}}

    -- Default values
    local DEFAULT = {
        [STR.HEAVY] = {
            cd = 120
        },
        [STR.LIGHT] = {
            mp = 80
        },
        [STR.CRITICAL] = {
            mp = 120
        },
        [STR.HASTE] = {
            cd = 80
        },
        [STR.RUTHLESS] = {
            cd = 200
        },
        [STR.POWERFUL] = {
            cd = 150
        },
        [STR.REGEN1] = {
            chance = 50,
            mp_recovery = 50
        },
        [STR.REGEN2] = {
            chance = 50,
            cd = 50
        },
        [STR.REVERSED] = {
            mp = 60,
            cd = 150
        },
        [STR.USEFUL] = {
            dmg = 80
        }
    }

    local function color(char)
        char = char or args[1] or args.char or 'Elsword'
        return char:gsub('/', '')
    end

    local trait_table = mw.html.create('div'):attr('class', 'content-table'):tag('table'):attr({
        cellpadding = '5',
        border = '1',
        class = 'colortable-' .. color()
    }):css({
        ['border-collapse'] = 'collapse',
        ['text-align'] = 'center'
    })

    function new_row()
        return trait_table:tag('tr')
    end

    -- headers
    local tr1 = new_row()
    local tr2 = new_row()
    local tr3 = new_row()

    -- Loop through 2 input traits.
    for trait_count, trait_name in ipairs(traits) do
        local th = tr1:tag('th'):wikitext(trait_name .. ' ' .. skill);
        local th_effect;
        local th_skilltext;
        local detail_list = {}
        local default_value = DEFAULT[trait_name] or {};

        -- Check if detail fields are required and which.
        for detail_key, detail in ipairs(details) do
            if not th_effect then
                th_effect = tr2:tag('th'):wikitext('Attribute Effect');
            end
            if indexOf(trait_name, detail) then
                local th_detail = tr2:tag('th'):wikitext(prop[detail_key]);
                th:attr('colspan', tonumber(th:getAttr('colspan') or 1) + 1)
            end
        end

        -- Unnamed argument.
        local unnamed = split(args[3 + trait_count]);
        if args[1] == 'Rose' then
            unnamed[2] = unnamed[1]
            unnamed[1] = 'ECP'
        end

        -- Append contents.
        for detail_key, detail in ipairs(details) do
            if not th_skilltext then
                th_skilltext = tr3:tag('td'):wikitext(frame:expandTemplate{
                    title = 'SkillText',
                    args = {
                        trait_name,
                        unnamed[1],
                        unnamed[2],
                        MP = args['mp' .. trait_count] or args['mp_recovery' .. trait_count] or default_value['mp'] or
                            default_value['mp_recovery'],
                        CD = args['cd' .. trait_count] or default_value['cd'],
                        DURATION = args['duration' .. trait_count],
                        CHANCE = args['chance' .. trait_count] or default_value['chance'],
                        DAMAGE = args['dmg' .. trait_count] or default_value['dmg']
                    }
                });
            end
            if indexOf(trait_name, detail) then
                local short_detail = prop_short[detail_key]
                local short_detail_improved = short_detail

                -- Fix Regen 1.
                if short_detail == 'mp_recovery' then
                    short_detail_improved = 'mp'
                end

                local detail_content = args[short_detail_improved .. trait_count]
                local multiplier = detail_content or default_value[short_detail_improved] or 100
                local suffix = ''
                if short_detail_improved == 'mp' then
                    suffix = STR.MP
                elseif short_detail == 'cd' or short_detail == 'duration' then
                    suffix = STR.SEC
                end

                local base_detail = args[short_detail_improved]

                local function calcEndValue(base)
                    local end_value;
                    if short_detail == 'hits' then
                        end_value = base or 0
                    else
                        end_value = (tonumber(multiplier) / 100) * tonumber(base or 0)
                    end
                    if tonumber(end_value) ~= nil and tonumber(end_value) <= 0 then
                        end_value = '-'
                    end
                    return end_value .. suffix
                end

                local end_value = calcEndValue(base_detail)

                if args[short_detail_improved .. '_enhanced'] ~= nil then
                    end_value = end_value .. "<br/>'''" .. frame:expandTemplate{
                        title = 'Tt',
                        args = {calcEndValue(args[short_detail_improved .. '_enhanced']) .. "'''",
                                "Final Enhanced Skill"}
                    }
                end

                local detail_cell = tr3:tag('td'):wikitext(end_value);
            end
        end

    end

    return tostring(trait_table);

end

return p
-- pyend