Module:ShipCapabilities

local BaseData = require("Module:BaseData")

local format = require('Module:StringInterpolation').format

local ShipCapabilities = BaseData{ -- _anti_air_cut_in_types = { -- 	{	-- 		name = "Akizuki (HA HA R)", -- 		ship = {"Akizuki"}, -- 		equipment = {"High-angle Gun", "High-angle Gun", "Radar"}, -- 	},	-- 	{	-- 		name = "Akizuki (HA AAR)", -- 		ship = {"Akizuki"}, -- 		equipment = {"High-angle Gun", "Radar"}, -- 	},	-- 	{	-- 		name = "Akizuki (HA HA)", -- 		ship = {"Akizuki"}, -- 		equipment = {"High-angle Gun", "High-angle Gun"} -- 	},	-- 	{	-- 		name = "Type 3 AAR", -- 		equipment = {"Large Caliber Main Gun", "Type 3 Shell", "Anti-Aircraft Fire Director", "Anti-Air Radar"}, -- 	},	-- 	{	-- 		name = "HAFD HAFD AAR", -- 		equipment = {"High-angle Gun + Fire Director", "High-angle Gun + Fire Director", "Anti-Air Radar"}, -- 	},	-- 	{	-- 		name = "Type 3", -- 		equipment = {"Large Caliber Main Gun", "Type 3 Shell", "Anti-Aircraft Fire Director"}, -- 	},	-- 	{	-- 		name = "HA AAFD AAR", -- 		equipment = {"High-angle Gun", "Anti-Aircraft Fire Director", "Anti-Air Radar"}, -- 	},	-- 	{	-- 		name = "HAFD AAR", -- 		equipment = {"High-angle Gun + Fire Director", "Anti-Air Radar"}, -- 	},	-- 	{	-- 		name = "HA AAFD", -- 		equipment = {"High-angle Gun + Fire Director", "Anti-Air Radar"}, -- 	},	-- 	{	-- 		name = "Maya Kai Ni (HA CD AAR)", -- 		ship = {"Maya/Kai Ni"}, -- 		equipment = {"High-angle Gun", "25mm Triple Autocannon Mount Concentrated Deployment", "Anti-Air Radar"}, -- 	},	-- 	{	-- 		name = "Maya Kai Ni (HA CD)", -- 		ship = {"Maya/Kai Ni"}, -- 		equipment = {"High-angle Gun", "25mm Triple Autocannon Mount Concentrated Deployment"}, -- 	},	-- 	{	-- 		name = "CD AAMG AAR", -- 		equipment = {"25mm Triple Autocannon Mount Concentrated Deployment", "Anti-Air Machine Gun", "Anti-Air Radar"} -- 	},	-- }, }

function ShipCapabilities:create(data) if data.ship then data._ship = data.ship data.ship = nil end setmetatable(data, data) data.__index = self return data end

--function ShipCapabilities:anti_air_cut_in --local result = false --base_name = self._ship:base_name --if base_name == "Akizuki" then --	result = self:akizuki_anti_air_cut_in --elseif base_name == "Maya" and self._ship:suffix == "Kai Ni" then --	result = self:maya_kai_ni_anti_air_cut_in

function ShipCapabilities:_is_asw_surface_ship(ship) if not ship then ship = self._ship end local ship_type = ship:type return ship_type == 2 or ship_type == 3 or ship_type == 21 end

function ShipCapabilities:_is_asw_aviation_ship(ship) if not ship then ship = self._ship end local ship_type = ship:type return ship_type == 6 or ship_type == 7 or ship_type == 10 or ship_type == 16 end

function ShipCapabilities:_is_aviation_ship(ship) if not ship then ship = self._ship end local ship_type = ship:type return ship_type == 6 or ship_type == 7 or ship_type == 10 or ship_type == 11 or ship_type == 14 or ship_type == 16 or ship_type == 17 or ship_type == 18 end

function ShipCapabilities:_is_light_carrier(ship) if not ship then ship = self._ship end return ship:type == 7 end

function ShipCapabilities:_is_carrier(ship) if not ship then ship = self._ship end local ship_type = ship:type return ship_type == 7 or ship_type == 11 or ship_type == 18 end

function ShipCapabilities:_is_submarine(ship) if not ship then ship = self._ship end local ship_type = ship:type return ship_type == 13 or ship_type == 14 end

function ShipCapabilities:_is_main_gun(equipment) local equipment_type = equipment:type return equipment_type == 1 or equipment_type == 2 or equipment_type == 3 or equipment_type == 38 end

function ShipCapabilities:_is_secondary_gun(equipment) return equipment:type == 4 end

function ShipCapabilities:_is_torpedo(equipment) local equipment_type = equipment:type return equipment_type == 5 or equipment_type == 32 end

