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 int[] CalcFighterPower(int slot)\r
41         {\r
42             if (!Spec.CanAirCombat || slot == 0)\r
43                 return new[] {0, 0};\r
44             var unskilled = (Spec.AntiAir + FighterPowerLevelBonus) * Math.Sqrt(slot);\r
45             return AlvBonus.Select(bonus => (int)(unskilled + bonus)).ToArray();\r
46         }\r
47 \r
48         public AirBaseParams[] CalcFighterPowerInBase(int slot)\r
49         {\r
50             if (!Spec.IsAircraft || slot == 0)\r
51                 return new[] {new AirBaseParams(), new AirBaseParams()};\r
52             var baseFighterPower = (new AirBaseParams(Spec.Interception * 1.5, Spec.AntiBomber * 2 + Spec.Interception) +\r
53                                    Spec.AntiAir  + FighterPowerLevelBonus) * Math.Sqrt(slot);\r
54             return AlvBonusInBase.Select(bonus => (baseFighterPower + bonus).Floor()).ToArray();\r
55         }\r
56 \r
57         private readonly double[] _alvBonusMin =\r
58         {\r
59             Math.Sqrt(0.0), Math.Sqrt(1.0), Math.Sqrt(2.5), Math.Sqrt(4.0), Math.Sqrt(5.5), Math.Sqrt(7.0),\r
60             Math.Sqrt(8.5), Math.Sqrt(10.0)\r
61         };\r
62 \r
63         private readonly double[] _alvBonusMax =\r
64         {\r
65             Math.Sqrt(0.9), Math.Sqrt(2.4), Math.Sqrt(3.9), Math.Sqrt(5.4), Math.Sqrt(6.9), Math.Sqrt(8.4),\r
66             Math.Sqrt(9.9), Math.Sqrt(12.0)\r
67         };\r
68 \r
69         private int[] AlvTypeBonusTable\r
70         {\r
71             get\r
72             {\r
73                 switch (Spec.Type)\r
74                 {\r
75                     case 6: // 艦戦\r
76                     case 45: // 水戦\r
77                     case 48: // 局地戦闘機\r
78                     case 56: // 噴式戦闘機\r
79                         return new[] {0, 0, 2, 5, 9, 14, 14, 22};\r
80                     case 7: // 艦爆\r
81                     case 8: // 艦攻\r
82                     case 47: // 陸攻\r
83                     case 57: // 噴式戦闘爆撃機\r
84                     case 58: // 噴式攻撃機\r
85                         return new[] {0, 0, 0, 0, 0, 0, 0, 0};\r
86                     case 11: // 水爆\r
87                         return new[] {0, 0, 1, 1, 1, 3, 3, 6};\r
88                     default:\r
89                         return null;\r
90                 }\r
91             }\r
92         }\r
93 \r
94         private double[] AlvBonus\r
95         {\r
96             get\r
97             {\r
98                 var table = AlvTypeBonusTable;\r
99                 if (table == null)\r
100                     return new[] {0.0, 0.0};\r
101                 return new[] {table[Alv] + _alvBonusMin[Alv], table[Alv] + _alvBonusMax[Alv]};\r
102             }\r
103         }\r
104 \r
105         private double[] AlvBonusInBase\r
106         {\r
107             get\r
108             {\r
109                 switch (Spec.Type)\r
110                 {\r
111                     case 9: // 艦偵\r
112                     case 10: // 水偵\r
113                     case 41: // 大艇\r
114                         return new[] {_alvBonusMin[Alv], _alvBonusMax[Alv]};\r
115                     default:\r
116                         return AlvBonus;\r
117                 }\r
118             }\r
119         }\r
120 \r
121         private double FighterPowerLevelBonus\r
122         {\r
123             get\r
124             {\r
125                 switch (Spec.Type)\r
126                 {\r
127                     case 6: // 艦戦\r
128                     case 45: // 水戦\r
129                     case 48: // 陸戦・局戦\r
130                         return 0.2 * Level;\r
131                     case 7: // 改修可能なのは爆戦のみ\r
132                         return 0.25 * Level;\r
133                 }\r
134                 return 0;\r
135             }\r
136         }\r
137 \r
138         public double LoSLevelBonus\r
139         {\r
140             get\r
141             {\r
142                 switch (Spec.Type)\r
143                 {\r
144                     case 10: // 水偵\r
145                         return 1.2 * Math.Sqrt(Level);\r
146                     case 11: // 水爆\r
147                         return 1.15 * Math.Sqrt(Level);\r
148                     case 12: // 小型電探\r
149                         return 1.25 * Math.Sqrt(Level);\r
150                     case 13: // 大型電探\r
151                         return 1.4 * Math.Sqrt(Level);\r
152                     case 9: // 艦偵\r
153                     case 94: // 艦上偵察機(II)\r
154                         return 1.2 * Math.Sqrt(Level);\r
155                     default:\r
156                         return 0;\r
157                 }\r
158             }\r
159         }\r
160 \r
161         public double FirepowerLevelBonus\r
162         {\r
163             get\r
164             {\r
165                 switch (Spec.Type)\r
166                 {\r
167                     case 1: // 小口径\r
168                     case 2: // 中口径\r
169                     case 19: // 徹甲弾\r
170                     case 21: // 対空機銃\r
171                     case 24: // 上陸用舟艇\r
172                     case 29: // 探照灯\r
173                     case 36: // 高射装置\r
174                     case 42: // 大型探照灯\r
175                     case 46: // 特型内火艇\r
176                         return Math.Sqrt(Level);\r
177                     case 3: // 大口径\r
178                         return 1.5 * Math.Sqrt(Level);\r
179                     case 4: // 副砲\r
180                         return SecondaryGunLevelBonus;\r
181                     case 14: // ソナー\r
182                     case 15: // 爆雷\r
183                         return Spec.Id == 226 // 九五式爆雷\r
184                             ? 0\r
185                             : 0.75 * Math.Sqrt(Level);\r
186                     default:\r
187                         return 0;\r
188                 }\r
189             }\r
190         }\r
191 \r
192         public double SecondaryGunLevelBonus\r
193         {\r
194             get\r
195             {\r
196                 switch (Spec.Id)\r
197                 {\r
198                     case 10: // 12.7cm連装高角砲\r
199                     case 66: // 8cm高角砲\r
200                     case 220: // 8cm高角砲改+増設機銃\r
201                     case 275: // 10cm連装高角砲改+増設機銃\r
202                         return 0.2 * Level;\r
203                     case 12: // 15.5cm三連装副砲\r
204                     case 234: // 15.5cm三連装副砲改\r
205                     case 247: // 15.2cm三連装砲\r
206                         return 0.3 * Level;\r
207                     default:\r
208                         return Math.Sqrt(Level);\r
209                 }\r
210             }\r
211         }\r
212 \r
213         public double TorpedoLevelBonus\r
214         {\r
215             get\r
216             {\r
217                 switch (Spec.Type)\r
218                 {\r
219                     case 5: // 魚雷\r
220                     case 21: // 機銃\r
221                         return 1.2 * Math.Sqrt(Level);\r
222                     default:\r
223                         return 0;\r
224                 }\r
225             }\r
226         }\r
227 \r
228         public double AntiSubmarineLevelBonus\r
229         {\r
230             get\r
231             {\r
232                 switch (Spec.Type)\r
233                 {\r
234                     case 14:\r
235                     case 15:\r
236                         return Math.Sqrt(Level);\r
237                     default:\r
238                         return 0;\r
239                 }\r
240             }\r
241         }\r
242 \r
243         public double BomberLevelBonus => Spec.Type == 11 /* 水爆 */ ? 0.2 * Level : 0;\r
244 \r
245         public double NightBattleLevelBonus\r
246         {\r
247             get\r
248             {\r
249                 switch (Spec.Type)\r
250                 {\r
251                     case 1: // 小口径\r
252                     case 2: // 中口径\r
253                     case 3: // 大口径\r
254                     case 5: // 魚雷\r
255                     case 19: // 徹甲弾\r
256                     case 24: // 上陸用舟艇\r
257                     case 29: // 探照灯\r
258                     case 36: // 高射装置\r
259                     case 42: // 大型探照灯\r
260                     case 46: // 特型内火艇\r
261                         return Math.Sqrt(Level);\r
262                     case 4: // 副砲\r
263                         return SecondaryGunLevelBonus;\r
264                     default:\r
265                         return 0;\r
266                 }\r
267             }\r
268         }\r
269 \r
270         public double EffectiveAntiAirForShip\r
271         {\r
272             get\r
273             {\r
274                 switch (Spec.IconType)\r
275                 {\r
276                     case 15: // 機銃\r
277                         return 6 * Spec.AntiAir + 4 * Math.Sqrt(Level);\r
278                     case 16: // 高角砲\r
279                         return 4 * Spec.AntiAir + (Spec.AntiAir >= 8 ? 3 : 2) * Math.Sqrt(Level);\r
280                     case 11: // 電探\r
281                         return 3 * Spec.AntiAir;\r
282                     case 30: // 高射装置\r
283                         return 4 * Spec.AntiAir + 2 * Math.Sqrt(Level);\r
284                 }\r
285                 return 0;\r
286             }\r
287         }\r
288 \r
289         public double EffectiveAntiAirForFleet\r
290         {\r
291             get\r
292             {\r
293                 switch (Spec.IconType)\r
294                 {\r
295                     case 1:\r
296                     case 2:\r
297                     case 3: // 主砲\r
298                     case 4: // 副砲\r
299                     case 6: // 艦戦\r
300                     case 7: // 艦爆\r
301                     case 15: // 機銃\r
302                         return 0.2 * Spec.AntiAir;\r
303                     case 11: // 電探\r
304                         return 0.4 * Spec.AntiAir + 1.5 * Math.Sqrt(Level);\r
305                     case 12: // 三式弾\r
306                         return 0.6 * Spec.AntiAir;\r
307                     case 16: // 高角砲\r
308                         return 0.35 * Spec.AntiAir + (Spec.AntiAir >= 8 ? 3 : 2) * Math.Sqrt(Level);\r
309                     case 30: // 高射装置\r
310                         return 0.35 * Spec.AntiAir + 2 * Math.Sqrt(Level);\r
311                     default:\r
312                         if (Spec.Id == 9) // 46cm三連装砲\r
313                             return 0.25 * Spec.AntiAir;\r
314                         if (Spec.Type == 10) // 水偵\r
315                             return 0.2 * Spec.AntiAir;\r
316                         break;\r
317                 }\r
318                 return 0;\r
319             }\r
320         }\r
321     }\r
322 }