OSDN Git Service

制空値の計算などを噴式機に対応させる
[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         }\r
38 \r
39         public bool NeedSave\r
40         {\r
41             get { return MaterialHistory.Any(m => m.NeedSave); }\r
42             private set\r
43             {\r
44                 foreach (var m in MaterialHistory)\r
45                     m.NeedSave = value;\r
46             }\r
47         }\r
48 \r
49         public void InspectMaterial(dynamic json, bool port = false)\r
50         {\r
51             if (!port)\r
52                 UpdatePrevPort();\r
53             foreach (var entry in json)\r
54             {\r
55                 var i = (int)entry.api_id - 1;\r
56                 var v = (int)entry.api_value;\r
57                 MaterialHistory[i].Now = v;\r
58             }\r
59             if (!port)\r
60                 return;\r
61             _inPort = true;\r
62             if (PrevPort[0] != 0)\r
63                 return;\r
64             for (var i = 0; i < MaterialHistory.Length; i++)\r
65                 PrevPort[i] = MaterialHistory[i].Now;\r
66         }\r
67 \r
68         private void UpdatePrevPort()\r
69         {\r
70             if (!_inPort)\r
71                 return;\r
72             for (var i = 0; i < MaterialHistory.Length; i++)\r
73                 PrevPort[i] = MaterialHistory[i].Now;\r
74             _inPort = false;\r
75         }\r
76 \r
77         public void InspectCharge(dynamic json)\r
78         {\r
79             SetMaterials((int[])json.api_material);\r
80         }\r
81 \r
82         public void InspectMissionResult(dynamic json)\r
83         {\r
84             if ((int)json.api_clear_result == 0) // 失敗\r
85                 return;\r
86             if (DateTime.Now - _lastMission < TimeSpan.FromMinutes(1))\r
87                 _inPort = false;\r
88             _lastMission = DateTime.Now;\r
89             AddMaterials((int[])json.api_get_material);\r
90         }\r
91 \r
92         public void InspectDestroyShip(dynamic json)\r
93         {\r
94             SetMaterials((int[])json.api_material);\r
95         }\r
96 \r
97         public void InspectCreateIem(dynamic json)\r
98         {\r
99             SetMaterials((int[])json.api_material);\r
100         }\r
101 \r
102         public void InspectDestroyItem(dynamic json)\r
103         {\r
104             AddMaterials((int[])json.api_get_material);\r
105         }\r
106 \r
107         public void InspectRemodelSlot(dynamic json)\r
108         {\r
109             SetMaterials((int[])json.api_after_material);\r
110         }\r
111 \r
112         public void InspectAirCorpsSupply(dynamic json)\r
113         {\r
114             SetMaterial(Material.Fuel, (int)json.api_after_fuel);\r
115             SetMaterial(Material.Bouxite, (int)json.api_after_bauxite);\r
116         }\r
117 \r
118         public void InspectAirCorpsSetPlane(dynamic json)\r
119         {\r
120             if (json.api_after_bauxite())\r
121                 SetMaterial(Material.Bouxite, (int)json.api_after_bauxite);\r
122         }\r
123 \r
124         public void SetMaterials(int[] material)\r
125         {\r
126             UpdatePrevPort();\r
127             for (var i = 0; i < material.Length; i++)\r
128                 MaterialHistory[i].Now = material[i];\r
129         }\r
130 \r
131         public void SetMaterial(Material m, int v)\r
132         {\r
133             UpdatePrevPort();\r
134             MaterialHistory[(int)m].Now = v;\r
135         }\r
136 \r
137         public void AddMaterials(int[] v)\r
138         {\r
139             UpdatePrevPort();\r
140             for (var i = 0; i < v.Length; i++)\r
141                 MaterialHistory[i].Now += v[i];\r
142         }\r
143 \r
144         public void SubMaterial(Material m, int v)\r
145         {\r
146             UpdatePrevPort();\r
147             MaterialHistory[(int)m].Now -= v;\r
148         }\r
149 \r
150         public void SaveState(Status status)\r
151         {\r
152             NeedSave = false;\r
153             status.MaterialHistory = MaterialHistory.ToList();\r
154         }\r
155 \r
156         public void LoadState(Status status)\r
157         {\r
158             status.MaterialHistory?.CopyTo(MaterialHistory, 0);\r
159         }\r
160     }\r
161 \r
162 \r
163     public enum Material\r
164     {\r
165         Fuel,\r
166         Bullet,\r
167         Steal,\r
168         Bouxite,\r
169         Burner,\r
170         Bucket,\r
171         Development,\r
172         Screw,\r
173     }\r
174 \r
175     public class MaterialCount\r
176     {\r
177         private int _now;\r
178 \r
179         public int BegOfDay { get; set; }\r
180         public int BegOfWeek { get; set; }\r
181         public DateTime LastSet { get; set; }\r
182         [XmlIgnore]\r
183         public bool NeedSave { get; set; }\r
184 \r
185         public int Now\r
186         {\r
187             get { return _now; }\r
188             set\r
189             {\r
190                 var prev = _now;\r
191                 _now = value;\r
192                 if (Status.Restoring) // JSONから値を復旧するときは履歴に触らない\r
193                     return;\r
194                 if (_now != prev)\r
195                     NeedSave = true;\r
196                 if (LastSet == DateTime.MinValue)\r
197                 {\r
198                     BegOfDay = BegOfWeek = value;\r
199                     LastSet = DateTime.Now;\r
200                     return;\r
201                 }\r
202                 UpdateHistory(prev);\r
203                 LastSet = DateTime.Now;\r
204             }\r
205         }\r
206 \r
207         private void UpdateHistory(int prev)\r
208         {\r
209             var morning = DateTime.Today.AddHours(5);\r
210             var dow = (int)morning.DayOfWeek;\r
211             var monday = morning.AddDays(dow == 0 ? -6 : -dow + 1);\r
212             if (DateTime.Now >= morning && LastSet < morning)\r
213                 BegOfDay = prev;\r
214             if (DateTime.Now >= monday && LastSet < monday)\r
215                 BegOfWeek = prev;\r
216         }\r
217     }\r
218 }