ElEditors, Interface administrators, Administrators
70,784
edits
No edit summary |
No edit summary Tag: Reverted |
||
Line 2: | Line 2: | ||
require('Module:CommonFunctions'); | require('Module:CommonFunctions'); | ||
local getArgs = require('Module:Arguments').getArgs | local getArgs = require('Module:Arguments').getArgs | ||
local p = {} | local p = {} | ||
Line 8: | Line 7: | ||
function p.main(frame) | function p.main(frame) | ||
local args = getArgs(frame) | local args = getArgs(frame) | ||
function inArgs(key) | function inArgs(key) | ||
Line 16: | Line 14: | ||
end | end | ||
local | -- Collect data from the input | ||
local data = {} | |||
local data_types = { | |||
'dmg', | |||
'awk_dmg', | |||
'hits', | |||
'avg_hits', | |||
'awk_hits', | |||
'avg_awk_hits', | |||
'hits_useful', | |||
'avg_hits_useful', | |||
'awk_hits_useful', | |||
'avg_awk_hits_useful', | |||
'perm_buff' | |||
} | |||
-- | -- Handle the PvP split values | ||
for k, v in spairs(data_types) do | |||
for | table.insert(data_types, 'pvp_' .. v) | ||
end | end | ||
for k, v in spairs(data_types) do | |||
for | local i = 1 | ||
if inArgs(v) then | |||
for k2, v2 in spairs(split(args[v])) do | |||
-- Check for operators. If detected, evaluate. | |||
if string.find(v2, '*') or string.find(v2, '+') then | |||
v2 = frame:preprocess('{{#expr:' .. v2 .. '}}') | |||
end | |||
-- 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 | ||
end | end | ||
function | -- For weird skills | ||
for | 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(inheritTable[n]) 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 | ||
end | end | ||
inheritMissing({'awk_dmg', 'pvp_awk_dmg', 'awk_hits', 'avg_awk_hits'}, {'dmg', 'pvp_dmg', 'hits', 'avg_hits'}) | |||
-- Laziness | |||
if args.hits and args.awk_dmg and not args.awk_hits then | |||
data.awk_hits = args.hits | |||
end | |||
if args.awk_dmg and args.avg_hits and not args.avg_awk_hits then | |||
data.avg_awk_hits = args.avg_hits | |||
end | end | ||
if args.awk_dmg and args.avg_hits_useful and not args.avg_awk_hits_useful then | |||
data.avg_awk_hits_useful = args.avg_hits_useful | |||
end | |||
-- | -- Handle trait table | ||
local | local traits = {} | ||
if inArgs('heavy') then | |||
traits.heavy = 1.44 | |||
end | |||
if inArgs('enhanced') then | |||
traits.enhanced = 0.8 | |||
end | 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 | |||
if args.useful == 'true' then | |||
args.useful = 0.7 | |||
end | |||
if args.useful_penalty == 'true' then | |||
args.useful_penalty = 0.7 | |||
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 | ||
end | end | ||
-- | function list(ispvp) | ||
if | -- 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 | end | ||
if | |||
if (ispvp) then | |||
pr = 'pvp_' | |||
su = '_pvp' | |||
end | end | ||
-- Define total/average damage calculation based on damage per hit and hit amount. | |||
function getTotal(dmg, hits, fval, count) | |||
-- Handle PvP prefixes/suffixes | |||
if | if inArgs(pr .. dmg) then | ||
dmg = pr .. dmg | |||
end | |||
if inArgs(pr .. hits) then | |||
hits = pr .. hits | |||
end | end | ||
if not | |||
if dmg == 'awk_dmg' and ispvp and not inArgs(pr .. 'awk_dmg') then | |||
dmg = pr .. 'dmg' | |||
end | end | ||
fval = fval .. su | |||
local i = 1 | |||
fvals[fval] = 0 | |||
for k, v in spairs(split(args.dmg)) do | |||
if -- If 'hits' defined, but 'avg_hits' not defined, inherit from 'hits'. | |||
(data[hits .. i] == nil and data['hits' .. i] ~= nil and hits == 'avg_hits') then | |||
data[hits .. i] = data['hits' .. i] | |||
elseif -- If 'hits' undefined, assume they're equal to 1. | |||
(data[hits .. i] == nil) then | |||
data[hits .. i] = 1 | |||
end | |||
-- Proceed to combine | |||
fvals[fval] = fvals[fval] + data[dmg .. i] * data[hits .. i] * (data[pr .. 'perm_buff' .. i] or data['perm_buff' .. i] or 1) | |||
i = i + 1 | |||
end | |||
-- For skills with multiple same parts, ex. Clementine, Enough Mineral | |||
if count == true then | |||
fvals[fval] = fvals[fval] * args.count | |||
if inArgs('count_extra' .. su) then | |||
if args.count_extra_hits == nil then | |||
args.count_extra_hits = 1 | |||
end | |||
if not string.find(fval, "each_") then | |||
fvals[fval] = fvals[fval] + (args['count_extra' .. su] * args['count_extra_hits']) | |||
end | end | ||
end | end | ||
end | |||
-- Apply Useful modifier. | |||
if string.find(fval, 'useful') then | |||
fvals[fval] = fvals[fval] * (args.useful_penalty or args.useful) | |||
end | end | ||
end | end | ||
-- Actually generate the values depending on arguments provided. | |||
if inArgs(pr .. 'dmg') then | |||
if (inArgs('count')) then | |||
getTotal('dmg', 'hits', 'each_damage') | |||
getTotal('dmg', 'hits', 'total_damage', true) | |||
else | |||
getTotal(pr .. 'dmg', 'hits', 'total_damage') | |||
end | |||
if inArgs('avg_hits') then | |||
getTotal('dmg', 'avg_hits', 'avg_damage') | |||
end | |||
end | |||
if inArgs(pr .. 'awk_dmg') or inArrayStarts(pr .. 'awk_dmg', data) then | |||
getTotal('awk_dmg', 'awk_hits', 'total_damage_awk') | |||
if (inArgs('avg_hits') and (inArgs('awk_dmg') or inArgs('awk_hits'))) or inArgs('avg_awk_hits') then | |||
getTotal('awk_dmg', 'avg_awk_hits', 'avg_damage_awk') | |||
end | |||
end | end | ||
-- Handling traits | |||
-- Useful handled separately | |||
if inArgs('useful_penalty') or inArgs('useful') then | |||
getTotal(pr .. 'dmg', 'hits_useful', 'total_damage_useful') | |||
if inArgs('avg_hits_useful') then | |||
getTotal('dmg', 'avg_hits_useful', 'avg_damage_useful') | |||
end | |||
if inArgs(pr .. 'awk_dmg') and inArgs('awk_hits_useful') then | |||
getTotal('awk_dmg', 'awk_hits_useful', 'total_damage_awk_useful') | |||
end | |||
if inArgs(pr .. 'avg_awk_hits') and inArgs('avg_awk_hits_useful') then | |||
getTotal('awk_dmg', 'avg_awk_hits_useful', 'avg_damage_awk_useful') | |||
end | |||
end | |||
-- Multiply all values with traits and store them in another table. | |||
if | 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 | |||
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 | 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 | ||
end | end | ||
if inArgs('passive1') then | |||
addPassive(1) | |||
if inArgs('passive2') then | |||
addPassive(2, 1) | |||
if inArgs('passive3') then | |||
addPassive(3, 12) | |||
end | end | ||
end | |||
if inArgs('passive3') then | |||
addPassive(3, 1) | |||
end | end | ||
end | end | ||
if inArgs('passive3') then | |||
addPassive(3) | |||
end | |||
-- Merge all tables into one. | |||
tableMerge(fvals, tvals) | |||
for k, v in spairs(pvals) do | |||
for | tableMerge(fvals, v) | ||
end | |||
return fvals | |||
end | |||
local out = list(false) | |||
local out_pvp = list(true) | |||
-- Merge the output to a unified table. | |||
tableMerge(out, out_pvp) | |||
-- Function wrapper for vardefine syntax in MW. | |||
function var(name, dmg, prefix) | |||
if prefix == nil then | |||
prefix = '' | |||
else | |||
prefix = prefix .. '_' | |||
end | |||
if dmg == 0 then | |||
dmg = 'N/A' | |||
else | |||
dmg = round(dmg) | |||
end | |||
if (args.format == 'false' or dmg == 'N/A') then | |||
return '{{#vardefine:' .. prefix .. name .. '|' .. dmg .. '}}' | |||
else | |||
return '{{#vardefine:' .. prefix .. name .. '|{{formatnum:' .. dmg .. '}}%}}' | |||
end | |||
end | |||
-- Apply ranges. | |||
function getRangeCount(arg) | |||
if inArgs(arg) then | |||
data[arg] = split(args[arg]) | |||
if data[arg][2] == nil then | |||
data[arg][2] = data[arg][1] | |||
end | end | ||
end | end | ||
end | end | ||
getRangeCount('range_min_count'); | |||
getRangeCount('range_max_count') | |||
function determineRange(minmax) | |||
function | if inArgs('range_' .. minmax) then | ||
data['range_' .. minmax] = split(args['range_' .. minmax]) | |||
if data['range_' .. minmax][2] == nil then | |||
data['range_' .. minmax][2] = data['range_' .. minmax][1] | |||
if | end | ||
if inArgs('range_' .. minmax .. '_count') then | |||
local i = 1; | |||
for k, v in spairs(data['range_' .. minmax]) do | |||
data['range_' .. minmax][i] = 1 + (-1 + data['range_' .. minmax][i]) * | |||
data['range_' .. minmax .. '_count'][i] | |||
i = i + 1 | |||
end | end | ||
end | end | ||
end | end | ||
end | end | ||
determineRange('min'); | |||
determineRange('max'); | |||
-- If maximum range is specified, but not minimum, and minimum count is specified. | |||
-- By default, it would just do the same as with max, don't want that. | |||
if inArgs('range_max') and not inArgs('range_min') then | |||
data['range_min'] = {1, 1} | |||
if inArgs('range_min_count') then | |||
local range_max_arg = split(args.range_max); | |||
if range_max_arg[2] == nil then | |||
range_max_arg[2] = range_max_arg[1] | |||
end | end | ||
data['range_min'] = {1 + range_max_arg[1] * data['range_min_count'][1], | |||
1 + range_max_arg[2] * data['range_min_count'][2]} | |||
end | end | ||
end | end | ||
local out_min = {} | |||
local out_max = {} | |||
function applyRange(minmax) | |||
function | local temp_tab = {}; | ||
if minmax == 'min' then | |||
for | temp_tab = out_min | ||
else | |||
temp_tab = out_max | |||
if | end | ||
if inArgs('range_max') then | |||
for k, v in spairs(out) do | |||
if not (string.starts(k, 'min_') or string.starts(k, 'max_')) then | |||
if (string.find(k, '_pvp')) then | |||
temp_tab[minmax .. '_' .. k] = v * data['range_' .. minmax][2]; | |||
else | |||
temp_tab[minmax .. '_' .. k] = v * data['range_' .. minmax][1]; | |||
end | end | ||
end | end | ||
end | end | ||
end | end | ||
tableMerge(out, temp_tab) | |||
end | end | ||
applyRange('min'); | |||
applyRange('max'); | |||
-- 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 | end | ||
local | -- Transform ranges to variables. | ||
local vars_range = {} | |||
if (inArgs('range_max')) then | |||
for | for k, v in spairs(out) do | ||
if not (string.starts(k, 'min_') or string.starts(k, 'max_')) then | |||
local prefix = '' | |||
if args.prefix ~= nil then | |||
prefix = args.prefix .. '_' | |||
end | end | ||
table.insert(vars_range, | |||
'{{#vardefine: ' .. prefix .. 'range_' .. k .. '|{{formatnum:' .. round(out_min['min_' .. k]) .. | |||
'}}% ~ {{formatnum:' .. round(out_max['max_' .. k]) .. '}}%}}'); | |||
end | end | ||
end | end | ||
indexTableMerge(vars, vars_range); | |||
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/>")) | |||
end | end | ||
-- Parse all variables | |||
local parsed = frame:preprocess('{{ ' .. table.concat(vars) .. 'trim2}}') | |||
local | if args[1] ~= 'true' and args.table ~= 'true' then | ||
return parsed | |||
end | |||
local char = args.char or args[2] or 'Elsword' | |||
-- Generate the table | |||
local tbl = mw.html.create('table'):attr({ | |||
['cellpadding'] = 5, | |||
['border'] = 1, | |||
['style'] = 'border-collapse: collapse; text-align: center', | |||
['class'] = 'colortable-' .. char | |||
}) | |||
-- For rowspan, colspan shenanigans | |||
function increaseSpace(el, type, num) | |||
if type == 'row' then | |||
type = 'rowspan' | |||
elseif type == 'col' then | |||
type = 'colspan' | |||
end | |||
num = num or 1 | |||
return el:attr(type, tonumber(el:getAttr(type) or 1) + num) | |||
end | |||
function multiplySpace(el, type, m) | |||
if not el then | |||
return false | |||
end | |||
if type == 'row' then | |||
type = 'rowspan' | |||
else | |||
type = 'colspan' | |||
end | |||
if m == nil then | |||
m = 2 | |||
end | end | ||
local span = el:getAttr(type) or 1 | |||
return el:attr(type, tonumber(span) * m) | |||
end | end | ||
local combine = split(args.combine) | |||
local combine_suffix = args.combine_suffix | |||
local append = split(args.append)[1] | |||
local append_alias = split(args.append)[2] | |||
local tbl_order = {'extra', 'passives_normal', 'passives_switch', 'awk', 'traits', 'hit_count'} | |||
local STR = { | |||
BASE = 'Base', | |||
MODE = 'Mode', | |||
REGULAR = 'Regular', | |||
NORMAL = 'Normal', | |||
AWK = 'Awakening Mode', | |||
AVG = 'Average', | |||
MAX = 'Max', | |||
TRAIT = {'Enhanced', 'Empowered', 'Useful', 'Heavy'}, | |||
PER = 'Per', | |||
INSTANCE = 'Instance' | |||
} | |||
local trait_args = {} | |||
for k, v in ipairs(STR.TRAIT) do | |||
table.insert(trait_args, string.lower(v)) | |||
end | |||
local trait_count = 0 | |||
for k, v in ipairs(trait_args) do | |||
if inArrayHas(v, out) then | |||
trait_count = trait_count + 1 | |||
end | |||
end | |||
local | local tbl_content = { | ||
extra = { | |||
mode = STR.MODE, | |||
long = STR.AVG | |||
}, | |||
passives_normal = { | |||
mode = STR.MODE, | |||
base = STR.BASE, | |||
combined = {}, | |||
aliases = {args.alias1 or false, args.alias2 or false, args.alias3 or false}, | |||
suffixes = {args.suffix1 or false, args.suffix2 or false, args.suffix3 or false} | |||
}, | }, | ||
passives_switch = { | |||
normal = STR.NORMAL, | |||
hide = true | |||
}, | |||
awk = { | |||
normal = STR.REGULAR, | |||
awk_link = '[[' .. STR.AWK .. ']]', | |||
hide = true | |||
}, | |||
traits = { | |||
normal = STR.NORMAL, | |||
hide = true | |||
}, | |||
hit_count = { | |||
avg = STR.AVG, | |||
max = STR.MAX, | |||
hide = true | |||
} | } | ||
} | } | ||
local | local count_name = args.count_name or STR.INSTANCE | ||
if inArgs('count') and not args.use_avg then | |||
tbl_content.hit_count.avg = table.concat({STR.PER, count_name}, ' ') | |||
end | |||
function getRowIndex(row) | |||
for k, v in ipairs(tbl_order) do | |||
if row == v then | |||
return k | |||
end | end | ||
end | end | ||
end | end | ||
for passive_i = 1, 3 do | |||
repeat | |||
-- Add normal passives to the first row. | |||
local passive_name = '' | |||
-- Alias for appended passives. | |||
if (inArgs('passive' .. passive_i)) then | |||
passive_name = args['passive' .. passive_i] | |||
end | |||
if indexOf(tostring(passive_i), combine) ~= nil then | |||
-- Add combined passives. | |||
tbl_content.passives_normal.combined[passive_i] = passive_name | |||
elseif tostring(passive_i) == append then | |||
-- Add switch passives. | |||
tbl_content.passives_switch[passive_i] = passive_name | |||
tbl_content.passives_switch.hide = false | |||
if append_alias ~= nil then | |||
tbl_content.passives_switch.display_name = append_alias | |||
end | |||
elseif (inArgs('passive' .. passive_i)) then | |||
-- Add regular passives to the first row. | |||
tbl_content.passives_normal[passive_i] = passive_name | |||
end | |||
until true | |||
end | |||
local | local ret = '' | ||
-- | for trait_order, trait_arg in ipairs(trait_args) do | ||
-- Add traits if exist. | |||
if (inArgs(trait_arg)) then | |||
tbl_content.traits[trait_arg] = args[trait_arg] | |||
tbl_content.traits.hide = false | |||
end | end | ||
end | |||
-- Add Useful trait. | |||
if inArgs('hits_useful') or inArgs('avg_hits_useful') then | |||
tbl_content.traits.useful = 'true' | |||
tbl_content.traits.hide = false | |||
end | |||
if inArgs('avg_hits') or inArgs('count') then | |||
-- Enable average/max if needed. | |||
tbl_content.hit_count.hide = false | |||
end | |||
if inArrayHas('awk_', args) then | |||
-- Enable Awakening if needed. | |||
tbl_content.awk.hide = false | |||
end | |||
local loop_factor, mode_th; | |||
local cells = {} | |||
local passive_normal_count = 0; | |||
local passive_switch_count = 0; | |||
function hidden(level) | |||
return tbl_content[level].hide | |||
return | |||
end | end | ||
local hit_count_table = {'total'} | |||
local awk_table = {''} | |||
local levels_exist = | |||
(next(passives) or args.append or args.awk_hits or args.awk_dmg or args.count) | |||
local no_max = args.no_max == 'true' | |||
function makePassiveLink(passive, alias, suffix, nil_cond) | |||
if | if nil_cond == nil then | ||
nil_cond = true | |||
end | end | ||
if nil_cond and alias ~= nil and alias ~= false then | |||
alias = '|' .. alias | |||
else | |||
alias = '' | |||
end | |||
suffix = suffix or '' | |||
passive = '[[' .. passive .. alias .. ']]' .. suffix | |||
return passive | |||
end | |||
-- Begin the main loop. | |||
for k, type in ipairs(tbl_order) do | |||
repeat | |||
local tr = tbl:tag('tr') | |||
local data = tbl_content[type]; | |||
local hide = data.hide; | |||
cells[type] = {} | |||
function new(wikitext, normal) | |||
local th = tr:tag('th'):wikitext(wikitext) | |||
if type | if normal == true then | ||
table.insert(cells[type].normal_th, th) | |||
elseif normal == false then | |||
table.insert(cells[type].th, th) | |||
else | else | ||
return | return th | ||
end | end | ||
end | end | ||
function multiplySpaceAll(level, num) | |||
if cells[level] == nil then | |||
return false | |||
end | end | ||
num = num or 2 | |||
for k, v in ipairs(cells[level].th) do | |||
multiplySpace(v, 'col', num) | |||
end | end | ||
for k, v in ipairs(cells[level].normal_th) do | |||
multiplySpace(v, 'col', num) | |||
end | end | ||
end | |||
end | |||
function reverseMultiplySpace(num, increase_mode) | |||
local i = #tbl_order; | |||
num = num or 2 | |||
local fix_for_no_max = 0 | |||
if no_max and not levels_exist then | |||
fix_for_no_max = -1 | |||
end | end | ||
while (i > 1) do | |||
multiplySpaceAll(tbl_order[i - 1 + fix_for_no_max], num) | |||
i = i - 1 | |||
end | end | ||
if increase_mode ~= false then | |||
increaseSpace(mode_th, 'row') | |||
end | end | ||
end | |||
end | |||
cells[type].normal_th = {} | |||
cells[type].th = {} | |||
if (type == 'extra' and no_max) then | |||
mode_th = new(data.mode) | |||
new(data.long, true) | |||
end | |||
if (type == 'passives_normal') then | |||
if not no_max then | |||
mode_th = new(data.mode) | |||
else | |||
reverseMultiplySpace(nil, false); | |||
end | |||
if (no_max and levels_exist) or not no_max then | |||
new(data.base, true) | |||
end | |||
for i = 1, 3, 1 do | |||
local passive_link = data[i] | |||
if (passive_link ~= nil) then | |||
local suffix = '' | |||
if | if next(data.suffixes) and data.suffixes[i] ~= false then | ||
suffix = ' ' .. data.suffixes[i] | |||
end | end | ||
passive_link = makePassiveLink(passive_link, data.aliases[i], suffix, next(data.aliases)) | |||
new(passive_link, false) | |||
passive_normal_count = passive_normal_count + 1 | |||
end | end | ||
end | |||
for | -- Handle combining passives. | ||
if next(data.combined) then | |||
local combined_str = '' | |||
for k, v in spairs(data.combined) do | |||
combined_str = combined_str .. makePassiveLink(v, data.aliases[k], data.suffixes[k]) .. '/' | |||
end | |||
combined_str = combined_str:gsub('/$', '') | |||
if combine_suffix then | |||
combined_str = combined_str .. ' ' .. combine_suffix | |||
end | |||
new(combined_str, false) | |||
passive_normal_count = passive_normal_count + 1 | |||
end | |||
end | |||
if (type == 'passives_switch') then | |||
if not hidden(type) then | |||
multiplySpaceAll('passives_normal') | |||
-- For some reason, whenever appending is active, it misses a 1 in rowspan of this cell. | |||
increaseSpace(mode_th, 'row') | |||
end | |||
-- Passives that appear in the second row | |||
loop_factor = (passive_normal_count + 1) | |||
for ix = 1, loop_factor, 1 do | |||
for i = 1, 3, 1 do | |||
if (data[i] ~= nil) then | |||
new(data.normal, true); | |||
local suffix = '' | |||
if next(tbl_content.passives_normal.suffixes) and tbl_content.passives_normal.suffixes[i] ~= false then | |||
suffix = ' ' .. tbl_content.passives_normal.suffixes[i] | |||
end | end | ||
local passive_link = data[i] | |||
passive_link = makePassiveLink(passive_link, data.display_name, suffix) | |||
new(passive_link, false) | |||
if (ix == 1) then | |||
-- Count switch passives. Only one iteration. | |||
passive_switch_count = passive_switch_count + 1 | |||
end | |||
end | end | ||
end | end | ||
end | end | ||
end | |||
if (type == 'awk' and not hide) then | |||
reverseMultiplySpace(); | |||
table.insert(awk_table, 'awk') | |||
loop_factor = loop_factor * (passive_switch_count + 1) | |||
for i = 1, loop_factor, 1 do | |||
new(data.normal, true) | |||
new(data.awk_link, false) | |||
end | end | ||
end | end | ||
if (type == 'traits' and not hide) then | |||
if trait_count == 2 then | |||
reverseMultiplySpace(3); | |||
if | |||
else | else | ||
reverseMultiplySpace(); | |||
end | |||
-- Manually fix certain situations. | |||
local has_awk = 1 | |||
if not hidden('awk') then | |||
has_awk = 2 | |||
end | end | ||
local extra = 1 | |||
if hidden('awk') and not hidden('passives_switch') then | |||
extra = 2 | |||
end | |||
loop_factor = loop_factor * has_awk | |||
for i = 1, loop_factor * extra, 1 do | |||
local ix = 1 | |||
new(data.normal, true) | |||
for k, trait_name in ipairs(trait_args) do | |||
if data[trait_name] ~= nil then | |||
new(STR.TRAIT[ix], false) | |||
end | |||
ix = ix + 1 | |||
end | |||
end | |||
end | |||
if (type == 'hit_count' and not hide) then | |||
if no_max and levels_exist then | |||
increaseSpace(mode_th, 'row') | |||
elseif levels_exist or (args.avg_hits and args.hits) then | |||
reverseMultiplySpace(); | |||
else | |||
reverseMultiplySpace(nil, false); | |||
end | |||
local avg_or_each = 'avg' | |||
if inArgs('count') and not args.use_avg then | |||
avg_or_each = 'each' | |||
end | |||
table.insert(hit_count_table, 1, avg_or_each) | |||
-- Some things are breaking here, so I needed to implement conditional patches. | |||
if hidden('awk') then | |||
loop_factor = loop_factor * (passive_switch_count + 1) | |||
end | |||
if hidden('passives_switch') then | |||
if | loop_factor = passive_normal_count + 1 | ||
end | end | ||
if (hidden('traits') and not hidden('awk')) or (not hidden('awk') and hidden('passives_switch')) then | |||
loop_factor = loop_factor * 2 | |||
end | end | ||
loop_factor = loop_factor * (trait_count + 1) | |||
for i = 1, | |||
if not no_max then | |||
for i = 1, loop_factor, 1 do | |||
new(data.avg, true) | |||
new(data.max, false) | |||
end | end | ||
end | end | ||
end | end | ||
end | |||
until true | |||
end | |||
if no_max and args.avg_hits then | |||
hit_count_table[2] = nil | |||
end | end | ||
function concat(tbl) | |||
local returned_str = '' | |||
for k, v in ipairs(tbl) do | |||
local delimiter = '_' | |||
if returned_str == '' then | |||
delimiter = '' | |||
end | |||
if v ~= '' then | |||
returned_str = returned_str .. delimiter .. v | |||
end | |||
end | end | ||
return | return returned_str | ||
end | end | ||
function | function makeValueRows(mode_flag) | ||
local | local mode_cell = 'PvE' | ||
if mode_flag == true then | |||
mode_flag = '_pvp' | |||
mode_cell = 'PvP' | |||
else | |||
mode_flag = '' | |||
end | |||
local value_row = tbl:tag('tr') | |||
function display(name, range_flag) | |||
local range_factor; | |||
local cell_content = {} | |||
if range_flag == true then | |||
range_factor = 2 | |||
else | |||
range_factor = 1 | |||
end | |||
for i = 1, range_factor, 1 do | |||
local range_prefix = ''; | |||
if range_flag == true then | |||
if i == 1 then | |||
range_prefix = 'min_' | |||
else | |||
range_prefix = 'max_' | |||
end | |||
end | |||
local value = out[range_prefix .. name]; | |||
if (value ~= nil) then | |||
if (args.dump_names == 'true') then | |||
table.insert(cell_content, name) | |||
elseif value ~= 0 then | |||
table.insert(cell_content, formatnum(math.round(value, 2)) .. '%') | |||
else | |||
table.insert(cell_content, 'N/A') | |||
end | |||
end | end | ||
end | |||
if next(cell_content) then | |||
return value_row:tag('td'):wikitext(table.concat(cell_content, '<span style="white-space:nowrap"> ~</span> ')); | |||
else | else | ||
if args.dump_names == 'true' then | |||
return value_row:tag('td'):wikitext(name) | |||
end | |||
return value_row:tag('td'):wikitext(frame:expandTemplate{ | |||
title = 'color', | |||
args = {'red', '#ERROR'} | |||
}) | |||
end | |||
end | |||
local ret2 = '' | |||
value_row:tag('td'):wikitext(frame:expandTemplate{ | |||
title = mode_cell | |||
}) | |||
for passive_normal_i = 0, 3, 1 do | |||
local combine_now = tostring(passive_normal_i) == combine[1] | |||
if tbl_content.passives_normal[passive_normal_i] or combine_now or passive_normal_i == 0 then | |||
local passive_normal_str = 'passive' .. passive_normal_i | |||
if combine_now then | |||
for k, v in ipairs(combine) do | |||
if k ~= 1 then | |||
passive_normal_str = passive_normal_str .. '_passive' .. v | |||
end | |||
end | |||
end | |||
if passive_normal_i == 0 then | |||
passive_normal_str = '' | |||
end | |||
for passive_switch_i = 0, 3, 1 do | |||
local current_switch = tbl_content.passives_switch[passive_switch_i] | |||
if current_switch or passive_switch_i == 0 then | |||
local passive_switch_str = 'passive' .. passive_switch_i | |||
if passive_switch_i == 0 then | |||
passive_switch_str = '' | |||
end | |||
for _, awk_str in ipairs(awk_table) do | |||
for trait_i = 0, #trait_args do | |||
repeat | |||
for hit_i, hit_v in ipairs(hit_count_table) do | |||
local trait_str = trait_args[trait_i] or '' | |||
local str_tbl = {'damage'} | |||
local passive_tbl = {} | |||
table.insert(str_tbl, awk_str) | |||
if tbl_content.traits[trait_str] then | |||
table.insert(str_tbl, trait_str) | |||
elseif trait_i > 0 then | |||
do | |||
break | |||
end | |||
end | |||
table.insert(str_tbl, 1, hit_v) | |||
table.insert(passive_tbl, passive_switch_str) | |||
table.insert(passive_tbl, passive_normal_str) | |||
table.sort(passive_tbl) | |||
for k, v in ipairs(passive_tbl) do | |||
table.insert(str_tbl, v) | |||
end | |||
if inArgs('range_max') then | |||
display(concat(str_tbl) .. mode_flag, true) | |||
else | |||
display(concat(str_tbl) .. mode_flag) | |||
end | |||
end | |||
until true | |||
end | |||
end | |||
end | |||
end | |||
end | end | ||
end | end | ||
end | end | ||
-- For debugging purposes | |||
if (args.debug == 'true') then | |||
ret = '' | |||
for i = 1, #tbl_order, 1 do | |||
ret = ret .. "'''" .. tbl_order[i] .. "''': <br/>" | |||
for k2, v2 in pairs(tbl_content[tbl_order[i]]) do | |||
if (v2 == true) then | |||
v2 = 'true' | |||
end | |||
local output = tostring(v2) | |||
if (type(v2) == 'table') then | |||
output = '' | |||
output = output .. '<br/>--<br/>' | |||
for k3, v3 in pairs(v2) do | |||
output = output .. k3 .. ': ' .. tostring(v3) .. '<br/>' | |||
end | |||
output = output .. '--' | |||
end | |||
ret = ret .. k2 .. ': ' .. output .. '<br/>' | |||
end | |||
ret = ret .. '<br/>' | |||
end | |||
return ret | |||
end | end | ||
makeValueRows(); | |||
makeValueRows(true); | |||
local bug = '' | local bug = '' | ||
if | if args.bug == 'true' then | ||
bug = frame:expandTemplate { | bug = frame:expandTemplate{ | ||
title = 'SkillText', | title = 'SkillText', | ||
args = { 'FreeTraining' } | args = {'FreeTraining'} | ||
} | } | ||
end | end | ||
return parsed .. bug .. tostring(tbl) | |||
end | end | ||
return p | return p | ||
-- pyend | -- pyend |