Module:Traits: Difference between revisions

From Elwiki
No edit summary
m (add i18n)
 
(107 intermediate revisions by 2 users not shown)
Line 1: Line 1:
-- pystart
require('Module:CommonFunctions')
require('Module:CommonFunctions')
local i18n = require('Module:I18n')
local getArgs = require('Module:Arguments').getArgs
local getArgs = require('Module:Arguments').getArgs
local getTranslations = i18n.getTranslations
local p = {}
local p = {}


-- Main process
-- Main process
function p.main(frame)
function p.main(frame)
     local args = getArgs(frame);
     local args = getArgs(frame)
    local tr = getTranslations(frame, 'Template:Traits', args.lang, true)
    local is_rose = args[1] == 'Rose' and args.ecp == 'true'
 
    function translate(key)
        return i18n.translate(tr, key)
    end


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


     -- Attribute effect
     -- Dictionary for headers
     local effects = {
     local prop = {  
         [1] = {},
         is_rose and translate('ECP Usage') or translate('MP Usage'),
         [2] = {}
        translate('Cooldown'),
        translate('Duration'),
        is_rose and translate('ECP Recovery') or translate('MP Recovery'),
        translate('Max Hits'),
         translate('Effects'),
     }
     }
    args.effects1 = args.effects1 or args[4]
    args.effects2 = args.effects2 or args[5]
    if args.effects1 ~= nil then
        effects[1] = split(args.effects1)
    end
    if args.effects2 ~= nil then
        effects[2] = split(args.effects2)
    end


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


    -- Extra effects
     local OPTIONS = {
     local counts = {}
        lang_suffix = args.lang and ('/' .. args.lang) or '',
    local desc_arg = nil;
         lang_append = args.lang ~= nil and args.lang ~= ''
    local header_data = {}
    }
    for i = 1, 2, 1 do
         if (i == 1) then
            desc_arg = args[6]
        else
            desc_arg = args[7]
        end


         if desc_arg == nil then
    local STR = {
            desc_arg = args['desc' .. i]
        LIGHT = 'Light',
         end
        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',
        ECP = 'ECP',
        PERSISTENT = 'Persistent',
        PERSISTENT2 = 'Persistent2'
    }


         if desc_arg ~= nil then
    local details = {
            traits[i] = trim(traits[i]);
        { STR.LIGHT, STR.CRITICAL, STR.REVERSED },
            local data_split = split(desc_arg, ';');
        { STR.HEAVY, STR.HASTE,    STR.REGEN2,  STR.RUTHLESS, STR.POWERFUL, STR.REVERSED },
            local headers;
         { STR.KB1 },
            local data;
        { STR.REGEN1 },
        { STR.USEFUL, STR.PERSISTENT2 },
        { STR.KB2 }
    }


            if (#data_split >= 2) then
    -- Default values
                headers = split(data_split[1]);
    local DEFAULT = {
                data = data_split[2];
        [STR.HEAVY] = {
             else
             cd = 120
                data = data_split[1];
        },
 
        [STR.LIGHT] = {
                -- Generate headers based on trait.
            mp = 80
                if (traits[i] == 'Light' or traits[i] == 'Critical') then
        },
                    headers = {
        [STR.CRITICAL] = {
                        [1] = 'MP Usage'
            mp = (args['def_ignore1'] ~= nil or args['def_ignore2'] ~= nil) and 100 or 120
                    }
        },
                elseif (traits[i] == 'Heavy' or traits[i] == 'Haste' or traits[i] == 'Regenerating (2)' or traits[i] ==
        [STR.HASTE] = {
                    'Ruthless' or traits[i] == 'Powerful') then
            cd = 80
                    headers = {
        },
                        [1] = 'Cooldown'
        [STR.RUTHLESS] = {
                    }
            cd = 200
                elseif (traits[i] == 'Reversed') then
        },
                    headers = {
        [STR.POWERFUL] = {
                        [1] = 'Cooldown',
            cd = 150
                        [2] = 'MP Usage'
        },
                    }
        [STR.REGEN1] = {
                elseif (traits[i] == 'Regenerating (1)') then
            chance = 50,
                    headers = {
             mp = 50
                        [1] = 'MP Recovery'
        },
                    }
        [STR.REGEN2] = {
                elseif (traits[i] == 'Killing Blow (1)') then
            chance = 50,
                    headers = {
             cd = 50
                        [1] = 'Duration'
        },
                    }
        [STR.REVERSED] = {
                else
             mp = 60,
                    headers = {}
             cd = 150
                end
        },
 
        [STR.USEFUL] = {
             end
            dmg = 80
 
        },
            for k, v in spairs(headers) do
        [STR.PERSISTENT2] = {
                header_data[i] = {}
            dmg = 100
                table.insert(header_data[i], trim(v))
        }
             end
    }
 
            data = split(data);
            counts[i] = 1 + #headers;
 
             local index = 1
             while index <= #headers do
                desc[i] = {}
                desc[i][index] = {}
                desc[i][index][headers[index]] = trim(data[index])
                index = index + 1
            end
        end


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


    -- Main block
     local trait_table = mw.html.create('div'):attr('class', 'content-table'):tag('table'):attr({
     local trait_table = mw.html.create('table'):attr({
         cellpadding = '5',
         ['cellpadding'] = '5',
         border = '1',
         ['border'] = '1'
        class = 'colortable-' .. color()
     }):css({
     }):css({
         ['border-collapse'] = 'collapse',
         ['border-collapse'] = 'collapse',
Line 115: Line 128:
     })
     })


     -- Get table head color
     function new_row()
    local function color(char)
         return trait_table:tag('tr')
        char = char or args[1]
         return frame:expandTemplate{
            title = 'ColorSel',
            args = {'CharLight', char}
        }:gsub("&#35;", "#")
     end
     end


     function newtr()
     -- headers
        return trait_table:tag('tr'):css('background-color', color())
    local tr1 = new_row()
    local tr2 = new_row()
    local tr3 = new_row()
 
    local has_pvp_values = false
    for k, v in pairs(args) do
        if string.find(k, '_pvp') then
            has_pvp_values = true
            break
        end
     end
     end


     -- Spawn headers
    local tr4
     local thead = newtr()
     -- If pvp values exist, we need the row to place them.
    thead:tag('th'):attr('colspan', counts[1]):wikitext(traits[1] .. ' ' .. skill)
     if has_pvp_values and not tr4 then
    thead:tag('th'):attr('colspan', counts[2]):wikitext(traits[2] .. ' ' .. skill)
        tr4 = new_row()
        -- Add indicator headers
        tr1:tag('th'):wikitext(translate('Mode')):attr('rowspan', 2)
        tr3:tag('td'):wikitext(frame:expandTemplate {
            title = translate('PvE')
        })
        tr4:tag('td'):wikitext(frame:expandTemplate {
            title = translate('PvP')
        })
    end


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


    local tr_2 = newtr();
         -- Check if detail fields are required and which.
    for i = 1, 2, 1 do
         for detail_key, detail in ipairs(details) do
         no_desc = args['desc' .. i] == nil and args[6] == nil and args[7] == nil;
            if not th_effect then
        tr_2:tag('th'):wikitext('Attribute Effect')
                 th_effect = tr2:tag('th'):wikitext(translate('Attribute Effect'));
         if not (no_desc or header_data[i] == nil) then
            for k, v in ipairs(header_data[i]) do
                 v = frame:preprocess(v);
                tr_2:tag('th'):wikitext(v)
             end
             end
            if indexOf(trait_name, detail) then
                local th_detail = tr2:tag('th'):wikitext(translate(prop[detail_key]));
                th:attr('colspan', tonumber(th:getAttr('colspan') or 1) + 1)
            end
        end
        -- Unnamed argument.
        local unnamed = split(args[3 + trait_count]);
        local MP_ARG = args['mp' .. trait_count] or args['mp_recovery' .. trait_count] or default_value['mp_recovery'] or
            default_value['mp'];
        local ECP_ARG = nil
        if is_rose then
            unnamed[2] = unnamed[1] or args['mp' .. trait_count]
            ECP_ARG = unnamed[1] or args['mp' .. trait_count]
            MP_ARG = nil
         end
         end
    end


    -- Spawn information
        -- Append contents.
    local tr = trait_table:tag('tr')
        for detail_key, detail in ipairs(details) do
    for i = 1, 2, 1 do
            if not th_skilltext then
        no_desc = args['desc' .. i] == nil and args[6] == nil and args[7] == nil;
                th_skilltext = tr3:tag('td'):attr('rowspan', has_pvp_values and 2 or 1):wikitext(frame:expandTemplate {
        tr:tag('td'):wikitext(frame:expandTemplate{
                    title = translate('SkillText'),
            title = 'SkillText',
                    args = {
            args = {traits[i], effects[i][1], effects[i][2]}
                        trait_name,
        })
                        unnamed[1],
        if not (no_desc or desc[i] == nil) then
                        unnamed[2],
            for k, v in ipairs(desc[i]) do
                        MP = args['def_ignore' .. trait_count] ~= nil and 'Energy' or MP_ARG,
                for k2, v2 in pairs(desc[i][k]) do
                        ECP = ECP_ARG,
                    local expr_header_table = {
                        CD = args['cd' .. trait_count] or default_value['cd'],
                         [1] = 'Cooldown',
                        DURATION = args['duration' .. trait_count],
                         [2] = 'MP Usage',
                         CHANCE = args['chance' .. trait_count] or default_value['chance'],
                         [3] = 'MP Recovery',
                         DAMAGE = args['dmg' .. trait_count] or default_value['dmg'],
                         [4] = 'Duration'
                         DEF_IGNORE = args['def_ignore' .. trait_count],
                         DEF_IGNORE_PVP = args['pvp_def_ignore' .. trait_count]
                     }
                     }
                     if (table.containsValue(expr_header_table, k2)) then
                });
                         v2 = '{{#expr:' .. v2 .. '}}'
            end
                         if (k2 == expr_header_table[1] or k2 == expr_header_table[3]) then
 
                             v2 = v2 .. ' MP'
            function doDetail()
                        else
                for _, modeSuffix in ipairs({ '', '_pvp' }) do
                             v2 = v2 .. ' Seconds'
                     if indexOf(trait_name, detail) then
                         local short_detail = prop_short[detail_key]
                        local short_detail_improved = short_detail
                        local is_pvp = modeSuffix == '_pvp'
 
                        -- 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
                            if is_rose then
                                suffix = STR.ECP
                            end
                        elseif short_detail == 'cd' or short_detail == 'duration' then
                            suffix = STR.SEC
                        end
                        suffix = suffix and (' ' .. suffix) or ''
 
                        local base_detail = args[short_detail_improved .. modeSuffix]
 
                         local function calcEndValue(base)
                            local end_value;
                            if base and tonumber(base) == nil then
                                end_value = base
                            else
                                end_value = (tonumber(multiplier) / 100) * tonumber(base or -1)
                            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)
 
                        local enhanced_detail = args[short_detail_improved .. modeSuffix .. '_enhanced']
                        if enhanced_detail ~= nil then
                            end_value = end_value .. "<br/>'''" .. frame:expandTemplate {
                                title = 'Tt',
                                args = { calcEndValue(enhanced_detail) .. "'''",
                                    translate("Final Enhanced Skill") }
                            }
                        end
 
                        if (is_pvp and base_detail) or not is_pvp then
                             local detail_text = end_value
                            if end_value == '-' and args['detail' .. trait_count] then
                                detail_text = args
                                    ['detail' .. trait_count]
                            end
 
                             local detail_cell = (is_pvp and tr4 or tr3):tag('td'):wikitext(detail_text):attr('rowspan', has_pvp_values and (not args[short_detail_improved .. '_pvp']) and 2 or 1);
                         end
                         end
                     end
                     end
                    tr:tag('td'):wikitext(frame:preprocess(v2))
                 end
                 end
             end
             end
            doDetail()
         end
         end
     end
     end


    -- Output point
     return tostring(trait_table);
     return tostring(trait_table);
