1 // Copyright (C) 2016 Kazuhiro Fujieda <fujieda@users.osdn.me>
\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
7 // http://www.apache.org/licenses/LICENSE-2.0
\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
16 using System.Collections.Generic;
\r
17 using System.Collections.Specialized;
\r
19 using KancolleSniffer.Util;
\r
21 namespace KancolleSniffer.Model
\r
23 public class BaseAirCoprs
\r
25 private readonly ItemInfo _itemInfo;
\r
26 private List<int> _relocationgPlanes = new List<int>();
\r
28 public BaseAirCoprs(ItemInfo item)
\r
33 public BaseInfo[] AllAirCorps { get; set; }
\r
35 public class BaseInfo
\r
37 public int AreaId { get; set; }
\r
38 public string AreaName => AreaId == 6 ? "中部海域" : "限定海域";
\r
39 public AirCorpsInfo[] AirCorps { get; set; }
\r
42 public class FighterPower
\r
44 public int[] AirCombat { get; set; }
\r
45 public int[] Interception { get; set; }
\r
46 public bool IsInterceptor => AirCombat[0] != Interception[0];
\r
49 public class AirCorpsInfo
\r
51 public int Distance { get; set; }
\r
52 public int Action { get; set; }
\r
53 public PlaneInfo[] Planes { get; set; }
\r
55 public string ActionName
\r
77 public FighterPower FighterPower =>
\r
78 new FighterPower {AirCombat = CalcFighterPower(false), Interception = CalcFighterPower(true)};
\r
80 private int[] CalcFighterPower(bool interception)
\r
82 var reconPlaneBonus = interception
\r
83 ? Planes.Max(plane => plane.Slot.Spec.ReconPlaneInterceptionBonus)
\r
85 return Planes.Aggregate(new[] {0, 0}, (prev, plane) =>
\r
87 if (plane.State != 1)
\r
89 var cur = plane.Slot.CalcFighterPowerInBase(plane.Count, interception);
\r
90 return new[] {prev[0] + cur[0], prev[1] + cur[1]};
\r
91 }).Select(fp => (int)(fp * reconPlaneBonus)).ToArray();
\r
94 public int[] CostForSortie => Planes.Aggregate(new[] {0, 0}, (prev, plane) =>
\r
96 if (plane.State != 1)
\r
99 if (plane.Slot.Spec.Type == 47)
\r
101 fuel = (int)Math.Ceiling(plane.Count * 1.5);
\r
102 bull = (int)(plane.Count * 0.7);
\r
106 fuel = plane.Count;
\r
107 bull = (int)Math.Ceiling(plane.Count * 0.6);
\r
109 return new[] {prev[0] + fuel, prev[1] + bull};
\r
113 public class PlaneInfo
\r
115 public int State { get; set; }
\r
116 public ItemStatus Slot { get; set; }
\r
117 public int Count { get; set; }
\r
118 public int MaxCount { get; set; }
\r
120 public string StateName
\r
138 public FighterPower FighterPower
\r
139 => new FighterPower{AirCombat = CalcFighterPower(false), Interception = CalcFighterPower(true)};
\r
141 private int[] CalcFighterPower(bool interception) => Slot.CalcFighterPowerInBase(Count, interception);
\r
144 public void Inspect(dynamic json)
\r
146 AllAirCorps = (from entry in (dynamic[])json
\r
150 Distance = (int)entry.api_distance,
\r
151 Action = (int)entry.api_action_kind,
\r
152 Planes = (from plane in (dynamic[])entry.api_plane_info
\r
153 select new PlaneInfo
\r
155 Slot = _itemInfo.GetStatus((int)plane.api_slotid),
\r
156 State = (int)plane.api_state,
\r
157 Count = plane.api_count() ? (int)plane.api_count : 0,
\r
158 MaxCount = plane.api_max_count() ? (int)plane.api_max_count : 0,
\r
160 } by entry.api_area_id() ? (int)entry.api_area_id : 0
\r
162 select new BaseInfo {AreaId = grp.Key, AirCorps = grp.ToArray()}).ToArray();
\r
165 public void InspectSetPlane(string request, dynamic json)
\r
167 if (AllAirCorps == null)
\r
169 var values = HttpUtility.ParseQueryString(request);
\r
170 var airCorps = GetBaseInfo(values).AirCorps[int.Parse(values["api_base_id"]) - 1];
\r
171 if (json.api_distance()) // 2016春イベにはない
\r
172 airCorps.Distance = (int)json.api_distance;
\r
173 foreach (var planeInfo in json.api_plane_info)
\r
175 var planeId = (int)planeInfo.api_squadron_id - 1;
\r
176 var prev = airCorps.Planes[planeId];
\r
177 if (!prev.Slot.Empty)
\r
178 _relocationgPlanes.Add(prev.Slot.Id);
\r
179 airCorps.Planes[planeId] = new PlaneInfo
\r
181 Slot = _itemInfo.GetStatus((int)planeInfo.api_slotid),
\r
182 State = (int)planeInfo.api_state,
\r
183 Count = planeInfo.api_count() ? (int)planeInfo.api_count : 0,
\r
184 MaxCount = planeInfo.api_max_count() ? (int)planeInfo.api_max_count : 0
\r
189 public void InspectSupply(string request, dynamic json)
\r
191 InspectSetPlane(request, json);
\r
194 public void InspectSetAction(string request)
\r
196 if (AllAirCorps == null)
\r
198 var values = HttpUtility.ParseQueryString(request);
\r
199 var airCorps = GetBaseInfo(values).AirCorps;
\r
200 foreach (var entry in
\r
201 values["api_base_id"].Split(',')
\r
202 .Zip(values["api_action_kind"].Split(','), (b, a) => new {baseId = b, action = a}))
\r
204 airCorps[int.Parse(entry.baseId) - 1].Action = int.Parse(entry.action);
\r
208 public void InspectExpandBase(string request, dynamic json)
\r
210 var values = HttpUtility.ParseQueryString(request);
\r
211 var baseInfo = GetBaseInfo(values);
\r
212 var airCorps = baseInfo.AirCorps;
\r
213 Array.Resize(ref airCorps, airCorps.Length + 1);
\r
214 baseInfo.AirCorps = airCorps;
\r
215 airCorps[airCorps.Length - 1] = new AirCorpsInfo
\r
218 ((dynamic[])json[0].api_plane_info).
\r
219 Select(plane => new PlaneInfo {Slot = new ItemStatus()}).ToArray()
\r
223 private BaseInfo GetBaseInfo(NameValueCollection values)
\r
225 var areaId = int.Parse(values["api_area_id"] ?? "0"); // 古いAPIに対応するため
\r
226 return AllAirCorps.First(b => b.AreaId == areaId);
\r
229 public void InspectPlaneInfo(dynamic json)
\r
231 _relocationgPlanes = json.api_base_convert_slot()
\r
232 ? new List<int>((int[])json.api_base_convert_slot)
\r
236 public void InspectEventObject(dynamic json)
\r
238 InspectPlaneInfo(json);
\r
241 public void SetItemHolder()
\r
243 if (AllAirCorps == null)
\r
245 var name = new[] {"第一", "第二", "第三"};
\r
246 foreach (var baseInfo in AllAirCorps.Select((data, i) => new {data, i}))
\r
248 var areaAame = baseInfo.data.AreaName;
\r
249 foreach (var airCorps in baseInfo.data.AirCorps.Select((data, i) => new {data, i}))
\r
251 var ship = new ShipStatus
\r
253 Id = 10000 + baseInfo.i * 1000 + airCorps.i,
\r
254 Spec = new ShipSpec {Name = areaAame + " " + name[airCorps.i] + "航空隊"}
\r
256 foreach (var plane in airCorps.data.Planes)
\r
258 if (plane.State != 1)
\r
260 _itemInfo.GetStatus(plane.Slot.Id).Holder = ship;
\r
264 if (_relocationgPlanes == null)
\r
266 var relocating = new ShipStatus {Id = 1500, Spec = new ShipSpec {Name = "配置転換中"}};
\r
267 foreach (var id in _relocationgPlanes)
\r
268 _itemInfo.GetStatus(id).Holder = relocating;
\r