OSDN Git Service

艦隊情報で一部の装備に色が付かないのを直す
[kancollesniffer/KancolleSniffer.git] / KancolleSniffer / ItemInfo.cs
1 // Copyright (C) 2013, 2014, 2015 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.Collections.Generic;\r
16 using System.Drawing;\r
17 using System.Linq;\r
18 using static System.Math;\r
19 \r
20 namespace KancolleSniffer\r
21 {\r
22     public class ItemSpec\r
23     {\r
24         public static bool IncreaceLandPowerTp = false;\r
25         public int Id;\r
26         public string Name;\r
27         public int Type;\r
28         public string TypeName;\r
29         public int IconType;\r
30         public int AntiAir;\r
31         public int LoS;\r
32         public int AntiSubmarine;\r
33         public int Torpedo;\r
34         public int Bomber;\r
35         public int Interception;\r
36         public int AntiBomber;\r
37 \r
38         public ItemSpec()\r
39         {\r
40             Id = -1;\r
41             Name = "";\r
42         }\r
43 \r
44         public bool CanAirCombat\r
45         {\r
46             get\r
47             {\r
48                 switch (Type)\r
49                 {\r
50                     case 6: // 艦戦\r
51                     case 7: // 艦爆\r
52                     case 8: // 艦攻\r
53                     case 11: // 水爆\r
54                     case 45: // 水戦\r
55                     case 56: // 噴式戦闘機\r
56                     case 57: // 噴式戦闘爆撃機\r
57                     case 58: // 噴式攻撃機\r
58                         return true;\r
59                 }\r
60                 return false;\r
61             }\r
62         }\r
63 \r
64         // http://ja.kancolle.wikia.com/wiki/%E3%83%9E%E3%83%83%E3%83%97%E7%B4%A2%E6%95%B5\r
65         public double LoSScaleFactor\r
66         {\r
67             get\r
68             {\r
69                 switch (Type)\r
70                 {\r
71                     case 8: // 艦攻\r
72                         return 0.8;\r
73                     case 9: // 艦偵\r
74                         return 1;\r
75                     case 10: // 水偵\r
76                         return 1.2;\r
77                     case 11: // 水爆\r
78                         return 1.1;\r
79                     default:\r
80                         return 0.6;\r
81                 }\r
82             }\r
83         }\r
84 \r
85         public bool IsAircraft\r
86         {\r
87             get\r
88             {\r
89                 switch (Type)\r
90                 {\r
91                     case 6:\r
92                     case 7:\r
93                     case 8:\r
94                     case 9:\r
95                     case 10:\r
96                     case 11:\r
97                     case 25: // オートジャイロ\r
98                     case 26: // 対潜哨戒機\r
99                     case 41: // 大艇\r
100                     case 45:\r
101                     case 56:\r
102                     case 57:\r
103                     case 58:\r
104                     case 59: // 噴式偵察機\r
105                         return true;\r
106                 }\r
107                 return false;\r
108             }\r
109         }\r
110 \r
111         public bool IsDiveBomber => Type == 7 || Type == 11 || Type == 57;\r
112 \r
113         public bool IsTorpedoBomber => Type == 8 || Type == 58;\r
114 \r
115         public int EffectiveAntiSubmarine\r
116         {\r
117             get\r
118             {\r
119                 switch (Type)\r
120                 {\r
121                     case 1: // 小口径(12.7cm連装高角砲(後期型))\r
122                     case 10: // 水偵\r
123                     case 12: // 小型電探(22号対水上電探改四)\r
124                     case 45: // 水戦\r
125                         return 0;\r
126                     default:\r
127                         return AntiSubmarine;\r
128                 }\r
129             }\r
130         }\r
131 \r
132         public bool IsSonar => Type == 14 || // ソナー\r
133                                Type == 40; // 大型ソナー\r
134 \r
135         public bool IsDepthCharge => Type == 15;\r
136 \r
137         public bool IsRepairFacility => Type == 31;\r
138 \r
139         public double ContactTriggerRate\r
140         {\r
141             get\r
142             {\r
143                 switch (Type)\r
144                 {\r
145                     case 9: // 艦偵\r
146                     case 10: // 水偵\r
147                     case 41: // 大艇\r
148                         return 0.04;\r
149                     default:\r
150                         return 0;\r
151                 }\r
152             }\r
153         }\r
154 \r
155         public double TransportPoint\r
156         {\r
157             get\r
158             {\r
159                 switch (Id)\r
160                 {\r
161                     case 75: // ドラム缶(輸送用)\r
162                         return 5.0;\r
163                     case 68: // 大発動艇\r
164                         return 8.0;\r
165                     case 193: // 特大発動艇\r
166                         return 8.0;\r
167                     case 166: // 大発動艇(八九式中戦車&陸戦隊)\r
168                         return IncreaceLandPowerTp ? 13.0 : 8.0;\r
169                     case 167: // 特二式内火艇\r
170                         return IncreaceLandPowerTp ? 7.0 : 2.0;\r
171                     case 230: // 特大発動艇+戦車第11連隊\r
172                         return 8.0;\r
173                     case 145: // 戦闘糧食\r
174                         return 1.0;\r
175                     case 150: // 秋刀魚の缶詰\r
176                         return 1.0;\r
177                     default:\r
178                         return 0;\r
179                 }\r
180             }\r
181         }\r
182 \r
183         public double AirDefenceBonus\r
184         {\r
185             get\r
186             {\r
187                 switch (Type)\r
188                 {\r
189                     case 9:\r
190                         return LoS <= 7 ? 1.2 : 1.3;\r
191                     case 10:\r
192                     case 41:\r
193                         return LoS <= 7 ? 1.1 : LoS <= 8 ? 1.13 : 1.16;\r
194                 }\r
195                 return 1;\r
196             }\r
197         }\r
198 \r
199         public Color Color\r
200         {\r
201             get\r
202             {\r
203                 switch (IconType)\r
204                 {\r
205                     case 1:\r
206                     case 2:\r
207                     case 3: // 主砲\r
208                     case 13: // 徹甲弾\r
209                         return Color.FromArgb(209, 89, 89);\r
210                     case 4: // 副砲\r
211                         return Color.FromArgb(253, 233, 0);\r
212                     case 5: // 魚雷\r
213                         return Color.FromArgb(88, 134, 170);\r
214                     case 6: // 艦戦\r
215                         return Color.FromArgb(93, 179, 108);\r
216                     case 7: // 艦爆\r
217                         return Color.FromArgb(223, 102, 102);\r
218                     case 8: // 艦攻\r
219                         return Color.FromArgb(95, 173, 234);\r
220                     case 9: // 艦偵\r
221                         return Color.FromArgb(254, 191, 0);\r
222                     case 10: // 水上機\r
223                     case 43: // 水上戦闘機\r
224                         return Color.FromArgb(142, 203, 152);\r
225                     case 11: // 電探\r
226                         return Color.FromArgb(231, 153, 53);\r
227                     case 12: // 三式弾\r
228                         return Color.FromArgb(69, 175, 88);\r
229                     case 14: // 応急修理要員\r
230                         return Color.FromArgb(254, 254, 254);\r
231                     case 15: // 機銃\r
232                     case 16: // 高角砲\r
233                         return Color.FromArgb(102, 204, 118);\r
234                     case 17: // 爆雷\r
235                     case 18: // ソナー\r
236                         return Color.FromArgb(126, 203, 215);\r
237                     case 19: // 缶\r
238                         return Color.FromArgb(254, 195, 77);\r
239                     case 20: // 大発\r
240                     case 36: // 特型内火艇\r
241                         return Color.FromArgb(154, 163, 90);\r
242                     case 21: // オートジャイロ\r
243                         return Color.FromArgb(99, 203, 115);\r
244                     case 22: // 対潜哨戒機\r
245                         return Color.FromArgb(125, 205, 217);\r
246                     case 23: // 追加装甲\r
247                         return Color.FromArgb(152, 124, 172);\r
248                     case 24: // 探照灯\r
249                     case 27: // 照明弾\r
250                         return Color.FromArgb(254, 155, 0);\r
251                     case 25: // ドラム缶\r
252                         return Color.FromArgb(161, 161, 160);\r
253                     case 26: // 艦艇修理施設\r
254                         return Color.FromArgb(175, 156, 126);\r
255                     case 28: // 司令部施設\r
256                         return Color.FromArgb(204, 172, 252);\r
257                     case 29: // 航空要員\r
258                         return Color.FromArgb(206, 166, 108);\r
259                     case 30: // 高射装置\r
260                         return Color.FromArgb(137, 153, 77);\r
261                     case 31: // 対地装備\r
262                         return Color.FromArgb(253, 49, 49);\r
263                     case 32: // 水上艦要員\r
264                         return Color.FromArgb(188, 238, 155);\r
265                     case 33: // 大型飛行艇\r
266                         return Color.FromArgb(142, 203, 152);\r
267                     case 34: // 戦闘糧食\r
268                         return Color.FromArgb(254, 254, 254);\r
269                     case 35: // 補給物資\r
270                         return Color.FromArgb(90, 200, 155);\r
271                     case 37: // 陸上攻撃機\r
272                     case 38: // 局地戦闘機\r
273                     case 44: // 陸軍戦闘機\r
274                         return Color.FromArgb(57, 182, 78);\r
275                     case 39: // 噴式景雲改\r
276                     case 40: // 橘花改\r
277                         return Color.FromArgb(72, 178, 141);\r
278                     case 42: // 潜水艦機材\r
279                         return Color.FromArgb(158, 187, 226);\r
280                     case 45: // 夜間戦闘機\r
281                     case 46: // 夜間攻撃機\r
282                         return Color.FromArgb(128, 121, 161);\r
283                     default:\r
284                         return SystemColors.Control;\r
285                 }\r
286             }\r
287         }\r
288     }\r
289 \r
290     public class ItemStatus\r
291     {\r
292         public int Id { get; set; }\r
293         public ItemSpec Spec { get; set; } = new ItemSpec();\r
294         public int Level { get; set; }\r
295         public int Alv { get; set; }\r
296         public ShipStatus Holder { get; set; }\r
297 \r
298         public ItemStatus()\r
299         {\r
300             Id = -1;\r
301         }\r
302 \r
303         public ItemStatus(int id)\r
304         {\r
305             Id = id;\r
306         }\r
307 \r
308         private readonly double[] _alvBonusMin =\r
309         {\r
310             Sqrt(0.0), Sqrt(1.0), Sqrt(2.5), Sqrt(4.0), Sqrt(5.5), Sqrt(7.0),\r
311             Sqrt(8.5), Sqrt(10.0)\r
312         };\r
313 \r
314         private readonly double[] _alvBonusMax =\r
315         {\r
316             Sqrt(0.9), Sqrt(2.4), Sqrt(3.9), Sqrt(5.4), Sqrt(6.9), Sqrt(8.4),\r
317             Sqrt(9.9), Sqrt(12.0)\r
318         };\r
319 \r
320         private int[] AlvTypeBonusTable\r
321         {\r
322             get\r
323             {\r
324                 switch (Spec.Type)\r
325                 {\r
326                     case 6: // 艦戦\r
327                     case 45: // 水戦\r
328                     case 48: // 局地戦闘機\r
329                     case 56: // 噴式戦闘機\r
330                         return new[] {0, 0, 2, 5, 9, 14, 14, 22};\r
331                     case 7: // 艦爆\r
332                     case 8: // 艦攻\r
333                     case 47: // 陸攻\r
334                     case 57: // 噴式戦闘爆撃機\r
335                     case 58: // 噴式攻撃機\r
336                         return new[] {0, 0, 0, 0, 0, 0, 0, 0};\r
337                     case 11: // 水爆\r
338                         return new[] {0, 0, 1, 1, 1, 3, 3, 6};\r
339                     default:\r
340                         return null;\r
341                 }\r
342             }\r
343         }\r
344 \r
345         public double[] AlvBonus\r
346         {\r
347             get\r
348             {\r
349                 var table = AlvTypeBonusTable;\r
350                 if (table == null)\r
351                     return new[] {0.0, 0.0};\r
352                 return new[] {table[Alv] + _alvBonusMin[Alv], table[Alv] + _alvBonusMax[Alv]};\r
353             }\r
354         }\r
355 \r
356         public double[] AlvBonusInBase\r
357         {\r
358             get\r
359             {\r
360                 switch (Spec.Type)\r
361                 {\r
362                     case 9: // 艦偵\r
363                     case 10: // 水偵\r
364                     case 41: // 大艇\r
365                         return new[] {_alvBonusMin[Alv], _alvBonusMax[Alv]};\r
366                     default:\r
367                         return AlvBonus;\r
368                 }\r
369             }\r
370         }\r
371 \r
372         public double FighterPowerLevelBonus\r
373         {\r
374             get\r
375             {\r
376                 switch (Spec.Type)\r
377                 {\r
378                     case 6: // 艦戦\r
379                     case 45: // 水戦\r
380                         return 0.2 * Level;\r
381                     case 7: // 改修可能なのは爆戦のみ\r
382                         return 0.25 * Level;\r
383                 }\r
384                 return 0;\r
385             }\r
386         }\r
387 \r
388         public double LoSLevelBonus\r
389         {\r
390             get\r
391             {\r
392                 switch (Spec.Type)\r
393                 {\r
394                     case 10: // 水偵\r
395                         return 1.2 * Sqrt(Level);\r
396                     case 12: // 小型電探\r
397                     case 13: // 大型電探\r
398                         return 1.25 * Sqrt(Level);\r
399                     default:\r
400                         return 0;\r
401                 }\r
402             }\r
403         }\r
404 \r
405         public double FirePowerLevelBonus\r
406         {\r
407             get\r
408             {\r
409                 switch (Spec.Type)\r
410                 {\r
411                     case 1: // 小口径\r
412                     case 2: // 中口径\r
413                         return Sqrt(Level);\r
414                     case 3: // 大口径\r
415                         return 1.5 * Sqrt(Level);\r
416                     case 4: // 副砲\r
417                         return Sqrt(Level);\r
418                     case 14: // ソナー\r
419                     case 15: // 爆雷\r
420                         return 0.75 * Sqrt(Level);\r
421                     case 19: // 徹甲弾\r
422                         return Sqrt(Level);\r
423                     default:\r
424                         return 0;\r
425                 }\r
426             }\r
427         }\r
428 \r
429         public double TorpedoLevelBonus\r
430         {\r
431             get\r
432             {\r
433                 if (Spec.Type == 5) // 魚雷\r
434                     return 1.2 * Sqrt(Level);\r
435                 if (Spec.Type == 21) // 機銃\r
436                     return 1.2 * Sqrt(Level);\r
437                 return 0;\r
438             }\r
439         }\r
440 \r
441         public double AntiSubmarineLevelBonus\r
442         {\r
443             get\r
444             {\r
445                 switch (Spec.Type)\r
446                 {\r
447                     case 14:\r
448                     case 15:\r
449                         return Sqrt(Level);\r
450                     default:\r
451                         return 0;\r
452                 }\r
453             }\r
454         }\r
455 \r
456         public double BomberLevelBonus => Spec.Type == 11 /* 水爆 */ ? 0.2 * Level : 0;\r
457 \r
458         public double NightBattleLevelBonus\r
459         {\r
460             get\r
461             {\r
462                 switch (Spec.Type)\r
463                 {\r
464                     case 1: // 小口径\r
465                     case 2: // 中口径\r
466                     case 3: // 大口径\r
467                         return Sqrt(Level);\r
468                     case 4: // 副砲\r
469                         return Sqrt(Level);\r
470                     case 5: // 魚雷\r
471                     case 19: // 徹甲弾\r
472                     case 29: // 探照灯\r
473                     case 36: // 高射装置\r
474                     case 42: // 大型探照灯\r
475                         return Sqrt(Level);\r
476                     default:\r
477                         return 0;\r
478                 }\r
479             }\r
480         }\r
481 \r
482         public double EffectiveAntiAirForShip\r
483         {\r
484             get\r
485             {\r
486                 switch (Spec.IconType)\r
487                 {\r
488                     case 15: // 機銃\r
489                         return 6 * Spec.AntiAir + 4 * Sqrt(Level);\r
490                     case 16: // 高角砲\r
491                         return 4 * Spec.AntiAir + 3 * Sqrt(Level);\r
492                     case 11: // 電探\r
493                         return 3 * Spec.AntiAir;\r
494                     case 30: // 高射装置\r
495                         return 4 * Spec.AntiAir;\r
496                 }\r
497                 return 0;\r
498             }\r
499         }\r
500 \r
501         public double EffectiveAntiAirForFleet\r
502         {\r
503             get\r
504             {\r
505                 switch (Spec.IconType)\r
506                 {\r
507                     case 1:\r
508                     case 2:\r
509                     case 3: // 主砲\r
510                     case 4: // 副砲\r
511                     case 6: // 艦戦\r
512                     case 7: // 艦爆\r
513                     case 15: // 機銃\r
514                         return 0.2 * Spec.AntiAir;\r
515                     case 11: // 電探\r
516                         return 0.4 * Spec.AntiAir + 1.5 * Sqrt(Level);\r
517                     case 12: // 三式弾\r
518                         return 0.6 * Spec.AntiAir;\r
519                     case 16: // 高角砲\r
520                         return 0.35 * Spec.AntiAir + 3 * Sqrt(Level);\r
521                     case 30: // 高射装置\r
522                         return 0.35 * Spec.AntiAir;\r
523                     default:\r
524                         if (Spec.Type == 10) // 水偵\r
525                             return 0.2 * Spec.AntiAir;\r
526                         break;\r
527                 }\r
528                 return 0;\r
529             }\r
530         }\r
531     }\r
532 \r
533     public class ItemInfo\r
534     {\r
535         private int _nowShips, _nowEquips;\r
536         private readonly Dictionary<int, ItemSpec> _itemSpecs = new Dictionary<int, ItemSpec>();\r
537         private readonly Dictionary<int, ItemStatus> _itemInfo = new Dictionary<int, ItemStatus>();\r
538         private readonly Dictionary<int, string> _useItemName = new Dictionary<int, string>();\r
539 \r
540         public int MaxShips { get; private set; }\r
541         public int MarginShips { get; set; }\r
542         public bool RingShips { get; set; }\r
543         public int MaxEquips { get; private set; }\r
544         public int MarginEquips { get; set; }\r
545         public bool RingEquips { get; set; }\r
546 \r
547         public int NowShips\r
548         {\r
549             get => _nowShips;\r
550             set\r
551             {\r
552                 if (MaxShips != 0)\r
553                 {\r
554                     var limit = MaxShips - MarginShips;\r
555                     RingShips = RingShips || _nowShips < limit && value >= limit;\r
556                 }\r
557                 _nowShips = value;\r
558             }\r
559         }\r
560 \r
561         public bool TooManyShips => MaxShips != 0 && NowShips >= MaxShips - MarginShips;\r
562 \r
563         public int NowEquips\r
564         {\r
565             get => _nowEquips;\r
566             private set\r
567             {\r
568                 if (MaxEquips != 0)\r
569                 {\r
570                     var limit = MaxEquips - MarginEquips;\r
571                     RingEquips = RingEquips || _nowEquips < limit && value >= limit;\r
572                 }\r
573                 _nowEquips = value;\r
574             }\r
575         }\r
576 \r
577         public bool TooManyEquips => MaxEquips != 0 && NowEquips >= MaxEquips - MarginEquips;\r
578 \r
579         public ItemInfo()\r
580         {\r
581             MarginShips = 4;\r
582             MarginEquips = 10;\r
583         }\r
584 \r
585         public void InspectBasic(dynamic json)\r
586         {\r
587             MaxShips = (int)json.api_max_chara;\r
588             var check = MaxEquips == 0;\r
589             MaxEquips = (int)json.api_max_slotitem;\r
590             if (check)\r
591                 RingEquips = NowEquips >= MaxEquips - MarginEquips;\r
592         }\r
593 \r
594         public void InspectMaster(dynamic json)\r
595         {\r
596             var dict = new Dictionary<int, string>();\r
597             foreach (var entry in json.api_mst_slotitem_equiptype)\r
598                 dict[(int)entry.api_id] = entry.api_name;\r
599             foreach (var entry in json.api_mst_slotitem)\r
600             {\r
601                 var type = (int)entry.api_type[2];\r
602                 _itemSpecs[(int)entry.api_id] = new ItemSpec\r
603                 {\r
604                     Id = (int)entry.api_id,\r
605                     Name = (string)entry.api_name,\r
606                     Type = type,\r
607                     TypeName = dict.TryGetValue(type, out var typeName) ? typeName : "不明",\r
608                     IconType = (int)entry.api_type[3],\r
609                     AntiAir = (int)entry.api_tyku,\r
610                     LoS = (int)entry.api_saku,\r
611                     AntiSubmarine = (int)entry.api_tais,\r
612                     Torpedo = (int)entry.api_raig,\r
613                     Bomber = (int)entry.api_baku,\r
614                     Interception = type == 48 ? (int)entry.api_houk : 0, // 局地戦闘機は回避の値が迎撃\r
615                     AntiBomber = type == 48 ? (int)entry.api_houm : 0 // 〃命中の値が対爆\r
616                 };\r
617             }\r
618             _itemSpecs[-1] = _itemSpecs[0] = new ItemSpec();\r
619             foreach (var entry in json.api_mst_useitem)\r
620                 _useItemName[(int)entry.api_id] = entry.api_name;\r
621         }\r
622 \r
623         public void InspectSlotItem(dynamic json, bool full = false)\r
624         {\r
625             if (!json.IsArray)\r
626                 json = new[] {json};\r
627             if (full)\r
628             {\r
629                 _itemInfo.Clear();\r
630                 _itemInfo[-1] = new ItemStatus();\r
631             }\r
632             foreach (var entry in json)\r
633             {\r
634                 var id = (int)entry.api_id;\r
635                 _itemInfo[id] = new ItemStatus(id)\r
636                 {\r
637                     Spec = _itemSpecs[(int)entry.api_slotitem_id],\r
638                     Level = entry.api_level() ? (int)entry.api_level : 0,\r
639                     Alv = entry.api_alv() ? (int)entry.api_alv : 0\r
640                 };\r
641             }\r
642             NowEquips = _itemInfo.Count - 1;\r
643         }\r
644 \r
645         public void InspectCreateItem(dynamic json)\r
646         {\r
647             if (!json.IsDefined("api_slot_item"))\r
648                 return;\r
649             InspectSlotItem(json.api_slot_item);\r
650         }\r
651 \r
652         public void InspectGetShip(dynamic json)\r
653         {\r
654             NowShips += 1;\r
655             if (json.api_slotitem == null) // まるゆにはスロットがない\r
656                 return;\r
657             InspectSlotItem(json.api_slotitem);\r
658         }\r
659 \r
660         public void InspectDestroyItem(string request, dynamic json)\r
661         {\r
662             var values = HttpUtility.ParseQueryString(request);\r
663             DeleteItems(values["api_slotitem_ids"].Split(',').Select(int.Parse).ToArray());\r
664         }\r
665 \r
666         public void InspectRemodelSlot(dynamic json)\r
667         {\r
668             if (json.api_after_slot())\r
669                 InspectSlotItem(json.api_after_slot);\r
670             if (!json.api_use_slot_id())\r
671                 return;\r
672             DeleteItems((int[])json.api_use_slot_id);\r
673         }\r
674 \r
675         public void DeleteItems(ItemStatus[] items)\r
676         {\r
677             DeleteItems(items.Select(item => item.Id));\r
678         }\r
679 \r
680         private void DeleteItems(IEnumerable<int> ids)\r
681         {\r
682             foreach (var id in ids.Where(id => id != -1))\r
683             {\r
684                 _itemInfo.Remove(id);\r
685                 NowEquips--;\r
686             }\r
687         }\r
688 \r
689         public ItemSpec GetSpecByItemId(int id) => _itemSpecs[id];\r
690 \r
691         public string GetName(int id) => GetStatus(id).Spec.Name;\r
692 \r
693         public ItemStatus GetStatus(int id)\r
694         {\r
695             return _itemInfo.TryGetValue(id, out var item) ? item : new ItemStatus(id);\r
696         }\r
697 \r
698         public void ClearHolder()\r
699         {\r
700             foreach (var item in _itemInfo.Values)\r
701                 item.Holder = new ShipStatus();\r
702         }\r
703 \r
704         public ItemStatus[] ItemList => (from e in _itemInfo where e.Key != -1 select e.Value).ToArray();\r
705 \r
706         public string GetUseItemName(int id) => _useItemName[id];\r
707     }\r
708 }