Module:Traits

From Elwiki
Revision as of 19:04, 28 August 2022 by Ritsu (talk | contribs)

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

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

    -- Dictionary for headers
    local headers = {'MP Usage', 'Cooldown', 'Duration', 'MP Recovery', 'Max Hits'}
    local header_dict = {
        [1] = {'Light', 'Critical', 'Reversed'},
        [2] = {'Heavy', 'Haste', 'Regenerating (2)', 'Ruthless', 'Powerful', 'Reversed'},
        [3] = {'Killing Blow (1)'},
        [4] = {'Regenerating (1)'},
        [5] = {'Useful'}
    }

    -- Default values
    local default_trait_values = {
        Heavy = {
            multi_cooldown = 120
        },
        Light = {
            multi_mp_cost = 80
        },
        Critical = {
            multi_mp_cost = 120
        },
        Haste = {
            multi_cooldown = 80
        },
        Ruthless = {
            multi_cooldown = 200
        },
        Powerful = {
            multi_cooldown = 120
        }
    }

    -- 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.cooldown, args.cooldown_pvp, args.cooldown_enhanced, args.cooldown_enhanced_pvp}
        t.details_duration = {args.duration, args.duration_pvp, args.duration_enhanced, args.duration_enhanced_pvp}

        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)
        char = char or args[1]
        return frame:expandTemplate{
            title = 'ColorSel',
            args = {'CharLight', char}
        }:gsub("#", "#")
    end

    -- Main block
    local trait_table = mw.html.create('table'):attr({
        ['cellpadding'] = '5',
        ['border'] = '1'
    }):css({
        ['border-collapse'] = 'collapse',
        ['text-align'] = 'center'
    })

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

    local thead = newtr()
    local tr = newtr()
    local tr_2 = newtr()

    -- Header spawning method
    function Trait:do_headers()
        local function getCustomHeader(spawn)
            local i = 1
            while true do
                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

        thead:tag('th'):attr('colspan', self.colspan + getCustomHeader()):wikitext(self.name .. ' ' .. skill)
        local has_details = table.matches(header_dict, self.name);

        tr_2:tag('th'):wikitext('Attribute Effect')
        if has_details then
            if self.multi_mp_cost ~= 100 then
                if self.name == 'Regenerating (1)' then
                    tr_2:tag('th'):wikitext('MP Recovery')
                else
                    tr_2:tag('th'):wikitext('MP Usage')
                end
            end
            if self.multi_cooldown ~= 100 then
                tr_2:tag('th'):wikitext('Cooldown')
            end
            if self.multi_duration ~= 100 then
                tr_2:tag('th'):wikitext('Duration')
            end
            if self.name == 'Useful' then
                tr_2:tag('th'):wikitext('Max Hits')
            end
        end
        getCustomHeader(true)
    end

    trait_left:do_headers()
    trait_right:do_headers()

    trait_left:calc()
    trait_right:calc()

    local tr = trait_table:tag('tr')

    function Trait:do_content()
        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)
            for k, v in ipairs(param_tbl) do
                if (self['multi_' .. v] ~= 100) then
                    tr:tag('td'):wikitext(self['details_' .. v][1])
                end
            end
        end

        addIfMultiExists({'mp_cost', 'cooldown', 'duration'})

        local function getCustomContent()
            local i = 1
            while true do
                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

        getCustomContent()
            
    end

    trait_left:do_content()
    trait_right:do_content()

    return tostring(trait_table);

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

end

return p