Documentation for this module may be created at Module:CalcCombat/doc
local Combat2 = {}
local sqrt = math.sqrt
local floor = math.floor
local min = math.min
local max = math.max
function morale_modifier(morale)
return not morale and 1 or morale <= 20 and 0.5 or morale <= 32 and 0.8 or morale <= 52 and 1 or 1.2
end
function target_morale_modifier(morale)
return not morale and 1 or morale <= 20 and 1.4 or morale <= 32 and 1.2 or morale <= 52 and 1 or 0.7
end
-- Calculate shelling hit (normal and critical) rate.
-- ship and target can be Ship, EnemyShip, ShipCapabilities, etc.
-- [[Category:Todo]]:
-- * ignoring _equipment, no fuel modifier
-- * also use _fields instead of getter functions? then any record will do for ship and target
function Combat2.hit_rate(ship, target, context)
ship = ship and ship.ship or ship
target = target and target.ship or target
context = context or {}
if not ship or not target then
return
end
local level = ship:level() or 1
local luck = ship:luck() or 0
local accuracy = ship:accuracy() or 0
local fit = ship._fit or 0
local as_modifier = ship._as_modifier or 1
local ap_modifier = ship._ap_modifier or 1
local morale = morale_modifier(ship:morale())
local formation = context._formation or ship._formation or 1
local accuracy_value = floor(((90 + 2 * sqrt(level) + sqrt(1.5 * luck) + accuracy) * morale * formation + fit) * as_modifier * ap_modifier)
local evasion = target:evasion() or 0
local target_luck = target:luck() or 0
local target_formation = context._target_formation or target._formation or 1
local target_morale = target_morale_modifier(target:morale())
local base_evasion_value = floor((evasion + sqrt(2 * target_luck)) * target_formation)
local capped_evasion_value
= base_evasion_value < 40
and base_evasion_value
or base_evasion_value < 65
and floor(40 + 3 * sqrt(base_evasion_value - 40))
or floor(55 + 2 * sqrt(base_evasion_value - 65))
local evasion_value = capped_evasion_value
local base_hit_rate = accuracy_value - evasion_value
local capped_hit_rate = min(96, max(10, base_hit_rate) * target_morale)
return capped_hit_rate + 1
end
function Combat2.test()
local Ship = require("Module:Ship")
mw.log(Combat2.hit_rate(Ship("Nagato/Kai Ni"){ _level = 99, _accuracy = 10, _morale = 25 }, Ship("Destroyer Ro-Class")))
end
return Combat2