Module:Damage: Difference between revisions

From Elwiki
(Undo revision 747726 by Ritsu (talk))
Tag: Undo
(for weird skills - fixed version)
Line 32: Line 32:
         if inArgs(v) then
         if inArgs(v) then
             for k2, v2 in spairs(split(args[v])) do
             for k2, v2 in spairs(split(args[v])) do
                 -- Check if proper hit count values provided. If placeholder empty string detected, inherit from 'hits'.
                 -- Check if proper hit count values provided. If empty string detected, inherit from 'hits'.
                 if string.find(v, 'avg_') and string.find(v, '_hits') and v2 == '' then
                 if string.find(v, 'avg_') and string.find(v, '_hits') and v2 == '' then
                     data[v .. i] = data['avg_hits' .. i]
                     data[v .. i] = data['avg_hits' .. i]
Line 50: Line 50:
         end
         end
     end
     end
    -- For weird skills
    function inheritMissing(keyTable, inheritTable)
        local n = 1; -- counter for the func. argument loop
        local i;
        for k_key, v_key in spairs(keyTable) do
            if inArgs('awk_hits') and not inArgs(v_key) then
                i = 1
                for k, v in spairs(split(args.dmg)) do
                    data[v_key .. i] = data[inheritTable[n] .. i]
                    i = i + 1
                end
            end
            n = n + 1
        end
    end
    inheritMissing({'awk_dmg', 'pvp_awk_dmg'}, {'dmg', 'pvp_dmg'})


     -- Handle trait table
     -- Handle trait table
     local traits = {}
     local traits = {}


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


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


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


         if inArgs(pr .. 'awk_dmg') then
         if inArgs(pr .. 'awk_dmg') or inArrayStarts(pr .. 'awk_dmg', data) then
             getTotal(pr .. 'awk_dmg', 'awk_hits', 'total_damage_awk' .. su)
             getTotal(pr .. 'awk_dmg', 'awk_hits', 'total_damage_awk' .. su)


Line 261: Line 279:
     if args.dump == 'true' then
     if args.dump == 'true' then
         local ret = {}
         local ret = {}
         for k, v in spairs(data) do
         for k, v in spairs(out) do
             table.insert(ret, k .. ': ' .. v)
             table.insert(ret, k .. ': ' .. v)
         end
         end

Revision as of 18:19, 8 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

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

    -- Handle undefined parameter situations.
    -- If 'hits' undefined, assume they're equal to 1.
    if not inArgs('hits') then
        local i = 1
        for k2, v2 in spairs(split(args.dmg)) do
            data['hits' .. i] = 1
            i = i + 1
        end
    end

    for k, v in spairs(data_types) do
        local i = 1
        if inArgs(v) then
            for k2, v2 in spairs(split(args[v])) do
                -- Check if proper hit count values provided. If empty string detected, inherit from 'hits'.
                if string.find(v, 'avg_') and string.find(v, '_hits') and v2 == '' then
                    data[v .. i] = data['avg_hits' .. i]
                elseif string.find(v, 'hits') and v2 == '' then
                    data[v .. i] = data['hits' .. i]
                elseif string.find(v, 'awk_dmg') and v2 == '' then
                    if string.find(v, 'pvp') then
                        data[v .. i] = data['pvp_dmg' .. i]
                    else
                        data[v .. i] = data['dmg' .. i]
                    end
                else
                    data[v .. i] = v2
                end
                i = i + 1
            end
        end
    end

    -- For weird skills
    function inheritMissing(keyTable, inheritTable)
        local n = 1; -- counter for the func. argument loop
        local i;
        for k_key, v_key in spairs(keyTable) do
            if inArgs('awk_hits') and not inArgs(v_key) then
                i = 1
                for k, v in spairs(split(args.dmg)) do
                    data[v_key .. i] = data[inheritTable[n] .. i]
                    i = i + 1
                end
            end
            n = n + 1
        end
    end

    inheritMissing({'awk_dmg', 'pvp_awk_dmg'}, {'dmg', 'pvp_dmg'})

    -- 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 passives = {}
    for i = 1, 3 do
        if inArgs('passive' .. i) then
            passives[i] = args['passive' .. i]
            passives[i] = split(frame:preprocess('{{:' .. passives[i] .. '}}{{#arrayprint:' .. passives[i] .. '}}'))
        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 pvals = {
            [1] = {},
            [2] = {},
            [3] = {},
            [12] = {},
            [13] = {},
            [23] = {},
            [123] = {}
        }

        -- 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(split(args.dmg)) do
                -- Proceed to combine
                fvals[fval] = fvals[fval] + data[dmg .. i] * data[hits .. i]
                i = i + 1
            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 inArgs(pr .. 'dmg') then
            getTotal(pr .. 'dmg', 'hits', 'total_damage' .. su)

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

        if inArgs(pr .. 'awk_dmg') or inArrayStarts(pr .. 'awk_dmg', data) then
            getTotal(pr .. 'awk_dmg', 'awk_hits', 'total_damage_awk' .. su)

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

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

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

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

            if inArgs('avg_awk_hits') and inArgs(pr .. 'avg_awk_hits_useful') 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)

        function addPassive(num, loop_table)
            local pval_index
            if loop_table == nil then
                pval_index = num
                loop_table = ftvals
            else
                pval_index = tonumber(loop_table .. num)
                loop_table = pvals[loop_table]
            end
            for k, v in spairs(loop_table) do
                local dmg_name = k .. '_passive' .. num
                if ispvp then
                    dmg_name = dmg_name:gsub(su, '') .. su
                end
                local dmg_formula = v * passives[num][p_index]
                pvals[pval_index][dmg_name] = dmg_formula
            end
        end

        -- Add passives and combine them.
        if inArgs('passive2') then
            addPassive(2)
            if inArgs('passive3') then
                addPassive(3, 2)
            end
        end

        if inArgs('passive1') then
            addPassive(1)
            if inArgs('passive2') then
                addPassive(2, 1)
                if inArgs('passive3') then
                    addPassive(3, 12)
                end
            end
            if inArgs('passive3') then
                addPassive(3, 1)
            end
        end

        if inArgs('passive3') then
            addPassive(3)
        end

        -- Merge all tables into one.
        tableMerge(fvals, tvals)
        for k, v in spairs(pvals) do
            tableMerge(fvals, v)
        end

        return fvals
    end

    local out = list(false)

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

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

    -- Get the actual variables with MW syntax.
    local vars = {}
    for k, v in spairs(out) do
        table.insert(vars, var(k, v, args.prefix))
    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