function ShipCapabilities:_is_bomber(equipment) local equipment_type = equipment:type return equipment_type == 7 or equipment_type == 8 or equipment_type == 11 end

function ShipCapabilities:_is_torpedo_bomber(equipment) return equipment:type == 8 end

function ShipCapabilities:_is_reconnaissance_seaplane(equipment) return equipment:type == 10 end

function ShipCapabilities:_is_seaplane(equipment) local equipment_type = equipment:type return equipment_type == 10 or equipment_type == 11 end

function ShipCapabilities:_is_radar(equipment) local equipment_type = equipment:type return equipment_type == 12 or equipment_type == 13 end

function ShipCapabilities:_is_sonar(equipment) local equipment_type = equipment:type return equipment_type == 14 or equipment_type == 40 end

function ShipCapabilities:_is_depth_charge(equipment) return equipment:type == 15 end

function ShipCapabilities:_is_ap_shell(equipment) return equipment:type == 19 end

function ShipCapabilities:_is_midget_submarine(equipment) return equipment:type == 22 end

function ShipCapabilities:_attack_power_cap(attack_power, cap) if attack_power > cap then return math.floor(cap + math.sqrt(attack_power - cap)) end return math.floor(attack_power) end

function ShipCapabilities:day_battle if not self:_is_submarine then local firepower = self._ship:firepower_leveled if not firepower then return "??" end if not self:_is_carrier then if firepower > 0 then for i = 1, self._ship:slots do					local equipment, size = self._ship:slot(i) if equipment then local equipment_firepower = equipment:firepower if equipment_firepower then firepower = firepower + equipment_firepower end end end return format{"Shelling (${attack_power})", attack_power = self:_attack_power_cap(firepower + 5, 150)} end else local total_space = self._ship:total_space if total_space and total_space > 0 then local has_planes, torpedo, bombing = false, self._ship:torpedo_leveled or 0, 0 for i = 1, self._ship:slots do					local equipment, size = self._ship:slot(i) if equipment then local is_bomber, equipment_firepower, equipment_torpedo, equipment_bombing = self:_is_bomber(equipment), equipment:firepower, equipment:torpedo, equipment:bombing if is_bomber then if size and size > 0 then has_planes = true else equipment_firepower = 0 equipment_torpedo = 0 equipment_bombing = 0 end end if equipment_firepower then firepower = firepower + equipment_firepower end if equipment_torpedo then torpedo = torpedo + equipment_torpedo end if equipment_bombing then bombing = bombing + equipment_bombing end end end if has_planes then return format{"Bombing (${attack_power})", attack_power = self:_attack_power_cap(1.5 * (firepower + torpedo) + bombing * 2 + 55, 150)} end end end end return "No Action" end

function ShipCapabilities:closing_torpedo local torpedo = self._ship:torpedo_leveled if torpedo and torpedo > 0 then for i = 1, self._ship:slots do			local equipment, size = self._ship:slot(i) if equipment then local equipment_torpedo = equipment:torpedo if equipment_torpedo then torpedo = torpedo + equipment_torpedo end end end return format{"Yes (${attack_power})", attack_power = self:_attack_power_cap(torpedo + 5, 150)} end return "None" end

function ShipCapabilities:artillery_spotting local total_space = self._ship:total_space if not total_space or total_space <= 0 then return false end local main_guns, secondary_guns, seaplanes, radars, ap_shells = 0, 0, 0, 0, 0 for i = 1, self._ship:slots or 0 do		local equipment, size = self._ship:slot(i) if equipment then if self:_is_main_gun(equipment) then main_guns = main_guns + 1 elseif self:_is_secondary_gun(equipment) then secondary_guns = secondary_guns + 1 elseif self:_is_seaplane(equipment) and size and size > 0 then seaplanes = seaplanes + 1 elseif self:_is_radar(equipment) then radars = radars + 1 elseif self:_is_ap_shell(equipment) then ap_shells = ap_shells + 1 end end end if seaplanes >= 1 then if main_guns >= 2 then if ap_shells >= 1 then return "Double Attack / Cut-in (AP)" elseif secondary_guns >= 1 then return "Double Attack / Cut-in (Secondary Gun)" end return "Double Attack" elseif main_guns == 1 and secondary_guns >= 1 then if radars >= 1 then return "Cut-in (Secondary Gun) / Cut-in (Radar)" elseif ap_shells >= 1 then return "Cut-in (Secondary Gun) / Cut-in (AP)" end return "Cut-in (Secondary Gun)" end end return false end

