| Line 1: |
Line 1: |
| | local U = require("Module:Core") | | local U = require("Module:Core") |
| − | local format = require("Module:Core").format
| |
| | local Formatting = require("Module:Formatting") | | local Formatting = require("Module:Formatting") |
| | local Equipment = require("Module:Equipment") | | local Equipment = require("Module:Equipment") |
| Line 16: |
Line 15: |
| | local ShipsByApiId = require("Module:Collection/ShipsByApiId") | | local ShipsByApiId = require("Module:Collection/ShipsByApiId") |
| | | | |
| | + | local args = nil |
| | local Ship = nil | | local Ship = nil |
| − |
| |
| − | local frame = nil
| |
| − | local args = nil
| |
| | local ship = nil | | local ship = nil |
| | + | local shipCapabilities = {} |
| | local target = nil | | local target = nil |
| − | local shipCapabilities = {}
| |
| | local equipment = nil | | local equipment = nil |
| | local filterArg = {} | | local filterArg = {} |
| | local sorted = false | | local sorted = false |
| − | | + | local sequence = nil |
| − | -- $('.calc-debug').show().appendTo('#mw-content-text')
| + | local sequence_position = nil |
| − | local debug = {} | + | local env = {} |
| − | | + | local implicitTrigger = true |
| − | function debugLog(k, v)
| |
| − | if args.debug then
| |
| − | k = U.trim(tostring(k))
| |
| − | v = U.trim(tostring(v))
| |
| − | table.insert(debug, k .. " = " .. v)
| |
| − | end
| |
| − | end
| |
| − | | |
| − | function debugString()
| |
| − | return #debug > 0 and args.debug and ([[<pre class="calc-debug" style="text-align:left;background:transparent;display:none"><code>]] .. table.concat(debug, "\n") .. [[</code></pre>]]) or ""
| |
| − | 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
| |
| | | | |
| | local enumerating_functions = { | | local enumerating_functions = { |
| − | | + | args = function() return mw.text.split(args.args, "%s*,%s*") end, |
| − | args = function() | + | base_names = function() return ShipIterator.baseForms end, |
| − | return mw.text.split(args.args, "%s*,%s*")
| + | all_names = function() return ShipIterator.allForms end, |
| − | end,
| + | enemy = function() return ShipIterator.enemyForms end, |
| − | | + | equipment = function() return U.imap(EquipmentCollection, function(e) return e._name end) end, |
| − | base_names = function() | |
| − | return ShipIterator.baseForms
| |
| − | end,
| |
| − | | |
| − | all_names = function() | |
| − | return ShipIterator.allForms
| |
| − | end,
| |
| − |
| |
| − | enemy = function() | |
| − | return ShipIterator.enemyForms
| |
| − | end,
| |
| − | | |
| − | equipment = function() | |
| − | return U.imap(EquipmentCollection, function(e) return e._name end)
| |
| − | end,
| |
| − |
| |
| | allEquipment = function() | | allEquipment = function() |
| | local result = {} | | local result = {} |
| Line 81: |
Line 43: |
| | return result | | return result |
| | end, | | end, |
| − |
| |
| | enemyEquipment = function() | | enemyEquipment = function() |
| | local result = {} | | local result = {} |
| Line 91: |
Line 52: |
| | return result | | return result |
| | end, | | end, |
| | + | } |
| | | | |
| − | }
| + | local function format_lua(lua) |
| | + | return tostring(type(lua) == "table" and table.concat(lua, args.concat_value or ", ") or lua) |
| | + | end |
| | | | |
| − | -- TODO: have a syntax for calling Module:Formatting functions?
| |
| | local formatting_functions = { | | local formatting_functions = { |
| − | | + | air_power = function(ship) return ship.air_power and ship:air_power() or -1 end, |
| − | air_power = function(ship) | + | equipment_range = function(ship) return U.imax(U.imap(ship._equipment or {}, function (e) return Equipment(e.equipment):range() or 0 end), 0) end, |
| − | return ship.air_power and ship:air_power() or -1
| |
| − | end,
| |
| − |
| |
| − | equipment_range = function(ship) | |
| − | return U.imax(U.imap(ship._equipment or {}, function (e) return Equipment(e.equipment):range() or 0 end), 0)
| |
| − | end,
| |
| − |
| |
| | equipment_range_diff = function(ship) | | equipment_range_diff = function(ship) |
| | local equipment_range = U.imax(U.imap(ship._equipment or {}, function (e) return Equipment(e.equipment):range() or 0 end), 0) | | local equipment_range = U.imax(U.imap(ship._equipment or {}, function (e) return Equipment(e.equipment):range() or 0 end), 0) |
| | return (ship:range() or 0) - equipment_range | | return (ship:range() or 0) - equipment_range |
| | end, | | end, |
| − | | + | night_battle_power = function(ship) return (ship:firepower_max() or 0) + (ship:torpedo_max() or 0) end, |
| − | night_battle_power = function(ship) | |
| − | return (ship:firepower_max() or 0) + (ship:torpedo_max() or 0)
| |
| − | end,
| |
| − |
| |
| | format_day_battle = function(ship) | | format_day_battle = function(ship) |
| | local mode, attack_power = shipCapabilities:day_battle() | | local mode, attack_power = shipCapabilities:day_battle() |
| | return shipCapabilities:format_day_battle(mode, attack_power) | | return shipCapabilities:format_day_battle(mode, attack_power) |
| | end, | | end, |
| − |
| |
| | format_night_battle = function(ship) | | format_night_battle = function(ship) |
| | local mode, attack_power = shipCapabilities:night_battle() | | local mode, attack_power = shipCapabilities:night_battle() |
| | return shipCapabilities:format_night_battle(mode, attack_power) | | return shipCapabilities:format_night_battle(mode, attack_power) |
| | end, | | end, |
| − |
| |
| | format_opening_torpedo = function(ship) | | format_opening_torpedo = function(ship) |
| | return shipCapabilities:format_torpedo(shipCapabilities:opening_torpedo()) | | return shipCapabilities:format_torpedo(shipCapabilities:opening_torpedo()) |
| | end, | | end, |
| − |
| |
| | format_closing_torpedo = function(ship) | | format_closing_torpedo = function(ship) |
| | return shipCapabilities:format_torpedo(shipCapabilities:closing_torpedo()) | | return shipCapabilities:format_torpedo(shipCapabilities:closing_torpedo()) |
| | end, | | end, |
| − |
| |
| | format_asw_attack = function(ship) | | format_asw_attack = function(ship) |
| | local attack_power, opening, day, night, uncertain = shipCapabilities:asw_attack() | | local attack_power, opening, day, night, uncertain = shipCapabilities:asw_attack() |
| | return shipCapabilities:format_asw_attack(attack_power, opening, day, night, uncertain) | | return shipCapabilities:format_asw_attack(attack_power, opening, day, night, uncertain) |
| | end, | | end, |
| − |
| |
| | format_opening_airstrike = function(ship) | | format_opening_airstrike = function(ship) |
| | return shipCapabilities:format_opening_airstrike(shipCapabilities:opening_airstrike()) | | return shipCapabilities:format_opening_airstrike(shipCapabilities:opening_airstrike()) |
| | end, | | end, |
| − | | + | slots = function(ship) return format_lua(U.imap(ship._equipment or {}, function (e) return e and e.size or '?' end)) end, |
| − | slots = function(ship) | |
| − | return format_lua(U.imap(ship._equipment or {}, function (e) return e and e.size or '?' end))
| |
| − | end,
| |
| − | | |
| | equips = function(ship) | | equips = function(ship) |
| | return 'style="text-align:left"|' .. U.ijoin(U.imap(ship._equipment or {}, function (e) | | return 'style="text-align:left"|' .. U.ijoin(U.imap(ship._equipment or {}, function (e) |
| Line 158: |
Line 101: |
| | end), "<br>") | | end), "<br>") |
| | end, | | end, |
| − | | + | code = function(obj) return equipment and Formatting:format_equipment_type(obj:type()) or Formatting:format_ship_code(obj:type()) end, |
| − | code = function(obj) | + | type = function(obj) return equipment and Formatting:format_equipment_type(obj:type()) or Formatting:format_ship_type(obj:type()) end, |
| − | return equipment and
| |
| − | Formatting:format_equipment_type(obj:type()) or
| |
| − | Formatting:format_ship_code(obj:type())
| |
| − | end,
| |
| − | | |
| − | -- overrides ShipData:type
| |
| − | type = function(obj) | |
| − | return equipment and
| |
| − | Formatting:format_equipment_type(obj:type()) or
| |
| − | Formatting:format_ship_type(obj:type())
| |
| − | end,
| |
| − | | |
| | icon = function(obj) | | icon = function(obj) |
| | if obj.hp then | | if obj.hp then |
| Line 183: |
Line 114: |
| | end | | end |
| | end, | | end, |
| − | | + | icon_damaged = function(obj) return string.format("[[File:Ship Icon %s Damaged.png|100px]]", obj:name()) end, |
| − | icon_damaged = function(obj) | |
| − | return string.format("[[File:Ship Icon %s Damaged.png|100px]]", obj:name())
| |
| − | end,
| |
| − | | |
| − | -- overrides ShipData:link
| |
| | link = function(obj) | | link = function(obj) |
| | if obj._dummy then | | if obj._dummy then |
| Line 200: |
Line 126: |
| | end | | end |
| | end, | | end, |
| − | | + | class = function(ship) return ship:class() and ship:class():name() or "?" end, |
| − | -- overrides ShipData:class
| |
| − | class = function(ship) | |
| − | return ship:class() and ship:class():name() or "?"
| |
| − | end,
| |
| − | | |
| − | -- overrides ShipData:implementation_date
| |
| | implementation_date = function(ship) | | implementation_date = function(ship) |
| | local date = ship:implementation_date() | | local date = ship:implementation_date() |
| − | return not date and "??" or format{ | + | return not date and "??" or string.format("%s/%s/%s", date[1], date[2] < 10 and "0" .. date[2] or date[2], date[3] < 10 and "0" .. date[3] or date[3]) |
| − | "${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, | | end, |
| − |
| |
| | banner = function(obj) | | banner = function(obj) |
| | if not obj or not obj.lua_name then | | if not obj or not obj.lua_name then |
| Line 223: |
Line 137: |
| | return ShipBattleCardKai:Asset({ obj:lua_name(), hd = true, size = "160px" }) | | return ShipBattleCardKai:Asset({ obj:lua_name(), hd = true, size = "160px" }) |
| | end, | | end, |
| − |
| |
| | card = function(obj) | | card = function(obj) |
| | if not obj or not obj.lua_name then | | if not obj or not obj.lua_name then |
| Line 234: |
Line 147: |
| | end | | end |
| | end, | | end, |
| − | | + | item = function(obj) return EquipmentGraphicKai:Asset({ obj:name(), size = "75px", link = "nil" }) end, |
| − | item = function(obj) | + | fairy = function(obj) return EquipmentGraphicKai:Asset({ obj:name(), size = "75px", fairy = "only", link = "nil" }) end, |
| − | return EquipmentGraphicKai:Asset({ obj:name(), size = "75px", link = "nil" })
| + | full = function(obj) return EquipmentGraphicKai:Asset({ obj:name(), size = "75px", fairy = "true", link = "nil" }) end, |
| − | end,
| |
| − | | |
| − | fairy = function(obj) | |
| − | return EquipmentGraphicKai:Asset({ obj:name(), size = "75px", fairy = "only", link = "nil" })
| |
| − | end,
| |
| − | | |
| − | full = function(obj) | |
| − | return EquipmentGraphicKai:Asset({ obj:name(), size = "75px", fairy = "true", link = "nil" })
| |
| − | end,
| |
| − | | |
| | card_ = function(o) return string.format("[[File:%s Card.png|75px]]", o:name()) end, | | card_ = function(o) return string.format("[[File:%s Card.png|75px]]", o:name()) end, |
| | equipment_ = function(o) return string.format("[[File:%s Equipment.png|75px]]", o:name()) end, | | equipment_ = function(o) return string.format("[[File:%s Equipment.png|75px]]", o:name()) end, |
| | character_ = function(o) return string.format("[[File:%s Character.png|75px]]", o:name()) end, | | character_ = function(o) return string.format("[[File:%s Character.png|75px]]", o:name()) end, |
| | full_ = function(o) return string.format("[[File:%s Full.png|75px]]", o:name()) end, | | full_ = function(o) return string.format("[[File:%s Full.png|75px]]", o:name()) end, |
| − |
| |
| | format_morale = function(ship) | | format_morale = function(ship) |
| | local morale = ship:morale() or 49 | | local morale = ship:morale() or 49 |
| | return morale <= 19 and "Red" or morale <= 29 and "Orange" or morale <= 49 and "Normal" or "Sparkle" | | return morale <= 19 and "Red" or morale <= 29 and "Orange" or morale <= 49 and "Normal" or "Sparkle" |
| | end, | | end, |
| − |
| |
| | hit_rate = function(ship, target) | | hit_rate = function(ship, target) |
| | local r = Combat.hit_rate(ship, target) | | local r = Combat.hit_rate(ship, target) |
| Line 266: |
Line 167: |
| | end | | end |
| | end, | | end, |
| − |
| |
| | critical_hit_rate = function(ship, target) | | critical_hit_rate = function(ship, target) |
| | local r = Combat.critical_hit_rate(ship, target) | | local r = Combat.critical_hit_rate(ship, target) |
| Line 276: |
Line 176: |
| | end | | end |
| | end, | | end, |
| − |
| |
| | scrap = function(eq) | | scrap = function(eq) |
| | local scrap = eq:scrap() | | local scrap = eq:scrap() |
| − | return format{ | + | return string.format("%s/%s/%s/%s", scrap.fuel or 0, scrap.ammo or 0, scrap.steel or 0, scrap.bauxite or 0) |
| − | "${fuel}/${ammo}/${steel}/${bauxite}",
| |
| − | fuel = scrap.fuel or 0,
| |
| − | ammo = scrap.ammo or 0,
| |
| − | steel = scrap.steel or 0,
| |
| − | bauxite = scrap.bauxite or 0,
| |
| − | }
| |
| − | end,
| |
| − | | |
| − | development = function(eq)
| |
| − | return Development.formatResources(eq)
| |
| − | end,
| |
| − | | |
| − | development_rate = function(eq)
| |
| − | return Development.formatRates(eq)
| |
| − | end,
| |
| − |
| |
| − | development_hq = function(eq)
| |
| − | return Development.formatHQ(eq)
| |
| | end, | | end, |
| − | | + | development = function(eq) return Development.formatResources(eq) end, |
| − | backMinusRarity = function(ship) | + | development_rate = function(eq) return Development.formatRates(eq) end, |
| − | return ship:back() - ship:rarity()
| + | development_hq = function(eq) return Development.formatHQ(eq) end, |
| − | end,
| + | backMinusRarity = function(ship) return ship:back() - ship:rarity() end, |
| − |
| |
| | rarity_bg = function(ship) | | rarity_bg = function(ship) |
| | return string.format('style="background:%s"|%s<br>%s', Formatting:format_ship_back(ship:rarity()), ship:rarity() or '??', Formatting:format_ship_rarity(ship:rarity())) | | return string.format('style="background:%s"|%s<br>%s', Formatting:format_ship_back(ship:rarity()), ship:rarity() or '??', Formatting:format_ship_rarity(ship:rarity())) |
| | end, | | end, |
| − |
| |
| | back_bg = function(ship) | | back_bg = function(ship) |
| | return string.format('style="background:%s"|%s<br>%s', Formatting:format_ship_back(ship:back()), ship:back() or '??', Formatting:format_ship_rarity(ship:back())) | | return string.format('style="background:%s"|%s<br>%s', Formatting:format_ship_back(ship:back()), ship:back() or '??', Formatting:format_ship_rarity(ship:back())) |
| | end, | | end, |
| − |
| |
| | } | | } |
| | | | |
| − | function addFormattingFunctions(name, table) | + | local function addFormattingFunctions(name, table) |
| | for k, v in pairs(table) do | | for k, v in pairs(table) do |
| | formatting_functions[name .. "." .. k] = v | | formatting_functions[name .. "." .. k] = v |
| Line 323: |
Line 201: |
| | addFormattingFunctions("Assets", require("Module:CalcAsset")) | | addFormattingFunctions("Assets", require("Module:CalcAsset")) |
| | | | |
| − | function format_value(key, ship, target) | + | local function format_value(key, ship, target) |
| | local formatting_function = formatting_functions[key] | | local formatting_function = formatting_functions[key] |
| | if formatting_function then | | if formatting_function then |
| Line 342: |
Line 220: |
| | end | | end |
| | | | |
| − | local sequence = nil | + | local function format_arg(arg) |
| − | local sequence_position = nil
| |
| − | | |
| − | function format_arg(arg) | |
| | return args.format == "table" and ("| " .. arg .. "\n") or arg | | return args.format == "table" and ("| " .. arg .. "\n") or arg |
| | end | | end |
| | | | |
| − | local env = {} | + | local function interpret_setter(s) |
| − | | |
| − | function interpret_setter(s) | |
| | local kv = mw.text.split(s, "%s*~%s*") | | local kv = mw.text.split(s, "%s*~%s*") |
| | local k = kv[1] | | local k = kv[1] |
| Line 393: |
Line 266: |
| | end | | end |
| | end | | end |
| − |
| |
| − | local implicitTrigger = true
| |
| | | | |
| | local function trigger(implicit) | | local function trigger(implicit) |
| Line 411: |
Line 282: |
| | end | | end |
| | | | |
| − | function interpret_arg(arg, args) | + | local 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) | | local prefix2 = string.sub(arg, 1, 2) |
| Line 489: |
Line 360: |
| | return format_arg(format_value(string.sub(arg, 3), target, ship)) | | return format_arg(format_value(string.sub(arg, 3), target, ship)) |
| | elseif prefix2 == "?#" then | | elseif prefix2 == "?#" then |
| − | return frame:preprocess(format{string.sub(arg, 3), this = env[this] or ""}) | + | return "?# is unimplemented" -- frame:preprocess(format{string.sub(arg, 3), this = env[this] or ""}) |
| | else | | else |
| | if #filterArg > 0 then | | if #filterArg > 0 then |
| Line 522: |
Line 393: |
| | end | | end |
| | | | |
| − | function interpret_args() | + | local function interpret_args(args_) |
| | + | args = args_ |
| | Ship = args.enemy and require("Module:EnemyShip") or require("Module:Ship") | | Ship = args.enemy and require("Module:EnemyShip") or require("Module:Ship") |
| − | debugLog("#args", #args)
| |
| − | debugLog("type(args)", type(args))
| |
| | if args.from and args.to then | | if args.from and args.to then |
| | sequence = {} | | sequence = {} |
| Line 537: |
Line 407: |
| | repeat | | repeat |
| | for _, arg in ipairs(args) do | | for _, arg in ipairs(args) do |
| − | debugLog("i", i)
| + | local value = interpret_arg(arg) |
| − | debugLog("arg", arg)
| |
| − | local value = interpret_arg(arg, args) | |
| − | debugLog("value", value)
| |
| | if value then | | if value then |
| | table.insert(values, value) | | table.insert(values, value) |
| Line 547: |
Line 414: |
| | end | | end |
| | until not sequence or sequence_position > #sequence | | until not sequence or sequence_position > #sequence |
| − | debugLog("#values", #values)
| + | return table.concat(values, args.concat or (args.format == "table" and "" or ", ")) |
| − | return table.concat(values, args.concat or (args.format == "table" and "" or ", ")) .. debugString() | |
| − | end
| |
| − | | |
| − | local Calc = {}
| |
| − | | |
| − | function Calc.format(frame_, args_)
| |
| − | frame = frame_
| |
| − | args = args_ or U.getTemplateArgs(frame).explicit
| |
| − | for _, arg in ipairs(args) do
| |
| − | debugLog("arg", arg)
| |
| − | end
| |
| − | return interpret_args()
| |
| | end | | end |
| | | | |
| − | function Calc.test()
| + | return { format = function(frame) return interpret_args(U.getTemplateArgs(frame).explicit) end } |
| − | mw.log(
| |
| − | Calc.format(nil, {
| |
| − | format = "table",
| |
| − | debug = "true",
| |
| − | "!Nagato/Kai Ni",
| |
| − | "!_equipment ~ 41cm Triple Gun Mount Kai, 41cm Triple Gun Mount Kai, Type 13 Air Radar Kai",
| |
| − | "!_level ~ 99",
| |
| − | "!_luck ~ nil",
| |
| − | "!_morale ~ 25",
| |
| − | "!!Destroyer Ro-Class",
| |
| − | "!cl0 ~ 56",
| |
| − | "!cl1 ~ 807",
| |
| − | "!cl2 ~ 137",
| |
| − | "?card",
| |
| − | "?level",
| |
| − | "?format_morale",
| |
| − | "?accuracy",
| |
| − | "?luck",
| |
| − | "??card",
| |
| − | "?cl0",
| |
| − | "?cl1",
| |
| − | "?cl2",
| |
| − | "",
| |
| − | "",
| |
| − | "",
| |
| − | "",
| |
| − | "-",
| |
| − | "?FitData.hit",
| |
| − | "?FitData.error",
| |
| − | "?FitData.crit",
| |
| − | "?hit_rate",
| |
| − | "?critical_hit_rate",
| |
| − | "?FitData.difference",
| |
| − | "?FitData.critical_difference",
| |
| − | "?FitData.accuracy_value",
| |
| − | "?FitData.fit",
| |
| − | })
| |
| − | )
| |
| − | end
| |
| − | | |
| − | function Calc.test2() | |
| − | mw.log(
| |
| − | Calc.format(nil, {
| |
| − | "@all_names",
| |
| − | "~hp_mod_married ~ 1",
| |
| − | -- "!@",
| |
| − | "?link"
| |
| − | })
| |
| − | )
| |
| − | end | |
| − | | |
| − | -- print(p.test2())
| |
| − | | |
| − | return Calc
| |