Module:Traits: Difference between revisions

m
add i18n
No edit summary
m (add i18n)
 
(84 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
Line 17: Line 26:
     end
     end
     local skill = args[2] or args.skill
     local skill = args[2] or args.skill
    local default_multiplier = 100


     -- Dictionary for headers
     -- Dictionary for headers
     local headers = {'MP Usage', 'Cooldown', 'Duration', 'MP Recovery', 'Max Hits'}
     local prop = {  
     local header_dict = {
        is_rose and translate('ECP Usage') or translate('MP Usage'),
         [1] = {'Light', 'Critical', 'Reversed'},
        translate('Cooldown'),
         [2] = {'Heavy', 'Haste', 'Regenerating (2)', 'Ruthless', 'Powerful', 'Reversed'},
        translate('Duration'),
         [3] = {'Killing Blow (1)'},
        is_rose and translate('ECP Recovery') or translate('MP Recovery'),
         [4] = {'Regenerating (1)'},
        translate('Max Hits'),
         [5] = {'Useful'}
        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
     -- Default values
     local default_trait_values = {
     local DEFAULT = {
         Heavy = {
         [STR.HEAVY] = {
             multi_cooldown = 120
             cd = 120
        },
        [STR.LIGHT] = {
            mp = 80
         },
         },
         Light = {
         [STR.CRITICAL] = {
             multi_mp_cost = 80
             mp = (args['def_ignore1'] ~= nil or args['def_ignore2'] ~= nil) and 100 or 120
         },
         },
         Critical = {
         [STR.HASTE] = {
             multi_mp_cost = 120
             cd = 80
         },
         },
         Haste = {
         [STR.RUTHLESS] = {
             multi_cooldown = 80
             cd = 200
         },
         },
         Ruthless = {
         [STR.POWERFUL] = {
             multi_cooldown = 200
             cd = 150
         },
         },
         Powerful = {
         [STR.REGEN1] = {
             multi_cooldown = 120
             chance = 50,
            mp = 50
        },
        [STR.REGEN2] = {
            chance = 50,
            cd = 50
        },
        [STR.REVERSED] = {
            mp = 60,
            cd = 150
        },
        [STR.USEFUL] = {
            dmg = 80
        },
        [STR.PERSISTENT2] = {
            dmg = 100
         }
         }
     }
     }


    -- Define the class blueprint for traits.
    Trait = {}
    function Trait:new(t)
        t = t or {}
        t.details_mp_cost = {args.mp, args.mp_pvp, args.mp_enhanced, args.mp_enhanced_pvp}
        t.details_cooldown = {args.cd, args.cd_pvp, args.cd_enhanced, args.cd_enhanced_pvp}
        t.details_duration = {args.duration, args.duration_pvp, args.duration_enhanced, args.duration_enhanced_pvp}
        -- Automatic math
        for k, v in pairs(t) do
            if string.find(k, 'details_') then
                for k2, v2 in ipairs(v) do
                    t[k][k2] = frame:preprocess('{{#expr: ' .. v2 .. '}}')
                end
            end
        end
        t.colspan = 1
        t.colspan = t.colspan + table.matches(header_dict, t.name)
        t.multi_mp_cost = args['mp' .. t.index] or 100
        t.multi_cooldown = args['cd' .. t.index] or 100
        t.multi_duration = args['duration' .. t.index] or 100
        -- Set defaults for generic trait values.
        local default = default_trait_values[t.name]
        if (default ~= nil) then
            for k, v in pairs(default) do
                if (t[k] == 100) then
                    t[k] = v
                end
            end
        end
        t.chance = args['chance' .. t.index]
        t.unnamed_2 = args['desc1_trait' .. t.index]
        t.unnamed_3 = args['desc2_trait' .. t.index]
        self.__index = self
        setmetatable(t, self)
        return t
    end
    -- Calculation method
    function Trait:calc()
        for k, v in pairs(self) do
            local mp_done = false
            if (string.find(k, 'details_') and next(v)) then
                for k2, v2 in ipairs(v) do
                    local current_data = k:gsub('details_', '')
                    self[k][k2] = self['multi_' .. current_data] / 100 * v2
                    if current_data == 'mp_cost' or current_data == 'mp_recovery' then
                        self[k][k2] = self[k][k2] .. ' MP'
                    else
                        self[k][k2] = self[k][k2] .. ' Seconds'
                    end
                end
            end
        end
        return self
    end
    local trait_left = Trait:new({
        name = traits[1],
        index = 1
    })
    local trait_right = Trait:new({
        name = traits[2],
        index = 2
    })
    -- Get table head color
     local function color(char)
     local function color(char)
         char = char or args[1] or args.char
         char = char or args[1] or args.char or 'Elsword'
         return frame:expandTemplate{
         return char:gsub('/', '')
            title = 'ColorSel',
            args = {'CharLight', 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 144: Line 128:
     })
     })


     function newtr()
     function new_row()
         return trait_table:tag('tr'):css('background-color', color())
         return trait_table:tag('tr')
     end
     end


     local thead = newtr()
    -- headers
     local tr = newtr()
     local tr1 = new_row()
     local tr_2 = newtr()
     local tr2 = new_row()
     local tr3 = new_row()


     -- Header spawning method
     local has_pvp_values = false
     function Trait:do_headers()
     for k, v in pairs(args) do
         local function getCustomHeader(spawn)
         if string.find(k, '_pvp') then
            local i = 1
            has_pvp_values = true
            while true do
            break
                local custom_header = args['header' .. i .. '_trait' .. self.index]
                if custom_header ~= nil then
                    if spawn then
                        tr_2:tag('th'):wikitext(custom_header)
                    end
                    i = i + 1
                else
                    break
                end
            end
            return i-1
         end
         end
    end


         thead:tag('th'):attr('colspan', self.colspan + getCustomHeader()):wikitext(self.name .. ' ' .. skill)
    local tr4
         tr_2:tag('th'):wikitext('Attribute Effect')
    -- 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


         local has_details = table.matches(header_dict, self.name);
    -- 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 {};


         if has_details then
         -- Check if detail fields are required and which.
             if self.multi_mp_cost ~= 100 then
        for detail_key, detail in ipairs(details) do
                 if self.name == 'Regenerating (1)' then
             if not th_effect then
                    tr_2:tag('th'):wikitext('MP Recovery')
                 th_effect = tr2:tag('th'):wikitext(translate('Attribute Effect'));
                else
                    tr_2:tag('th'):wikitext('MP Usage')
                end
             end
             end
             if self.multi_cooldown ~= 100 then
             if indexOf(trait_name, detail) then
                 tr_2:tag('th'):wikitext('Cooldown')
                 local th_detail = tr2:tag('th'):wikitext(translate(prop[detail_key]));
                th:attr('colspan', tonumber(th:getAttr('colspan') or 1) + 1)
             end
             end
             if self.multi_duration ~= 100 then
        end
                 tr_2:tag('th'):wikitext('Duration')
 
        -- 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
             end
            if self.name == 'Useful' then
                tr_2:tag('th'):wikitext('Max Hits')
            end
        end
        getCustomHeader(true)
    end


    trait_left:do_headers()
            function doDetail()
    trait_right:do_headers()
                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 ''


    trait_left:calc()
                        local base_detail = args[short_detail_improved .. modeSuffix]
    trait_right:calc()


    local tr = trait_table:tag('tr')
                        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


    function Trait:do_content()
                        local end_value = calcEndValue(base_detail)
        tr:tag('td'):wikitext(frame:expandTemplate{
            title = 'SkillText',
            args = {
                self.name,
                self.unnamed_2,
                self.unnamed_3,
                MP = self.multi_mp_cost,
                CD = self.multi_cooldown,
                DURATION = self.multi_duration,
                CHANCE = self.chance
            }
        })


        local function addIfMultiExists(param_tbl)
                        local enhanced_detail = args[short_detail_improved .. modeSuffix .. '_enhanced']
            for k, v in ipairs(param_tbl) do
                        if enhanced_detail ~= nil then
                if (self['multi_' .. v] ~= 100) then
                            end_value = end_value .. "<br/>'''" .. frame:expandTemplate {
                    tr:tag('td'):wikitext(self['details_' .. v][1])
                                title = 'Tt',
                end
                                args = { calcEndValue(enhanced_detail) .. "'''",
            end
                                    translate("Final Enhanced Skill") }
        end
                            }
                        end


        addIfMultiExists({'mp_cost', 'cooldown', 'duration'})
                        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 function getCustomContent()
                            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);
            local i = 1
                        end
            while true do
                     end
                local custom_content = args['detail' .. i .. '_trait' .. self.index]
                if custom_content ~= nil then
                    tr:tag('td'):wikitext(custom_content)
                    i = i + 1
                else
                     break
                 end
                 end
             end
             end
            doDetail()
         end
         end
        getCustomContent()
           
     end
     end
    trait_left:do_content()
    trait_right:do_content()


     return tostring(trait_table);
     return tostring(trait_table);
    -- return dump(trait_left) .. '<br><br>' .. dump(trait_right);
end
end


return p
return p
-- pyend