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 KancolleSniffer.Util;
\r
22 using static System.Math;
\r
24 namespace KancolleSniffer.Model
\r
26 public class QuestStatus
\r
28 public int Id { get; set; }
\r
29 public int Category { get; set; }
\r
30 public QuestInterval Interval { get; set; }
\r
31 public string Name { get; set; }
\r
32 public string Detail { get; set; }
\r
33 public int[] Material { get; set; }
\r
34 public int Progress { get; set; }
\r
37 public QuestCount Count { get; set; }
\r
40 public Color Color { get; set; }
\r
42 public string ToToolTip() =>
\r
44 (Material == null || Material.All(x => x == 0)
\r
46 : "\r\n" + string.Join(" ",
\r
47 new[] {"燃", "弾", "鋼", "ボ", "建造", "修復", "開発", "改修"}
\r
48 .Zip(Material, (m, num) => num == 0 ? "" : m + num)
\r
49 .Where(s => !string.IsNullOrEmpty(s))));
\r
52 public enum QuestInterval
\r
54 // ReSharper disable once UnusedMember.Global
\r
62 public class QuestSpec
\r
64 public QuestInterval Interval { get; set; }
\r
65 public int Max { get; set; }
\r
66 public int[] MaxArray { get; set; }
\r
67 public bool AdjustCount { get; set; } = true;
\r
68 public int Shift { get; set; }
\r
69 public int[] Material { get; set; }
\r
72 public class QuestSortie : QuestSpec
\r
74 public string Rank { get; set; }
\r
75 public int[] Maps { get; set; }
\r
77 public static int CompareRank(string a, string b)
\r
79 const string ranks = "SABCDE";
\r
80 return ranks.IndexOf(a, StringComparison.Ordinal) -
\r
81 ranks.IndexOf(b, StringComparison.Ordinal);
\r
84 public bool Check(string rank, int map, bool boss)
\r
86 return (Rank == null || CompareRank(rank, Rank) <= 0) &&
\r
87 (Maps == null || Maps.Contains(map) && boss);
\r
91 public class QuestEnemyType : QuestSpec
\r
93 public int[] EnemyType { get; set; } = new int[0];
\r
95 public int CountResult(IEnumerable<ShipStatus> enemyResult) =>
\r
96 enemyResult.Count(ship => ship.NowHp == 0 && EnemyType.Contains(ship.Spec.ShipType));
\r
99 public class QuestPractice : QuestSpec
\r
101 public bool Win { get; set; }
\r
102 public bool Check(string rank) => !Win || QuestSortie.CompareRank(rank, "B") <= 0;
\r
105 public class QuestMission : QuestSpec
\r
107 public int[] Ids { get; set; }
\r
108 public bool Check(int id) => Ids == null || Ids.Contains(id);
\r
111 public class QuestDestroyItem : QuestSpec
\r
113 public int[] Types { get; set; }
\r
114 public int[] Ids { get; set; }
\r
116 public bool Count(QuestCount count, ItemSpec[] specs)
\r
118 if (count.NowArray == null)
\r
120 var num = specs.Count(spec => Types?.Contains(spec.Type) ?? (Ids?.Contains(spec.Id) ?? true));
\r
124 if (Types == null && Ids == null)
\r
126 var result = false;
\r
127 for (var i = 0; i < count.NowArray.Length; i++)
\r
129 var num = specs.Count(spec => Types != null ? Types[i] == spec.Type : Ids[i] == spec.Id);
\r
130 count.NowArray[i] += num;
\r
138 public class QuestPowerUp : QuestSpec
\r
142 public class QuestCount
\r
144 public int Id { get; set; }
\r
145 public int Now { get; set; }
\r
146 public int[] NowArray { get; set; }
\r
149 public QuestSpec Spec { get; set; }
\r
151 public bool AdjustCount(int progress)
\r
153 if (!Spec.AdjustCount)
\r
155 if (NowArray != null)
\r
157 if (progress != 100)
\r
159 NowArray = NowArray.Zip(Spec.MaxArray, Max).ToArray();
\r
178 var now = Now + Spec.Shift;
\r
179 var max = Spec.Max + Spec.Shift;
\r
180 var low = (int)Ceiling(max * progress / 100.0);
\r
181 if (low >= max && progress != 100)
\r
183 var high = (int)Ceiling(max * next / 100.0);
\r
186 Now = low - Spec.Shift;
\r
191 Now = high - 1 - Spec.Shift;
\r
197 public override string ToString()
\r
199 if (Id == 426 || Id == 854 || Id == 873 || Id == 888 || Id == 894)
\r
200 return $"{NowArray.Count(n => n >= 1)}/{Spec.MaxArray.Length}";
\r
201 return NowArray != null
\r
202 ? string.Join(" ", NowArray.Zip(Spec.MaxArray, (n, m) => $"{n}/{m}"))
\r
203 : $"{Now}/{Spec.Max}";
\r
206 public string ToToolTip()
\r
211 return string.Join(" ",
\r
212 new[] {"警備任務", "対潜警戒任務", "海上護衛任務", "強硬偵察任務"}
\r
213 .Zip(NowArray, (mission, n) => n >= 1 ? mission : "")
\r
214 .Where(s => !string.IsNullOrEmpty(s)));
\r
216 return string.Join(" ",
\r
217 new[] {"対潜警戒任務", "海峡警備行動", "長時間対潜警戒"}.Zip(NowArray, (mission, n) => n >= 1 ? mission + n : "")
\r
218 .Where(s => !string.IsNullOrEmpty(s)));
\r
220 return string.Join(" ",
\r
221 new[] {"2-4", "6-1", "6-3", "6-4"}.Zip(NowArray, (map, n) => n >= 1 ? map : "")
\r
222 .Where(s => !string.IsNullOrEmpty(s)));
\r
224 return string.Join(" ",
\r
225 new[] {"3-1", "3-2", "3-3"}.Zip(NowArray, (map, n) => n >= 1 ? map : "")
\r
226 .Where(s => !string.IsNullOrEmpty(s)));
\r
228 return string.Join(" ",
\r
229 new[] {"5-1", "5-3", "5-4"}.Zip(NowArray, (map, n) => n >= 1 ? map : "")
\r
230 .Where(s => !string.IsNullOrEmpty(s)));
\r
232 return string.Join(" ",
\r
233 new[] {"艦戦", "艦爆", "艦攻", "水偵"}.Zip(NowArray, (type, n) => n >= 1 ? type + n : "")
\r
234 .Where(s => !string.IsNullOrEmpty(s)));
\r
236 return string.Join(" ",
\r
237 new[] {"1-5", "7-1", "7-2G", "7-2M"}.Zip(NowArray, (map, n) => n >= 1 ? $"{map}:{n}" : "")
\r
238 .Where(s => !string.IsNullOrEmpty(s)));
\r
240 return string.Join(" ",
\r
241 new[] {"1-3", "1-4", "2-1", "2-2", "2-3"}.Zip(NowArray, (map, n) => n >= 1 ? map : "")
\r
242 .Where(s => !string.IsNullOrEmpty(s)));
\r
247 public bool Cleared => NowArray?.Zip(Spec.MaxArray, (n, m) => n >= m).All(x => x) ??
\r
248 Spec.Max != 0 && Now >= Spec.Max;
\r
251 public class QuestInfo : IHaveState
\r
253 private readonly SortedDictionary<int, QuestStatus> _quests = new SortedDictionary<int, QuestStatus>();
\r
254 private readonly QuestCountList _countList = new QuestCountList();
\r
255 private readonly ItemInfo _itemInfo;
\r
256 private readonly BattleInfo _battleInfo;
\r
257 private readonly Func<DateTime> _nowFunc = () => DateTime.Now;
\r
258 private DateTime _lastReset;
\r
259 private IEnumerable<QuestStatus> _clearedQuest = new List<QuestStatus>();
\r
261 private readonly Color[] _color =
\r
263 Color.FromArgb(60, 141, 76), Color.FromArgb(232, 57, 41), Color.FromArgb(136, 204, 120),
\r
264 Color.FromArgb(52, 147, 185), Color.FromArgb(220, 198, 126), Color.FromArgb(168, 111, 76),
\r
265 Color.FromArgb(200, 148, 231), Color.FromArgb(232, 57, 41)
\r
268 public int AcceptMax { get; set; } = 5;
\r
270 public QuestStatus[] Quests => _quests.Values.ToArray();
\r
272 public QuestInfo(ItemInfo itemInfo, BattleInfo battleInfo, Func<DateTime> nowFunc = null)
\r
274 _itemInfo = itemInfo;
\r
275 _battleInfo = battleInfo;
\r
276 if (nowFunc != null)
\r
277 _nowFunc = nowFunc;
\r
280 public void GetNotifications(out string[] notify, out string[] stop)
\r
282 var cleared = _quests.Values.Where(q => q.Count.Cleared).ToArray();
\r
283 notify = cleared.Except(_clearedQuest, new QuestComparer()).Select(q => q.Name).ToArray();
\r
284 stop = _clearedQuest.Except(cleared, new QuestComparer()).Select(q => q.Name).ToArray();
\r
285 _clearedQuest = cleared;
\r
288 private class QuestComparer : IEqualityComparer<QuestStatus>
\r
290 public bool Equals(QuestStatus x, QuestStatus y)
\r
292 return x?.Id == y?.Id;
\r
295 public int GetHashCode(QuestStatus obj)
\r
301 private readonly QuestInterval[] _intervals =
\r
303 QuestInterval.Daily, QuestInterval.Weekly, QuestInterval.Monthly,
\r
304 QuestInterval.Other, QuestInterval.Quarterly
\r
307 public void InspectQuestList(dynamic json)
\r
310 if (json.api_list == null)
\r
312 for (var i = 0; i < 2; i++)
\r
314 foreach (var entry in json.api_list)
\r
316 if (entry is double) // -1の場合がある。
\r
319 var id = (int)entry.api_no;
\r
320 var state = (int)entry.api_state;
\r
321 var progress = (int)entry.api_progress_flag;
\r
322 var cat = (int)entry.api_category;
\r
323 var interval = _intervals[(int)entry.api_type - 1];
\r
324 var name = (string)entry.api_title;
\r
325 var detail = ((string)entry.api_detail).Replace("<br>", "\r\n");
\r
326 var material = (int[])entry.api_get_material;
\r
342 if (_quests.Remove(id))
\r
349 AddQuest(id, cat, interval, name, detail, material, progress, true);
\r
353 if (_quests.Count <= AcceptMax)
\r
356 * ほかのPCで任務を達成した場合、任務が消えずに受領した任務の数が_questCountを超えることがある。
\r
357 * その場合はいったん任務をクリアして、現在のページの任務だけを登録し直す。
\r
363 private void AddQuest(int id, int category, QuestInterval interval, string name, string detail, int[] material,
\r
367 var count = _countList.GetCount(id);
\r
370 if (count.AdjustCount(progress))
\r
373 _quests[id] = new QuestStatus
\r
376 Category = category,
\r
377 Interval = interval,
\r
380 Material = adjustCount ? material?.Concat(count.Spec.Material).ToArray() : material,
\r
382 Progress = progress,
\r
383 Color = category <= _color.Length ? _color[category - 1] : Control.DefaultBackColor
\r
387 public void ClearQuests()
\r
392 private void ResetQuests()
\r
394 var now = _nowFunc();
\r
395 var daily = now.Date.AddHours(5);
\r
397 daily = daily.AddDays(-1);
\r
398 if (!(_lastReset < daily && daily <= now))
\r
400 RemoveQuest(QuestInterval.Daily);
\r
401 _countList.Remove(QuestInterval.Daily);
\r
402 var weekly = now.Date.AddDays(-((6 + (int)now.DayOfWeek) % 7)).AddHours(5);
\r
403 if (_lastReset < weekly && weekly <= now)
\r
405 RemoveQuest(QuestInterval.Weekly);
\r
406 _countList.Remove(QuestInterval.Weekly);
\r
408 var monthly = new DateTime(now.Year, now.Month, 1, 5, 0, 0);
\r
409 if (_lastReset < monthly && monthly <= now)
\r
411 RemoveQuest(QuestInterval.Monthly);
\r
412 _countList.Remove(QuestInterval.Monthly);
\r
414 var season = now.Month / 3;
\r
415 var quarterly = new DateTime(now.Year - (season == 0 ? 1 : 0), (season == 0 ? 12 : season * 3), 1, 5, 0, 0);
\r
416 if (_lastReset < quarterly && quarterly <= now)
\r
418 RemoveQuest(QuestInterval.Quarterly);
\r
419 _countList.Remove(QuestInterval.Quarterly);
\r
425 private void RemoveQuest(QuestInterval interval)
\r
428 (from kv in _quests
\r
429 where kv.Value.Count.Spec.Interval == interval || // 輸送5と空母3はカウンタを見ないとデイリーにならない
\r
430 kv.Value.Interval == interval
\r
431 select kv.Key).ToArray())
\r
432 _quests.Remove(id);
\r
437 private bool _boss;
\r
439 public void InspectMapStart(dynamic json)
\r
441 if (_quests.TryGetValue(214, out var ago)) // あ号
\r
442 ago.Count.NowArray[0]++;
\r
443 InspectMapNext(json);
\r
446 public void InspectMapNext(dynamic json)
\r
448 _map = (int)json.api_maparea_id * 10 + (int)json.api_mapinfo_no;
\r
449 _cell = json.api_no() ? (int)json.api_no : 0;
\r
450 _boss = (int)json.api_event_id == 5;
\r
452 if (_quests.TryGetValue(861, out var q861))
\r
454 if (_map == 16 && (int)json.api_event_id == 8)
\r
456 var fleet = _battleInfo.Result.Friend.Main.Where(s => s.NowHp > 0).Select(s => s.Spec.ShipType)
\r
458 if (fleet.Count(s => s == 10 || s == 22) == 2)
\r
459 IncrementCount(q861.Count);
\r
464 public void InspectBattleResult(dynamic json)
\r
466 var rank = json.api_win_rank;
\r
467 foreach (var quest in _quests.Values)
\r
469 var count = quest.Count;
\r
470 switch (count.Spec)
\r
472 case QuestSortie sortie:
\r
473 if (count.Id == 216 && !_boss || sortie.Check(rank, _map, _boss))
\r
474 IncrementCount(count);
\r
476 case QuestEnemyType enemyType:
\r
477 var num = enemyType.CountResult(
\r
478 _battleInfo.Result.Enemy.Main.Concat(_battleInfo.Result.Enemy.Guard));
\r
480 AddCount(count, num);
\r
484 if (_quests.TryGetValue(214, out var ago))
\r
486 var count = ago.Count;
\r
489 IncrementNowArray(count, 2);
\r
490 if (QuestSortie.CompareRank(rank, "B") <= 0)
\r
491 IncrementNowArray(count, 3);
\r
494 IncrementNowArray(count, 1);
\r
496 if (_quests.TryGetValue(249, out var q249))
\r
498 if (_map == 25 && _boss && QuestSortie.CompareRank(rank, "S") == 0)
\r
500 var fleet = _battleInfo.Result.Friend.Main.Where(s => s.NowHp > 0).Select(s => s.Spec.Id)
\r
502 if (fleet.Intersect(new[] {62, 63, 64, 265, 266, 268, 319, 192, 194}).Count() == 3)
\r
503 IncrementCount(q249.Count);
\r
506 if (_quests.TryGetValue(257, out var q257))
\r
508 if (_map == 14 && _boss && QuestSortie.CompareRank(rank, "S") == 0)
\r
510 var fleet = _battleInfo.Result.Friend.Main.Where(s => s.NowHp > 0).Select(s => s.Spec.ShipType)
\r
512 if (fleet[0] == 3 && fleet.Count(s => s == 3) <= 3 && fleet.All(s => s == 2 || s == 3))
\r
513 IncrementCount(q257.Count);
\r
516 if (_quests.TryGetValue(259, out var q259))
\r
518 if (_map == 51 && _boss && QuestSortie.CompareRank(rank, "S") == 0)
\r
520 var fleet = _battleInfo.Result.Friend.Main.Where(s => s.NowHp > 0).Select(s => s.Spec).ToArray();
\r
521 // ReSharper disable once IdentifierTypo
\r
529 if (fleet.Select(s => s.ShipClass).Count(c => ctype.Contains(c)) == 3 &&
\r
530 fleet.Count(s => s.ShipType == 3) > 0)
\r
532 IncrementCount(q259.Count);
\r
536 if (_quests.TryGetValue(264, out var q264))
\r
538 if (_map == 42 && _boss && QuestSortie.CompareRank(rank, "S") == 0)
\r
540 var fleet = _battleInfo.Result.Friend.Main.Where(s => s.NowHp > 0).Select(s => s.Spec)
\r
542 if (fleet.Count(spec => spec.ShipType == 2) >= 2 &&
\r
543 fleet.Count(spec => spec.IsAircraftCarrier) >= 2)
\r
544 IncrementCount(q264.Count);
\r
547 if (_quests.TryGetValue(266, out var q266))
\r
549 if (_map == 25 && _boss && QuestSortie.CompareRank(rank, "S") == 0)
\r
551 var fleet = _battleInfo.Result.Friend.Main.Where(s => s.NowHp > 0).Select(s => s.Spec.ShipType)
\r
553 if (fleet[0] == 2 && fleet.OrderBy(x => x).SequenceEqual(new[] {2, 2, 2, 2, 3, 5}))
\r
554 IncrementCount(q266.Count);
\r
557 if (_quests.TryGetValue(854, out var opz) && _boss)
\r
559 var count = opz.Count;
\r
562 case 24 when QuestSortie.CompareRank(rank, "A") <= 0:
\r
563 IncrementNowArray(count, 0);
\r
565 case 61 when QuestSortie.CompareRank(rank, "A") <= 0:
\r
566 IncrementNowArray(count, 1);
\r
568 case 63 when QuestSortie.CompareRank(rank, "A") <= 0:
\r
569 IncrementNowArray(count, 2);
\r
572 case 64 when QuestSortie.CompareRank(rank, "S") <= 0:
\r
573 IncrementNowArray(count, 3);
\r
577 if (_quests.TryGetValue(862, out var q862))
\r
579 if (_map == 63 && _boss && QuestSortie.CompareRank(rank, "A") <= 0)
\r
581 var fleet = _battleInfo.Result.Friend.Main.Where(s => s.NowHp > 0).Select(s => s.Spec.ShipType)
\r
583 if (fleet.Count(s => s == 3) >= 2 && fleet.Count(s => s == 16) >= 1)
\r
584 IncrementCount(q862.Count);
\r
587 if (_quests.TryGetValue(873, out var q873))
\r
589 if (_battleInfo.Result.Friend.Main.Count(s => s.NowHp > 0 && s.Spec.ShipType == 3) >= 1 &&
\r
590 _boss && QuestSortie.CompareRank(rank, "A") <= 0)
\r
592 var count = q873.Count;
\r
596 IncrementNowArray(count, 0);
\r
599 IncrementNowArray(count, 1);
\r
602 IncrementNowArray(count, 2);
\r
607 if (_quests.TryGetValue(875, out var q875))
\r
609 if (_map == 54 && _boss && QuestSortie.CompareRank(rank, "S") == 0)
\r
611 var fleet = _battleInfo.Result.Friend.Main.Where(s => s.NowHp > 0).Select(s => s.Spec.Id).ToArray();
\r
612 if (fleet.Contains(543) && fleet.Intersect(new[] {344, 345, 359}).Any())
\r
613 IncrementCount(q875.Count);
\r
616 if (_quests.TryGetValue(888, out var q888))
\r
618 if (!_boss || QuestSortie.CompareRank(rank, "S") != 0)
\r
620 var fleet = from ship in _battleInfo.Result.Friend.Main where ship.NowHp > 0 select ship.Spec.Id;
\r
623 69, 272, 427, // 鳥海
\r
625 123, 295, 142, // 衣笠
\r
626 59, 262, 416, // 古鷹
\r
627 60, 263, 417, // 加古
\r
628 51, 213, 477, // 天龍
\r
631 if (fleet.Intersect(member).Count() < 4)
\r
633 var count = q888.Count;
\r
637 IncrementNowArray(count, 0);
\r
640 IncrementNowArray(count, 1);
\r
643 IncrementNowArray(count, 2);
\r
647 if (_quests.TryGetValue(893, out var q893))
\r
649 if (QuestSortie.CompareRank(rank, "S") != 0)
\r
651 var count = q893.Count;
\r
655 IncrementNowArray(count, 0);
\r
658 IncrementNowArray(count, 1);
\r
663 IncrementNowArray(count, 2);
\r
666 IncrementNowArray(count, 3);
\r
670 if (_quests.TryGetValue(894, out var q894))
\r
673 QuestSortie.CompareRank(rank, "S") != 0 ||
\r
674 !_battleInfo.Result.Friend.Main.Any(s => s.Spec.IsAircraftCarrier && s.NowHp > 0))
\r
676 var count = q894.Count;
\r
680 IncrementNowArray(count, 0);
\r
683 IncrementNowArray(count, 1);
\r
686 IncrementNowArray(count, 2);
\r
689 IncrementNowArray(count, 3);
\r
692 IncrementNowArray(count, 4);
\r
698 private int _questFleet;
\r
700 public void StartPractice(string request)
\r
702 var values = HttpUtility.ParseQueryString(request);
\r
703 _questFleet = int.Parse(values["api_deck_id"]) - 1;
\r
706 public void InspectPracticeResult(dynamic json)
\r
708 foreach (var quest in _quests.Values)
\r
710 var count = quest.Count;
\r
711 if (!(count.Spec is QuestPractice practice))
\r
713 if (practice.Check(json.api_win_rank))
\r
714 IncrementCount(count);
\r
716 if (_quests.TryGetValue(318, out var q318))
\r
718 if (_questFleet == 0 && QuestSortie.CompareRank(json.api_win_rank, "B") <= 0 &&
\r
719 _battleInfo.Result.Friend.Main.Count(s => s.Spec.ShipType == 3) >= 2)
\r
721 IncrementCount(q318.Count);
\r
726 private readonly int[] _missionId = new int[ShipInfo.FleetCount];
\r
728 public void InspectDeck(dynamic json)
\r
730 foreach (var entry in json)
\r
731 _missionId[(int)entry.api_id - 1] = (int)entry.api_mission[1];
\r
734 public void InspectMissionResult(string request, dynamic json)
\r
736 var values = HttpUtility.ParseQueryString(request);
\r
737 var deck = int.Parse(values["api_deck_id"]);
\r
738 if ((int)json.api_clear_result == 0)
\r
740 var mid = _missionId[deck - 1];
\r
741 foreach (var quest in _quests.Values)
\r
743 var count = quest.Count;
\r
744 if (!(count.Spec is QuestMission mission))
\r
746 if (mission.Check(mid))
\r
747 IncrementCount(count);
\r
749 if (_quests.TryGetValue(426, out var q426))
\r
751 var count = q426.Count;
\r
755 IncrementNowArray(count, 0);
\r
758 IncrementNowArray(count, 1);
\r
761 IncrementNowArray(count, 2);
\r
764 IncrementNowArray(count, 3);
\r
768 if (_quests.TryGetValue(428, out var q428))
\r
770 var count = q428.Count;
\r
774 IncrementNowArray(count, 0);
\r
777 IncrementNowArray(count, 1);
\r
780 IncrementNowArray(count, 2);
\r
786 private void IncrementCount(QuestCount count)
\r
792 private void AddCount(QuestCount count, int value)
\r
794 count.Now += value;
\r
798 private void IncrementCount(int id)
\r
803 private void AddCount(int id, int value)
\r
805 if (_quests.TryGetValue(id, out var quest))
\r
807 quest.Count.Now += value;
\r
812 private void IncrementNowArray(QuestCount count, int n)
\r
814 count.NowArray[n]++;
\r
818 public void CountNyukyo() => IncrementCount(503);
\r
820 public void CountCharge() => IncrementCount(504);
\r
822 public void CountCreateItem()
\r
824 IncrementCount(605);
\r
825 IncrementCount(607);
\r
828 public void CountCreateShip()
\r
830 IncrementCount(606);
\r
831 IncrementCount(608);
\r
834 public void InspectDestroyShip(string request)
\r
836 AddCount(609, HttpUtility.ParseQueryString(request)["api_ship_id"].Split(',').Length);
\r
839 public void CountRemodelSlot() => IncrementCount(619);
\r
841 public void InspectDestroyItem(string request, dynamic json)
\r
843 var values = HttpUtility.ParseQueryString(request);
\r
844 var items = values["api_slotitem_ids"].Split(',')
\r
845 .Select(id => _itemInfo.GetStatus(int.Parse(id)).Spec).ToArray();
\r
846 IncrementCount(613); // 613: 資源の再利用
\r
847 foreach (var quest in _quests.Values)
\r
849 var count = quest.Count;
\r
850 if (!(count.Spec is QuestDestroyItem destroy))
\r
852 if (destroy.Count(count, items))
\r
855 if (_quests.TryGetValue(680, out var q680))
\r
857 q680.Count.NowArray[0] += items.Count(spec => spec.Type == 21);
\r
858 q680.Count.NowArray[1] += items.Count(spec => spec.Type == 12 || spec.Type == 13);
\r
863 public void InspectPowerUp(dynamic json)
\r
865 if ((int)json.api_powerup_flag == 0)
\r
867 foreach (var quest in _quests.Values)
\r
869 var count = quest.Count;
\r
870 if (!(count.Spec is QuestPowerUp))
\r
872 IncrementCount(count);
\r
876 public void InspectStop(string request)
\r
878 var values = HttpUtility.ParseQueryString(request);
\r
879 _quests.Remove(int.Parse(values["api_quest_id"]));
\r
883 public void InspectClearItemGet(string request)
\r
885 var values = HttpUtility.ParseQueryString(request);
\r
886 var id = int.Parse(values["api_quest_id"]);
\r
887 _countList.Remove(id);
\r
888 _quests.Remove(id);
\r
892 public bool NeedSave { get; private set; }
\r
894 public void SaveState(Status status)
\r
897 status.QuestLastReset = _lastReset;
\r
898 if (_quests != null)
\r
899 status.QuestList = _quests.Values.ToArray();
\r
900 if (_countList != null)
\r
901 status.QuestCountList = _countList.CountList.ToArray();
\r
904 public void LoadState(Status status)
\r
906 _lastReset = status.QuestLastReset;
\r
907 if (status.QuestCountList != null)
\r
908 _countList.CountList = status.QuestCountList;
\r
909 if (status.QuestList != null)
\r
912 foreach (var q in status.QuestList)
\r
913 AddQuest(q.Id, q.Category, q.Interval, q.Name, q.Detail, q.Material, q.Progress, false);
\r