public int Fuel { get; set; }\r
public int Bull { get; set; }\r
public int[] OnSlot { get; set; }\r
- public int NdockTime { get; set; }\r
public int[] NdockItem { get; set; }\r
public int LoS { get; set; }\r
public int Firepower { get; set; }\r
\r
public enum Attack\r
{\r
+ // ReSharper disable once UnusedMember.Global\r
None,\r
Fire,\r
Fired\r
// ReSharper disable once CompareOfFloatsByEqualityOperator\r
if (Spec.IsAircraftCarrier && EffectiveFirepower == 0 && !CanOpeningAntiSubmarineAttack)\r
return 0;\r
- var sonar = false;\r
- var dct = false;\r
- var dc = false;\r
- var special = false;\r
- var aircraft = false;\r
- var all = 0.0;\r
- foreach (var spec in Slot.Select(item => item.Spec))\r
+ var check = new AntiSubmarineChecker(Slot);\r
+ var vanilla = ShipAntiSubmarine;\r
+ if (vanilla == 0 && !check.Aircraft) // 素対潜0で航空機なしは対潜攻撃なし\r
+ return 0;\r
+ var bonus = 1.0;\r
+ if (check.DCT && check.DC)\r
+ bonus = 1.1;\r
+ if (check.Sonar && (check.DCT || check.DC || check.SpecialDCT))\r
+ bonus = 1.15;\r
+ if (check.Sonar && check.DCT && check.DC)\r
+ bonus = 1.15 * 1.25;\r
+ var levelBonus = Slot.Sum(item => item.AntiSubmarineLevelBonus);\r
+ return bonus * (Sqrt(vanilla) * 2 + check.All * 1.5 + levelBonus + (check.Aircraft ? 8 : 13));\r
+ }\r
+ }\r
+\r
+ private class AntiSubmarineChecker\r
+ {\r
+ public readonly bool Sonar;\r
+ public readonly bool DCT;\r
+ public readonly bool DC;\r
+ public readonly bool SpecialDCT;\r
+ public readonly bool Aircraft;\r
+ public readonly double All;\r
+\r
+ public AntiSubmarineChecker(IEnumerable<ItemStatus> items)\r
+ {\r
+ foreach (var spec in items.Select(item => item.Spec))\r
{\r
if (spec.IsSonar)\r
{\r
- sonar = true;\r
+ Sonar = true;\r
}\r
else if (spec.IsDCT)\r
{\r
- dct = true;\r
+ DCT = true;\r
}\r
else if (spec.IsDC)\r
{\r
- dc = true;\r
+ DC = true;\r
}\r
else if (spec.IsSpecialDCT)\r
{\r
- special = true;\r
+ SpecialDCT = true;\r
}\r
else if (spec.IsAircraft)\r
{\r
- aircraft = true;\r
+ Aircraft = true;\r
}\r
- all += spec.EffectiveAntiSubmarine;\r
+ All += spec.EffectiveAntiSubmarine;\r
}\r
- var vanilla = ShipAntiSubmarine;\r
- if (vanilla == 0 && !aircraft) // 素対潜0で航空機なしは対潜攻撃なし\r
- return 0;\r
- var bonus = 1.0;\r
- if (dct && dc)\r
- bonus = 1.1;\r
- if (sonar && (dct || dc || special))\r
- bonus = 1.15;\r
- if (sonar && dct && dc)\r
- bonus = 1.15 * 1.25;\r
- var levelBonus = Slot.Sum(item => item.AntiSubmarineLevelBonus);\r
- return bonus * (Sqrt(vanilla) * 2 + all * 1.5 + levelBonus + (aircraft ? 8 : 13));\r
}\r
}\r
\r
- public int ShipAntiSubmarine => AntiSubmarine - Slot.Sum(item => item.Spec.AntiSubmarine);\r
+ public int ShipAntiSubmarine => AntiSubmarine - Slot.Sum(item => item.Spec.AntiSubmarine + AntiSubmarineBonus(item.Spec));\r
+\r
+ private int AntiSubmarineBonus(ItemSpec spec)\r
+ {\r
+ switch (spec.Name)\r
+ {\r
+ case "四式水中聴音機":\r
+ if (Spec.ShipClass == 54) // 秋月型\r
+ return 1;\r
+ if (new[] {"五十鈴改二", "那珂改二", "由良改二", "夕張改二", "夕張改二特"}.Any(name => Spec.Name == name))\r
+ return 1;\r
+ if (Spec.Name == "夕張改二丁")\r
+ return 3;\r
+ break;\r
+ case "三式水中探信儀":\r
+ if (new[] {"神風", "春風", "時雨", "山風", "舞風", "朝霜"}.Any(Spec.Name.StartsWith))\r
+ return 3;\r
+ if (new[] {"潮", "雷", "山雲", "磯風", "浜風", "岸波"}.Any(Spec.Name.StartsWith))\r
+ return 2;\r
+ break;\r
+ case "三式爆雷投射機 集中配備":\r
+ if (new[] {"五十鈴改二", "那珂改二", "由良改二"}.Any(name => Spec.Name == name))\r
+ return 1;\r
+ break;\r
+ case "試製15cm9連装対潜噴進砲":\r
+ if (new[] {"五十鈴改二", "那珂改二", "由良改二", "夕張改二"}.Any(name => Spec.Name == name))\r
+ return 2;\r
+ if (Spec.Name == "夕張改二丁")\r
+ return 3;\r
+ break;\r
+ }\r
+ return 0;\r
+ }\r
\r
public bool CanOpeningAntiSubmarineAttack\r
{\r
get\r
{\r
+ var specs = Slot.Select(item => item.Spec).ToArray();\r
switch (Name)\r
{\r
case "五十鈴改二":\r
case "龍田改二":\r
case "Jervis改":\r
+ case "Janus改":\r
case "Samuel B.Roberts改":\r
+ case "Johnston":\r
+ case "Johnston改":\r
+ case "Fletcher":\r
+ case "Fletcher改":\r
return true;\r
case "大鷹改":\r
case "大鷹改二":\r
- return Slot.Any(item => item.Spec.IsAircraft && item.Spec.EffectiveAntiSubmarine > 0);\r
+ case "神鷹改":\r
+ case "神鷹改二":\r
+ return specs.Any(spec => spec.IsTorpedoBomber && spec.AntiSubmarine >= 1 ||\r
+ spec.IsArmyAircraft || spec.IsDiveBomber);\r
case "大鷹":\r
case "Gambier Bay":\r
case "Gambier Bay改":\r
case "瑞鳳改二乙":\r
case "神鷹":\r
- case "神鷹改":\r
- case "神鷹改二":\r
- return Slot.Any(item => item.Spec.IsAircraft && item.Spec.EffectiveAntiSubmarine >= 7) &&\r
- AntiSubmarine >= (HaveSonar ? 50 : 65);\r
+ if (AntiSubmarine < 50)\r
+ return false;\r
+ if (AntiSubmarine >= 50 && AntiSubmarine < 100)\r
+ return (AntiSubmarine >= 65 || HaveSonar) &&\r
+ specs.Any(spec => spec.IsTorpedoBomber && spec.AntiSubmarine >= 7 ||\r
+ spec.IsArmyAircraft);\r
+ return HaveSonar &&\r
+ specs.Any(spec => spec.IsTorpedoBomber && spec.AntiSubmarine >= 1 ||\r
+ spec.IsDiveBomber);\r
+ case "瑞鳳改二":\r
+ if (AntiSubmarine < 50)\r
+ return false;\r
+ return HaveSonar &&\r
+ specs.Any(spec => spec.IsTorpedoBomber && spec.AntiSubmarine >= 7 ||\r
+ spec.IsArmyAircraft);\r
default:\r
- return Spec.ShipType == 1\r
- ? Slot.Sum(item => item.Spec.AntiSubmarine) >= 4 && AntiSubmarine >= 75 ||\r
- HaveSonar && AntiSubmarine >= 60\r
- : HaveSonar && AntiSubmarine >= 100;\r
+ if (HaveSonar && AntiSubmarine >= 100)\r
+ return true;\r
+ if (Spec.ShipType != 1)\r
+ return false;\r
+ return Slot.Sum(item => item.Spec.AntiSubmarine) >= 4 && AntiSubmarine >= 75 ||\r
+ HaveSonar && AntiSubmarine >= 60;\r
}\r
}\r
}\r
\r
if (Slot.Any(item => item.Spec.IconType == 45 || item.Spec.IconType == 46) && // 夜戦か夜攻\r
(Spec.Id == 545 || // Saratoga Mk.II\r
+ Spec.Id == 599 || // 赤城改二戊\r
Slot.Any(item => item.Spec.Id == 258 || item.Spec.Id == 259))) // 夜間作戦航空要員\r
{\r
return Firepower + Slot.Zip(OnSlot, (item, onSlot) =>\r
case 242: // Swordfish\r
case 243: // Swordfish Mk.II(熟練)\r
case 244: // Swordfish Mk.III(熟練)\r
+ case 320: // 彗星一二型(三一号光電管爆弾搭載機)\r
a = 0.0;\r
b = 0.3;\r
break;\r
\r
public int EffectiveAntiAirForFleet => (int)AllSlot.Sum(item => item.EffectiveAntiAirForFleet);\r
\r
+ public double AntiAirPropellantBarrageChance\r
+ {\r
+ get\r
+ {\r
+ var launcherCount = AllSlot.Count(item => item.Spec.Id == 274);\r
+ if (launcherCount == 0)\r
+ return 0;\r
+ var iseClass = Spec.ShipClass == 2;\r
+ var baseChance = (EffectiveAntiAirForShip + 0.9 * Lucky) / 281.0;\r
+ return (baseChance + 0.15 * (launcherCount - 1) + (iseClass ? 0.25 : 0)) * 100;\r
+ }\r
+ }\r
+\r
public int EffectiveFuelMax => Max((int)(Spec.FuelMax * (Level >= 100 ? 0.85 : 1.0)), 1);\r
\r
public int EffectiveBullMax => Max((int)(Spec.BullMax * (Level >= 100 ? 0.85 : 1.0)), 1);\r
\r
+ public int RawLoS =>\r
+ LoS - AllSlot.Sum(item => item.Spec.LoS + (Spec.HaveSgRadarBonus ? item.Spec.LoSSgRadarBonus : 0));\r
+\r
public object Clone()\r
{\r
var r = (ShipStatus)MemberwiseClone();\r