- 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"
Jump to navigation
Jump to search
m |
m |
||
Line 173: | Line 173: | ||
local StatIcons = require('Module:StatIcons') | local StatIcons = require('Module:StatIcons') | ||
− | local | + | local templates = { |
− | + | main = [[{| 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=" | + | !<span title="Damage: normal attack without equipment, ${db_attack_note} with maxed equipment (all other modifiers = 1, see notes)">Hit</span> |
− | !<span title="Normal torpedo salvo damage, all modifiers = 1, see notes"> | + | !<span title="Normal torpedo salvo damage, all modifiers = 1, see notes">Salvo</span> |
!${fp_plus_torp} | !${fp_plus_torp} | ||
− | !<span title="Maximal damage from double attack (combined)"> | + | !<span title="Maximal damage from double attack (combined)">DA</span> |
− | !<span title="Maximal damage from cut-in"> | + | !<span title="Maximal damage from cut-in">CI</span> |
!${luck_minus_cap} | !${luck_minus_cap} | ||
− | !<span title="Torpedo/mixed cut-in rate, gun cut-in rate (only luck dependent part, no bonuses)"> | + | !<span title="Torpedo/mixed cut-in rate, gun cut-in rate (only luck dependent part, no bonuses)">CI%</span> |
${rows}|}]], | ${rows}|}]], | ||
− | + | carrier = [[{| class="wikitable sortable typography-xl-optout" style="width:100%;" | |
+ | !Rank | ||
+ | !Name | ||
+ | !${fp} | ||
+ | !<span title=""></span> | ||
+ | !<span title=""></span> | ||
+ | ${rows}|}]], | ||
+ | |||
+ | main_row = [[|- | ||
|${rank} | |${rank} | ||
|${name} | |${name} | ||
Line 205: | Line 213: | ||
|${luck_minus_cap} | |${luck_minus_cap} | ||
|${nb_ci_rate} | |${nb_ci_rate} | ||
− | ]= | + | ]], |
+ | |||
+ | carrier_row = [[|- | ||
+ | |${rank} | ||
+ | |${name} | ||
+ | |${fp} | ||
+ | | | ||
+ | | | ||
+ | ]], | ||
} | } | ||
− | local map_types = { dd = " | + | local map_types = { |
+ | dd = "main", cl = "main", clt = "main", ca = "main", bb = "main", | ||
+ | cvl = "carrier", cv = "carrier", | ||
+ | } | ||
function Combat.table(frame) | function Combat.table(frame) | ||
− | local | + | local type = frame.args["type"] |
+ | local db_attack_notes = { | ||
+ | dd = "normal attack", | ||
+ | cl = "double attack", | ||
+ | clt = "normal attack", | ||
+ | ca = "double attack", | ||
+ | } | ||
return format{ | return format{ | ||
− | + | templates[map_types[type]], | |
rows = frame.args[1] or "", | rows = frame.args[1] or "", | ||
+ | db_attack_note = db_attack_notes[type] 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")}, | ||
torp = Formatting:format_image{StatIcons.torpedo, caption = Formatting:format_stat_name("torpedo")}, | torp = Formatting:format_image{StatIcons.torpedo, caption = Formatting:format_stat_name("torpedo")}, | ||
Line 227: | Line 253: | ||
} | } | ||
end | end | ||
− | |||
− | |||
function get_db_attack_string(fp, t) | function get_db_attack_string(fp, t) | ||
+ | local modifiers = default_modifiers(false) | ||
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)), | cl = 2 * 10 + math.floor(2 * math.sqrt(10)), | ||
clt = 2 * 8 + math.floor(2 * math.sqrt(10)), | clt = 2 * 8 + math.floor(2 * math.sqrt(10)), | ||
+ | ca = 2 * 10 + math.floor(2 * math.sqrt(10)) + 3, | ||
} | } | ||
− | + | local normal = damage(shelling_attack_power(fp, 0, modifiers), modifiers) | |
− | + | if t == "cl" or t == "ca" then | |
− | + | modifiers.spotting = spotting_modifiers.double | |
− | + | end | |
+ | local special = damage(shelling_attack_power(fp, equip_fp[t] or 0, modifiers), modifiers) | ||
+ | return normal .. ", " .. special | ||
end | end | ||
Line 246: | Line 274: | ||
local rank = frame.args[1] | local rank = frame.args[1] | ||
local ship_key = frame.args[2] | local ship_key = frame.args[2] | ||
− | local typ = | + | local typ = frame.args["type"] |
local note = frame.args["note"] | local note = frame.args["note"] | ||
Line 252: | Line 280: | ||
local ship_table = Ship:get_table(name, suffix) | local ship_table = Ship:get_table(name, suffix) | ||
− | if rank and name and ship_table and ship_table._type then | + | if rank and typ and name and ship_table and ship_table._type then |
+ | local fp = ship_table._firepower_max | ||
local torp = ship_table._torpedo_max or 0 | local torp = ship_table._torpedo_max or 0 | ||
− | local luck_diff = 60 - | + | local luck = ship_table._luck |
+ | local luck_diff = 60 - luck | ||
return format{ | return format{ | ||
− | + | templates[map_types[typ] .. "_row"], | |
rank = rank, | rank = rank, | ||
name = | name = | ||
note and format{'[[${name}|<span title="${note}">${name}</span>]]<sup>?</sup>', name = name, note = note} or | note and format{'[[${name}|<span title="${note}">${name}</span>]]<sup>?</sup>', name = name, note = note} or | ||
string.format("[[%s]]", name), | string.format("[[%s]]", name), | ||
− | fp = | + | fp = fp, |
torp = torp, | torp = torp, | ||
− | fp_plus_torp = | + | fp_plus_torp = fp + torp, |
− | db_attack = get_db_attack_string( | + | db_attack = get_db_attack_string(fp, typ), |
db_torp = "", | db_torp = "", | ||
nb_da = "", | nb_da = "", | ||
Line 270: | Line 300: | ||
luck_minus_cap = luck_diff < 0 and "−" .. -luck_diff or luck_diff, | luck_minus_cap = luck_diff < 0 and "−" .. -luck_diff or luck_diff, | ||
nb_ci_rate = | nb_ci_rate = | ||
− | cut_in_rate( | + | cut_in_rate(luck, cut_in_types.torpedo) .. "%, " .. |
− | cut_in_rate( | + | cut_in_rate(luck, cut_in_types.main) .. "%", |
} | } | ||
else | else | ||
Line 278: | Line 308: | ||
end | end | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
return Combat | return Combat |
Revision as of 15:55, 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 templates = {
main = [[{| 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="Damage: normal attack without equipment, ${db_attack_note} with maxed equipment (all other modifiers = 1, see notes)">Hit</span>
!<span title="Normal torpedo salvo damage, all modifiers = 1, see notes">Salvo</span>
!${fp_plus_torp}
!<span title="Maximal damage from double attack (combined)">DA</span>
!<span title="Maximal damage from cut-in">CI</span>
!${luck_minus_cap}
!<span title="Torpedo/mixed cut-in rate, gun cut-in rate (only luck dependent part, no bonuses)">CI%</span>
${rows}|}]],
carrier = [[{| class="wikitable sortable typography-xl-optout" style="width:100%;"
!Rank
!Name
!${fp}
!<span title=""></span>
!<span title=""></span>
${rows}|}]],
main_row = [[|-
|${rank}
|${name}
|${fp}
|${torp}
|${db_attack}
|${db_torp}
|${fp_plus_torp}
|${nb_da}
|${nb_ci}
|${luck_minus_cap}
|${nb_ci_rate}
]],
carrier_row = [[|-
|${rank}
|${name}
|${fp}
|
|
]],
}
local map_types = {
dd = "main", cl = "main", clt = "main", ca = "main", bb = "main",
cvl = "carrier", cv = "carrier",
}
function Combat.table(frame)
local type = frame.args["type"]
local db_attack_notes = {
dd = "normal attack",
cl = "double attack",
clt = "normal attack",
ca = "double attack",
}
return format{
templates[map_types[type]],
rows = frame.args[1] or "",
db_attack_note = db_attack_notes[type] 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
function get_db_attack_string(fp, t)
local modifiers = default_modifiers(false)
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)),
ca = 2 * 10 + math.floor(2 * math.sqrt(10)) + 3,
}
local normal = damage(shelling_attack_power(fp, 0, modifiers), modifiers)
if t == "cl" or t == "ca" then
modifiers.spotting = spotting_modifiers.double
end
local special = damage(shelling_attack_power(fp, equip_fp[t] or 0, modifiers), modifiers)
return normal .. ", " .. special
end
function Combat.table_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 typ and name and ship_table and ship_table._type then
local fp = ship_table._firepower_max
local torp = ship_table._torpedo_max or 0
local luck = ship_table._luck
local luck_diff = 60 - luck
return format{
templates[map_types[typ] .. "_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 = fp,
torp = torp,
fp_plus_torp = fp + torp,
db_attack = get_db_attack_string(fp, 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(luck, cut_in_types.torpedo) .. "%, " ..
cut_in_rate(luck, cut_in_types.main) .. "%",
}
else
return ""
end
end
return Combat