1 // Copyright (C) 2013, 2014 Kazuhiro Fujieda <fujieda@users.sourceforge.jp>
\r
3 // This program is part of KancolleSniffer.
\r
5 // KancolleSniffer is free software: you can redistribute it and/or modify
\r
6 // it under the terms of the GNU General Public License as published by
\r
7 // the Free Software Foundation, either version 3 of the License, or
\r
8 // (at your option) any later version.
\r
10 // This program is distributed in the hope that it will be useful,
\r
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
13 // GNU General Public License for more details.
\r
15 // You should have received a copy of the GNU General Public License
\r
16 // along with this program; if not, see <http://www.gnu.org/licenses/>.
\r
19 using System.Collections.Generic;
\r
23 namespace KancolleSniffer
\r
25 public class ItemSpec
\r
30 public string TypeName;
\r
40 public bool CanAirCombat()
\r
53 // http://ch.nicovideo.jp/biikame/blomaga/ar663428
\r
54 public double LoSScaleFactor()
\r
79 public class ItemStatus
\r
81 public ItemSpec Spec { get; set; }
\r
82 public int Level { get; set; }
\r
83 public ShipStatus Ship { get; set; }
\r
87 Spec = new ItemSpec();
\r
88 Ship = new ShipStatus();
\r
92 public class ItemInfo
\r
94 private int _nowShips, _nowEquips;
\r
95 private readonly Dictionary<int, ItemSpec> _itemSpecs = new Dictionary<int, ItemSpec>();
\r
96 private readonly Dictionary<int, ItemStatus> _itemInfo = new Dictionary<int, ItemStatus>();
\r
98 public int MaxShips { get; private set; }
\r
99 public int MarginShips { get; set; }
\r
100 public bool RingShips { get; set; }
\r
101 public int MaxEquips { get; private set; }
\r
102 public int MarginEquips { get; set; }
\r
103 public bool RingEquips { get; set; }
\r
104 public MaterialCount[] MaterialHistory { get; private set; }
\r
106 public bool NeedSave
\r
108 get { return MaterialHistory.Any(m => m.NeedSave); }
\r
111 foreach (var m in MaterialHistory)
\r
112 m.NeedSave = value;
\r
116 public int NowShips
\r
118 get { return _nowShips; }
\r
123 var limit = MaxShips - MarginShips;
\r
124 RingShips = _nowShips < limit && value >= limit;
\r
130 public bool TooManyShips
\r
132 get { return MaxShips != 0 && NowShips >= MaxShips - MarginShips; }
\r
135 public int NowEquips
\r
137 get { return _nowEquips; }
\r
140 if (MaxEquips != 0)
\r
142 var limit = MaxEquips - MarginEquips;
\r
143 RingEquips = _nowEquips < limit && value >= limit;
\r
145 _nowEquips = value;
\r
149 public bool TooManyEquips
\r
151 get { return MaxEquips != 0 && NowEquips >= MaxEquips - MarginEquips; }
\r
156 MaterialHistory = new MaterialCount[Enum.GetValues(typeof (Material)).Length];
\r
157 foreach (Material m in Enum.GetValues(typeof (Material)))
\r
158 MaterialHistory[(int)m] = new MaterialCount();
\r
163 public void InspectBasic(dynamic json)
\r
165 MaxShips = (int)json.api_max_chara;
\r
166 MaxEquips = (int)json.api_max_slotitem;
\r
169 public void InspectMaterial(dynamic json)
\r
171 foreach (var entry in json)
\r
172 MaterialHistory[(int)entry.api_id - 1].Now = (int)entry.api_value;
\r
175 public void InspectMaster(dynamic json)
\r
177 var dict = new Dictionary<int, string>();
\r
178 foreach (var entry in json.api_mst_slotitem_equiptype)
\r
179 dict[(int)entry.api_id] = entry.api_name;
\r
180 foreach (var entry in json.api_mst_slotitem)
\r
182 _itemSpecs[(int)entry.api_id] = new ItemSpec
\r
184 Id = (int)entry.api_id,
\r
185 Name = (string)entry.api_name,
\r
186 Type = (int)entry.api_type[2],
\r
187 TypeName = dict[(int)entry.api_type[2]],
\r
188 AntiAir = (int)entry.api_tyku,
\r
189 LoS = (int)entry.api_saku
\r
192 _itemSpecs[-1] = new ItemSpec();
\r
195 public void InspectSlotItem(dynamic json, bool full = false)
\r
198 json = new[] {json};
\r
202 _itemInfo[-1] = new ItemStatus();
\r
204 foreach (var entry in json)
\r
206 _itemInfo[(int)entry.api_id] = new ItemStatus
\r
208 Spec = _itemSpecs[(int)entry.api_slotitem_id],
\r
209 Level = entry.api_level() ? (int)entry.api_level : 0
\r
212 NowEquips = _itemInfo.Count - 1;
\r
215 public void InspectCreateItem(dynamic json)
\r
217 var m = (dynamic[])json.api_material;
\r
218 for (var i = 0; i < m.Length; i++)
\r
219 MaterialHistory[i].Now = (int)m[i];
\r
220 if (!json.IsDefined("api_slot_item"))
\r
222 InspectSlotItem(json.api_slot_item);
\r
225 public void InspectGetShip(dynamic json)
\r
228 if (json.api_slotitem == null) // まるゆにはスロットがない
\r
230 InspectSlotItem(json.api_slotitem);
\r
233 public void InspectDestroyItem(string request, dynamic json)
\r
235 var values = HttpUtility.ParseQueryString(request);
\r
236 DeleteItems(values["api_slotitem_ids"].Split(',').Select(int.Parse).ToArray());
\r
237 var get = (int[])json.api_get_material;
\r
238 for (var i = 0; i < get.Length; i++)
\r
239 MaterialHistory[i].Now += get[i];
\r
242 public void InspectRemodelSlot(dynamic json)
\r
244 if (json.api_after_slot())
\r
245 InspectSlotItem(json.api_after_slot);
\r
246 if (!json.api_use_slot_id())
\r
248 DeleteItems(((int[])json.api_use_slot_id));
\r
251 public void DeleteItems(int[] ids)
\r
253 foreach (var id in ids.Where(id => id != -1))
\r
255 _itemInfo.Remove(id);
\r
260 public void CountNewItems(int[] ids)
\r
262 foreach (var id in ids.Where(id => id != -1 && !_itemInfo.ContainsKey(id)))
\r
264 _itemInfo[id] = new ItemStatus();
\r
269 public void InspectMissionResult(dynamic json)
\r
271 if ((int)json.api_clear_result == 0) // 失敗
\r
273 var get = (int[])json.api_get_material;
\r
274 for (var i = 0; i < get.Length; i++)
\r
275 MaterialHistory[i].Now += get[i];
\r
278 public ItemSpec this[int id]
\r
280 get { return GetSpecById(id); }
\r
283 public ItemSpec GetSpecById(int id)
\r
285 return _itemInfo[id].Spec;
\r
288 public ItemSpec GetSpecByItemId(int id)
\r
290 return _itemSpecs[id];
\r
293 public ItemStatus[] GetItemList(ShipInfo ship)
\r
295 foreach (var e in _itemInfo)
\r
296 e.Value.Ship = new ShipStatus();
\r
297 foreach (var s in ship.ShipList)
\r
299 foreach (var id in s.Slot)
\r
300 _itemInfo[id].Ship = s;
\r
302 return _itemInfo.Where(e => e.Key != -1).Select(e => e.Value).ToArray();
\r
305 public void SaveState(Status status)
\r
308 status.MatreialHistory = MaterialHistory;
\r
311 public void LoadSate(Status status)
\r
313 if (status.MatreialHistory != null)
\r
314 status.MatreialHistory.CopyTo(MaterialHistory, 0);
\r
318 public enum Material
\r
330 public class MaterialCount
\r
334 public int BegOfDay { get; set; }
\r
335 public int BegOfWeek { get; set; }
\r
336 public DateTime LastSet { get; set; }
\r
337 public bool NeedSave { get; set; }
\r
341 get { return _now; }
\r
346 if (Status.Restoring) // JSONから値を復旧するときは履歴に触らない
\r
350 if (LastSet == DateTime.MinValue)
\r
352 BegOfDay = BegOfWeek = value;
\r
353 LastSet = DateTime.Now;
\r
356 UpdateHistory(prev);
\r
357 LastSet = DateTime.Now;
\r
361 private void UpdateHistory(int prev)
\r
363 var morning = DateTime.Today.AddHours(5);
\r
364 var dow = (int)morning.DayOfWeek;
\r
365 var monday = morning.AddDays(dow == 0 ? -6 : -dow + 1);
\r
366 if (DateTime.Now >= morning && LastSet < morning)
\r
368 if (DateTime.Now >= monday && LastSet < monday)
\r