- Welcome to the Kancolle Wiki!
- If you have any questions regarding site content, account registration, etc., please visit the KanColle Wiki Discord
Difference between revisions of "Module:Calc"
Jump to navigation
Jump to search
Line 8: | Line 8: | ||
local args = nil | local args = nil | ||
local ship = nil | local ship = nil | ||
+ | local target = nil | ||
local shipCapabilities = nil | local shipCapabilities = nil | ||
local frame = nil | local frame = nil | ||
Line 61: | Line 62: | ||
day = date[3] < 10 and "0" .. date[3] or date[3], | day = date[3] < 10 and "0" .. date[3] or date[3], | ||
} | } | ||
+ | end, | ||
+ | |||
+ | test = function(ship, target) | ||
+ | return ship:level() + ship._accuracy - target:evasion() | ||
end, | end, | ||
Line 76: | Line 81: | ||
local formatting_function = formatting_functions[key] | local formatting_function = formatting_functions[key] | ||
if formatting_function then | if formatting_function then | ||
− | return formatting_function(ship) | + | return formatting_function(ship, target) |
else | else | ||
if shipCapabilities[key] then | if shipCapabilities[key] then | ||
Line 97: | Line 102: | ||
function interpret_arg(arg) | function interpret_arg(arg) | ||
local prefix = string.sub(arg, 1, 1) | local prefix = string.sub(arg, 1, 1) | ||
+ | local prefix2 = string.sub(arg, 1, 2) | ||
if prefix == "@" then | if prefix == "@" then | ||
local enumerator = string.sub(arg, 2) | local enumerator = string.sub(arg, 2) | ||
Line 109: | Line 115: | ||
ship = Ship(ship_key) | ship = Ship(ship_key) | ||
shipCapabilities = ShipCapabilities{ ship = ship } | shipCapabilities = ShipCapabilities{ ship = ship } | ||
+ | elseif prefix2 == "!!" then | ||
+ | local key = string.sub(arg, 3) | ||
+ | target = Ship(key) | ||
elseif prefix == "!" then | elseif prefix == "!" then | ||
local ship_key = string.sub(arg, 2) | local ship_key = string.sub(arg, 2) | ||
− | if string.sub(ship_key, 1, | + | if string.sub(ship_key, 1, 1) == "_" and ship then |
− | local | + | local kv = mw.text.split(ship_key, "%s*=%s*") |
− | local equipment = {} | + | local k = kv[1] |
− | + | local v = kv[2] | |
− | + | if k and v then | |
+ | if k == "_equipment" then | ||
+ | local equipment = {} | ||
+ | for eq in string.gmatch(v, '([^,]+)') do | ||
+ | table.insert(equipment, { equipment = eq }) | ||
+ | end | ||
+ | ship._equipment = equipment | ||
+ | else | ||
+ | ship[k] = tonumber(v) | ||
+ | end | ||
end | end | ||
− | |||
else | else | ||
local parts = string.gmatch(ship_key, '([^:]+)') | local parts = string.gmatch(ship_key, '([^:]+)') | ||
Line 126: | Line 143: | ||
ship = Ship(ship_key) | ship = Ship(ship_key) | ||
shipCapabilities = ShipCapabilities{ ship = ship } | shipCapabilities = ShipCapabilities{ ship = ship } | ||
− | + | else | |
− | + | local kv = mw.text.split(part, "%s*=%s*") | |
− | + | local k = kv[0] | |
− | + | local v = kv[1] | |
+ | if k and v then | ||
+ | if k == "_equipment" then | ||
+ | local equipment = {} | ||
+ | for eq in string.gmatch(part, '([^,]+)') do | ||
+ | table.insert(equipment, { equipment = eq }) | ||
+ | end | ||
+ | ship._equipment = equipment | ||
+ | else | ||
+ | ship[k] = tonumber(v) | ||
+ | end | ||
end | end | ||
− | |||
end | end | ||
i = i + 1 | i = i + 1 | ||
Line 206: | Line 232: | ||
mw.log( | mw.log( | ||
Calc.format(nil, { | Calc.format(nil, { | ||
− | "!Nagato/Kai Ni | + | "!Nagato/Kai Ni", |
− | "? | + | "!_level = 99", |
+ | "!_accuracy = 10", | ||
+ | "!!Destroyer Ro-Class", | ||
+ | "?test" | ||
}) | }) | ||
) | ) |
Revision as of 17:07, 4 November 2017
Documentation for this module may be created at Module:Calc/doc
local Utils = require("Module:Utils")
local format = require("Module:StringOperations").format
local Formatting = require("Module:Formatting")
local Ship = require("Module:Ship")
local ShipIterator = require("Module:ShipIterator")
local ShipCapabilities = require("Module:ShipCapabilities")
local args = nil
local ship = nil
local target = nil
local shipCapabilities = nil
local frame = nil
local enumerating_functions = {
args = function()
return mw.text.split(args.args, "%s*,%s*")
end,
base_names = function()
return ShipIterator.baseForms
end,
all_names = function()
return ShipIterator.allForms
end,
enemy = function()
return ShipIterator.enemyForms
end,
}
-- TODO: have a syntax for calling Module:Formatting functions?
local formatting_functions = {
night_battle_power = function(ship)
return (ship:firepower_max() or 0) + (ship:torpedo_max() or 0)
end,
code = function(ship)
return Formatting:format_ship_code(ship:type())
end,
-- overrides ShipData:type
type = function(ship)
return Formatting:format_ship_type(ship:type())
end,
-- overrides ShipData:link
link = function(ship)
return Formatting:format_link(ship:link())
end,
-- overrides ShipData:implementation_date
implementation_date = function(ship)
local date = ship:implementation_date()
return not date and "??" or format{
"${year}/${month}/${day}",
year = date[1],
month = date[2] < 10 and "0" .. date[2] or date[2],
day = date[3] < 10 and "0" .. date[3] or date[3],
}
end,
test = function(ship, target)
return ship:level() + ship._accuracy - target:evasion()
end,
}
function format_lua(lua)
if type(lua) == "table" then
return tostring(table.concat(lua, args.concat_value or ", "))
else
return tostring(lua)
end
end
function format_value(key)
local formatting_function = formatting_functions[key]
if formatting_function then
return formatting_function(ship, target)
else
if shipCapabilities[key] then
local a, b = shipCapabilities[key](shipCapabilities)
return format_lua(b or a)
else
local lua = ship[key]
if type(lua) == "function" then
return format_lua(lua(ship))
else
return format_lua(lua)
end
end
end
end
local sequence = nil
local sequence_position = nil
function interpret_arg(arg)
local prefix = string.sub(arg, 1, 1)
local prefix2 = string.sub(arg, 1, 2)
if prefix == "@" then
local enumerator = string.sub(arg, 2)
local enumerating_function = enumerating_functions[enumerator]
if enumerating_function and not sequence then
sequence = enumerating_function()
sequence_position = 1
end
elseif arg == "!@" then
local ship_key = sequence[sequence_position]
sequence_position = sequence_position + 1
ship = Ship(ship_key)
shipCapabilities = ShipCapabilities{ ship = ship }
elseif prefix2 == "!!" then
local key = string.sub(arg, 3)
target = Ship(key)
elseif prefix == "!" then
local ship_key = string.sub(arg, 2)
if string.sub(ship_key, 1, 1) == "_" and ship then
local kv = mw.text.split(ship_key, "%s*=%s*")
local k = kv[1]
local v = kv[2]
if k and v then
if k == "_equipment" then
local equipment = {}
for eq in string.gmatch(v, '([^,]+)') do
table.insert(equipment, { equipment = eq })
end
ship._equipment = equipment
else
ship[k] = tonumber(v)
end
end
else
local parts = string.gmatch(ship_key, '([^:]+)')
local i = 1
for part in parts do
if i == 1 then
ship_key = part
ship = Ship(ship_key)
shipCapabilities = ShipCapabilities{ ship = ship }
else
local kv = mw.text.split(part, "%s*=%s*")
local k = kv[0]
local v = kv[1]
if k and v then
if k == "_equipment" then
local equipment = {}
for eq in string.gmatch(part, '([^,]+)') do
table.insert(equipment, { equipment = eq })
end
ship._equipment = equipment
else
ship[k] = tonumber(v)
end
end
end
i = i + 1
end
end
elseif prefix == "#" and args.format == "table" then
return "|-\n"
elseif prefix == "?" then
prefix = string.sub(arg, 2, 2)
if prefix == "?" then
local key = string.sub(arg, 3)
return frame:preprocess(format{
'{{${template}|${ship}}}',
template = key,
ship = ship:name('/')
})
else
local key = string.sub(arg, 2)
local value = format_value(key)
if args.format == "table" then
return "|" .. value .. "\n"
else
return value
end
end
else
return arg
end
end
local special_functions = {
apply = function(args_)
local frame_ = frame:getParent()
local template = args_[2]
local values = {}
for i = 3, #args_ do
table.insert(values, format{
'{{${template}|${arg}}}',
template = template,
arg = args_[i]
})
end
return frame_:preprocess(table.concat(values, args.concat or ""))
end
}
function interpret_args(args_)
args = args_
local special_function = special_functions[args[1]]
if special_function then
return special_function(args)
else
local values = {}
repeat
for _, arg in ipairs(args_) do
local value = interpret_arg(arg)
if value then
table.insert(values, value)
end
end
until not sequence or sequence_position > #sequence
return table.concat(values, args.concat or "")
end
end
local Calc = {}
function Calc.format(frame_, args_)
frame = frame_
return interpret_args(args_ or Utils.getTemplateArgs(frame_).explicit)
end
function Calc.test()
mw.log(
Calc.format(nil, {
"!Nagato/Kai Ni",
"!_level = 99",
"!_accuracy = 10",
"!!Destroyer Ro-Class",
"?test"
})
)
end
return Calc