• Welcome to the Kancolle Wiki!
  • If you have any questions regarding site content, account registration, etc., please visit the KanColle Wiki Discord

Module:CalcCombat

From Kancolle Wiki
Revision as of 13:52, 7 November 2017 by がか (talk | contribs)
Jump to navigation Jump to search

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 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

-- [[Category:Todo]]: in case of other types (torpedo, etc.), use generic functions.

-- * Shelling.

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

-- Shelling hit rate.
-- ship and target can be Ship, EnemyShip, ShipCapabilities, or a plain table.
-- [[Category:Todo]]: detection based on _equipment, fuel modifier.
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)

    local proficiency = ship._proficiency or 0

    return floor(capped_hit_rate) + proficiency + 1, capped_hit_rate

end

-- Shelling critical hit rate.
function Combat2.critical_hit_rate(ship, target, context)
    local _, capped_hit_rate = Combat2.hit_rate(ship, target, context)
    local proficiency = ship._proficiency or 0
    return floor(1.3 * sqrt(capped_hit_rate)) + proficiency + 1
end

-- * Tests.

function Combat2.test()
    local Ship = require("Module:Ship")
    local ship = Ship("Nagato/Kai Ni"){
        _level = 99,
        _accuracy = 10,
        _morale = 25,
        _fit = 5 * sqrt(2)
    }
    local target = Ship("Destroyer Ro-Class")
    mw.log(Combat2.hit_rate(ship, target))
    mw.log(Combat2.critical_hit_rate(ship, target))
end

return Combat2