ElEditors, Interface administrators, Administrators
70,866
edits
No edit summary |
No edit summary |
||
(57 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
-- pystart | -- pystart | ||
require('Module:CommonFunctions') | require('Module:CommonFunctions') | ||
local i18n = require('Module:I18n') | |||
local getArgs = require('Module:Arguments').getArgs | local getArgs = require('Module:Arguments').getArgs | ||
local inspect = require('Module:Inspect').inspect | local inspect = require('Module:Inspect').inspect | ||
local getTranslations = i18n.getTranslations | |||
local p = {} | local p = {} | ||
Line 8: | Line 10: | ||
function p.main(frame) | function p.main(frame) | ||
local args = getArgs(frame) | local args = getArgs(frame) | ||
local tr = getTranslations(frame, 'Template:Damage', args.lang, true) | |||
local out | |||
function translate(key) | |||
return i18n.translate(tr, key) | |||
end | |||
function inArgs(key) | function inArgs(key) | ||
Line 14: | Line 22: | ||
end | end | ||
end | end | ||
local modes = { 'PvE', 'PvP' } | |||
-- Define the schema for the table | -- Define the schema for the table | ||
local tableSchema = { | local tableSchema = {} | ||
for _, mode in ipairs(modes) do | |||
tableSchema[mode] = {} | |||
end | |||
function forEach(func) | |||
for _, mode in ipairs(modes) do | |||
func(mode) | |||
end | |||
end | |||
function forEachDamageType(func) | |||
for _, damage_type in ipairs({ 'min', 'max' }) do | |||
func(damage_type) | |||
end | |||
end | |||
-- Function to create a new table with the desired schema | -- Function to create a new table with the desired schema | ||
Line 36: | Line 58: | ||
do_table = args[1] == 'true', | do_table = args[1] == 'true', | ||
character = args[2] or args.char or 'Elsword', | character = args[2] or args.char or 'Elsword', | ||
lang_suffix = args.lang and ('/' .. args.lang) or '', | |||
lang_append = args.lang ~= nil and args.lang ~= '', | |||
format = args.format ~= 'false', | format = args.format ~= 'false', | ||
no_max = args.no_max == 'true', | no_max = args.no_max == 'true', | ||
Line 76: | Line 100: | ||
{ | { | ||
key = '', | key = '', | ||
name = 'Normal', | name = translate('Normal'), | ||
value = 1 | value = 1 | ||
}, | }, | ||
{ | { | ||
key = 'enhanced', | key = 'enhanced', | ||
name = 'Enhanced', | name = translate('Enhanced (Trait)'), | ||
value = args.enhanced ~= nil and 0.8 | value = args.enhanced ~= nil and 0.8 | ||
}, | }, | ||
{ | { | ||
key = 'empowered', | key = 'empowered', | ||
name = 'Empowered', | name = translate('Empowered'), | ||
value = args.empowered == 'true' and 1.2 or tonumber(args.empowered) or false | value = args.empowered == 'true' and 1.2 or tonumber(args.empowered) or false | ||
}, | }, | ||
{ | { | ||
key = 'useful', | key = 'useful', | ||
name = 'Useful', | name = translate('Useful'), | ||
value = (args.hits_useful or args.avg_hits_useful) and (args.useful_penalty or args.useful or 0. | value = (args.hits_useful or args.avg_hits_useful) and (args.useful_penalty or args.useful or 0.8) or false | ||
}, | }, | ||
{ | { | ||
key = 'heavy', | key = 'heavy', | ||
name = 'Heavy', | name = translate('Heavy'), | ||
value = args.heavy ~= nil and 1.44 | value = args.heavy ~= nil and 1.44 | ||
} | } | ||
Line 116: | Line 140: | ||
|passive1=... |passive2=... -> { passive1, passive2 } | |passive1=... |passive2=... -> { passive1, passive2 } | ||
--]] | --]] | ||
local passive_name = v | |||
local passive_title = v .. OPTIONS.lang_suffix | |||
local is_custom = string.find(k, '_define') ~= nil | |||
local passive_index = string.match(k, "%d") | local passive_index = string.match(k, "%d") | ||
local passive_values = split(frame:preprocess('{{:' .. | local passive_values = split(is_custom and v or | ||
frame:preprocess('{{:' .. passive_name .. '}}{{#arrayprint:' .. passive_name .. '}}')); | |||
local display_title | |||
if is_custom then | |||
passive_name = passive_values[#passive_values] | |||
passive_values[#passive_values] = nil | |||
elseif OPTIONS.lang_append then | |||
--[[ | |||
Translate page's display title to passive name. | |||
Customized will override this name, thus no need to perform the translation | |||
--]] | |||
display_title = i18n.getTranslatedTitle(passive_title) | |||
end | |||
PASSIVES[tonumber(passive_index)] = { | PASSIVES[tonumber(passive_index)] = { | ||
name = | name = passive_name, | ||
value = passive_values[1], | value = passive_values[1], | ||
value_pvp = passive_values[2], | value_pvp = passive_values[2], | ||
alias = args['alias' .. passive_index] or (passive_index == OPTIONS.append_index and OPTIONS.append_name), | alias = args['alias' .. passive_index] or (passive_index == OPTIONS.append_index and OPTIONS.append_name) or display_title, | ||
suffix = args['suffix' .. passive_index] and (' ' .. args['suffix' .. passive_index]) or '', | suffix = args['suffix' .. passive_index] and (' ' .. args['suffix' .. passive_index]) or '', | ||
prefix = args['prefix' .. passive_index] and (args['prefix' .. passive_index] .. ' ') or '', | |||
exist = frame:preprocess('{{#ifexist:' .. passive_name .. '|true|false}}') == 'true' | |||
} | } | ||
elseif | elseif string.match(v, '^[()+%-*/%d%s,.i]+$') then | ||
--[[ | --[[ | ||
Change how args are received. | Change how args are received. | ||
Line 150: | Line 193: | ||
if not args.hits[k] then | if not args.hits[k] then | ||
args.hits[k] = 1 | args.hits[k] = 1 | ||
end | |||
end | |||
-- Set basic hit count to 1 for all cancel damage. | |||
if args.cancel_dmg then | |||
for k, v in ipairs(args.cancel_dmg) do | |||
if not args.cancel_hits then | |||
args.cancel_hits = {} | |||
end | |||
if not args.cancel_hits[k] then | |||
args.cancel_hits[k] = 1 | |||
end | |||
end | end | ||
end | end | ||
Line 155: | Line 210: | ||
-- Store a configuration that will tell the main function how to behave given different inputs. | -- Store a configuration that will tell the main function how to behave given different inputs. | ||
-- It will always take the first value if available. If not, fall back to the other (recursively). | -- It will always take the first value if available. If not, fall back to the other (recursively). | ||
local | local BASE_DAMAGE_CONFIG = { | ||
total_damage = { | total_damage = { | ||
damage_numbers = { 'dmg' }, | damage_numbers = { 'dmg' }, | ||
Line 198: | Line 253: | ||
}, | }, | ||
} | } | ||
local DAMAGE_CONFIG = {} | |||
function handleCancel() | |||
local processed_keys = {} | |||
for config_key, config_value in pairs(BASE_DAMAGE_CONFIG) do | |||
if not config_key:match('cancel_') then | |||
local new_config_value = {} | |||
for arg_table_key, arg_table in pairs(config_value) do | |||
local new_arg_table = {} | |||
for _, arg in ipairs(arg_table) do | |||
table.insert(new_arg_table, 'cancel_' .. arg) | |||
end | |||
new_config_value[arg_table_key] = new_arg_table | |||
end | |||
local new_key = 'cancel_' .. config_key | |||
DAMAGE_CONFIG[new_key] = new_config_value | |||
processed_keys[new_key] = true | |||
end | |||
end | |||
return processed_keys | |||
end | |||
if args.cancel_dmg then | |||
handleCancel() | |||
DAMAGE_CONFIG = table.fuse(BASE_DAMAGE_CONFIG, DAMAGE_CONFIG) | |||
else | |||
DAMAGE_CONFIG = BASE_DAMAGE_CONFIG | |||
end | |||
-- Helper function to check if a table is not empty | |||
local function isTableNotEmpty(tbl) | |||
return next(tbl) ~= nil | |||
end | |||
-- Function to apply inheritance for a specific damage type and argument | |||
local function applyInheritance(mainArgValues, inheritArg, mainArgValue, inheritValue) | |||
if mainArgValue == '' then | |||
return inheritValue | |||
elseif mainArgValue and string.find(mainArgValue, 'i') and inheritValue then | |||
return eval(mainArgValue:gsub('i', inheritValue)) | |||
end | |||
return mainArgValue | |||
end | |||
-- Function to apply inheritance for a specific argument key | |||
local function applyInheritanceForKey(args, prefix, argTable, damageTypeIndex, damageType) | |||
local mainKey = argTable[1] .. damageType | |||
local mainKeyPrefixed = prefix .. mainKey | |||
local mainArgValues = args[mainKeyPrefixed] | |||
if mainArgValues then | |||
local i = 1 | |||
local cancelDmgLen = args.cancel_dmg and #args.cancel_dmg or 0 | |||
while i <= (#args.dmg + cancelDmgLen) do | |||
local mainArgValue = mainArgValues[i] | |||
for ix, inheritKey in ipairs(argTable) do | |||
local inheritArg = args[prefix .. inheritKey .. damageType] or args[inheritKey .. damageType] | |||
-- Basic damage/hits inheritance request detected. Ignore min/max. | |||
if damageType and mainKey:gsub(damageType, "") == argTable[#argTable] then | |||
inheritArg = args[prefix .. inheritKey] or args[inheritKey] | |||
end | |||
if inheritArg and inheritArg[i] and | |||
(damageTypeIndex == 1 and ix ~= 1 or damageTypeIndex ~= 1) and tonumber(inheritArg[i]) | |||
then | |||
mainArgValues[i] = applyInheritance(mainArgValues, inheritArg, mainArgValue, inheritArg[i]) | |||
break | |||
end | |||
end | |||
i = i + 1 | |||
end | |||
end | |||
end | |||
-- Inherits values from args if not provided, but usage suggests that they're meant to be generated. | -- Inherits values from args if not provided, but usage suggests that they're meant to be generated. | ||
function inherit(mode) | function inherit(mode) | ||
local prefix = mode == 'PvE' and '' or string.lower(mode .. '_') | local prefix = mode == 'PvE' and '' or string.lower(mode .. '_') | ||
for configKey, configValue in pairs(DAMAGE_CONFIG) do | |||
for argTableKey, argTable in pairs(configValue) do | |||
if argTableKey ~= 'provided' and isTableNotEmpty(argTable) then | |||
for damageTypeIndex, damageType in ipairs({ '', '_min', '_max' }) do | |||
applyInheritanceForKey(args, prefix, argTable, damageTypeIndex, damageType) | |||
end | end | ||
end | end | ||
Line 243: | Line 346: | ||
end | end | ||
forEach(inherit) | |||
local DAMAGE_PARSED = createDamageDataTable() | local DAMAGE_PARSED = createDamageDataTable() | ||
Line 251: | Line 353: | ||
for config_key, config_value in pairs(DAMAGE_CONFIG) do | for config_key, config_value in pairs(DAMAGE_CONFIG) do | ||
for k, v in pairs(config_value) do | for k, v in pairs(config_value) do | ||
local output_value = | local output_value = {} | ||
for _, v2 in ipairs(v) do | |||
local arg_from_template = args[prefix .. v2] or args[v2] | -- When both min and max are found, we need to break from the loop. | ||
local isValueFound = { min = false, max = false } | |||
for _, v2 in ipairs(v) do -- This array holds the argument names with fallbacks | |||
forEachDamageType(function(damage_type) | |||
-- If there already is a value for this damage type (min or max), do not continue. | |||
if isValueFound[damage_type] == true then | |||
return | |||
end | |||
local arg_from_template = | |||
args[prefix .. v2 .. '_' .. damage_type] | |||
or args[v2 .. '_' .. damage_type] | |||
or args[prefix .. v2] | |||
or args[v2]; | |||
if arg_from_template ~= nil then | |||
if k == 'provided' then | |||
output_value = true | |||
-- Do not generate total_damage values at all if the skill can't reach them. | |||
if string.find(config_key, 'total_') and OPTIONS.no_max then | |||
output_value = false | |||
end | |||
else | |||
if type(output_value) ~= "table" then | |||
output_value = {} | |||
end | |||
output_value[damage_type] = arg_from_template | |||
end | |||
-- Mark the value as found. | |||
isValueFound[damage_type] = true | |||
else | |||
if k == 'provided' then | |||
output_value = false | output_value = false | ||
else | |||
output_value[damage_type] = {} | |||
end | end | ||
end | end | ||
end) | |||
-- Both values found, we can now break the loop. | |||
if isValueFound.min and isValueFound.max then | |||
break | break | ||
end | end | ||
end | end | ||
Line 278: | Line 408: | ||
end | end | ||
forEach(parseConfig) | |||
-- Detected "count", for skills like Clementine, Enough Mineral, etc. | -- Detected "count", for skills like Clementine, Enough Mineral, etc. | ||
function doEachDamage() | function doEachDamage() | ||
local WITH_EACH = table.deep_copy(DAMAGE_PARSED) | |||
for mode, mode_content in pairs(DAMAGE_PARSED) do | for mode, mode_content in pairs(DAMAGE_PARSED) do | ||
for damage_key, damage_value in pairs(mode_content) do | for damage_key, damage_value in pairs(mode_content) do | ||
Line 288: | Line 418: | ||
local new_value = table.deep_copy(damage_value) | local new_value = table.deep_copy(damage_value) | ||
for k, hit_count in ipairs(new_value.hit_counts) do | forEachDamageType(function(damage_type) | ||
for k, hit_count in ipairs(new_value.hit_counts[damage_type]) do | |||
hit_count = hit_count == '' and 1 or hit_count | |||
new_value.hit_counts[damage_type][k] = hit_count * | |||
end | ((string.find(damage_key, 'awk') and args.awk_count) and args.awk_count[1] or args.count[1]) | ||
end | |||
end) | |||
WITH_EACH[mode][damage_key:gsub("total_", "each_")] = damage_value | |||
WITH_EACH[mode][damage_key] = new_value | |||
end | end | ||
end | end | ||
end | end | ||
return WITH_EACH | |||
end | end | ||
if args.count then | if args.count then | ||
doEachDamage() | DAMAGE_PARSED = doEachDamage() | ||
end | end | ||
Line 308: | Line 441: | ||
for mode, mode_content in pairs(DAMAGE_PARSED) do | for mode, mode_content in pairs(DAMAGE_PARSED) do | ||
for damage_key, damage_value in pairs(mode_content) do | for damage_key, damage_value in pairs(mode_content) do | ||
local i = 1 | forEachDamageType(function(damage_type) | ||
local i = 1 | |||
local output = 0 | |||
-- Check if to even generate the damage. | |||
if damage_value.provided then | |||
-- Loop through damage numbers and multiply them with hits. | |||
for k, damage_number in ipairs(damage_value.damage_numbers[damage_type]) do | |||
local hit_count = damage_value.hit_counts[damage_type][i] | |||
hit_count = hit_count == '' and 1 or hit_count | |||
output = output + (damage_number * hit_count) | |||
i = i + 1 | |||
end | |||
-- Write the result to a separate object. | |||
if not BASIC_DAMAGE[mode][damage_key] then | |||
BASIC_DAMAGE[mode][damage_key] = {} | |||
end | |||
BASIC_DAMAGE[mode][damage_key][damage_type] = output | |||
end | end | ||
end) | |||
end | |||
end | end | ||
end | end | ||
Line 327: | Line 465: | ||
doBasicDamage() | doBasicDamage() | ||
-- Adding missing cancel part damage to full, so that repetition wouldn't be a problem. | |||
function addCancelDamage() | |||
for mode, mode_content in pairs(BASIC_DAMAGE) do | |||
for damage_key, damage_value in pairs(mode_content) do | |||
local cancel_candidate = BASIC_DAMAGE[mode]['cancel_' .. damage_key] | |||
forEachDamageType(function(damage_type) | |||
if not string.find(damage_key, 'cancel_') and cancel_candidate then | |||
BASIC_DAMAGE[mode][damage_key][damage_type] = damage_value[damage_type] + | |||
cancel_candidate[damage_type] | |||
end | |||
end) | |||
end | |||
end | |||
end | |||
if args.cancel_dmg then | |||
addCancelDamage() | |||
end | |||
local WITH_TRAITS = createDamageDataTable() | local WITH_TRAITS = createDamageDataTable() | ||
Line 341: | Line 498: | ||
--]] | --]] | ||
if (trait.value and trait.key ~= 'useful') or (string.find(damage_key, 'useful') and trait.key == 'useful') then | if (trait.value and trait.key ~= 'useful') or (string.find(damage_key, 'useful') and trait.key == 'useful') then | ||
forEachDamageType(function(damage_type) | |||
damage_value * trait.value | local new_key = damage_key .. | ||
((trait.key == 'useful' or trait.key == '') and "" or ('_' .. trait.key)); | |||
if not WITH_TRAITS[mode][new_key] then | |||
WITH_TRAITS[mode][new_key] = {} | |||
end | |||
WITH_TRAITS[mode][new_key][damage_type] = damage_value[damage_type] * trait.value | |||
end) | |||
end | end | ||
end | end | ||
Line 361: | Line 524: | ||
for mode, mode_content in pairs(WITH_TRAITS) do | for mode, mode_content in pairs(WITH_TRAITS) do | ||
for damage_key, damage_value in pairs(mode_content) do | for damage_key, damage_value in pairs(mode_content) do | ||
local combinations = { {} } | forEachDamageType(function(damage_type) | ||
local combinations = { {} } | |||
for passive_key, passive in pairs(PASSIVES) do | |||
local count = #combinations | |||
for i = 1, count do | |||
local new_combination = { unpack(combinations[i]) } | |||
table.insert(new_combination, passive_key) | |||
table.insert(combinations, new_combination) | |||
end | |||
end | end | ||
for _, combination in pairs(combinations) do | |||
local passive_multiplier = 1 | |||
local name_suffix = '' | |||
if #combination > 0 then | |||
table.sort(combination) | |||
for _, passive_key in pairs(combination) do | |||
passive_multiplier = passive_multiplier * | |||
tonumber(PASSIVES[passive_key][mode == 'PvE' and 'value' or 'value_pvp']) | |||
name_suffix = name_suffix .. '_passive' .. passive_key | |||
end | |||
end | |||
local new_damage_key = damage_key .. name_suffix; | |||
if not WITH_PASSIVES[mode][new_damage_key] then | |||
WITH_PASSIVES[mode][new_damage_key] = {} | |||
end | end | ||
WITH_PASSIVES[mode][new_damage_key][damage_type] = damage_value[damage_type] * passive_multiplier | |||
end | end | ||
end) | |||
end | |||
end | end | ||
end | end | ||
Line 390: | Line 559: | ||
local RANGE = { | local RANGE = { | ||
min_count = args.range_min_count and args.range_min_count[1] | min_count = args.range_min_count and args.range_min_count[1], | ||
max_count = args.range_max_count and args.range_max_count[1] | max_count = args.range_max_count and args.range_max_count[1], | ||
PvE = { | PvE = { | ||
min = args.range_min and args.range_min[1] | min = args.range_min and args.range_min[1], | ||
max = args.range_max and args.range_max[1] | max = args.range_max and args.range_max[1] | ||
}, | }, | ||
PvP = { | PvP = { | ||
min = args.range_min and (args.range_min[2] or args.range_min[1]) | min = args.range_min and (args.range_min[2] or args.range_min[1]), | ||
max = args.range_max and (args.range_max[2] or args.range_max[1]) | max = args.range_max and (args.range_max[2] or args.range_max[1]) | ||
} | } | ||
} | } | ||
Line 408: | Line 577: | ||
for damage_key, damage_value in pairs(mode_content) do | for damage_key, damage_value in pairs(mode_content) do | ||
WITH_RANGE[mode][damage_key] = { min = 0, max = 0 } | WITH_RANGE[mode][damage_key] = { min = 0, max = 0 } | ||
for | forEachDamageType(function(damage_type) | ||
local | local range_count = RANGE[damage_type .. '_count'] or 1; | ||
-- If min count preset, use range_max for the multiplier. | |||
WITH_RANGE[mode][damage_key][ | local range_multiplier = RANGE[mode][damage_type] or (damage_type == 'min' and RANGE.min_count and RANGE[mode].max) or 1; | ||
local final_range_multiplier = (1 + ((range_multiplier - 1) * range_count)); | |||
local perm_buff = OPTIONS.perm_buff[mode]; | |||
local final_damage_value = damage_value[damage_type] * final_range_multiplier * perm_buff; | |||
WITH_RANGE[mode][damage_key][damage_type] = not OPTIONS.format and final_damage_value or | |||
formatDamage(final_damage_value) | formatDamage(final_damage_value) | ||
end | end) | ||
end | end | ||
end | end | ||
Line 479: | Line 653: | ||
{ | { | ||
type = 'extra', | type = 'extra', | ||
text = { 'Average' }, | text = { translate('Average') }, | ||
is_visible = OPTIONS.no_max, | is_visible = OPTIONS.no_max, | ||
no_damage = true | no_damage = true | ||
Line 486: | Line 660: | ||
type = 'passives', | type = 'passives', | ||
text = checkPassives({ | text = checkPassives({ | ||
output = { 'Base' }, | output = { translate('Base') }, | ||
action = function(passive, output) | action = function(passive, output) | ||
if passive.is_combined then | if passive.is_combined then | ||
Line 493: | Line 667: | ||
for _, passive_key in ipairs(OPTIONS.combine) do | for _, passive_key in ipairs(OPTIONS.combine) do | ||
passive = PASSIVES[passive_key] | passive = PASSIVES[passive_key] | ||
table.insert(combo, link(passive.name, passive.alias | table.insert(combo, | ||
link(passive.name, passive.alias, passive.prefix, passive.suffix, passive.exist)) | |||
end | end | ||
table.insert(output, table.concat(combo, '/') .. OPTIONS.combine_suffix) | table.insert(output, table.concat(combo, '/') .. OPTIONS.combine_suffix) | ||
else | else | ||
table.insert(output, link(passive.name, passive.alias | table.insert(output, | ||
link(passive.name, passive.alias, passive.prefix, passive.suffix, passive.exist)) | |||
end | end | ||
end | end | ||
Line 515: | Line 691: | ||
{ | { | ||
type = 'passive_appended', | type = 'passive_appended', | ||
text = { 'Normal', | text = { | ||
translate('Normal'), | |||
OPTIONS.is_append and | OPTIONS.is_append and | ||
link(PASSIVES[OPTIONS.append_index].name, PASSIVES[OPTIONS.append_index].alias or OPTIONS.append_name) }, | link(PASSIVES[OPTIONS.append_index].name, | ||
PASSIVES[OPTIONS.append_index].alias or OPTIONS.append_name or nil, | |||
PASSIVES[OPTIONS.append_index].prefix, | |||
PASSIVES[OPTIONS.append_index].suffix, | |||
PASSIVES[OPTIONS.append_index].exist | |||
) | |||
}, | |||
keywords = { OPTIONS.is_append and ('passive' .. OPTIONS.append_index) or nil }, | keywords = { OPTIONS.is_append and ('passive' .. OPTIONS.append_index) or nil }, | ||
is_visible = OPTIONS.is_append or false | is_visible = OPTIONS.is_append or false | ||
Line 523: | Line 706: | ||
{ | { | ||
type = 'awakening', | type = 'awakening', | ||
text = { 'Regular', (function() | text = { translate('Regular'), (function() | ||
if OPTIONS.dmp then | if OPTIONS.dmp then | ||
return link('Dynamo Point System', 'Dynamo Configuration', | return link('Dynamo Point System' .. OPTIONS.lang_suffix, 'Dynamo Configuration', args.awk_prefix, | ||
OPTIONS.dmp ~= 'false' and (fillTemplate('({1} DMP)', { OPTIONS.dmp })) .. (args.awk_suffix and (' ' .. args.awk_suffix) or '')) | |||
elseif args.awk_alias then | elseif args.awk_alias then | ||
return link | return link(args.awk_alias[1], args.awk_alias[2], args.awk_prefix, args.awk_suffix) | ||
end | end | ||
return link('Awakening Mode') | return link('Awakening Mode' .. OPTIONS.lang_suffix, translate('Awakening Mode'), args.awk_prefix, args.awk_suffix) | ||
end)() | end)() | ||
}, | }, | ||
Line 540: | Line 723: | ||
type = 'traits', | type = 'traits', | ||
text = checkTraits({ | text = checkTraits({ | ||
output = { 'Normal' }, | output = { translate('Normal') }, | ||
action = function(trait, output) | action = function(trait, output) | ||
table.insert(output, trait.name) | table.insert(output, trait.name) | ||
Line 551: | Line 734: | ||
}), | }), | ||
is_visible = checkTraits() | is_visible = checkTraits() | ||
}, | |||
{ | |||
type = 'cancel', | |||
text = { | |||
translate('Cancel'), | |||
translate('Full'), | |||
}, | |||
keywords = { 'cancel' }, | |||
keyword_first = true, | |||
is_visible = inArgs('cancel_dmg') | |||
}, | }, | ||
{ | { | ||
Line 556: | Line 749: | ||
text = { | text = { | ||
(inArgs('count') and not OPTIONS.use_avg) and | (inArgs('count') and not OPTIONS.use_avg) and | ||
( | (fillTemplate(translate('Per {1}'), { args.count_name or translate('Group') })) or | ||
'Max' | translate('Average'), | ||
translate('Max') | |||
}, | }, | ||
keywords = (function() | keywords = (function() | ||
Line 602: | Line 796: | ||
if current_row.keyword_next_to_main_key then | if current_row.keyword_next_to_main_key then | ||
new_key = prev_key:gsub(main_key, main_key .. '_' .. keyword) | new_key = prev_key:gsub(main_key, main_key .. '_' .. keyword) | ||
elseif current_row.keyword_first then | |||
new_key = keyword .. '_' .. prev_key | |||
end | end | ||
table.insert(new_list, new_key) | table.insert(new_list, new_key) | ||
Line 613: | Line 809: | ||
end | end | ||
end | end | ||
end | |||
-- Sort the list once more, in order to swap the order of cancel & full. | |||
if inArgs('cancel_dmg') then | |||
local new_list = {} | |||
local cancel_counter = 1 | |||
local full_counter = 2 | |||
for i, damage_key in ipairs(all_list) do | |||
local regex = "^(%w+_)" | |||
local prefix = 'cancel_' | |||
local match = string.match(damage_key, regex) | |||
if (match == prefix) then | |||
new_list[i] = damage_key:gsub(prefix, "") | |||
else | |||
new_list[i] = prefix .. damage_key | |||
end | |||
end | |||
all_list = new_list | |||
end | end | ||
Line 619: | Line 833: | ||
function doInitialCell(new_row) | function doInitialCell(new_row) | ||
return new_row:tag('th'):wikitext('Mode') | return new_row:tag('th'):wikitext(translate('Mode')) | ||
end | end | ||
Line 678: | Line 892: | ||
function doContentByMode(mode) | function doContentByMode(mode) | ||
local mode_row = TABLE:new() | local mode_row = TABLE:new() | ||
mode_row:tag('td'):wikitext(frame:expandTemplate { title = mode }) | mode_row:tag('td'):wikitext(frame:expandTemplate { title = translate(mode) }) | ||
local damage_entries = returnDamageInOrder() | local damage_entries = returnDamageInOrder() | ||
local last_number | |||
local last_unique_cell | |||
for _, damage_key in ipairs(damage_entries) do | for _, damage_key in ipairs(damage_entries) do | ||
if args.dump_names ~= 'true' then | if args.dump_names ~= 'true' then | ||
local damage_number = FINAL_DAMAGE[mode][damage_key] | local damage_number = FINAL_DAMAGE[mode][damage_key] | ||
damage_number = doRangeText(damage_number) | damage_number = doRangeText(damage_number) | ||
mode_row:tag('td'):wikitext(damage_number | if last_number ~= damage_number then | ||
-- Display ranges. | |||
local new_cell = mode_row:tag('td'):wikitext(damage_number | |||
-- Error out if it doesn't exist | |||
or frame:expandTemplate { | |||
title = 'color', | |||
args = { 'red', '#ERROR' } | |||
}) | |||
last_unique_cell = new_cell | |||
else | |||
last_unique_cell:attr('colspan', (last_unique_cell:getAttr('colspan') or 1) + 1) | |||
end | |||
last_number = damage_number | |||
else | else | ||
mode_row:tag('td'):wikitext(damage_key) | mode_row:tag('td'):wikitext(damage_key) | ||
Line 702: | Line 923: | ||
function doTable() | function doTable() | ||
doHeaders() | doHeaders() | ||
forEach(doContentByMode) | |||
end | end | ||
doTable() | if OPTIONS.do_table then | ||
doTable() | |||
end | |||
-- Dump all values if wanted. | -- Dump all values if wanted. | ||
Line 720: | Line 942: | ||
if OPTIONS.bug then | if OPTIONS.bug then | ||
bug = frame:expandTemplate { | bug = frame:expandTemplate { | ||
title = 'SkillText', | title = translate('SkillText'), | ||
args = { 'FreeTraining' } | args = { 'FreeTraining' } | ||
} | } | ||
Line 727: | Line 949: | ||
-- Transform into variables | -- Transform into variables | ||
local variables = doVariables(frame, FINAL_DAMAGE, OPTIONS.prefix) | local variables = doVariables(frame, FINAL_DAMAGE, OPTIONS.prefix) | ||
if out ~= nil then | |||
return inspect_dump(frame, out) | |||
end | |||
return variables .. bug .. (OPTIONS.do_table and tostring(TABLE) or '') | return variables .. bug .. (OPTIONS.do_table and tostring(TABLE) or '') |