1 // Copyright (C) 2013, 2015 Kazuhiro Fujieda <fujieda@users.osdn.me>
\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
7 // http://www.apache.org/licenses/LICENSE-2.0
\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
16 using System.Collections.Generic;
\r
17 using System.Drawing;
\r
19 using System.Windows.Forms;
\r
20 using System.Xml.Serialization;
\r
21 using static System.Math;
\r
23 namespace KancolleSniffer
\r
25 public class QuestStatus
\r
27 public int Id { get; set; }
\r
28 public int Category { get; set; }
\r
29 public string Name { get; set; }
\r
30 public string Detail { get; set; }
\r
31 public int Progress { get; set; }
\r
34 public QuestCount Count { get; set; }
\r
37 public Color Color { get; set; }
\r
40 public enum QuestInterval
\r
49 public class QuestSpec
\r
51 public QuestInterval Interval { get; set; }
\r
52 public int Max { get; set; }
\r
53 public int[] MaxArray { get; set; }
\r
54 public bool AdjustCount { get; set; } = true;
\r
55 public int Shift { get; set; }
\r
58 public class QuestSortie : QuestSpec
\r
60 public string Rank { get; set; }
\r
61 public int[] Maps { get; set; }
\r
62 public int[] ShipTypes { get; set; }
\r
64 public static int CompareRank(string a, string b)
\r
66 const string ranks = "SABCDE";
\r
67 return ranks.IndexOf(a, StringComparison.Ordinal) -
\r
68 ranks.IndexOf(b, StringComparison.Ordinal);
\r
71 public bool Check(string rank, int map, bool boss)
\r
73 return (Rank == null || CompareRank(rank, Rank) <= 0) &&
\r
74 (Maps == null || Maps.Contains(map) && boss);
\r
78 public class QuestEnemyType : QuestSpec
\r
80 public int[] EnemyType { get; set; } = new int[0];
\r
82 public int CountResult(IEnumerable<ShipStatus> enemyResult) =>
\r
83 enemyResult.Count(ship => ship.NowHp == 0 && EnemyType.Contains(ship.Spec.ShipType));
\r
86 public class QuestPractice : QuestSpec
\r
88 public bool Win { get; set; }
\r
89 public bool Check(string rank) => !Win || QuestSortie.CompareRank(rank, "B") <= 0;
\r
92 public class QuestMission : QuestSpec
\r
94 public int[] Ids { get; set; }
\r
95 public bool Check(int id) => Ids == null || Ids.Contains(id);
\r
98 public class QuestDestroyItem : QuestSpec
\r
100 public int[] Items { get; set; }
\r
101 public bool Check(int id) => Items == null || Items.Contains(id);
\r
104 public class QuestPowerup : QuestSpec
\r
108 public class QuestCount
\r
110 public int Id { get; set; }
\r
111 public int Now { get; set; }
\r
112 public int[] NowArray { get; set; }
\r
115 public QuestSpec Spec { get; set; }
\r
117 public bool AdjustCount(int progress)
\r
119 if (!Spec.AdjustCount)
\r
121 if (NowArray != null)
\r
123 if (progress != 100)
\r
125 NowArray = NowArray.Zip(Spec.MaxArray, Max).ToArray();
\r
144 var now = Now + Spec.Shift;
\r
145 var max = Spec.Max + Spec.Shift;
\r
146 var low = (int)Ceiling(max * progress / 100.0);
\r
147 var high = (int)Ceiling(max * next / 100.0);
\r
150 Now = low - Spec.Shift;
\r
155 Now = high - 1 - Spec.Shift;
\r
161 public override string ToString()
\r
163 if (Id == 426 || Id == 854)
\r
164 return $"{NowArray.Count(n => n >= 1)}/{Spec.MaxArray.Length}";
\r
165 return NowArray != null
\r
166 ? string.Join(" ", NowArray.Zip(Spec.MaxArray, (n, m) => $"{n}/{m}"))
\r
167 : $"{Now}/{Spec.Max}";
\r
170 public string ToToolTip()
\r
175 return string.Join(" ",
\r
176 new[] {"警備任務", "対潜警戒任務", "海上護衛任務", "強硬偵察任務"}.Zip(NowArray, (mission, n) => n >= 1 ? mission : "")
\r
177 .Where(s => !string.IsNullOrEmpty(s)));
\r
179 return string.Join(" ",
\r
180 new[] {"対潜警戒任務", "海峡警備行動", "長時間対潜警戒"}.Zip(NowArray, (mission, n) => n >= 1 ? mission + n : "")
\r
181 .Where(s => !string.IsNullOrEmpty(s)));
\r
183 return string.Join(" ",
\r
184 new[] {"2-4", "6-1", "6-3", "6-4"}.Zip(NowArray, (map, n) => n >= 1 ? map : "")
\r
185 .Where(s => !string.IsNullOrEmpty(s)));
\r
190 public bool Cleared => NowArray?.Zip(Spec.MaxArray, (n, m) => n >= m).All(x => x) ?? Now >= Spec.Max;
\r
194 public class QuestCountList
\r
196 private const QuestInterval Daily = QuestInterval.Daily;
\r
197 private const QuestInterval Weekly = QuestInterval.Weekly;
\r
198 private const QuestInterval Monthly = QuestInterval.Monthly;
\r
199 private const QuestInterval Quarterly = QuestInterval.Quarterly;
\r
202 /// このテーブルは七四式電子観測儀を参考に作成した。
\r
203 /// https://github.com/andanteyk/ElectronicObserver/blob/develop/ElectronicObserver/Data/Quest/QuestProgressManager.cs
\r
205 private static readonly Dictionary<int, QuestSpec> QuestSpecs = new Dictionary<int, QuestSpec>
\r
207 {201, new QuestSortie {Interval = Daily, Max = 1, Rank = "B"}}, // 201: 敵艦隊を撃滅せよ!
\r
208 {216, new QuestSortie {Interval = Daily, Max = 1, Rank = "B"}}, // 216: 敵艦隊主力を撃滅せよ!
\r
209 {210, new QuestSortie {Interval = Daily, Max = 10}}, // 210: 敵艦隊を10回邀撃せよ!
\r
210 {211, new QuestEnemyType {Interval = Daily, Max = 3, EnemyType = new[] {7, 11}}}, // 211: 敵空母を3隻撃沈せよ!
\r
211 {212, new QuestEnemyType {Interval = Daily, Max = 5, EnemyType = new[] {15}}}, // 212: 敵輸送船団を叩け!
\r
212 {218, new QuestEnemyType {Interval = Daily, Max = 3, EnemyType = new[] {15}}}, // 218: 敵補給艦を3隻撃沈せよ!
\r
213 {226, new QuestSortie {Interval = Daily, Max = 5, Rank = "B", Maps = new[] {21, 22, 23, 24, 25}}}, // 226: 南西諸島海域の制海権を握れ!
\r
214 {230, new QuestEnemyType {Interval = Daily, Max = 6, EnemyType = new[] {13}}}, // 230: 敵潜水艦を制圧せよ!
\r
216 {213, new QuestEnemyType {Interval = Weekly, Max = 20, EnemyType = new[] {15}}}, // 213: 海上通商破壊作戦
\r
217 {214, new QuestSpec {Interval = Weekly, MaxArray = new[] {36, 6, 24, 12}}}, // 214: あ号作戦
\r
218 {220, new QuestEnemyType {Interval = Weekly, Max = 20, EnemyType = new[] {7, 11}}}, // 220: い号作戦
\r
219 {221, new QuestEnemyType {Interval = Weekly, Max = 50, EnemyType = new[] {15}}}, // 221: ろ号作戦
\r
220 {228, new QuestEnemyType {Interval = Weekly, Max = 15, EnemyType = new[] {13}}}, // 228: 海上護衛戦
\r
221 {229, new QuestSortie {Interval = Weekly, Max = 12, Rank = "B", Maps = new[] {41, 42, 43, 44, 45}}}, // 229: 敵東方艦隊を撃滅せよ!
\r
222 {241, new QuestSortie {Interval = Weekly, Max = 5, Rank = "B", Maps = new[] {33, 34, 35}}}, // 241: 敵北方艦隊主力を撃滅せよ!
\r
223 {242, new QuestSortie {Interval = Weekly, Max = 1, Rank = "B", Maps = new[] {44}}}, // 242: 敵東方中枢艦隊を撃破せよ!
\r
224 {243, new QuestSortie {Interval = Weekly, Max = 2, Rank = "S", Maps = new[] {52}}}, // 243: 南方海域珊瑚諸島沖の制空権を握れ!
\r
225 {256, new QuestSortie {Interval = Monthly, Max = 3, Rank = "S", Maps = new[] {61}}}, // 256: 「潜水艦隊」出撃せよ!
\r
226 {261, new QuestSortie {Interval = Weekly, Max = 3, Rank = "A", Maps = new[] {15}}}, // 261: 海上輸送路の安全確保に努めよ!
\r
227 {265, new QuestSortie {Interval = Monthly, Max = 10, Rank = "A", Maps = new[] {15}}}, // 265: 海上護衛強化月間
\r
229 {822, new QuestSortie {Interval = Quarterly, Max = 2, Rank = "S", Maps = new[] {24}}}, // 822: 沖ノ島海域迎撃戦
\r
230 {854, new QuestSpec {Interval = Quarterly, MaxArray = new[] {1, 1, 1, 1}}}, // 854: 戦果拡張任務!「Z作戦」前段作戦
\r
232 {303, new QuestPractice {Interval = Daily, Max = 3, Win = false}}, // 303: 「演習」で練度向上!
\r
233 {304, new QuestPractice {Interval = Daily, Max = 5, Win = true}}, // 304: 「演習」で他提督を圧倒せよ!
\r
234 {302, new QuestPractice {Interval = Weekly, Max = 20, Win = true}}, // 302: 大規模演習
\r
235 {311, new QuestPractice {Interval = Daily, Max = 7, Win = true}}, // 311: 精鋭艦隊演習
\r
237 {402, new QuestMission {Interval = Daily, Max = 3}}, // 402: 「遠征」を3回成功させよう!
\r
238 {403, new QuestMission {Interval = Daily, Max = 10}}, // 403: 「遠征」を10回成功させよう!
\r
239 {404, new QuestMission {Interval = Weekly, Max = 30}}, // 404: 大規模遠征作戦、発令!
\r
240 {410, new QuestMission {Interval = Weekly, Max = 1, Ids = new[] {37, 38}}}, // 410: 南方への輸送作戦を成功させよ!
\r
241 {411, new QuestMission {Interval = Weekly, Max = 6, Shift = 1, Ids = new[] {37, 38}}}, // 411: 南方への鼠輸送を継続実施せよ!
\r
242 {424, new QuestMission {Interval = Monthly, Max = 4, Shift = 1, Ids = new[] {5}}}, // 424: 輸送船団護衛を強化せよ!
\r
243 {426, new QuestSpec {Interval = Quarterly, MaxArray = new[] {1, 1, 1, 1}}}, // 426: 海上通商航路の警戒を厳とせよ!
\r
244 {428, new QuestSpec {Interval = Quarterly, MaxArray = new[] {2, 2, 2}}}, // 428: 近海に侵入する敵潜を制圧せよ!
\r
246 {503, new QuestSpec {Interval = Daily, Max = 5}}, // 503: 艦隊大整備!
\r
247 {504, new QuestSpec {Interval = Daily, Max = 15}}, // 504: 艦隊酒保祭り!
\r
249 {605, new QuestSpec {Interval = Daily, Max = 1}}, // 605: 新装備「開発」指令
\r
250 {606, new QuestSpec {Interval = Daily, Max = 1}}, // 606: 新造艦「建造」指令
\r
251 {607, new QuestSpec {Interval = Daily, Max = 3, Shift = 1}}, // 607: 装備「開発」集中強化!
\r
252 {608, new QuestSpec {Interval = Daily, Max = 3, Shift = 1}}, // 608: 艦娘「建造」艦隊強化!
\r
253 {609, new QuestSpec {Interval = Daily, Max = 2}}, // 609: 軍縮条約対応!
\r
254 {619, new QuestSpec {Interval = Daily, Max = 1}}, // 619: 装備の改修強化
\r
256 {613, new QuestSpec {Interval = Weekly, Max = 24}}, // 613: 資源の再利用
\r
257 {638, new QuestDestroyItem {Interval = Weekly, Max = 6, Items = new[] {21}}}, // 638: 対空機銃量産
\r
258 {663, new QuestDestroyItem {Interval = Quarterly, Max = 10, Items = new[] {3}} }, // 663: 新型艤装の継続研究
\r
259 {673, new QuestDestroyItem {Interval = Daily, Max = 4, Items = new[] {1}, Shift = 1}}, // 673: 装備開発力の整備
\r
260 {674, new QuestDestroyItem {Interval = Daily, Max = 3, Items = new[] {21}, Shift = 2}}, // 674: 工廠環境の整備
\r
261 {675, new QuestSpec {Interval = Quarterly, MaxArray = new[] {6, 4}}}, // 675: 運用装備の統合整備
\r
262 {676, new QuestSpec {Interval = Weekly, MaxArray = new[] {3, 3, 1}}}, // 676: 装備開発力の集中整備
\r
263 {677, new QuestSpec {Interval = Weekly, MaxArray = new[] {4, 2, 3}}}, // 677: 継戦支援能力の整備
\r
265 {702, new QuestPowerup {Interval = Daily, Max = 2}}, // 702: 艦の「近代化改修」を実施せよ!
\r
266 {703, new QuestPowerup {Interval = Weekly, Max = 15}} // 703: 「近代化改修」を進め、戦備を整えよ!
\r
270 private readonly Dictionary<int, QuestCount> _countDict = new Dictionary<int, QuestCount>();
\r
272 public QuestCount GetCount(int id)
\r
274 if (_countDict.TryGetValue(id, out var value))
\r
276 if (QuestSpecs.TryGetValue(id, out var spec))
\r
278 var nowArray = spec.MaxArray?.Select(x => 0).ToArray();
\r
279 return _countDict[id] = new QuestCount
\r
283 NowArray = nowArray,
\r
287 return new QuestCount {Spec = new QuestSpec {AdjustCount = false}};
\r
290 public void Remove(int id)
\r
292 _countDict.Remove(id);
\r
295 public void Remove(QuestInterval interval)
\r
298 _countDict.Where(pair => pair.Value.Spec.Interval == interval).Select(pair => pair.Key).ToArray())
\r
300 _countDict.Remove(id);
\r
304 public IEnumerable<QuestCount> CountList
\r
306 get => _countDict.Values.Where(c => c.Now > 0 || (c.NowArray?.Any(n => n > 0) ?? false));
\r
311 foreach (var count in value)
\r
313 count.Spec = QuestSpecs[count.Id];
\r
314 _countDict[count.Id] = count;
\r
320 public class QuestInfo : IHaveState
\r
322 private readonly SortedDictionary<int, QuestStatus> _quests = new SortedDictionary<int, QuestStatus>();
\r
323 private readonly QuestCountList _countList = new QuestCountList();
\r
324 private readonly ItemInfo _itemInfo;
\r
325 private readonly BattleInfo _battleInfo;
\r
326 private readonly Func<DateTime> _nowFunc = () => DateTime.Now;
\r
327 private DateTime _lastReset;
\r
329 private readonly Color[] _color =
\r
331 Color.FromArgb(60, 141, 76), Color.FromArgb(232, 57, 41), Color.FromArgb(136, 204, 120),
\r
332 Color.FromArgb(52, 147, 185), Color.FromArgb(220, 198, 126), Color.FromArgb(168, 111, 76),
\r
333 Color.FromArgb(200, 148, 231), Color.FromArgb(232, 57, 41)
\r
336 public int AcceptMax { get; set; } = 5;
\r
338 public QuestStatus[] Quests => _quests.Values.ToArray();
\r
340 public QuestInfo(ItemInfo itemInfo, BattleInfo battleInfo, Func<DateTime> nowFunc = null)
\r
342 _itemInfo = itemInfo;
\r
343 _battleInfo = battleInfo;
\r
344 if (nowFunc != null)
\r
345 _nowFunc = nowFunc;
\r
348 public void InspectQuestList(dynamic json)
\r
351 if (json.api_list == null)
\r
353 for (var i = 0; i < 2; i++)
\r
355 foreach (var entry in json.api_list)
\r
357 if (entry is double) // -1の場合がある。
\r
360 var id = (int)entry.api_no;
\r
361 var state = (int)entry.api_state;
\r
362 var progress = (int)entry.api_progress_flag;
\r
363 var cat = (int)entry.api_category;
\r
364 var name = (string)entry.api_title;
\r
365 var detail = ((string)entry.api_detail).Replace("<br>", "\r\n");
\r
381 if (_quests.Remove(id))
\r
388 AddQuest(id, cat, name, detail, progress, true);
\r
392 if (_quests.Count <= AcceptMax)
\r
395 * ほかのPCで任務を達成した場合、任務が消えずに受領した任務の数が_questCountを超えることがある。
\r
396 * その場合はいったん任務をクリアして、現在のページの任務だけを登録し直す。
\r
402 private void AddQuest(int id, int category, string name, string detail, int progress, bool adjustCount)
\r
404 var count = _countList.GetCount(id);
\r
407 count.AdjustCount(progress);
\r
410 _quests[id] = new QuestStatus
\r
413 Category = category,
\r
417 Progress = progress,
\r
418 Color = category <= _color.Length ? _color[category - 1] : Control.DefaultBackColor
\r
422 public void ClearQuests()
\r
427 private void ResetQuests()
\r
429 var now = _nowFunc();
\r
430 var daily = now.Date.AddHours(5);
\r
431 if (!(_lastReset < daily && daily <= now))
\r
433 _quests.Clear(); // 前日に未消化のデイリーを消す。
\r
434 _countList.Remove(QuestInterval.Daily);
\r
435 var weekly = now.Date.AddDays(-((6 + (int)now.DayOfWeek) % 7)).AddHours(5);
\r
436 if (_lastReset < weekly && weekly <= now)
\r
437 _countList.Remove(QuestInterval.Weekly);
\r
438 var monthly = new DateTime(now.Year, now.Month, 1, 5, 0, 0);
\r
439 if (_lastReset < monthly && monthly <= now)
\r
440 _countList.Remove(QuestInterval.Monthly);
\r
441 var season = now.Month / 3;
\r
442 var quarterly = new DateTime(now.Year - (season == 0 ? 1 : 0), (season == 0 ? 12 : season * 3), 1, 5, 0, 0);
\r
443 if (_lastReset < quarterly && quarterly <= now)
\r
444 _countList.Remove(QuestInterval.Quarterly);
\r
449 private bool _boss;
\r
452 public void InspectMapStart(dynamic json)
\r
454 if (_quests.TryGetValue(214, out var ago)) // あ号
\r
455 ago.Count.NowArray[0]++;
\r
456 InspectMapNext(json);
\r
459 public void InspectMapNext(dynamic json)
\r
461 _map = (int)json.api_maparea_id * 10 + (int)json.api_mapinfo_no;
\r
462 _boss = (int)json.api_event_id == 5;
\r
465 public void InspectBattleResult(dynamic json)
\r
467 var rank = json.api_win_rank;
\r
468 foreach (var quest in _quests.Values)
\r
470 var count = quest.Count;
\r
471 switch (count.Spec)
\r
473 case QuestSortie sortie:
\r
474 if (count.Id == 216 && !_boss || sortie.Check(rank, _map, _boss))
\r
475 IncrementCount(count);
\r
477 case QuestEnemyType enemyType:
\r
478 var num = enemyType.CountResult(
\r
479 _battleInfo.Result.Enemy.Main.Concat(_battleInfo.Result.Enemy.Guard));
\r
481 AddCount(count, num);
\r
485 if (_quests.TryGetValue(214, out var ago))
\r
487 var array = ago.Count.NowArray;
\r
491 if (QuestSortie.CompareRank(rank, "B") <= 0)
\r
501 if (_quests.TryGetValue(854, out var opz) && _boss)
\r
503 var array = opz.Count.NowArray;
\r
506 case 24 when QuestSortie.CompareRank(rank, "A") <= 0:
\r
510 case 61 when QuestSortie.CompareRank(rank, "A") <= 0:
\r
514 case 63 when QuestSortie.CompareRank(rank, "A") <= 0:
\r
518 case 64 when QuestSortie.CompareRank(rank, "S") <= 0:
\r
526 public void InspectPracticeResult(dynamic json)
\r
528 foreach (var quest in _quests.Values)
\r
530 var count = quest.Count;
\r
531 if (!(count.Spec is QuestPractice practice))
\r
533 if (practice.Check(json.api_win_rank))
\r
534 IncrementCount(count);
\r
538 private readonly int[] _missionId = new int[ShipInfo.FleetCount];
\r
540 public void InspectDeck(dynamic json)
\r
542 foreach (var entry in json)
\r
543 _missionId[(int)entry.api_id - 1] = (int)entry.api_mission[1];
\r
546 public void InspectMissionResult(string request, dynamic json)
\r
548 var values = HttpUtility.ParseQueryString(request);
\r
549 var deck = int.Parse(values["api_deck_id"]);
\r
550 if ((int)json.api_clear_result == 0)
\r
552 var mid = _missionId[deck - 1];
\r
553 foreach (var quest in _quests.Values)
\r
555 var count = quest.Count;
\r
556 if (!(count.Spec is QuestMission mission))
\r
558 if (mission.Check(mid))
\r
559 IncrementCount(count);
\r
561 if (_quests.TryGetValue(426, out var q426))
\r
563 var count = q426.Count;
\r
567 count.NowArray[0]++;
\r
570 count.NowArray[1]++;
\r
573 count.NowArray[2]++;
\r
576 count.NowArray[3]++;
\r
580 if (_quests.TryGetValue(428, out var q428))
\r
582 var count = q428.Count;
\r
586 count.NowArray[0]++;
\r
589 count.NowArray[1]++;
\r
592 count.NowArray[2]++;
\r
598 private void IncrementCount(QuestCount count)
\r
604 private void AddCount(QuestCount count, int value)
\r
606 count.Now += value;
\r
610 private void IncrementCount(int id)
\r
615 private void AddCount(int id, int value)
\r
617 if (_quests.TryGetValue(id, out var quest))
\r
619 quest.Count.Now += value;
\r
624 public void CountNyukyo() => IncrementCount(503);
\r
626 public void CountCharge() => IncrementCount(504);
\r
628 public void CountCreateItem()
\r
630 IncrementCount(605);
\r
631 IncrementCount(607);
\r
634 public void CountCreateShip()
\r
636 IncrementCount(606);
\r
637 IncrementCount(608);
\r
640 public void InspectDestroyShip(string request)
\r
642 AddCount(609, HttpUtility.ParseQueryString(request)["api_ship_id"].Split(',').Length);
\r
645 public void CountRemodelSlot() => IncrementCount(619);
\r
647 public void InspectDestroyItem(string request, dynamic json)
\r
649 var values = HttpUtility.ParseQueryString(request);
\r
650 var items = values["api_slotitem_ids"].Split(',')
\r
651 .Select(id => _itemInfo.GetStatus(int.Parse(id)).Spec.Type).ToArray();
\r
652 IncrementCount(613); // 613: 資源の再利用
\r
653 foreach (var quest in _quests.Values)
\r
655 var count = quest.Count;
\r
656 if (!(count.Spec is QuestDestroyItem destroy))
\r
658 AddCount(count, items.Count(destroy.Check));
\r
660 if (_quests.TryGetValue(675, out var q675))
\r
662 q675.Count.NowArray[0] += items.Count(id => id == 6);
\r
663 q675.Count.NowArray[1] += items.Count(id => id == 21);
\r
666 if (_quests.TryGetValue(676, out var q676))
\r
668 q676.Count.NowArray[0] += items.Count(id => id == 2);
\r
669 q676.Count.NowArray[1] += items.Count(id => id == 4);
\r
670 q676.Count.NowArray[2] += items.Count(id => id == 30);
\r
673 if (_quests.TryGetValue(677, out var q677))
\r
675 q677.Count.NowArray[0] += items.Count(id => id == 3);
\r
676 q677.Count.NowArray[1] += items.Count(id => id == 10);
\r
677 q677.Count.NowArray[2] += items.Count(id => id == 5);
\r
682 public void InspectPowerup(dynamic json)
\r
684 if ((int)json.api_powerup_flag == 0)
\r
686 foreach (var quest in _quests.Values)
\r
688 var count = quest.Count;
\r
689 if (!(count.Spec is QuestPowerup))
\r
691 IncrementCount(count);
\r
695 public void InspectStop(string request)
\r
697 var values = HttpUtility.ParseQueryString(request);
\r
698 _quests.Remove(int.Parse(values["api_quest_id"]));
\r
702 public void InspectClearItemGet(string request)
\r
704 var values = HttpUtility.ParseQueryString(request);
\r
705 var id = int.Parse(values["api_quest_id"]);
\r
706 _countList.Remove(id);
\r
707 _quests.Remove(id);
\r
711 public bool NeedSave { get; private set; }
\r
713 public void SaveState(Status status)
\r
716 status.QuestLastReset = _lastReset;
\r
717 if (_quests != null)
\r
718 status.QuestList = _quests.Values.ToArray();
\r
719 if (_countList != null)
\r
720 status.QuestCountList = _countList.CountList.ToArray();
\r
723 public void LoadState(Status status)
\r
725 _lastReset = status.QuestLastReset;
\r
726 if (status.QuestCountList != null)
\r
727 _countList.CountList = status.QuestCountList;
\r
728 if (status.QuestList != null)
\r
731 foreach (var q in status.QuestList)
\r
732 AddQuest(q.Id, q.Category, q.Name, q.Detail, q.Progress, false);
\r