function ShipCapabilities:night_battle local main_guns, secondary_guns, torpedoes, has_planes, firepower, torpedo = 0, 0, 0, false, self._ship:firepower_leveled, self._ship:torpedo_leveled if not firepower or not torpedo then return "Unknown" end for i = 1, self._ship:slots or 0 do		local equipment, size = self._ship:slot(i) if equipment then local equipment_firepower, equipment_torpedo = equipment:firepower, equipment:torpedo if self:_is_main_gun(equipment) then main_guns = main_guns + 1 elseif self:_is_secondary_gun(equipment) then secondary_guns = secondary_guns + 1 elseif self:_is_torpedo(equipment) then torpedoes = torpedoes + 1 elseif self:_is_bomber(equipment) then if size and size > 0 then has_planes = true else equipment_firepower = 0 equipment_torpedo = 0 end end if equipment_firepower then firepower = firepower + equipment_firepower end if equipment_torpedo then torpedo = torpedo + equipment_torpedo end end end if self:_is_carrier then if has_planes and self._ship:night_bombing then return format{"Bombing Run (${attack_power})", attack_power = self:_attack_power_cap(firepower + torpedo, 300)} end return "No Action" else if torpedoes >= 2 then return format{"Cut-in: Torpedo (${attack_power} x2)", attack_power = self:_attack_power_cap((firepower + torpedo) * 1.5, 300)} elseif main_guns >= 3 then return format{"Cut-in: Main Gun (${attack_power})", attack_power = self:_attack_power_cap((firepower + torpedo) * 2, 300)} elseif main_guns >= 2 and secondary_guns >= 1 then return format{"Cut-in: Secondary Gun (${attack_power})", attack_power = self:_attack_power_cap((firepower + torpedo) * 1.75, 300)} elseif main_guns >= 1 and torpedoes == 1 then return format{"Cut-in: Mixed (${attack_power} x2)", attack_power = self:_attack_power_cap((firepower + torpedo) * 1.3, 300)} elseif main_guns + secondary_guns >= 2 then return format{"Double Attack (${attack_power} x2)", attack_power = self:_attack_power_cap((firepower + torpedo) * 1.2, 300)} elseif torpedoes > 0 then return format{"Single Torpedo (${attack_power})", attack_power = self:_attack_power_cap(firepower + torpedo, 300)} else return format{"Single Attack (${attack_power})", attack_power = self:_attack_power_cap(firepower + torpedo, 300)} end end end

function ShipCapabilities:opening_torpedo local torpedo = self._ship:torpedo_leveled if not torpedo or torpedo <= 0 then return "No" end local opening_torpedo = false if self:_is_submarine then if self:level >= 10 then opening_torpedo = true end end for i = 1, self._ship:slots or 0 do		local equipment, size = self._ship:slot(i) if equipment then if self:_is_midget_submarine(equipment) then opening_torpedo = true end local equipment_torpedo = equipment:torpedo if equipment_torpedo then torpedo = torpedo + equipment_torpedo end end end if opening_torpedo then return format{"Yes (${attack_power})", attack_power = self:_attack_power_cap(torpedo + 5, 150)} end return "No" end

function ShipCapabilities:asw_attack local base_asw if self:_is_asw_surface_ship then base_asw = 25 elseif self:_is_asw_aviation_ship then base_asw = 10 else return "No" end local ship_asw, equipment_asw, depth_charge, sonar, bomber = self._ship:asw_leveled / 5, 0, false, false, false for i = 1, self._ship:slots or 0 do		local equipment, size = self._ship:slot(i) if equipment then if not self:_is_reconnaissance_seaplane(equipment) then if self:_is_sonar(equipment) then sonar = true elseif self:_is_depth_charge(equipment) then depth_charge = true elseif self:_is_bomber(equipment) then bomber = true end equipment_asw = equipment_asw + (equipment:asw or 0) end end end if self:_is_light_carrier and not bomber then return "No" end local depth_charge_sonar_boost = 1 if depth_charge and sonar then depth_charge_sonar_boost = 1.15 end return format{"Yes (${attack_power})", attack_power = self:_attack_power_cap(depth_charge_sonar_boost * (base_asw + 2 * equipment_asw + ship_asw / 5), 100)} end

function ShipCapabilities:opening_airstrike if not self:_is_aviation_ship then return "No" end local airstrikes = {} for i = 1, self._ship:slots or 0 do		local equipment, size = self._ship:slot(i) if size and size > 0 and equipment and self:_is_bomber(equipment) then local equipment_torpedo, equipment_bombing = equipment:torpedo or 0, equipment:bombing or 0 local attack_power = (equipment_torpedo + equipment_bombing) * math.sqrt(size) + 25 if self:_is_torpedo_bomber(equipment) then table.insert(airstrikes, format{"${low}/${high}", low = self:_attack_power_cap(attack_power * 0.8, 150), high = self:_attack_power_cap(attack_power * 1.5, 150)}) else table.insert(airstrikes, tostring(self:_attack_power_cap(attack_power, 150))) end end end if #airstrikes > 0 then return format{"Yes (${airstrikes})", airstrikes = table.concat(airstrikes, ",")} end return "No" end

return ShipCapabilities