OSDN Git Service

出撃から帰投したときの資材の増減が正しく表示されないのを直す
[kancollesniffer/KancolleSniffer.git] / KancolleSniffer / BaseAirCoprs.cs
1 // Copyright (C) 2016 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.Collections.Generic;\r
17 using System.Collections.Specialized;\r
18 using System.Linq;\r
19 using static System.Math;\r
20 \r
21 namespace KancolleSniffer\r
22 {\r
23     public class BaseAirCoprs\r
24     {\r
25         private readonly ItemInfo _itemInfo;\r
26         private List<int> _relocationgPlanes = new List<int>();\r
27 \r
28         public BaseAirCoprs(ItemInfo item)\r
29         {\r
30             _itemInfo = item;\r
31         }\r
32 \r
33         public BaseInfo[] AllAirCorps { get; set; }\r
34 \r
35         public class BaseInfo\r
36         {\r
37             public int AreaId { get; set; }\r
38             public string AreaName => AreaId == 6 ? "中部海域" : "限定海域";\r
39             public AirCorpsInfo[] AirCorps { get; set; }\r
40         }\r
41 \r
42         public class AirCorpsInfo\r
43         {\r
44             public int Distance { get; set; }\r
45             public int Action { get; set; }\r
46             public PlaneInfo[] Planes { get; set; }\r
47 \r
48             public string ActionName\r
49             {\r
50                 get\r
51                 {\r
52                     switch (Action)\r
53                     {\r
54                         case 0:\r
55                             return "待機";\r
56                         case 1:\r
57                             return "出撃";\r
58                         case 2:\r
59                             return "防空";\r
60                         case 3:\r
61                             return "退避";\r
62                         case 4:\r
63                             return "休息";\r
64                         default:\r
65                             return "";\r
66                     }\r
67                 }\r
68             }\r
69 \r
70             public int[] FighterPower\r
71             {\r
72                 get\r
73                 {\r
74                     var airDefenceBonus = Action == 2\r
75                             ? Planes.Select(plane => plane.Slot.Spec.AirDefenceBonus).Max()\r
76                             : 1.0;\r
77                     var fighterPower = Planes.Aggregate(new[] {0, 0}, (prev, plane) =>\r
78                     {\r
79                         if (plane.State != 1)\r
80                             return prev;\r
81                         var slot = plane.Slot;\r
82                         var intercepterBonus = Action == 2\r
83                             ? slot.Spec.AntiBomber * 2 + slot.Spec.Interception\r
84                             : slot.Spec.Interception * 1.5;\r
85                         var unskilled = (slot.Spec.AntiAir + intercepterBonus + slot.FighterPowerLevelBonus) *\r
86                                         Sqrt(plane.Count);\r
87                         return new[]\r
88                         {\r
89                             prev[0] + (int)(unskilled + slot.AlvBonusInBase[0]),\r
90                             prev[1] + (int)(unskilled + slot.AlvBonusInBase[1])\r
91                         };\r
92                     });\r
93                     return new[]\r
94                     {\r
95                         (int)(fighterPower[0] * airDefenceBonus),\r
96                         (int)(fighterPower[1] * airDefenceBonus)\r
97                     };\r
98                 }\r
99             }\r
100         }\r
101 \r
102         public class PlaneInfo\r
103         {\r
104             public int State { get; set; }\r
105             public ItemStatus Slot { get; set; }\r
106             public int Count { get; set; }\r
107             public int MaxCount { get; set; }\r
108 \r
109             public string StateName\r
110             {\r
111                 get\r
112                 {\r
113                     switch (State)\r
114                     {\r
115                         case 0:\r
116                             return "未配備";\r
117                         case 1:\r
118                             return "配備中";\r
119                         case 2:\r
120                             return "配置転換中";\r
121                         default:\r
122                             return "";\r
123                     }\r
124                 }\r
125             }\r
126         }\r
127 \r
128         public void Inspect(dynamic json)\r
129         {\r
130             AllAirCorps = (from entry in (dynamic[])json\r
131                 group\r
132                 new AirCorpsInfo\r
133                 {\r
134                     Distance = (int)entry.api_distance,\r
135                     Action = (int)entry.api_action_kind,\r
136                     Planes = (from plane in (dynamic[])entry.api_plane_info\r
137                         select new PlaneInfo\r
138                         {\r
139                             Slot = _itemInfo.GetStatus((int)plane.api_slotid),\r
140                             State = (int)plane.api_state,\r
141                             Count = plane.api_count() ? (int)plane.api_count : 0,\r
142                             MaxCount = plane.api_max_count() ? (int)plane.api_max_count : 0,\r
143                         }).ToArray()\r
144                 } by entry.api_area_id() ? (int)entry.api_area_id : 0\r
145                 into grp\r
146                 select new BaseInfo {AreaId = grp.Key, AirCorps = grp.ToArray()}).ToArray();\r
147         }\r
148 \r
149         public void InspectSetPlane(string request, dynamic json)\r
150         {\r
151             if (AllAirCorps == null)\r
152                 return;\r
153             var values = HttpUtility.ParseQueryString(request);\r
154             var airCorps = GetBaseInfo(values).AirCorps[int.Parse(values["api_base_id"]) - 1];\r
155             if (json.api_distance()) // 2016春イベにはない\r
156                 airCorps.Distance = (int)json.api_distance;\r
157             foreach (var planeInfo in json.api_plane_info)\r
158             {\r
159                 var planeId = (int)planeInfo.api_squadron_id - 1;\r
160                 var prev = airCorps.Planes[planeId];\r
161                 if (prev.Slot.Id != -1)\r
162                     _relocationgPlanes.Add(prev.Slot.Id);\r
163                 airCorps.Planes[planeId] = new PlaneInfo\r
164                 {\r
165                     Slot = _itemInfo.GetStatus((int)planeInfo.api_slotid),\r
166                     State = (int)planeInfo.api_state,\r
167                     Count = planeInfo.api_count() ? (int)planeInfo.api_count : 0,\r
168                     MaxCount = planeInfo.api_max_count() ? (int)planeInfo.api_max_count : 0,\r
169                 };\r
170             }\r
171         }\r
172 \r
173         public void InspectSupply(string request, dynamic json)\r
174         {\r
175             InspectSetPlane(request, json);\r
176         }\r
177 \r
178         public void InspectSetAction(string request)\r
179         {\r
180             if (AllAirCorps == null)\r
181                 return;\r
182             var values = HttpUtility.ParseQueryString(request);\r
183             var airCorps = GetBaseInfo(values).AirCorps;\r
184             foreach (var entry in\r
185                 values["api_base_id"].Split(',')\r
186                     .Zip(values["api_action_kind"].Split(','), (b, a) => new {baseId = b, action = a}))\r
187             {\r
188                 airCorps[int.Parse(entry.baseId) - 1].Action = int.Parse(entry.action);\r
189             }\r
190         }\r
191 \r
192         public void InspectExpandBase(string request, dynamic json)\r
193         {\r
194             var values = HttpUtility.ParseQueryString(request);\r
195             var baseInfo = GetBaseInfo(values);\r
196             var airCorps = baseInfo.AirCorps;\r
197             Array.Resize(ref airCorps, airCorps.Length + 1);\r
198             baseInfo.AirCorps = airCorps;\r
199             airCorps[airCorps.Length - 1] = new AirCorpsInfo\r
200             {\r
201                 Planes =\r
202                     ((dynamic[])json[0].api_plane_info).\r
203                         Select(plane => new PlaneInfo {Slot = new ItemStatus()}).ToArray()\r
204             };\r
205         }\r
206 \r
207         private BaseInfo GetBaseInfo(NameValueCollection values)\r
208         {\r
209             var areaId = int.Parse(values["api_area_id"] ?? "0"); // 古いAPIに対応するため\r
210             return AllAirCorps.First(b => b.AreaId == areaId);\r
211         }\r
212 \r
213         public void InspectPlaneInfo(dynamic json)\r
214         {\r
215             _relocationgPlanes = json.api_base_convert_slot()\r
216                 ? new List<int>((int[])json.api_base_convert_slot)\r
217                 : new List<int>();\r
218         }\r
219 \r
220         public void InspectEventObject(dynamic json)\r
221         {\r
222             InspectPlaneInfo(json);\r
223         }\r
224 \r
225         public void SetItemHolder()\r
226         {\r
227             if (AllAirCorps == null)\r
228                 return;\r
229             var name = new[] {"第一", "第二", "第三"};\r
230             var i = 0;\r
231             foreach (var baseInfo in AllAirCorps)\r
232             {\r
233                 var areaAame = baseInfo.AreaName;\r
234                 foreach (var airCorps in baseInfo.AirCorps)\r
235                 {\r
236                     if (i >= name.Length)\r
237                         break;\r
238                     var ship = new ShipStatus\r
239                     {\r
240                         Id = 1000 + i,\r
241                         Spec = new ShipSpec {Name = areaAame + " " + name[i++] + "航空隊"}\r
242                     };\r
243                     foreach (var plane in airCorps.Planes)\r
244                     {\r
245                         if (plane.State != 1)\r
246                             continue;\r
247                         _itemInfo.GetStatus(plane.Slot.Id).Holder = ship;\r
248                     }\r
249                 }\r
250             }\r
251             if (_relocationgPlanes == null)\r
252                 return;\r
253             var relocating = new ShipStatus {Id = 1500, Spec = new ShipSpec {Name = "配置転換中"}};\r
254             foreach (var id in _relocationgPlanes)\r
255                 _itemInfo.GetStatus(id).Holder = relocating;\r
256         }\r
257     }\r
258 }