OSDN Git Service

ボス前で空襲戦があるとボス戦で大破警告が出るのを直す
[kancollesniffer/KancolleSniffer.git] / KancolleSniffer / Model / ItemStatus.cs
1 // Copyright (C) 2018 Kazuhiro Fujieda <fujieda@users.osdn.me>\r
2 //\r
3 // Licensed under the Apache License, Version 2.0 (the "License");\r
4 // you may not use this file except in compliance with the License.\r
5 // You may obtain a copy of the License at\r
6 //\r
7 //    http://www.apache.org/licenses/LICENSE-2.0\r
8 //\r
9 // Unless required by applicable law or agreed to in writing, software\r
10 // distributed under the License is distributed on an "AS IS" BASIS,\r
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
12 // See the License for the specific language governing permissions and\r
13 // limitations under the License.\r
14 \r
15 using System;\r
16 using System.Linq;\r
17 \r
18 namespace KancolleSniffer.Model\r
19 {\r
20     public class ItemStatus\r
21     {\r
22         public int Id { get; set; }\r
23         public bool Empty => Id == -1;\r
24         public bool Unimplemented => Id == 0;\r
25         public ItemSpec Spec { get; set; } = new ItemSpec();\r
26         public int Level { get; set; }\r
27         public int Alv { get; set; }\r
28         public ShipStatus Holder { get; set; }\r
29 \r
30         public ItemStatus()\r
31         {\r
32             Id = -1;\r
33         }\r
34 \r
35         public ItemStatus(int id)\r
36         {\r
37             Id = id;\r
38         }\r
39 \r
40         public Range CalcFighterPower(int slot)\r
41         {\r
42             if (!Spec.CanAirCombat || slot == 0)\r
43                 return new Range();\r
44             var withoutAlv = (Spec.AntiAir + FighterPowerLevelBonus) * Math.Sqrt(slot);\r
45             return new Range(withoutAlv, AlvBonus);\r
46         }\r
47 \r
48         private RangeD AlvBonus\r
49         {\r
50             get\r
51             {\r
52                 var table = AlvTypeBonusTable;\r
53                 if (table == null)\r
54                     return new RangeD();\r
55                 return _alvBonus[Alv] + table[Alv];\r
56             }\r
57         }\r
58 \r
59         public AirCorpsFighterPower.Range CalcFighterPowerInBase(int slot)\r
60         {\r
61             if (!Spec.IsAircraft || slot == 0)\r
62                 return new AirCorpsFighterPower.Range();\r
63             var withoutAlv =\r
64                 (new AirCorpsFighterPower.Pair(Spec.Interception * 1.5, Spec.AntiBomber * 2 + Spec.Interception) +\r
65                  Spec.AntiAir + FighterPowerLevelBonus) * Math.Sqrt(slot);\r
66             return new AirCorpsFighterPower.Range(withoutAlv, AlvBonusInBase);\r
67         }\r
68 \r
69         private RangeD AlvBonusInBase\r
70         {\r
71             get\r
72             {\r
73                 switch (Spec.Type)\r
74                 {\r
75                     case 9: // 艦偵\r
76                     case 10: // 水偵\r
77                     case 41: // 大艇\r
78                     case 49: // 陸偵\r
79                         return _alvBonus[Alv];\r
80                     default:\r
81                         return AlvBonus;\r
82                 }\r
83             }\r
84         }\r
85 \r
86         private readonly RangeD[] _alvBonus =\r
87             new[]\r
88             {\r
89                 new RangeD(0.0, 0.9), new RangeD(1.0, 2.4), new RangeD(2.5, 3.9), new RangeD(4.0, 5.4),\r
90                 new RangeD(5.5, 6.9), new RangeD(7.0, 8.4), new RangeD(8.5, 9.9), new RangeD(10.0, 12.0)\r
91             }.Select(range => range.Sqrt()).ToArray();\r
92 \r
93 \r
94         private int[] AlvTypeBonusTable\r
95         {\r
96             get\r
97             {\r
98                 switch (Spec.Type)\r
99                 {\r
100                     case 6: // 艦戦\r
101                     case 45: // 水戦\r
102                     case 48: // 局地戦闘機\r
103                     case 56: // 噴式戦闘機\r
104                         return new[] {0, 0, 2, 5, 9, 14, 14, 22};\r
105                     case 7: // 艦爆\r
106                     case 8: // 艦攻\r
107                     case 47: // 陸攻\r
108                     case 57: // 噴式戦闘爆撃機\r
109                     case 58: // 噴式攻撃機\r
110                         return new[] {0, 0, 0, 0, 0, 0, 0, 0};\r
111                     case 11: // 水爆\r
112                         return new[] {0, 0, 1, 1, 1, 3, 3, 6};\r
113                     default:\r
114                         return null;\r
115                 }\r
116             }\r
117         }\r
118 \r
119         private double FighterPowerLevelBonus\r
120         {\r
121             get\r
122             {\r
123                 switch (Spec.Type)\r
124                 {\r
125                     case 6: // 艦戦\r
126                     case 45: // 水戦\r
127                     case 48: // 陸戦・局戦\r
128                         return 0.2 * Level;\r
129                     case 7: // 改修可能なのは爆戦のみ\r
130                         return 0.25 * Level;\r
131                 }\r
132                 return 0;\r
133             }\r
134         }\r
135 \r
136         public double LoSLevelBonus\r
137         {\r
138             get\r
139             {\r
140                 switch (Spec.Type)\r
141                 {\r
142                     case 10: // 水偵\r
143                         return 1.2 * Math.Sqrt(Level);\r
144                     case 11: // 水爆\r
145                         return 1.15 * Math.Sqrt(Level);\r
146                     case 12: // 小型電探\r
147                         return 1.25 * Math.Sqrt(Level);\r
148                     case 13: // 大型電探\r
149                         return 1.4 * Math.Sqrt(Level);\r
150                     case 9: // 艦偵\r
151                     case 94: // 艦上偵察機(II)\r
152                         return 1.2 * Math.Sqrt(Level);\r
153                     default:\r
154                         return 0;\r
155                 }\r
156             }\r
157         }\r
158 \r
159         public double FirepowerLevelBonus\r
160         {\r
161             get\r
162             {\r
163                 switch (Spec.Type)\r
164                 {\r
165                     case 1: // 小口径\r
166                     case 2: // 中口径\r
167                     case 19: // 徹甲弾\r
168                     case 21: // 対空機銃\r
169                     case 24: // 上陸用舟艇\r
170                     case 29: // 探照灯\r
171                     case 36: // 高射装置\r
172                     case 42: // 大型探照灯\r
173                     case 46: // 特型内火艇\r
174                         return Math.Sqrt(Level);\r
175                     case 3: // 大口径\r
176                         return 1.5 * Math.Sqrt(Level);\r
177                     case 4: // 副砲\r
178                         return SecondaryGunLevelBonus;\r
179                     case 14: // ソナー\r
180                     case 15: // 爆雷\r
181                         return Spec.Id == 226 // 九五式爆雷\r
182                             ? 0\r
183                             : 0.75 * Math.Sqrt(Level);\r
184                     default:\r
185                         return 0;\r
186                 }\r
187             }\r
188         }\r
189 \r
190         public double SecondaryGunLevelBonus\r
191         {\r
192             get\r
193             {\r
194                 switch (Spec.Id)\r
195                 {\r
196                     case 10: // 12.7cm連装高角砲\r
197                     case 66: // 8cm高角砲\r
198                     case 220: // 8cm高角砲改+増設機銃\r
199                     case 275: // 10cm連装高角砲改+増設機銃\r
200                         return 0.2 * Level;\r
201                     case 12: // 15.5cm三連装副砲\r
202                     case 234: // 15.5cm三連装副砲改\r
203                     case 247: // 15.2cm三連装砲\r
204                         return 0.3 * Level;\r
205                     default:\r
206                         return Math.Sqrt(Level);\r
207                 }\r
208             }\r
209         }\r
210 \r
211         public double TorpedoLevelBonus\r
212         {\r
213             get\r
214             {\r
215                 switch (Spec.Type)\r
216                 {\r
217                     case 5: // 魚雷\r
218                     case 21: // 機銃\r
219                         return 1.2 * Math.Sqrt(Level);\r
220                     default:\r
221                         return 0;\r
222                 }\r
223             }\r
224         }\r
225 \r
226         public double AntiSubmarineLevelBonus\r
227         {\r
228             get\r
229             {\r
230                 switch (Spec.Type)\r
231                 {\r
232                     case 14:\r
233                     case 15:\r
234                         return Math.Sqrt(Level);\r
235                     default:\r
236                         return 0;\r
237                 }\r
238             }\r
239         }\r
240 \r
241         public double BomberLevelBonus => Spec.Type == 11 /* 水爆 */ ? 0.2 * Level : 0;\r
242 \r
243         public double NightBattleLevelBonus\r
244         {\r
245             get\r
246             {\r
247                 switch (Spec.Type)\r
248                 {\r
249                     case 1: // 小口径\r
250                     case 2: // 中口径\r
251                     case 3: // 大口径\r
252                     case 5: // 魚雷\r
253                     case 19: // 徹甲弾\r
254                     case 22: // 特殊潜航艇\r
255                     case 24: // 上陸用舟艇\r
256                     case 29: // 探照灯\r
257                     case 36: // 高射装置\r
258                     case 42: // 大型探照灯\r
259                     case 46: // 特型内火艇\r
260                         return Math.Sqrt(Level);\r
261                     case 4: // 副砲\r
262                         return SecondaryGunLevelBonus;\r
263                     default:\r
264                         return 0;\r
265                 }\r
266             }\r
267         }\r
268 \r
269         public double EffectiveAntiAirForShip\r
270         {\r
271             get\r
272             {\r
273                 switch (Spec.IconType)\r
274                 {\r
275                     case 15: // 機銃\r
276                         return 6 * Spec.AntiAir + 4 * Math.Sqrt(Level);\r
277                     case 16: // 高角砲\r
278                         return 4 * Spec.AntiAir + (Spec.AntiAir >= 8 ? 3 : 2) * Math.Sqrt(Level);\r
279                     case 11: // 電探\r
280                         return 3 * Spec.AntiAir;\r
281                     case 30: // 高射装置\r
282                         return 4 * Spec.AntiAir + 2 * Math.Sqrt(Level);\r
283                 }\r
284                 return 0;\r
285             }\r
286         }\r
287 \r
288         public double EffectiveAntiAirForFleet\r
289         {\r
290             get\r
291             {\r
292                 switch (Spec.IconType)\r
293                 {\r
294                     case 1:\r
295                     case 2:\r
296                     case 3: // 主砲\r
297                     case 4: // 副砲\r
298                     case 6: // 艦戦\r
299                     case 7: // 艦爆\r
300                     case 15: // 機銃\r
301                         return 0.2 * Spec.AntiAir;\r
302                     case 11: // 電探\r
303                         return 0.4 * Spec.AntiAir + 1.5 * Math.Sqrt(Level);\r
304                     case 12: // 三式弾\r
305                         return 0.6 * Spec.AntiAir;\r
306                     case 16: // 高角砲\r
307                         return 0.35 * Spec.AntiAir + (Spec.AntiAir >= 8 ? 3 : 2) * Math.Sqrt(Level);\r
308                     case 30: // 高射装置\r
309                         return 0.35 * Spec.AntiAir + 2 * Math.Sqrt(Level);\r
310                     default:\r
311                         if (Spec.Id == 9) // 46cm三連装砲\r
312                             return 0.25 * Spec.AntiAir;\r
313                         if (Spec.Type == 10) // 水偵\r
314                             return 0.2 * Spec.AntiAir;\r
315                         break;\r
316                 }\r
317                 return 0;\r
318             }\r
319         }\r
320     }\r
321 }