OSDN Git Service

装備が多すぎるときに通知する
[kancollesniffer/KancolleSniffer.git] / KancolleSniffer / ItemInfo.cs
1 // Copyright (C) 2013, 2014 Kazuhiro Fujieda <fujieda@users.sourceforge.jp>\r
2 // \r
3 // This program is part of KancolleSniffer.\r
4 //\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
9 //\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
14 //\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
17 \r
18 using System;\r
19 using System.Collections.Generic;\r
20 using System.Web;\r
21 \r
22 namespace KancolleSniffer\r
23 {\r
24     public struct ItemSpec\r
25     {\r
26         public string Name;\r
27         public int TyKu;\r
28     }\r
29 \r
30     public class ItemInfo\r
31     {\r
32         private int _nowShips, _nowEquips;\r
33         private readonly Dictionary<int, ItemSpec> _itemSpecs = new Dictionary<int, ItemSpec>();\r
34         private readonly Dictionary<int, int> _itemIds = new Dictionary<int, int>();\r
35 \r
36         public int MaxShips { get; private set; }\r
37         public int MarginShips { get; set; }\r
38         public bool RingShips { get; set; }\r
39         public int MaxEquips { get; private set; }\r
40         public int MarginEquips { get; set; }\r
41         public bool RingEquips { get; set; }\r
42         public MaterialCount[] MaterialHistory { get; private set; }\r
43 \r
44         public int NowShips\r
45         {\r
46             get { return _nowShips; }\r
47             set\r
48             {\r
49                 if (MaxShips != 0)\r
50                 {\r
51                     var limit = MaxShips - MarginShips;\r
52                     RingShips = _nowShips < limit && value >= limit;\r
53                 }\r
54                 _nowShips = value;\r
55             }\r
56         }\r
57 \r
58         public bool TooManyShips\r
59         {\r
60             get { return MaxShips != 0 && NowShips >= MaxShips - MarginShips; }\r
61         }\r
62 \r
63         public int NowEquips\r
64         {\r
65             get { return _nowEquips; }\r
66             set\r
67             {\r
68                 if (MaxEquips != 0)\r
69                 {\r
70                     var limit = MaxEquips - MarginEquips;\r
71                     RingEquips = _nowEquips < limit && value >= limit;\r
72                 }\r
73                 _nowEquips = value;\r
74             }\r
75         }\r
76 \r
77         public bool TooManyEquips\r
78         {\r
79             get { return MaxEquips != 0 && NowEquips >= MaxEquips - MarginEquips; }\r
80         }\r
81 \r
82         public ItemInfo()\r
83         {\r
84             MaterialHistory = new MaterialCount[Enum.GetValues(typeof (Material)).Length];\r
85             foreach (Material m in Enum.GetValues(typeof (Material)))\r
86                 MaterialHistory[(int)m] = new MaterialCount();\r
87             MarginShips = 4;\r
88         }\r
89 \r
90         public void InspectBasic(dynamic json)\r
91         {\r
92             MaxShips = (int)json.api_max_chara;\r
93             MaxEquips = (int)json.api_max_slotitem;\r
94         }\r
95 \r
96         public void InspectMaterial(dynamic json)\r
97         {\r
98             foreach (var entry in json)\r
99                 MaterialHistory[(int)entry.api_id - 1].Now = (int)entry.api_value;\r
100         }\r
101 \r
102         public void InspectMaster(dynamic json)\r
103         {\r
104             foreach (var entry in json)\r
105             {\r
106                 _itemSpecs[(int)entry.api_id] = new ItemSpec\r
107                 {\r
108                     Name = (string)entry.api_name,\r
109                     TyKu = (int)entry.api_type[0] == 3 || (int)entry.api_type[2] == 11 ? (int)entry.api_tyku : 0\r
110                     // 艦載機と水上爆撃機のみ\r
111                 };\r
112             }\r
113             _itemSpecs[-1] = new ItemSpec();\r
114         }\r
115 \r
116         public void InspectSlotItem(dynamic json, bool full = false)\r
117         {\r
118             if (!json.IsArray)\r
119                 json = new[] {json};\r
120             if (full)\r
121                 NowEquips = ((object[])json).Length;\r
122             foreach (var entry in json)\r
123                 _itemIds[(int)entry.api_id] = (int)entry.api_slotitem_id;\r
124             _itemIds[-1] = -1;\r
125         }\r
126 \r
127         public void InspectCreateItem(dynamic json)\r
128         {\r
129             var m = (dynamic[])json.api_material;\r
130             for (var i = 0; i < m.Length; i++)\r
131                 MaterialHistory[i].Now = (int)m[i];\r
132             if (!json.IsDefined("api_slot_item"))\r
133                 return;\r
134             InspectSlotItem(json.api_slot_item);\r
135             NowEquips++;\r
136         }\r
137 \r
138         public void InspectGetShip(dynamic json)\r
139         {\r
140             NowShips += 1;\r
141             if (json.api_slotitem == null) // まるゆにはスロットがない\r
142                 return;\r
143             InspectSlotItem(json.api_slotitem);\r
144             NowEquips += ((object[])json.api_slotitem).Length;\r
145         }\r
146 \r
147         public void InspectDestroyItem(string request, dynamic json)\r
148         {\r
149             var values = HttpUtility.ParseQueryString(request);\r
150             NowEquips -= values["api_slotitem_ids"].Split(',').Length;\r
151             var get = (int[])json.api_get_material;\r
152             for (var i = 0; i < get.Length; i++)\r
153                 MaterialHistory[i].Now += get[i];\r
154         }\r
155 \r
156         public void InspectMissionResult(dynamic json)\r
157         {\r
158             if ((int)json.api_clear_result == 0) // 失敗\r
159                 return;\r
160             var get = (int[])json.api_get_material;\r
161             for (var i = 0; i < get.Length; i++)\r
162                 MaterialHistory[i].Now += get[i];\r
163         }\r
164 \r
165         public ItemSpec this[int id]\r
166         {\r
167             get { return GetSpecById(id); }\r
168         }\r
169 \r
170         public ItemSpec GetSpecById(int id)\r
171         {\r
172             int itemId;\r
173             if (!_itemIds.TryGetValue(id, out itemId))\r
174                 itemId = -1;\r
175             return _itemSpecs[itemId];\r
176         }\r
177 \r
178         public ItemSpec GetSpecByItemId(int id)\r
179         {\r
180             return _itemSpecs[id];\r
181         }\r
182 \r
183         public void SaveState(Status status)\r
184         {\r
185             status.MatreialHistory = MaterialHistory;\r
186         }\r
187 \r
188         public void LoadSate(Status status)\r
189         {\r
190             if (status.MatreialHistory != null)\r
191                 status.MatreialHistory.CopyTo(MaterialHistory, 0);\r
192         }\r
193     }\r
194 \r
195     public enum Material\r
196     {\r
197         Fuel,\r
198         Bullet,\r
199         Steal,\r
200         Bouxite,\r
201         Development,\r
202         Bucket,\r
203         Burner,\r
204         Irago,\r
205     }\r
206 \r
207     public class MaterialCount\r
208     {\r
209         private int _now;\r
210 \r
211         public int BegOfDay { get; set; }\r
212         public int BegOfWeek { get; set; }\r
213         public DateTime LastSet { get; set; }\r
214 \r
215         public int Now\r
216         {\r
217             get { return _now; }\r
218             set\r
219             {\r
220                 if (!Status.Restoring) // JSONから値を復旧するときは履歴に触らない\r
221                 {\r
222                     UpdateHistory();\r
223                     LastSet = DateTime.Now;\r
224                 }\r
225                 _now = value;\r
226             }\r
227         }\r
228 \r
229         public void UpdateHistory()\r
230         {\r
231             var morning = DateTime.Today.AddHours(5);\r
232             var dow = (int)morning.DayOfWeek;\r
233             var monday = morning.AddDays(dow == 0 ? -6 : -dow + 1);\r
234             if (DateTime.Now >= morning && LastSet < morning)\r
235                 BegOfDay = _now;\r
236             if (DateTime.Now >= monday && LastSet < monday)\r
237                 BegOfWeek = _now;\r
238         }\r
239     }\r
240 }