OSDN Git Service

設定ファイルをこまめに保存する
[kancollesniffer/KancolleSniffer.git] / KancolleSniffer / ShipMaster.cs
1 // Copyright (C) 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 \r
17 namespace KancolleSniffer\r
18 {\r
19     public class ShipMaster\r
20     {\r
21         public const int NumSlots = 5;\r
22         private readonly Dictionary<int, ShipSpec> _shipSpecs = new Dictionary<int, ShipSpec>();\r
23 \r
24         public bool UseOldEnemyId { get; set; }\r
25 \r
26         public void Inspect(dynamic json)\r
27         {\r
28             var dict = new Dictionary<double, string>();\r
29             foreach (var entry in json.api_mst_stype)\r
30                 dict[entry.api_id] = entry.api_name;\r
31             dict[8] = "巡洋戦艦";\r
32             foreach (var entry in json.api_mst_ship)\r
33             {\r
34                 var shipSpec = _shipSpecs[(int)entry.api_id] = new ShipSpec\r
35                 {\r
36                     Id = (int)entry.api_id,\r
37                     SortNo = entry.api_sortno() ? (int)entry.api_sortno : 0,\r
38                     Name = ShipName(entry),\r
39                     FuelMax = entry.api_fuel_max() ? (int)entry.api_fuel_max : 0,\r
40                     BullMax = entry.api_bull_max() ? (int)entry.api_bull_max : 0,\r
41                     SlotNum = (int)entry.api_slot_num,\r
42                     ShipType = (int)entry.api_stype,\r
43                     ShipTypeName = dict[entry.api_stype]\r
44                 };\r
45                 if (entry.api_afterlv())\r
46                 {\r
47                     shipSpec.Remodel.Level = (int)entry.api_afterlv;\r
48                     shipSpec.Remodel.After = int.Parse(entry.api_aftershipid);\r
49                 }\r
50                 shipSpec.MaxEq = entry.api_maxeq()\r
51                     ? entry.api_maxeq\r
52                     : MissingData.MaxEq.TryGetValue(shipSpec.Id + (UseOldEnemyId ? 1000 : 0), out var maxEq)\r
53                         ? maxEq\r
54                         : null;\r
55             }\r
56             _shipSpecs[-1] = new ShipSpec();\r
57             SetRemodelBaseAndStep();\r
58         }\r
59 \r
60         // 深海棲艦の名前にelite/flagshipを付ける\r
61         private string ShipName(dynamic json)\r
62         {\r
63             var name = json.api_name;\r
64             var flagship = json.api_yomi;\r
65             if ((int)json.api_id <= (UseOldEnemyId ? 500 : 1500) || flagship == "-" || flagship == "")\r
66                 return name;\r
67             return name + "(" + flagship + ")";\r
68         }\r
69 \r
70         public ShipSpec GetSpec(int id) => _shipSpecs.TryGetValue(id, out var spec) ? spec : new ShipSpec();\r
71 \r
72         private void SetRemodelBaseAndStep()\r
73         {\r
74             // 改造後のデータをマーク\r
75             foreach (var spec in _shipSpecs.Values)\r
76             {\r
77                 if (spec.Remodel.After == 0)\r
78                     continue;\r
79                 _shipSpecs[spec.Remodel.After].Remodel.Base = 1;\r
80             }\r
81             foreach (var spec in _shipSpecs.Values)\r
82             {\r
83                 if (spec.Remodel.Base != 0)\r
84                     continue;\r
85                 var step = 0;\r
86                 var hash = new HashSet<int> {spec.Id};\r
87                 var s = spec;\r
88                 s.Remodel.Base = spec.Id;\r
89                 while (s.Remodel.After != 0)\r
90                 {\r
91                     s.Remodel.Step = ++step;\r
92                     if (!hash.Add(s.Remodel.After))\r
93                         break;\r
94                     s = _shipSpecs[s.Remodel.After];\r
95                     s.Remodel.Base = spec.Id;\r
96                 }\r
97             }\r
98         }\r
99 \r
100         /// <summary>\r
101         /// テスト用\r
102         /// </summary>\r
103         /// <param name="id"></param>\r
104         public void InjectSpec(int id) => _shipSpecs[id] = new ShipSpec {Id = id};\r
105     }\r
106 \r
107     public class ShipSpec\r
108     {\r
109         public int Id { get; set; }\r
110         public int SortNo { get; set; }\r
111         public string Name { get; set; }\r
112         public int FuelMax { get; set; }\r
113         public int BullMax { get; set; }\r
114         public int SlotNum { get; set; }\r
115         public int[] MaxEq { get; set; }\r
116         public int ShipType { get; set; }\r
117         public string ShipTypeName { get; set; }\r
118         public RemodelInfo Remodel { get; } = new RemodelInfo();\r
119 \r
120         public class RemodelInfo\r
121         {\r
122             public int Level { get; set; }\r
123             public int After { get; set; }\r
124             public int Base { get; set; } // 艦隊晒しページ用\r
125             public int Step { get; set; } // 同上\r
126         }\r
127 \r
128         public ShipSpec()\r
129         {\r
130             Id = -1;\r
131             Name = "";\r
132             MaxEq = new int[0];\r
133         }\r
134 \r
135         public double RepairWeight\r
136         {\r
137             get\r
138             {\r
139                 switch (ShipType)\r
140                 {\r
141                     case 1: // 海防艦\r
142                     case 13: // 潜水艦\r
143                         return 0.5;\r
144                     case 2: // 駆逐艦\r
145                     case 3: // 軽巡洋艦\r
146                     case 4: // 重雷装巡洋艦\r
147                     case 14: // 潜水空母\r
148                     case 16: // 水上機母艦\r
149                     case 17: // 揚陸艦\r
150                     case 21: // 練習巡洋艦\r
151                         return 1.0;\r
152                     case 5: // 重巡洋艦\r
153                     case 6: // 航空巡洋艦\r
154                     case 7: // 軽空母\r
155                     case 8: // 高速戦艦\r
156                     case 20: // 潜水母艦\r
157                         return 1.5;\r
158                     case 9: // 低速戦艦\r
159                     case 10: // 航空戦艦\r
160                     case 11: // 正規空母\r
161                     case 18: // 装甲空母\r
162                     case 19: // 工作艦\r
163                         return 2.0;\r
164                 }\r
165                 return 1.0;\r
166             }\r
167         }\r
168 \r
169         public double TransportPoint\r
170         {\r
171             get\r
172             {\r
173                 switch (ShipType)\r
174                 {\r
175                     case 2:\r
176                         return 5.0;\r
177                     case 3:\r
178                         return Id == 487 ? 10.0 : 2.0; // 鬼怒改二は大発分を加算\r
179                     case 6:\r
180                         return 4.0;\r
181                     case 10:\r
182                         return 7.0;\r
183                     case 15:\r
184                         return 15.0;\r
185                     case 16:\r
186                         return 9.0;\r
187                     case 17:\r
188                         return 12.0;\r
189                     case 20:\r
190                         return 7.0;\r
191                     case 21:\r
192                         return 6.0;\r
193                     default:\r
194                         return 0;\r
195                 }\r
196             }\r
197         }\r
198 \r
199         public bool IsSubmarine => ShipType == 13 || ShipType == 14;\r
200 \r
201         public bool IsAircraftCarrier => ShipType == 7 || ShipType == 11 || ShipType == 18;\r
202 \r
203         public bool IsAntiSubmarine\r
204         {\r
205             get\r
206             {\r
207                 switch (ShipType)\r
208                 {\r
209                     case 1: // 海防艦\r
210                     case 2: // 駆逐\r
211                     case 3: // 軽巡\r
212                     case 4: // 雷巡\r
213                     case 6: // 航巡\r
214                     case 7: // 軽空\r
215                     case 10: // 航戦\r
216                     case 16: // 水母\r
217                     case 17: // 揚陸艦\r
218                     case 21: // 練巡\r
219                     case 22: // 補給艦\r
220                         return true;\r
221                 }\r
222                 return false;\r
223             }\r
224         }\r
225 \r
226         public bool IsRepairShip => ShipType == 19;\r
227     }\r
228 }