Module:Damage: Difference between revisions

From Elwiki
No edit summary
No edit summary
Line 53: Line 53:
             end
             end
         end
         end
    end
    -- For skills with no maximum hit count
    if not inArgs('hits') then
        args.hits = 1
     end
     end


Line 147: Line 142:
         -- Actually generate the values depending on arguments provided.
         -- Actually generate the values depending on arguments provided.
         -- TODO: Change how this works once the old input method is removed.
         -- TODO: Change how this works once the old input method is removed.
         getTotal(pr .. 'dmg', 'hits', 'total_damage' .. su)
         if inArgsStarts('hits') then
 
            getTotal(pr .. 'dmg', 'hits', 'total_damage' .. su)
        end
       
         if inArgsStarts('avg_hits') then
         if inArgsStarts('avg_hits') then
             getTotal(pr .. 'dmg', 'avg_hits', 'avg_damage' .. su)
             getTotal(pr .. 'dmg', 'avg_hits', 'avg_damage' .. su)

Revision as of 00:10, 4 April 2022

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

    -- Collect data from the input
    local data = {}
    local data_types = {
        'dmg', 'pvp_dmg', 'awk_dmg', 'pvp_awk_dmg',
        'hits', 'avg_hits',
        'awk_hits', 'avg_awk_hits',
        'hits_useful', 'avg_hits_useful',
        'awk_hits_useful', 'avg_awk_hits_useful'
    }
    for k,v in spairs(data_types) do
        local i = 1
        if (inArgs(v)) then
            local x = split(args[v])
            for k2,v2 in spairs(x) do
                data[v .. i] = v2
                i = i + 1
            end
        -- Deprecated, will be removed (probably)
        elseif inArgsStarts(v) then
            for k2,v2 in spairs(args) do
                data[k2] = v2
            end
        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

    -- Output passives if provided.
    local array_regex = "%d+%.%d+,%s%d+%.%d+"
    local passive1 = 0
    local passive2 = 0

    if inArgs('passive1') then
        passive1 = args.passive1
        if string.match(passive1, array_regex) then
            passive1 = split(passive1)
        else
            passive1 = split(frame:preprocess('{{:' .. passive1 .. '}}{{#arrayprint:' .. passive1 .. '}}'))
        end
    end

    if inArgs('passive2') then
        passive2 = args.passive2
        if string.match(passive2, array_regex) then
            passive2 = split(passive2)
        else
            passive2 = split(frame:preprocess('{{:' .. passive2 .. '}}{{#arrayprint:' .. passive2 .. '}}'))
        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(data) do
                -- TODO: Change how this works once the old input method is removed.
                if string.starts(k, pr .. 'dmg') then
                    -- Proceed to combine
                    fvals[fval] = fvals[fval] + data[dmg .. i] * data[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.
        -- TODO: Change how this works once the old input method is removed.
        if inArgsStarts('hits') then
            getTotal(pr .. 'dmg', 'hits', 'total_damage' .. su)
        end
        
        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

            if inArgsStarts(pr .. 'awk_dmg') then
                getTotal(pr .. 'awk_dmg', 'awk_hits_useful', 'total_damage_awk_useful' .. su)
            end

            if inArgsStarts('avg_awk_hits') then
                getTotal(pr .. 'awk_dmg', 'avg_awk_hits_useful', 'avg_damage_awk_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

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

        if inArgs('passive2') then

            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

        if inArgs('passive1') then

            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)

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

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