Line 247: |
Line 247: |
| | | |
| end | | end |
| + | |
| + | -- Using Module:ShipCapabilities. |
| + | |
| + | local BaseData = require("Module:BaseData") |
| + | local ShipCapabilities = require("Module:ShipCapabilities") |
| + | |
| + | local Combat2 = BaseData{ |
| + | |
| + | fleet = { |
| + | single = { |
| + | line_ahead = { shelling = 1.0, salvo = 1.0, asw = 0.6, firepower = 0, torpedo = 0, }, |
| + | double_line = { shelling = 0.8, salvo = 0.8, asw = 0.8, firepower = 0, torpedo = 0, }, |
| + | diamond = { shelling = 0.7, salvo = 0.7, asw = 1.2, firepower = 0, torpedo = 0, }, |
| + | echelon = { shelling = 0.6, salvo = 0.6, asw = 1.0, firepower = 0, torpedo = 0, }, |
| + | line_abreast = { shelling = 0.6, salvo = 0.6, asw = 1.3, firepower = 0, torpedo = 0, }, |
| + | }, |
| + | ctf_main = { |
| + | line_abreast = { shelling = 0.8, salvo = nil, asw = 1.0, firepower = 0, torpedo = nil, }, |
| + | double_line = { shelling = 1.0, salvo = nil, asw = 0.8, firepower = 0, torpedo = nil, }, |
| + | diamond = { shelling = 0.7, salvo = nil, asw = 0.75, firepower = 0, torpedo = nil, }, |
| + | line_ahead = { shelling = 1.1, salvo = nil, asw = 0.5, firepower = 0, torpedo = nil, }, |
| + | }, |
| + | ctf_escort = { |
| + | line_abreast = { shelling = 0.8, salvo = 0.7, asw = 1.0, firepower = 10, torpedo = -5, }, |
| + | double_line = { shelling = 1.0, salvo = 0.9, asw = 0.8, firepower = 10, torpedo = -5, }, |
| + | diamond = { shelling = 0.7, salvo = 0.6, asw = 0.75, firepower = 10, torpedo = -5, }, |
| + | line_ahead = { shelling = 1.1, salvo = 1.0, asw = 0.5, firepower = 10, torpedo = -5, }, |
| + | }, |
| + | stf_main = { |
| + | line_abreast = { shelling = 0.8, salvo = nil, asw = 1.0, firepower = 10, torpedo = nil, }, |
| + | double_line = { shelling = 1.0, salvo = nil, asw = 0.8, firepower = 10, torpedo = nil, }, |
| + | diamond = { shelling = 0.7, salvo = nil, asw = 0.75, firepower = 10, torpedo = nil, }, |
| + | line_ahead = { shelling = 1.1, salvo = nil, asw = 0.5, firepower = 10, torpedo = nil, }, |
| + | }, |
| + | stf_escort = { |
| + | line_abreast = { shelling = 0.8, salvo = 0.7, asw = 1.0, firepower = -5, torpedo = -5, }, |
| + | double_line = { shelling = 1.0, salvo = 0.9, asw = 0.8, firepower = -5, torpedo = -5, }, |
| + | diamond = { shelling = 0.7, salvo = 0.6, asw = 0.75, firepower = -5, torpedo = -5, }, |
| + | line_ahead = { shelling = 1.1, salvo = 1.0, asw = 0.5, firepower = -5, torpedo = -5, }, |
| + | }, |
| + | }, |
| + | |
| + | engagement = { |
| + | green_t = 1.2, |
| + | parallel = 1.0, |
| + | head_on = 0.8, |
| + | red_t = 0.6, |
| + | }, |
| + | |
| + | health = { |
| + | normal = 1.0, |
| + | chuuha = 0.7, |
| + | taiha = 0.4, |
| + | }, |
| + | |
| + | --night_attack = { |
| + | -- cut_in = { |
| + | -- main = 2, |
| + | -- main_misc = 1.75, |
| + | -- torpedo = 1.5, |
| + | -- mixed = 1.3, |
| + | -- }, |
| + | -- double = 1.2, |
| + | -- normal = 1, |
| + | --}, |
| + | |
| + | spotting = { |
| + | cut_in = { |
| + | main_main = 1.5, |
| + | main_ap = 1.3, |
| + | main_radar = 1.2, |
| + | main_second = 1.1, |
| + | }, |
| + | double = 1.2, |
| + | }, |
| + | |
| + | ap = { |
| + | main_ap = 1.08, |
| + | main_ap_radar = 1.1, |
| + | main_second_ap = 1.15, |
| + | main_second_ap_radar = 1.15, |
| + | }, |
| + | |
| + | contact = { |
| + | [0] = 1.12, |
| + | [1] = 1.12, |
| + | [2] = 1.17, |
| + | [3] = 1.20, |
| + | } |
| + | |
| + | } |
| + | |
| + | function Combat2:create(stage) |
| + | local this = {} |
| + | this.stage = stage or { |
| + | fleet = Combat2.fleet.single.line_ahead, |
| + | engagement = Combat2.engagement.parallel, |
| + | } |
| + | setmetatable(this, this) |
| + | this.__index = self |
| + | return this |
| + | end |
| + | |
| + | function Combat2:_get_ammo_modifier(ammo_bars) |
| + | return ammo_bars >= 5 and 1 or ammo_bars / 5 |
| + | end |
| + | |
| + | function Combat2:damage(basic_attack_power_fn, ship, enemy, critical) |
| + | |
| + | local vs_installation = enemy and enemy:is_installation() |
| + | |
| + | local fleet = self.stage.fleet |
| + | local formation = fleet.shelling |
| + | local engagement = self.stage.engagement |
| + | |
| + | local health = ship._health or Combat2.health.normal |
| + | |
| + | local cap = 150 |
| + | local spotting = 1 |
| + | local ap = 1 |
| + | local contact = 1 |
| + | local expert = 1 |
| + | local attack_power = 0 |
| + | |
| + | if basic_attack_power_fn == ShipCapabilities.day_battle then |
| + | spotting = ship._spotting or 1 |
| + | ap = ship._ap or 1 |
| + | expert = 1 + ((ship._expert_n or 0) + (ship._expert_first and 1 or 0)) / 10 |
| + | _, attack_power = basic_attack_power_fn(ship, vs_installation, fleet.firepower) |
| + | elseif basic_attack_power_fn == ShipCapabilities.closing_torpedo or basic_attack_power_fn == ShipCapabilities.opening_torpedo then |
| + | if not fleet.torpedo then |
| + | return false |
| + | end |
| + | formation = fleet.salvo |
| + | attack_power = basic_attack_power_fn(ship, fleet.torpedo) |
| + | elseif basic_attack_power_fn == ShipCapabilities.format_asw_attack then |
| + | formation = fleet.asw |
| + | cap = 100 |
| + | attack_power = basic_attack_power_fn(ship) |
| + | elseif basic_attack_power_fn == ShipCapabilities.night_battle then |
| + | if health == Combat2.health.taiha then |
| + | return false |
| + | end |
| + | formation = 1 |
| + | engagement = 1 |
| + | cap = 300 |
| + | _, attack_power = basic_attack_power_fn(ship, vs_installation, self.stage.night_contact) |
| + | elseif basic_attack_power_fn == ShipCapabilities.opening_airstrike then |
| + | expert = 1 + ((ship._expert_n or 0) + (ship._expert_first and 1 or 0)) / 10 |
| + | contact = self.stage.contact and Combat2.contact[self.stage.contact] or 1 |
| + | attack_power = basic_attack_power_fn(ship) |
| + | end |
| + | |
| + | if not attack_power then |
| + | return false |
| + | end |
| + | |
| + | attack_power = engagement * formation * health * attack_power |
| + | |
| + | if attack_power > cap then |
| + | attack_power = cap + math.sqrt(attack_power - cap) |
| + | end |
| + | attack_power = math.floor(attack_power) |
| + | |
| + | expert = critical and expert or 1 |
| + | local critical = critical and 1.5 or 1 |
| + | |
| + | attack_power = spotting * contact * math.floor(expert * critical * math.floor(ap * attack_power)) |
| + | |
| + | local ammo_modifier = ship._ammo_bars and self:_get_ammo_modifier(ship._ammo_bars) or 1 |
| + | |
| + | if enemy and enemy._armor then |
| + | local armor = enemy._armor |
| + | local min_armor = armor * 0.7 |
| + | local max_armor = armor * 0.7 + math.max(armor - 1, 0) * 0.6 |
| + | local min = math.floor((attack_power - max_armor) * ammo_modifier) |
| + | local max = math.floor((attack_power - min_armor) * ammo_modifier) |
| + | return { min = min, max = max } |
| + | else |
| + | return math.floor(attack_power * ammo_modifier) |
| + | end |
| + | |
| + | end |
| + | |
| + | Combat.Combat2 = Combat2 |
| | | |
| return Combat | | return Combat |