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

Difference between revisions of "Module:Sandbox/Combat"

From Kancolle Wiki
Jump to navigation Jump to search
m
m
Line 175: Line 175:
 
local table_templates = {
 
local table_templates = {
  
table_dd = [[{| class="wikitable sortable typography-xl-optout" style="width:100%;"
+
dd = [[{| class="wikitable sortable typography-xl-optout" style="width:100%;"
 
! colspan="2" |
 
! colspan="2" |
 
! colspan="4" |Day Battle
 
! colspan="4" |Day Battle
Line 184: Line 184:
 
!${fp}
 
!${fp}
 
!${torp}
 
!${torp}
!<span title="Normal attack damage: without equipment, with 2x maxed guns; all modifiers = 1, see notes">Attack</span>
+
!<span title="Normal attack damage: without equipment, with maxed equipment; all modifiers = 1, see notes">Attack</span>
 
!<span title="Normal torpedo salvo damage, all modifiers = 1, see notes">Torpedo</span>
 
!<span title="Normal torpedo salvo damage, all modifiers = 1, see notes">Torpedo</span>
 
!${fp_plus_torp}
 
!${fp_plus_torp}
Line 195: Line 195:
 
table_dd_row = [===[|-
 
table_dd_row = [===[|-
 
|${rank}
 
|${rank}
|[[${name}]]
+
|${name}
 
|${fp}
 
|${fp}
 
|${torp}
 
|${torp}
Line 209: Line 209:
 
}
 
}
  
function Combat.table_dd(frame)
+
function Combat.table(frame)
 +
    local types = { dd = dd, cl = dd, clt = dd, ca = dd, bb = dd }
 +
    local typ = types[frame.args["type"]]
 +
    if not typ then
 +
        return ""
 +
    end
 
return format{
 
return format{
table_templates.table_dd,
+
table_templates[typ],
 
rows = frame.args[1] or "",
 
rows = frame.args[1] or "",
 
fp = Formatting:format_image{StatIcons.firepower, caption = Formatting:format_stat_name("firepower")},
 
fp = Formatting:format_image{StatIcons.firepower, caption = Formatting:format_stat_name("firepower")},
Line 229: Line 234:
 
function get_db_attack_string(fp, t)
 
function get_db_attack_string(fp, t)
 
     local equip_fp = {
 
     local equip_fp = {
         dd = 2 * 3 + math.floor(2 * math.sqrt(10))  
+
         dd = 2 * 3 + math.floor(2 * math.sqrt(10)),
 +
        cl = 2 * 10 + math.floor(2 * math.sqrt(10)),
 +
        clt = 2 * 8 + math.floor(2 * math.sqrt(10)),
 
     }
 
     }
 
     return
 
     return
 
         damage(shelling_attack_power(fp, 0, modifiers), modifiers)
 
         damage(shelling_attack_power(fp, 0, modifiers), modifiers)
 
         .. ", " ..
 
         .. ", " ..
         damage(shelling_attack_power(fp, equip_fp[t], modifiers), modifiers)
+
         damage(shelling_attack_power(fp, equip_fp[t] or 0, modifiers), modifiers)
 
end
 
end
  
Line 241: Line 248:
 
local rank = frame.args[1]
 
local rank = frame.args[1]
 
local ship_key = frame.args[2]
 
local ship_key = frame.args[2]
 +
local typ = frame.args["type"]
 +
local note = frame.args["note"]
 +
 
local name, suffix = Ship:process_ship_key(ship_key)
 
local name, suffix = Ship:process_ship_key(ship_key)
 
local ship_table = Ship:get_table(name, suffix)
 
local ship_table = Ship:get_table(name, suffix)
Line 248: Line 258:
 
return format{
 
return format{
 
table_templates.table_dd_row,
 
table_templates.table_dd_row,
rank = rank, name = name,
+
rank = rank,
 +
name =
 +
    note and format{'[[${name}|<span title="${note}">${name}</span>]]<sup>?</sup>', name = name, note = note} or
 +
    string.format("[[%s]]", name),
 
fp = ship_table._firepower_max,
 
fp = ship_table._firepower_max,
 
torp = ship_table._torpedo_max,
 
torp = ship_table._torpedo_max,
 
fp_plus_torp = ship_table._firepower_max + ship_table._torpedo_max,
 
fp_plus_torp = ship_table._firepower_max + ship_table._torpedo_max,
db_attack = get_db_attack_string(ship_table._firepower_max, "dd"),
+
db_attack = get_db_attack_string(ship_table._firepower_max, typ),
 
db_torp = "",
 
db_torp = "",
 
nb_da = "",
 
nb_da = "",
Line 267: Line 280:
 
end
 
end
  
function Combat.table_cl(frame)
+
function Combat.table_cl(frame) return Combat.table_dd(frame) end
return Combat.table_dd(frame)
+
function Combat.table_cl_row(frame) return Combat.table_dd_row(frame) end
end
+
function Combat.table_ca(frame) return Combat.table_dd(frame) end
 +
function Combat.table_ca_row(frame) return Combat.table_dd_row(frame) end
 +
function Combat.table_cav(frame) return Combat.table_dd(frame) end
 +
function Combat.table_cav_row(frame) return Combat.table_dd_row(frame) end
 +
function Combat.table_bb(frame) return Combat.table_dd(frame) end
 +
function Combat.table_bb_row(frame) return Combat.table_dd_row(frame) end
 +
function Combat.table_bbv(frame) return Combat.table_dd(frame) end
 +
function Combat.table_bbv_row(frame) return Combat.table_dd_row(frame) end
  
function Combat.table_cl_row(frame)
 
return Combat.table_dd_row(frame)
 
end
 
  
 
return Combat
 
return Combat

Revision as of 14:19, 21 October 2015

Documentation for this module may be created at Module:Sandbox/Combat/doc

local Combat = {}

-- * Damage calculator.
-- 
-- TBD
-- 
--   http://kancollecalc.web.fc2.com/damage_formula.html
--   http://kancollecalc.web.fc2.com/damage.js
-- 
--   http://wikiwiki.jp/kancolle/?%C0%EF%C6%AE%A4%CB%A4%C4%A4%A4%A4%C6
--   http://wikiwiki.jp/kancolle/?%BB%D9%B1%E7%B4%CF%C2%E2
-- 

local engagement_modifiers = {
	green_t = 1.2,
	parallel = 1.0,
	head_on = 0.8,
	red_t = 0.6
}

local spotting_modifiers = {
	cut_in = {
		main_second = 1.1,
		main_radar = 1.2,
		main_ap = 1.3,
		main_main = 1.5,
	},
	double = 1.2
}

local comined_fp = {
	ctf_first = 0,
	ctf_second = 10,
	stf_first = 10,
	stf_second = -5
}

local comined_torp = -5

local formation_modifiers = {
	line_ahead = 1.0,
	double_line = 0.8,
	diamond = 0.7,
	echelon = 0.6,
	line_abreast = 0.6,
	combined = {
		line_ahead = 1.1,
		diamond = 0.7,
		double_line = 1.0,
		line_abreast = 0.8,
	}
}

local health_modifiers = {
	normal = 1.0,
	chuuha = 0.7,
	taiha = 0.4
}

function ammo_modifier(ammo)
	return ammo >= 5 and 1 or ammo / 5
end

local ap_modifiers = {
	main_ap = 1.08,
	main_ap_radar = 1.1,
	main_second_ap = 1.15,
	main_second_ap_radar = 1.15
}

local critical_modifier = 1.5

local anti_ground_modifier = 2.5
local anti_ground_wg_bonus = 75

local db_cap = 150
local nb_cap = 300

local equip_coeffs = {
	small_gun = 1,
	medium_gun = 1,
	main_gun = 1.5,
	ap = 1,
	torpedo = 1.2,
}

function default_modifiers(critical)
	return {
		combined_fp = 0,
		combined_torp = 0,
		anti_ground_bonus = 0,
		engagement = engagement_modifiers.parallel,
		formation = formation_modifiers.line_ahead,
		health = health_modifiers.normal,
		anti_ground = 1,
		anti_sub = 1,
		night = 1,
		cap = db_cap,
		spotting = 1,
		contact = 1,
		expert = 1,
		critical = critical and critical_modifier or 1,
		ap = 1,
		ammo = 1,
	}
end

function shelling_attack_power(fp, equip_bonus, modifiers)
	return 5 + fp + equip_bonus + modifiers.combined_fp + modifiers.anti_ground_bonus
end

function torpedo_attack_power(torp, equip_bonus, modifiers)
	return 5 + torp + equip_bonus + modifiers.combined_torp
end

function damage_pre_cap(attack_power, modifiers)
	return 
		modifiers.engagement * modifiers.formation * modifiers.health *
		modifiers.anti_ground * modifiers.anti_sub *
		modifiers.night *
		attack_power
end

function damage_cap(attack_power, modifiers)
	if attack_power > modifiers.cap then
		attack_power = modifiers.cap + math.sqrt(attack_power - modifiers.cap)
	end
	return math.floor(attack_power)
end

function damage_post_cap(attack_power, modifiers, armor)
	attack_power =
		modifiers.spotting * modifiers.contact *
		math.floor(modifiers.expert * modifiers.critical *
		math.floor(modifiers.ap * attack_power))
	if armor then
		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) * modifiers.ammo)
		local max = math.floor((attack_power - min_armor) * modifiers.ammo)
		return { min, max }
	else
		return math.floor(attack_power * modifiers.ammo)
	end
end

function damage(attack_power, modifiers, armor)
	return damage_post_cap(damage_cap(damage_pre_cap(attack_power, modifiers), modifiers), modifiers, armor)
end

-- * CI rate formula.

local cut_in_types = {
	torpedo = { k = 70, cap = 60 },
	mixed = { k = 70, cap = 70 },
	main = { k = 50, cap = 55 }
}

function cut_in_rate(luck, t)
	if luck <= t.cap then
		return math.floor(math.sqrt(t.k * luck))
	else
		return cut_in_rate(t.cap, t)
	end
end

-- * Tables.

local format = require('Module:StringInterpolation').format
local Ship = require('Module:Ship')
local Formatting = require('Module:Formatting')
local StatIcons = require('Module:StatIcons')

local table_templates = {

	dd = [[{| class="wikitable sortable typography-xl-optout" style="width:100%;"
! colspan="2" |
! colspan="4" |Day Battle
! colspan="5" |Night Battle
|-
!Rank
!Name
!${fp}
!${torp}
!<span title="Normal attack damage: without equipment, with maxed equipment; all modifiers = 1, see notes">Attack</span>
!<span title="Normal torpedo salvo damage, all modifiers = 1, see notes">Torpedo</span>
!${fp_plus_torp}
!<span title="Maximal damage from double attack (combined)">Double Attack</span>
!<span title="Maximal damage from cut-in">Cut-In</span>
!${luck_minus_cap}
!<span title="Torpedo/mixed cut-in rate, gun cut-in rate (only luck dependent part, no bonuses)">Cut-In Rates</span>
${rows}|}]],

	table_dd_row = [===[|-
|${rank}
|${name}
|${fp}
|${torp}
|${db_attack}
|${db_torp}
|${fp_plus_torp}
|${nb_da}
|${nb_ci}
|${luck_minus_cap}
|${nb_ci_rate}
]===]

}

function Combat.table(frame)
    local types = { dd = dd, cl = dd, clt = dd, ca = dd, bb = dd }
    local typ = types[frame.args["type"]]
    if not typ then
        return ""
    end
	return format{
		table_templates[typ],
		rows = frame.args[1] or "",
		fp = Formatting:format_image{StatIcons.firepower, caption = Formatting:format_stat_name("firepower")},
		torp = Formatting:format_image{StatIcons.torpedo, caption = Formatting:format_stat_name("torpedo")},
		fp_plus_torp =
			Formatting:format_image{StatIcons.firepower, caption = Formatting:format_stat_name("firepower")}
			.. "+" ..
			Formatting:format_image{StatIcons.torpedo, caption = Formatting:format_stat_name("torpedo")},
		luck_minus_cap =
		    '<span title="Luck cap">60</span>−' ..
			Formatting:format_image{StatIcons.luck, caption = Formatting:format_stat_name("luck")}
	}
end

local modifiers = default_modifiers(false)

function get_db_attack_string(fp, t)
    local equip_fp = {
        dd = 2 * 3 + math.floor(2 * math.sqrt(10)),
        cl = 2 * 10 + math.floor(2 * math.sqrt(10)),
        clt = 2 * 8 + math.floor(2 * math.sqrt(10)),
    }
    return
        damage(shelling_attack_power(fp, 0, modifiers), modifiers)
        .. ", " ..
        damage(shelling_attack_power(fp, equip_fp[t] or 0, modifiers), modifiers)
end

function Combat.table_dd_row(frame)

	local rank = frame.args[1]
	local ship_key = frame.args[2]
	local typ = frame.args["type"]
	local note = frame.args["note"]

	local name, suffix = Ship:process_ship_key(ship_key)
	local ship_table = Ship:get_table(name, suffix)

	if rank and name and ship_table and ship_table._type then
		local luck_diff = 60 - ship_table._luck
		return format{
			table_templates.table_dd_row,
			rank = rank,
			name =
			    note and format{'[[${name}|<span title="${note}">${name}</span>]]<sup>?</sup>', name = name, note = note} or
			    string.format("[[%s]]", name),
			fp = ship_table._firepower_max,
			torp = ship_table._torpedo_max,
			fp_plus_torp = ship_table._firepower_max + ship_table._torpedo_max,
			db_attack = get_db_attack_string(ship_table._firepower_max, typ),
			db_torp = "",
			nb_da = "",
			nb_ci = "",
			luck_minus_cap = luck_diff < 0 and "−" .. -luck_diff or luck_diff,
			nb_ci_rate =
			    cut_in_rate(ship_table._luck, cut_in_types.torpedo) .. "%, " ..
			    cut_in_rate(ship_table._luck, cut_in_types.main) .. "%",
		}
	else
		return ""
	end

end

function Combat.table_cl(frame) return Combat.table_dd(frame) end
function Combat.table_cl_row(frame) return Combat.table_dd_row(frame) end
function Combat.table_ca(frame) return Combat.table_dd(frame) end
function Combat.table_ca_row(frame) return Combat.table_dd_row(frame) end
function Combat.table_cav(frame) return Combat.table_dd(frame) end
function Combat.table_cav_row(frame) return Combat.table_dd_row(frame) end
function Combat.table_bb(frame) return Combat.table_dd(frame) end
function Combat.table_bb_row(frame) return Combat.table_dd_row(frame) end
function Combat.table_bbv(frame) return Combat.table_dd(frame) end
function Combat.table_bbv_row(frame) return Combat.table_dd_row(frame) end


return Combat