end
end


return p
return p
-- pyend

Latest revision as of 00:43, 15 March 2024

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

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

-- Main process
function p.main(frame)
    local args = getArgs(frame)
    local tr = getTranslations(frame, 'Template:Traits', args.lang, true)
    local is_rose = args[1] == 'Rose' and args.ecp == 'true'

    function translate(key)
        return i18n.translate(tr, key)
    end

    -- 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 = { 
        is_rose and translate('ECP Usage') or translate('MP Usage'),
        translate('Cooldown'),
        translate('Duration'),
        is_rose and translate('ECP Recovery') or translate('MP Recovery'),
        translate('Max Hits'),
        translate('Effects'),
    }

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

    local OPTIONS = {
        lang_suffix = args.lang and ('/' .. args.lang) or '',
        lang_append = args.lang ~= nil and args.lang ~= ''
    }

    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',
        ECP = 'ECP',
        PERSISTENT = 'Persistent',
        PERSISTENT2 = 'Persistent2'
    }

    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, STR.PERSISTENT2 },
        { STR.KB2 }
    }

    -- Default values
    local DEFAULT = {
        [STR.HEAVY] = {
            cd = 120
        },
        [STR.LIGHT] = {
            mp = 80
        },
        [STR.CRITICAL] = {
            mp = (args['def_ignore1'] ~= nil or args['def_ignore2'] ~= nil) and 100 or 120
        },
        [STR.HASTE] = {
            cd = 80
        },
        [STR.RUTHLESS] = {
            cd = 200
        },
        [STR.POWERFUL] = {
            cd = 150
        },
        [STR.REGEN1] = {
            chance = 50,
            mp = 50
        },
        [STR.REGEN2] = {
            chance = 50,
            cd = 50
        },
        [STR.REVERSED] = {
            mp = 60,
            cd = 150
        },
        [STR.USEFUL] = {
            dmg = 80
        },
        [STR.PERSISTENT2] = {
            dmg = 100
        }
    }

    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()

    local has_pvp_values = false
    for k, v in pairs(args) do
        if string.find(k, '_pvp') then
            has_pvp_values = true
            break
        end
    end

    local tr4
    -- If pvp values exist, we need the row to place them.
    if has_pvp_values and not tr4 then
        tr4 = new_row()
        -- Add indicator headers
        tr1:tag('th'):wikitext(translate('Mode')):attr('rowspan', 2)
        tr3:tag('td'):wikitext(frame:expandTemplate {
            title = translate('PvE')
        })
        tr4:tag('td'):wikitext(frame:expandTemplate {
            title = translate('PvP')
        })
    end

    -- Loop through 2 input traits.
    for trait_count, trait_name in ipairs(traits) do
        local th = tr1:tag('th'):wikitext(trait_name:gsub(translate(STR.PERSISTENT) .. 2, translate(STR.PERSISTENT)) .. ' ' .. skill);
        local th_effect;
        local th_skilltext;
        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(translate('Attribute Effect'));
            end
            if indexOf(trait_name, detail) then
                local th_detail = tr2:tag('th'):wikitext(translate(prop[detail_key]));
                th:attr('colspan', tonumber(th:getAttr('colspan') or 1) + 1)
            end
        end

        -- Unnamed argument.
        local unnamed = split(args[3 + trait_count]);
        local MP_ARG = args['mp' .. trait_count] or args['mp_recovery' .. trait_count] or default_value['mp_recovery'] or
            default_value['mp'];
        local ECP_ARG = nil

        if is_rose then
            unnamed[2] = unnamed[1] or args['mp' .. trait_count]
            ECP_ARG = unnamed[1] or args['mp' .. trait_count]
            MP_ARG = nil
        end

        -- Append contents.
        for detail_key, detail in ipairs(details) do
            if not th_skilltext then
                th_skilltext = tr3:tag('td'):attr('rowspan', has_pvp_values and 2 or 1):wikitext(frame:expandTemplate {
                    title = translate('SkillText'),
                    args = {
                        trait_name,
                        unnamed[1],
                        unnamed[2],
                        MP = args['def_ignore' .. trait_count] ~= nil and 'Energy' or MP_ARG,
                        ECP = ECP_ARG,
                        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'],
                        DEF_IGNORE = args['def_ignore' .. trait_count],
                        DEF_IGNORE_PVP = args['pvp_def_ignore' .. trait_count]
                    }
                });
            end

            function doDetail()
                for _, modeSuffix in ipairs({ '', '_pvp' }) do
                    if indexOf(trait_name, detail) then
                        local short_detail = prop_short[detail_key]
                        local short_detail_improved = short_detail
                        local is_pvp = modeSuffix == '_pvp'

                        -- 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
                            if is_rose then
                                suffix = STR.ECP
                            end
                        elseif short_detail == 'cd' or short_detail == 'duration' then
                            suffix = STR.SEC
                        end
                        suffix = suffix and (' ' .. suffix) or ''

                        local base_detail = args[short_detail_improved .. modeSuffix]

                        local function calcEndValue(base)
                            local end_value;
                            if base and tonumber(base) == nil then
                                end_value = base
                            else
                                end_value = (tonumber(multiplier) / 100) * tonumber(base or -1)
                            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)

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

                        if (is_pvp and base_detail) or not is_pvp then
                            local detail_text = end_value
                            if end_value == '-' and args['detail' .. trait_count] then
                                detail_text = args
                                    ['detail' .. trait_count]
                            end

                            local detail_cell = (is_pvp and tr4 or tr3):tag('td'):wikitext(detail_text):attr('rowspan', has_pvp_values and (not args[short_detail_improved .. '_pvp']) and 2 or 1);
                        end
                    end
                end
            end

            doDetail()
        end
    end

    return tostring(trait_table);
end

return p
-- pyend