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;\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 NeedRing { get; set; }\r
39         public int NowItems { get; set; }\r
40         public int MaxItems { get; private set; }\r
41         public MaterialCount[] MaterialHistory { get; private set; }\r
42 \r
43         public int NowShips\r
44         {\r
45             get { return _nowShips; }\r
46             set\r
47             {\r
48                 if (MaxShips != 0)\r
49                 {\r
50                     var limit = MaxShips - MarginShips;\r
51                     NeedRing = _nowShips < limit && value >= limit;\r
52                 }\r
53                 _nowShips = value;\r
54             }\r
55         }\r
56 \r
57         public bool TooManyShips\r
58         {\r
59             get { return MaxShips != 0 && NowShips >= MaxShips - MarginShips; }\r
60         }\r
61 \r
62         public ItemInfo()\r
63         {\r
64             MaterialHistory = new MaterialCount[Enum.GetValues(typeof (Material)).Length];\r
65             foreach (Material m in Enum.GetValues(typeof (Material)))\r
66                 MaterialHistory[(int)m] = new MaterialCount();\r
67             MarginShips = 4;\r
68         }\r
69 \r
70         public void InspectBasic(dynamic json)\r
71         {\r
72             MaxShips = (int)json.api_max_chara;\r
73             MaxItems = (int)json.api_max_slotitem;\r
74         }\r
75 \r
76         public void InspectMaterial(dynamic json)\r
77         {\r
78             foreach (var entry in json)\r
79                 MaterialHistory[(int)entry.api_id - 1].Now = (int)entry.api_value;\r
80         }\r
81 \r
82         public void InspectMaster(dynamic json)\r
83         {\r
84             foreach (var entry in json)\r
85             {\r
86                 _itemSpecs[(int)entry.api_id] = new ItemSpec\r
87                 {\r
88                     Name = (string)entry.api_name,\r
89                     TyKu = (int)entry.api_type[0] == 3 || (int)entry.api_type[2] == 11 ? (int)entry.api_tyku : 0\r
90                     // 艦載機と水上爆撃機のみ\r
91                 };\r
92             }\r
93             _itemSpecs[-1] = new ItemSpec();\r
94         }\r
95 \r
96         public void InspectSlotItem(dynamic json, bool full = false)\r
97         {\r
98             if (!json.IsArray)\r
99                 json = new[] {json};\r
100             if (full)\r
101                 NowItems = ((object[])json).Length;\r
102             foreach (var entry in json)\r
103                 _itemIds[(int)entry.api_id] = (int)entry.api_slotitem_id;\r
104             _itemIds[-1] = -1;\r
105         }\r
106 \r
107         public void InspectCreateItem(dynamic json)\r
108         {\r
109             var m = (dynamic[])json.api_material;\r
110             for (var i = 0; i < m.Length; i++)\r
111                 MaterialHistory[i].Now = (int)m[i];\r
112             if (!json.IsDefined("api_slot_item"))\r
113                 return;\r
114             InspectSlotItem(json.api_slot_item);\r
115             NowItems++;\r
116         }\r
117 \r
118         public void InspectGetShip(dynamic json)\r
119         {\r
120             NowShips += 1;\r
121             if (json.api_slotitem == null) // まるゆにはスロットがない\r
122                 return;\r
123             InspectSlotItem(json.api_slotitem);\r
124             NowItems += ((object[])json.api_slotitem).Length;\r
125         }\r
126 \r
127         public void InspectDestroyItem(string request, dynamic json)\r
128         {\r
129             var values = HttpUtility.ParseQueryString(request);\r
130             NowItems -= values["api_slotitem_ids"].Split(',').Length;\r
131             var get = (int[])json.api_get_material;\r
132             for (var i = 0; i < get.Length; i++)\r
133                 MaterialHistory[i].Now += get[i];\r
134         }\r
135 \r
136         public void InspectMissionResult(dynamic json)\r
137         {\r
138             if ((int)json.api_clear_result == 0) // 失敗\r
139                 return;\r
140             var get = (int[])json.api_get_material;\r
141             for (var i = 0; i < get.Length; i++)\r
142                 MaterialHistory[i].Now += get[i];\r
143         }\r
144 \r
145         public ItemSpec this[int id]\r
146         {\r
147             get { return GetSpecById(id); }\r
148         }\r
149 \r
150         public ItemSpec GetSpecById(int id)\r
151         {\r
152             return _itemSpecs[_itemIds[id]];\r
153         }\r
154 \r
155         public ItemSpec GetSpecByItemId(int id)\r
156         {\r
157             return _itemSpecs[id];\r
158         }\r
159 \r
160         public void SaveState(Status status)\r
161         {\r
162             status.MatreialHistory = MaterialHistory;\r
163         }\r
164 \r
165         public void LoadSate(Status status)\r
166         {\r
167             if (status.MatreialHistory != null)\r
168                 status.MatreialHistory.CopyTo(MaterialHistory, 0);\r
169         }\r
170     }\r
171 \r
172     public enum Material\r
173     {\r
174         Fuel,\r
175         Bullet,\r
176         Steal,\r
177         Bouxite,\r
178         Development,\r
179         Bucket,\r
180         Burner,\r
181         Irago,\r
182     }\r
183 \r
184     public class MaterialCount\r
185     {\r
186         private int _now;\r
187 \r
188         public int BegOfDay { get; set; }\r
189         public int BegOfWeek { get; set; }\r
190         public DateTime LastSet { get; set; }\r
191 \r
192         public int Now\r
193         {\r
194             get { return _now; }\r
195             set\r
196             {\r
197                 if (!Status.Restoring) // JSONから値を復旧するときは履歴に触らない\r
198                 {\r
199                     UpdateHistory();\r
200                     LastSet = DateTime.Now;\r
201                 }\r
202                 _now = value;\r
203             }\r
204         }\r
205 \r
206         public void UpdateHistory()\r
207         {\r
208             var morning = DateTime.Today.AddHours(5);\r
209             var dow = (int)morning.DayOfWeek;\r
210             var monday = morning.AddDays(dow == 0 ? -6 : -dow + 1);\r
211             if (DateTime.Now >= morning && LastSet < morning)\r
212                 BegOfDay = _now;\r
213             if (DateTime.Now >= monday && LastSet < monday)\r
214                 BegOfWeek = _now;\r
215         }\r
216     }\r
217 }