Module:Damage

From Elwiki
Revision as of 01:40, 3 April 2022 by Ritsu (talk | contribs)

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

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

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

    function inArgs(key)
        if args[key] ~= nil then
            return true
        end
    end

    function inArgsStarts(key)
        for k, v in spairs(args) do
            if string.starts(k, key) then
                return true
            end
        end
    end

    -- Function wrapper for vardefine syntax in MW.
    function var(name, dmg)
        if (args.format == 'false') then
            return '{{#vardefine:' .. name .. '|' .. round(dmg) .. '}}'
        else
            return '{{#vardefine:' .. name .. '|{{formatnum:' .. round(dmg) .. '}}%}}'
        end
    end

    -- Handle trait table
    local traits = {}

    if (inArgs('heavy')) then
        traits.heavy = 1.44
    end

    if (inArgs('enhanced')) then
        traits.enhanced = 0.8
    end

    -- Customizable for empowered, it had to be special lol.
    if (inArgs('empowered')) then
        if (args.empowered == 'true') then
            traits.empowered = 1.2
        else
            traits.empowered = args.empowered
        end
    end

    function list(ispvp)

        -- Define tables that hold the subsequent damage values.
        -- I know this isn't the best, but I don't want to work with nested tables in this language.
        local fvals = {}
        local tvals = {}
        local pvals1 = {}
        local pvals2 = {}
        local pvals12 = {}

        -- Check the specified mode and define the prefixes/suffixes first.
        local pr = ''
        local su = ''
        local p_index = 1
        if ispvp then
            p_index = 2
        end

        if (ispvp) then
            pr = 'pvp_'
            su = '_pvp'
        end

        -- Define total/average damage calculation based on damage per hit and hit amount.
        function getTotal(dmg, hits, fval)
            local i = 1
            fvals[fval] = 0
            for k, v in spairs(args) do
                if string.starts(k, pr .. 'dmg') then
                    -- Proceed to combine
                    fvals[fval] = fvals[fval] + args[dmg .. i] * args[hits .. i]
                    i = i + 1
                end
            end
            -- Apply Useful modifier.
            if string.find(fval, 'useful') then
                fvals[fval] = fvals[fval] * args.useful_penalty
            end
        end

        -- Actually generate the values depending on arguments provided.
        getTotal(pr .. 'dmg', 'hits', 'total_damage' .. su)

        if inArgsStarts('avg_hits') then
            getTotal(pr .. 'dmg', 'avg_hits', 'avg_damage' .. su)
        end

        if inArgsStarts(pr .. 'awk_dmg') then
            getTotal(pr .. 'awk_dmg', 'awk_hits', 'total_damage_awk' .. su)
        end

        if inArgsStarts('avg_awk_hits') then
            getTotal(pr .. 'awk_dmg', 'avg_awk_hits', 'avg_damage_awk' .. su)
        end

        -- Handling traits
        -- Useful handled separately
        if inArgs('useful_penalty') then
            getTotal(pr .. 'dmg', 'hits_useful', 'total_damage_useful' .. su)

            if (inArgsStarts('avg_hits_useful')) then
                getTotal(pr .. 'dmg', 'avg_hits_useful', 'avg_damage_useful' .. su)
            end
        end

        -- Multiply all values with traits and store them in another table.
        for k, v in spairs(fvals) do
            if not string.find(k, 'useful') then
                for kt, vt in spairs(traits) do
                    if inArgs(kt) then
                        local dmg_name = k .. '_' .. kt
                        if ispvp then
                            dmg_name = dmg_name:gsub(su, '') .. su
                        end
                        local dmg_formula = v * vt
                        tvals[dmg_name] = dmg_formula
                    end
                end
            end
        end

        -- Define passives and fill the respective tables.
        local passive2 = 0

        -- Get a table of merged base & trait values
        local ftvals = fvals
        tableMerge(ftvals, tvals)

        if inArgs('passive2') then
            passive2 = split(args.passive2)

            for k, v in spairs(ftvals) do
                local dmg_name = k .. '_passive2'
                if ispvp then
                    dmg_name = dmg_name:gsub(su, '') .. su
                end
                local dmg_formula = v * passive2[p_index]
                pvals2[dmg_name] = dmg_formula
            end

        end

        local passive1 = 0
        if inArgs('passive1') then
            passive1 = split(args.passive1)

            for k, v in spairs(ftvals) do
                local dmg_name = k .. '_passive1'
                if ispvp then
                    dmg_name = dmg_name:gsub(su, '') .. su
                end
                local dmg_formula = v * passive1[p_index]
                pvals1[dmg_name] = dmg_formula
            end

            -- Combine both passives.
            if inArgs('passive2') then
                for k, v in spairs(pvals1) do
                    local dmg_name = k .. '_passive2'
                    if ispvp then
                        dmg_name = dmg_name:gsub(su, '') .. su
                    end
                    pvals12[dmg_name] = v * passive2[p_index]
                end
            end

        end

        -- Merge all tables into one.
        tableMerge(fvals, tvals)
        tableMerge(fvals, pvals1)
        tableMerge(fvals, pvals2)
        tableMerge(fvals, pvals12)

        return fvals
    end

    local out = list(false)
    local pvp = list(true)

    -- Merge the output to a unified table.
    tableMerge(out, pvp)

    -- Get the actual variables with MW syntax.
    local vars = {}
    for k, v in spairs(out) do
        table.insert(vars, var(k, v))
    end

    -- Dump all values if wanted.
    if args.dump == 'true' then
        local ret = {}
        for k, v in spairs(out) do
            table.insert(ret, k .. ': ' .. v)
        end
        return frame:preprocess(table.concat(ret, "<br/>"))
    else
        -- Parse all variables - end point
        return frame:preprocess(table.concat(vars))
    end

end

return p