OSDN Git Service

ヘッダのCondとExpのマウスカーソルを変える
[kancollesniffer/KancolleSniffer.git] / KancolleSniffer / MaterialInfo.cs
1 // Copyright (C) 2015 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.Linq;\r
17 using System.Xml.Serialization;\r
18 \r
19 namespace KancolleSniffer\r
20 {\r
21     public class MaterialInfo : IHaveState\r
22     {\r
23         private bool _inPort;\r
24         private DateTime _lastMission;\r
25 \r
26         public MaterialCount[] MaterialHistory { get; }\r
27         public int[] PrevPort { get; }\r
28         public int[] Current => MaterialHistory.Select(h => h.Now).ToArray();\r
29 \r
30         public MaterialInfo()\r
31         {\r
32             var n = Enum.GetValues(typeof(Material)).Length;\r
33             MaterialHistory = new MaterialCount[n];\r
34             for (var i = 0; i < n; i++)\r
35                 MaterialHistory[i] = new MaterialCount();\r
36             PrevPort = new int[n];\r
37             PrevPort[0] = -1;\r
38         }\r
39 \r
40         public bool NeedSave\r
41         {\r
42             get { return MaterialHistory.Any(m => m.NeedSave); }\r
43             private set\r
44             {\r
45                 foreach (var m in MaterialHistory)\r
46                     m.NeedSave = value;\r
47             }\r
48         }\r
49 \r
50         public void InspectMaterialPort(dynamic json)\r
51         {\r
52             InspectMaterial(json);\r
53             _inPort = true;\r
54             if (PrevPort[0] == -1)\r
55             {\r
56                 // 初期化する\r
57                 for (var i = 0; i < MaterialHistory.Length; i++)\r
58                     PrevPort[i] = MaterialHistory[i].Now;\r
59             }\r
60         }\r
61 \r
62         public void InspectMaterial(dynamic json)\r
63         {\r
64             UpdatePrevPort();\r
65             foreach (var entry in json)\r
66             {\r
67                 var i = (int)entry.api_id - 1;\r
68                 var v = (int)entry.api_value;\r
69                 MaterialHistory[i].Now = v;\r
70             }\r
71         }\r
72 \r
73         // 母港に戻ってから最初に資材に変化があったときに、母港の時点の資材を記録する\r
74         private void UpdatePrevPort()\r
75         {\r
76             if (!_inPort)\r
77                 return;\r
78             for (var i = 0; i < MaterialHistory.Length; i++)\r
79                 PrevPort[i] = MaterialHistory[i].Now;\r
80             _inPort = false;\r
81         }\r
82 \r
83         public void InspectCharge(dynamic json)\r
84         {\r
85             SetMaterials((int[])json.api_material);\r
86         }\r
87 \r
88         public void InspectMissionResult(dynamic json)\r
89         {\r
90             if ((int)json.api_clear_result == 0) // 失敗\r
91                 return;\r
92             // 連続して遠征が帰投したときに資材の増加を積算する\r
93             if (DateTime.Now - _lastMission < TimeSpan.FromMinutes(1))\r
94                 _inPort = false;\r
95             _lastMission = DateTime.Now;\r
96             AddMaterials((int[])json.api_get_material);\r
97         }\r
98 \r
99         public void InspectDestroyShip(dynamic json)\r
100         {\r
101             SetMaterials((int[])json.api_material);\r
102         }\r
103 \r
104         public void InspectCreateIem(dynamic json)\r
105         {\r
106             SetMaterials((int[])json.api_material);\r
107         }\r
108 \r
109         public void InspectDestroyItem(dynamic json)\r
110         {\r
111             AddMaterials((int[])json.api_get_material);\r
112         }\r
113 \r
114         public void InspectRemodelSlot(dynamic json)\r
115         {\r
116             SetMaterials((int[])json.api_after_material);\r
117         }\r
118 \r
119         public void InspectAirCorpsSupply(dynamic json)\r
120         {\r
121             SetMaterial(Material.Fuel, (int)json.api_after_fuel);\r
122             SetMaterial(Material.Bouxite, (int)json.api_after_bauxite);\r
123         }\r
124 \r
125         public void InspectAirCorpsSetPlane(dynamic json)\r
126         {\r
127             if (json.api_after_bauxite())\r
128                 SetMaterial(Material.Bouxite, (int)json.api_after_bauxite);\r
129         }\r
130 \r
131         public void SetMaterials(int[] material)\r
132         {\r
133             UpdatePrevPort();\r
134             for (var i = 0; i < material.Length; i++)\r
135                 MaterialHistory[i].Now = material[i];\r
136         }\r
137 \r
138         public void SetMaterial(Material m, int v)\r
139         {\r
140             UpdatePrevPort();\r
141             MaterialHistory[(int)m].Now = v;\r
142         }\r
143 \r
144         public void AddMaterials(int[] v)\r
145         {\r
146             UpdatePrevPort();\r
147             for (var i = 0; i < v.Length; i++)\r
148                 MaterialHistory[i].Now += v[i];\r
149         }\r
150 \r
151         public void SubMaterial(Material m, int v)\r
152         {\r
153             UpdatePrevPort();\r
154             MaterialHistory[(int)m].Now -= v;\r
155         }\r
156 \r
157         public void SaveState(Status status)\r
158         {\r
159             NeedSave = false;\r
160             status.MaterialHistory = MaterialHistory.ToList();\r
161         }\r
162 \r
163         public void LoadState(Status status)\r
164         {\r
165             status.MaterialHistory?.CopyTo(MaterialHistory, 0);\r
166         }\r
167     }\r
168 \r
169 \r
170     public enum Material\r
171     {\r
172         Fuel,\r
173         Bullet,\r
174         Steal,\r
175         Bouxite,\r
176         Burner,\r
177         Bucket,\r
178         Development,\r
179         Screw,\r
180     }\r
181 \r
182     public class MaterialCount\r
183     {\r
184         private int _now;\r
185 \r
186         public int BegOfDay { get; set; }\r
187         public int BegOfWeek { get; set; }\r
188         public DateTime LastSet { get; set; }\r
189         [XmlIgnore]\r
190         public bool NeedSave { get; set; }\r
191 \r
192         public int Now\r
193         {\r
194             get => _now;\r
195             set\r
196             {\r
197                 var prev = _now;\r
198                 _now = value;\r
199                 if (Status.Restoring) // JSONから値を復旧するときは履歴に触らない\r
200                     return;\r
201                 if (_now != prev)\r
202                     NeedSave = true;\r
203                 if (LastSet == DateTime.MinValue)\r
204                 {\r
205                     BegOfDay = BegOfWeek = value;\r
206                     LastSet = DateTime.Now;\r
207                     return;\r
208                 }\r
209                 UpdateHistory(prev);\r
210                 LastSet = DateTime.Now;\r
211             }\r
212         }\r
213 \r
214         private void UpdateHistory(int prev)\r
215         {\r
216             var morning = DateTime.Today.AddHours(5);\r
217             var dow = (int)morning.DayOfWeek;\r
218             var monday = morning.AddDays(dow == 0 ? -6 : -dow + 1);\r
219             if (DateTime.Now >= morning && LastSet < morning)\r
220                 BegOfDay = prev;\r
221             if (DateTime.Now >= monday && LastSet < monday)\r
222                 BegOfWeek = prev;\r
223         }\r
224     }\r
225 }