Module:Damage
From Elwiki
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 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