using System.Windows.Forms;\r
using System.Xml.Serialization;\r
using KancolleSniffer.Util;\r
-using static System.Math;\r
\r
namespace KancolleSniffer.Model\r
{\r
new[] {"燃", "弾", "鋼", "ボ", "建造", "修復", "開発", "改修"}\r
.Zip(Material, (m, num) => num == 0 ? "" : m + num)\r
.Where(s => !string.IsNullOrEmpty(s))));\r
+\r
+ public QuestStatus Clone()\r
+ {\r
+ var clone = (QuestStatus)MemberwiseClone();\r
+ clone.Count = Count.Clone();\r
+ return clone;\r
+ }\r
}\r
\r
public enum QuestInterval\r
Quarterly\r
}\r
\r
- public class QuestSpec\r
- {\r
- public QuestInterval Interval { get; set; }\r
- public int Max { get; set; }\r
- public int[] MaxArray { get; set; }\r
- public bool AdjustCount { get; set; } = true;\r
- public int Shift { get; set; }\r
- public int[] Material { get; set; }\r
- }\r
-\r
- public class QuestSortie : QuestSpec\r
- {\r
- public string Rank { get; set; }\r
- public int[] Maps { get; set; }\r
-\r
- public static int CompareRank(string a, string b)\r
- {\r
- const string ranks = "SABCDE";\r
- return ranks.IndexOf(a, StringComparison.Ordinal) -\r
- ranks.IndexOf(b, StringComparison.Ordinal);\r
- }\r
-\r
- public bool Check(string rank, int map, bool boss)\r
- {\r
- return (Rank == null || CompareRank(rank, Rank) <= 0) &&\r
- (Maps == null || Maps.Contains(map) && boss);\r
- }\r
- }\r
-\r
- public class QuestEnemyType : QuestSpec\r
- {\r
- public int[] EnemyType { get; set; } = new int[0];\r
-\r
- public int CountResult(IEnumerable<ShipStatus> enemyResult) =>\r
- enemyResult.Count(ship => ship.NowHp == 0 && EnemyType.Contains(ship.Spec.ShipType));\r
- }\r
-\r
- public class QuestPractice : QuestSpec\r
- {\r
- public bool Win { get; set; }\r
- public bool Check(string rank) => !Win || QuestSortie.CompareRank(rank, "B") <= 0;\r
- }\r
-\r
- public class QuestMission : QuestSpec\r
- {\r
- public int[] Ids { get; set; }\r
- public bool Check(int id) => Ids == null || Ids.Contains(id);\r
- }\r
-\r
- public class QuestDestroyItem : QuestSpec\r
- {\r
- public int[] Types { get; set; }\r
- public int[] Ids { get; set; }\r
-\r
- public bool Count(QuestCount count, ItemSpec[] specs)\r
- {\r
- if (count.NowArray == null)\r
- {\r
- var num = specs.Count(spec => Types?.Contains(spec.Type) ?? (Ids?.Contains(spec.Id) ?? true));\r
- count.Now += num;\r
- return num > 0;\r
- }\r
- if (Types == null && Ids == null)\r
- return false;\r
- var result = false;\r
- for (var i = 0; i < count.NowArray.Length; i++)\r
- {\r
- var num = specs.Count(spec => Types != null ? Types[i] == spec.Type : Ids[i] == spec.Id);\r
- count.NowArray[i] += num;\r
- if (num > 0)\r
- result = true;\r
- }\r
- return result;\r
- }\r
- }\r
-\r
- public class QuestPowerUp : QuestSpec\r
- {\r
- }\r
-\r
- public class QuestCount\r
- {\r
- public int Id { get; set; }\r
- public int Now { get; set; }\r
- public int[] NowArray { get; set; }\r
-\r
- [XmlIgnore]\r
- public QuestSpec Spec { get; set; }\r
-\r
- public bool AdjustCount(int progress)\r
- {\r
- if (!Spec.AdjustCount)\r
- return false;\r
- if (NowArray != null)\r
- {\r
- if (progress != 100)\r
- return false;\r
- NowArray = NowArray.Zip(Spec.MaxArray, Max).ToArray();\r
- return true;\r
- }\r
- var next = 0;\r
- switch (progress)\r
- {\r
- case 0:\r
- next = 50;\r
- break;\r
- case 50:\r
- next = 80;\r
- break;\r
- case 80:\r
- next = 100;\r
- break;\r
- case 100:\r
- next = 100000;\r
- break;\r
- }\r
- var now = Now + Spec.Shift;\r
- var max = Spec.Max + Spec.Shift;\r
- var low = (int)Ceiling(max * progress / 100.0);\r
- if (low >= max && progress != 100)\r
- low = max - 1;\r
- var high = (int)Ceiling(max * next / 100.0);\r
- if (now < low)\r
- {\r
- Now = low - Spec.Shift;\r
- return true;\r
- }\r
- if (now >= high)\r
- {\r
- Now = high - 1 - Spec.Shift;\r
- return true;\r
- }\r
- return false;\r
- }\r
-\r
- public override string ToString()\r
- {\r
- if (Id == 280 || Id == 426 || Id == 854 || Id == 873 || Id == 888 || Id == 894)\r
- return $"{NowArray.Count(n => n >= 1)}/{Spec.MaxArray.Length}";\r
- return NowArray != null\r
- ? string.Join(" ", NowArray.Zip(Spec.MaxArray, (n, m) => $"{n}/{m}"))\r
- : $"{Now}/{Spec.Max}";\r
- }\r
-\r
- public string ToToolTip()\r
- {\r
- switch (Id)\r
- {\r
- case 280:\r
- return string.Join(" ",\r
- new[] {"1-2", "1-3", "1-4", "2-1"}.Zip(NowArray, (map, n) => n >= 1 ? map : "")\r
- .Where(s => !string.IsNullOrEmpty(s)));\r
- case 426:\r
- return string.Join(" ",\r
- new[] {"警備任務", "対潜警戒任務", "海上護衛任務", "強硬偵察任務"}\r
- .Zip(NowArray, (mission, n) => n >= 1 ? mission : "")\r
- .Where(s => !string.IsNullOrEmpty(s)));\r
- case 428:\r
- return string.Join(" ",\r
- new[] {"対潜警戒任務", "海峡警備行動", "長時間対潜警戒"}.Zip(NowArray, (mission, n) => n >= 1 ? mission + n : "")\r
- .Where(s => !string.IsNullOrEmpty(s)));\r
- case 854:\r
- return string.Join(" ",\r
- new[] {"2-4", "6-1", "6-3", "6-4"}.Zip(NowArray, (map, n) => n >= 1 ? map : "")\r
- .Where(s => !string.IsNullOrEmpty(s)));\r
- case 873:\r
- return string.Join(" ",\r
- new[] {"3-1", "3-2", "3-3"}.Zip(NowArray, (map, n) => n >= 1 ? map : "")\r
- .Where(s => !string.IsNullOrEmpty(s)));\r
- case 888:\r
- return string.Join(" ",\r
- new[] {"5-1", "5-3", "5-4"}.Zip(NowArray, (map, n) => n >= 1 ? map : "")\r
- .Where(s => !string.IsNullOrEmpty(s)));\r
- case 688:\r
- return string.Join(" ",\r
- new[] {"艦戦", "艦爆", "艦攻", "水偵"}.Zip(NowArray, (type, n) => n >= 1 ? type + n : "")\r
- .Where(s => !string.IsNullOrEmpty(s)));\r
- case 893:\r
- return string.Join(" ",\r
- new[] {"1-5", "7-1", "7-2G", "7-2M"}.Zip(NowArray, (map, n) => n >= 1 ? $"{map}:{n}" : "")\r
- .Where(s => !string.IsNullOrEmpty(s)));\r
- case 894:\r
- return string.Join(" ",\r
- new[] {"1-3", "1-4", "2-1", "2-2", "2-3"}.Zip(NowArray, (map, n) => n >= 1 ? map : "")\r
- .Where(s => !string.IsNullOrEmpty(s)));\r
- }\r
- return "";\r
- }\r
-\r
- public bool Cleared => NowArray?.Zip(Spec.MaxArray, (n, m) => n >= m).All(x => x) ??\r
- Spec.Max != 0 && Now >= Spec.Max;\r
- }\r
-\r
public class QuestInfo : IHaveState\r
{\r
private readonly SortedDictionary<int, QuestStatus> _quests = new SortedDictionary<int, QuestStatus>();\r
private readonly QuestCountList _countList = new QuestCountList();\r
- private readonly ItemInfo _itemInfo;\r
- private readonly BattleInfo _battleInfo;\r
private readonly Func<DateTime> _nowFunc = () => DateTime.Now;\r
+ private DateTime _now;\r
private DateTime _lastReset;\r
private IEnumerable<QuestStatus> _clearedQuest = new List<QuestStatus>();\r
\r
\r
public int AcceptMax { get; set; } = 5;\r
\r
+ public SortedDictionary<int, QuestStatus> QuestDictionary => _quests;\r
+\r
public QuestStatus[] Quests => _quests.Values.ToArray();\r
\r
- public QuestInfo(ItemInfo itemInfo, BattleInfo battleInfo, Func<DateTime> nowFunc = null)\r
+ public QuestInfo(Func<DateTime> nowFunc = null)\r
{\r
- _itemInfo = itemInfo;\r
- _battleInfo = battleInfo;\r
if (nowFunc != null)\r
_nowFunc = nowFunc;\r
}\r
quest.Progress = 100;\r
goto case 2;\r
case 2:\r
- AddQuest(quest, true);\r
+ SetProcessedQuest(quest);\r
break;\r
}\r
}\r
if (_quests.Count <= AcceptMax)\r
break;\r
/*\r
- * ほかのPCで任務を達成した場合、任務が消えずに受領した任務の数が_questCountを超えることがある。\r
+ * ほかのPCで任務を達成した場合、任務が消えずに受領した任務の数がAcceptMaxを超えることがある。\r
* その場合はいったん任務をクリアして、現在のページの任務だけを登録し直す。\r
*/\r
_quests.Clear();\r
}\r
}\r
\r
- private void AddQuest(QuestStatus quest, bool adjustCount)\r
+ private void SetProcessedQuest(QuestStatus quest)\r
{\r
var count = _countList.GetCount(quest.Id);\r
- if (adjustCount)\r
- {\r
- if (count.AdjustCount(quest.Progress))\r
- NeedSave = true;\r
- quest.Material = quest.Material.Concat(count.Spec.Material).ToArray();\r
- }\r
- quest.Count = count;\r
+ if (count.AdjustCount(quest.Progress))\r
+ NeedSave = true;\r
+ quest.Material = quest.Material.Concat(count.Spec.Material).ToArray();\r
+ if (!_quests.ContainsKey(quest.Id))\r
+ NeedSave = true;\r
+ SetQuest(quest);\r
+ }\r
+\r
+ private void SetQuest(QuestStatus quest)\r
+ {\r
+ quest.Count = _countList.GetCount(quest.Id);\r
quest.Color = quest.Category <= _color.Length ? _color[quest.Category - 1] : Control.DefaultBackColor;\r
_quests[quest.Id] = quest;\r
}\r
\r
private void ResetQuests()\r
{\r
- var now = _nowFunc();\r
- var daily = now.Date.AddHours(5);\r
- if (now.Hour < 5)\r
- daily = daily.AddDays(-1);\r
- if (!(_lastReset < daily && daily <= now))\r
+ _now = _nowFunc();\r
+ if (!CrossBoundary(LastMorning))\r
return;\r
RemoveQuest(QuestInterval.Daily);\r
_countList.Remove(QuestInterval.Daily);\r
- var weekly = now.Date.AddDays(-((6 + (int)now.DayOfWeek) % 7)).AddHours(5);\r
- if (_lastReset < weekly && weekly <= now)\r
- {\r
- RemoveQuest(QuestInterval.Weekly);\r
- _countList.Remove(QuestInterval.Weekly);\r
- }\r
- var monthly = new DateTime(now.Year, now.Month, 1, 5, 0, 0);\r
- if (_lastReset < monthly && monthly <= now)\r
- {\r
- RemoveQuest(QuestInterval.Monthly);\r
- _countList.Remove(QuestInterval.Monthly);\r
- }\r
- var season = now.Month / 3;\r
- var quarterly = new DateTime(now.Year - (season == 0 ? 1 : 0), (season == 0 ? 12 : season * 3), 1, 5, 0, 0);\r
- if (_lastReset < quarterly && quarterly <= now)\r
- {\r
- RemoveQuest(QuestInterval.Quarterly);\r
- _countList.Remove(QuestInterval.Quarterly);\r
- }\r
- _lastReset = now;\r
+ ResetWeekly();\r
+ ResetMonthly();\r
+ ResetQuarterly();\r
+ _lastReset = _now;\r
NeedSave = true;\r
}\r
\r
- private void RemoveQuest(QuestInterval interval)\r
- {\r
- foreach (var id in\r
- (from kv in _quests\r
- where kv.Value.Count.Spec.Interval == interval || // 輸送5と空母3はカウンタを見ないとデイリーにならない\r
- kv.Value.Interval == interval\r
- select kv.Key).ToArray())\r
- _quests.Remove(id);\r
- }\r
-\r
- private int _map;\r
- private int _cell;\r
- private bool _boss;\r
-\r
- public void InspectMapStart(dynamic json)\r
- {\r
- if (_quests.TryGetValue(214, out var ago)) // あ号\r
- ago.Count.NowArray[0]++;\r
- InspectMapNext(json);\r
- }\r
-\r
- public void InspectMapNext(dynamic json)\r
- {\r
- _map = (int)json.api_maparea_id * 10 + (int)json.api_mapinfo_no;\r
- _cell = json.api_no() ? (int)json.api_no : 0;\r
- _boss = (int)json.api_event_id == 5;\r
-\r
- if (_quests.TryGetValue(861, out var q861))\r
- {\r
- if (_map == 16 && (int)json.api_event_id == 8)\r
- {\r
- var fleet = _battleInfo.Result.Friend.Main.Where(s => s.NowHp > 0).Select(s => s.Spec.ShipType)\r
- .ToArray();\r
- if (fleet.Count(s => s == 10 || s == 22) == 2)\r
- IncrementCount(q861.Count);\r
- }\r
- }\r
- }\r
-\r
- public void InspectBattleResult(dynamic json)\r
- {\r
- var rank = json.api_win_rank;\r
- foreach (var quest in _quests.Values)\r
- {\r
- var count = quest.Count;\r
- switch (count.Spec)\r
- {\r
- case QuestSortie sortie:\r
- if (count.Id == 216 && !_boss || sortie.Check(rank, _map, _boss))\r
- IncrementCount(count);\r
- break;\r
- case QuestEnemyType enemyType:\r
- var num = enemyType.CountResult(\r
- _battleInfo.Result.Enemy.Main.Concat(_battleInfo.Result.Enemy.Guard));\r
- if (num > 0)\r
- AddCount(count, num);\r
- break;\r
- }\r
- }\r
- if (_quests.TryGetValue(214, out var ago))\r
- {\r
- var count = ago.Count;\r
- if (_boss)\r
- {\r
- IncrementNowArray(count, 2);\r
- if (QuestSortie.CompareRank(rank, "B") <= 0)\r
- IncrementNowArray(count, 3);\r
- }\r
- if (rank == "S")\r
- IncrementNowArray(count, 1);\r
- }\r
- if (_quests.TryGetValue(249, out var q249))\r
- {\r
- if (_map == 25 && _boss && QuestSortie.CompareRank(rank, "S") == 0)\r
- {\r
- var fleet = _battleInfo.Result.Friend.Main.Where(s => s.NowHp > 0).Select(s => s.Spec.Id)\r
- .ToArray();\r
- if (fleet.Intersect(new[] {62, 63, 64, 265, 266, 268, 319, 192, 194}).Count() == 3)\r
- IncrementCount(q249.Count);\r
- }\r
- }\r
- if (_quests.TryGetValue(257, out var q257))\r
- {\r
- if (_map == 14 && _boss && QuestSortie.CompareRank(rank, "S") == 0)\r
- {\r
- var fleet = _battleInfo.Result.Friend.Main.Where(s => s.NowHp > 0).Select(s => s.Spec.ShipType)\r
- .ToArray();\r
- if (fleet[0] == 3 && fleet.Count(s => s == 3) <= 3 && fleet.All(s => s == 2 || s == 3))\r
- IncrementCount(q257.Count);\r
- }\r
- }\r
- if (_quests.TryGetValue(259, out var q259))\r
- {\r
- if (_map == 51 && _boss && QuestSortie.CompareRank(rank, "S") == 0)\r
- {\r
- var fleet = _battleInfo.Result.Friend.Main.Where(s => s.NowHp > 0).Select(s => s.Spec).ToArray();\r
- // ReSharper disable once IdentifierTypo\r
- var ctype = new[]\r
- {\r
- 2, // 伊勢型\r
- 19, // 長門型\r
- 26, // 扶桑型\r
- 37 // 大和型\r
- };\r
- if (fleet.Select(s => s.ShipClass).Count(c => ctype.Contains(c)) == 3 &&\r
- fleet.Count(s => s.ShipType == 3) > 0)\r
- {\r
- IncrementCount(q259.Count);\r
- }\r
- }\r
- }\r
- if (_quests.TryGetValue(264, out var q264))\r
- {\r
- if (_map == 42 && _boss && QuestSortie.CompareRank(rank, "S") == 0)\r
- {\r
- var fleet = _battleInfo.Result.Friend.Main.Where(s => s.NowHp > 0).Select(s => s.Spec)\r
- .ToArray();\r
- if (fleet.Count(spec => spec.ShipType == 2) >= 2 &&\r
- fleet.Count(spec => spec.IsAircraftCarrier) >= 2)\r
- IncrementCount(q264.Count);\r
- }\r
- }\r
- if (_quests.TryGetValue(266, out var q266))\r
- {\r
- if (_map == 25 && _boss && QuestSortie.CompareRank(rank, "S") == 0)\r
- {\r
- var fleet = _battleInfo.Result.Friend.Main.Where(s => s.NowHp > 0).Select(s => s.Spec.ShipType)\r
- .ToArray();\r
- if (fleet[0] == 2 && fleet.OrderBy(x => x).SequenceEqual(new[] {2, 2, 2, 2, 3, 5}))\r
- IncrementCount(q266.Count);\r
- }\r
- }\r
- if (_quests.TryGetValue(280, out var q280))\r
- {\r
- if (!(_boss && QuestSortie.CompareRank(rank, "S") == 0))\r
- return;\r
- var shipTypes = _battleInfo.Result.Friend.Main.Where(s => s.NowHp > 0).Select(s => s.Spec.ShipType)\r
- .ToArray();\r
- if (!(shipTypes.Count(type => type == 1 || type == 2) >= 3 &&\r
- shipTypes.Any(type => new[] {3, 4, 7, 21}.Contains(type))))\r
- return;\r
- var count = q280.Count;\r
- switch (_map)\r
- {\r
- case 12:\r
- IncrementNowArray(count, 0);\r
- break;\r
- case 13:\r
- IncrementNowArray(count, 1);\r
- break;\r
- case 14:\r
- IncrementNowArray(count, 2);\r
- break;\r
- case 21:\r
- IncrementNowArray(count, 3);\r
- break;\r
- }\r
- }\r
- if (_quests.TryGetValue(854, out var opz) && _boss)\r
- {\r
- var count = opz.Count;\r
- switch (_map)\r
- {\r
- case 24 when QuestSortie.CompareRank(rank, "A") <= 0:\r
- IncrementNowArray(count, 0);\r
- break;\r
- case 61 when QuestSortie.CompareRank(rank, "A") <= 0:\r
- IncrementNowArray(count, 1);\r
- break;\r
- case 63 when QuestSortie.CompareRank(rank, "A") <= 0:\r
- IncrementNowArray(count, 2);\r
- NeedSave = true;\r
- break;\r
- case 64 when QuestSortie.CompareRank(rank, "S") <= 0:\r
- IncrementNowArray(count, 3);\r
- break;\r
- }\r
- }\r
- if (_quests.TryGetValue(862, out var q862))\r
- {\r
- if (_map == 63 && _boss && QuestSortie.CompareRank(rank, "A") <= 0)\r
- {\r
- var fleet = _battleInfo.Result.Friend.Main.Where(s => s.NowHp > 0).Select(s => s.Spec.ShipType)\r
- .ToArray();\r
- if (fleet.Count(s => s == 3) >= 2 && fleet.Count(s => s == 16) >= 1)\r
- IncrementCount(q862.Count);\r
- }\r
- }\r
- if (_quests.TryGetValue(873, out var q873))\r
- {\r
- if (_battleInfo.Result.Friend.Main.Count(s => s.NowHp > 0 && s.Spec.ShipType == 3) >= 1 &&\r
- _boss && QuestSortie.CompareRank(rank, "A") <= 0)\r
- {\r
- var count = q873.Count;\r
- switch (_map)\r
- {\r
- case 31:\r
- IncrementNowArray(count, 0);\r
- break;\r
- case 32:\r
- IncrementNowArray(count, 1);\r
- break;\r
- case 33:\r
- IncrementNowArray(count, 2);\r
- break;\r
- }\r
- }\r
- }\r
- if (_quests.TryGetValue(875, out var q875))\r
- {\r
- if (_map == 54 && _boss && QuestSortie.CompareRank(rank, "S") == 0)\r
- {\r
- var fleet = _battleInfo.Result.Friend.Main.Where(s => s.NowHp > 0).Select(s => s.Spec.Id).ToArray();\r
- if (fleet.Contains(543) && fleet.Intersect(new[] {344, 345, 359}).Any())\r
- IncrementCount(q875.Count);\r
- }\r
- }\r
- if (_quests.TryGetValue(888, out var q888))\r
- {\r
- if (!_boss || QuestSortie.CompareRank(rank, "S") != 0)\r
- return;\r
- var fleet = from ship in _battleInfo.Result.Friend.Main where ship.NowHp > 0 select ship.Spec.Id;\r
- var member = new[]\r
- {\r
- 69, 272, 427, // 鳥海\r
- 61, 264, // 青葉\r
- 123, 295, 142, // 衣笠\r
- 59, 262, 416, // 古鷹\r
- 60, 263, 417, // 加古\r
- 51, 213, 477, // 天龍\r
- 115, 293 // 夕張\r
- };\r
- if (fleet.Intersect(member).Count() < 4)\r
- return;\r
- var count = q888.Count;\r
- switch (_map)\r
- {\r
- case 51:\r
- IncrementNowArray(count, 0);\r
- break;\r
- case 53:\r
- IncrementNowArray(count, 1);\r
- break;\r
- case 54:\r
- IncrementNowArray(count, 2);\r
- break;\r
- }\r
- }\r
- if (_quests.TryGetValue(893, out var q893))\r
- {\r
- if (!_boss || QuestSortie.CompareRank(rank, "S") != 0)\r
- return;\r
- var count = q893.Count;\r
- switch (_map)\r
- {\r
- case 15:\r
- IncrementNowArray(count, 0);\r
- break;\r
- case 71:\r
- IncrementNowArray(count, 1);\r
- break;\r
- case 72:\r
- if (_cell == 7)\r
- {\r
- IncrementNowArray(count, 2);\r
- break;\r
- }\r
- IncrementNowArray(count, 3);\r
- break;\r
- }\r
- }\r
- if (_quests.TryGetValue(894, out var q894))\r
- {\r
- if (!_boss ||\r
- QuestSortie.CompareRank(rank, "S") != 0 ||\r
- !_battleInfo.Result.Friend.Main.Any(s => s.Spec.IsAircraftCarrier && s.NowHp > 0))\r
- return;\r
- var count = q894.Count;\r
- switch (_map)\r
- {\r
- case 13:\r
- IncrementNowArray(count, 0);\r
- break;\r
- case 14:\r
- IncrementNowArray(count, 1);\r
- break;\r
- case 21:\r
- IncrementNowArray(count, 2);\r
- break;\r
- case 22:\r
- IncrementNowArray(count, 3);\r
- break;\r
- case 23:\r
- IncrementNowArray(count, 4);\r
- break;\r
- }\r
- }\r
- }\r
-\r
- private int _questFleet;\r
-\r
- public void StartPractice(string request)\r
- {\r
- var values = HttpUtility.ParseQueryString(request);\r
- _questFleet = int.Parse(values["api_deck_id"]) - 1;\r
- }\r
-\r
- public void InspectPracticeResult(dynamic json)\r
- {\r
- foreach (var quest in _quests.Values)\r
- {\r
- var count = quest.Count;\r
- if (!(count.Spec is QuestPractice practice))\r
- continue;\r
- if (practice.Check(json.api_win_rank))\r
- IncrementCount(count);\r
- }\r
- if (_quests.TryGetValue(318, out var q318))\r
- {\r
- if (_questFleet == 0 && QuestSortie.CompareRank(json.api_win_rank, "B") <= 0 &&\r
- _battleInfo.Result.Friend.Main.Count(s => s.Spec.ShipType == 3) >= 2)\r
- {\r
- IncrementCount(q318.Count);\r
- }\r
- }\r
- if (_quests.TryGetValue(330, out var q330))\r
- {\r
- var fleet = _battleInfo.Result.Friend.Main;\r
- if (QuestSortie.CompareRank(json.api_win_rank, "B") <= 0 &&\r
- fleet.Count(s => s.Spec.IsAircraftCarrier) >= 2 &&\r
- fleet.Count(s => s.Spec.ShipType == 2) >= 2 &&\r
- fleet[0].Spec.IsAircraftCarrier)\r
- {\r
- IncrementCount(q330.Count);\r
- }\r
- }\r
- }\r
-\r
- private readonly int[] _missionId = new int[ShipInfo.FleetCount];\r
-\r
- public void InspectDeck(dynamic json)\r
- {\r
- foreach (var entry in json)\r
- _missionId[(int)entry.api_id - 1] = (int)entry.api_mission[1];\r
- }\r
+ private DateTime LastMorning => _now.Date.AddDays(_now.Hour < 5 ? -1 : 0).AddHours(5);\r
\r
- public void InspectMissionResult(string request, dynamic json)\r
+ private void ResetWeekly()\r
{\r
- var values = HttpUtility.ParseQueryString(request);\r
- var deck = int.Parse(values["api_deck_id"]);\r
- if ((int)json.api_clear_result == 0)\r
+ if (!CrossBoundary(LastMonday.AddHours(5)))\r
return;\r
- var mid = _missionId[deck - 1];\r
- foreach (var quest in _quests.Values)\r
- {\r
- var count = quest.Count;\r
- if (!(count.Spec is QuestMission mission))\r
- continue;\r
- if (mission.Check(mid))\r
- IncrementCount(count);\r
- }\r
- if (_quests.TryGetValue(426, out var q426))\r
- {\r
- var count = q426.Count;\r
- switch (mid)\r
- {\r
- case 3:\r
- IncrementNowArray(count, 0);\r
- break;\r
- case 4:\r
- IncrementNowArray(count, 1);\r
- break;\r
- case 5:\r
- IncrementNowArray(count, 2);\r
- break;\r
- case 10:\r
- IncrementNowArray(count, 3);\r
- break;\r
- }\r
- }\r
- if (_quests.TryGetValue(428, out var q428))\r
- {\r
- var count = q428.Count;\r
- switch (mid)\r
- {\r
- case 4:\r
- IncrementNowArray(count, 0);\r
- break;\r
- case 101:\r
- IncrementNowArray(count, 1);\r
- break;\r
- case 102:\r
- IncrementNowArray(count, 2);\r
- break;\r
- }\r
- }\r
- }\r
-\r
- private void IncrementCount(QuestCount count)\r
- {\r
- count.Now++;\r
- NeedSave = true;\r
- }\r
-\r
- private void AddCount(QuestCount count, int value)\r
- {\r
- count.Now += value;\r
- NeedSave = true;\r
- }\r
-\r
- private void IncrementCount(int id)\r
- {\r
- AddCount(id, 1);\r
- }\r
-\r
- private void AddCount(int id, int value)\r
- {\r
- if (_quests.TryGetValue(id, out var quest))\r
- {\r
- quest.Count.Now += value;\r
- NeedSave = true;\r
- }\r
- }\r
-\r
- private void IncrementNowArray(QuestCount count, int n)\r
- {\r
- count.NowArray[n]++;\r
- NeedSave = true;\r
+ RemoveQuest(QuestInterval.Weekly);\r
+ _countList.Remove(QuestInterval.Weekly);\r
}\r
\r
- public void CountNyukyo() => IncrementCount(503);\r
-\r
- public void CountCharge() => IncrementCount(504);\r
-\r
- public void CountCreateItem()\r
- {\r
- IncrementCount(605);\r
- IncrementCount(607);\r
- }\r
+ private DateTime LastMonday => _now.Date.AddDays(-((6 + (int)_now.DayOfWeek) % 7));\r
\r
- public void CountCreateShip()\r
+ private void ResetMonthly()\r
{\r
- IncrementCount(606);\r
- IncrementCount(608);\r
+ if (!CrossBoundary(new DateTime(_now.Year, _now.Month, 1, 5, 0, 0)))\r
+ return;\r
+ RemoveQuest(QuestInterval.Monthly);\r
+ _countList.Remove(QuestInterval.Monthly);\r
}\r
\r
- public void InspectDestroyShip(string request)\r
+ private void ResetQuarterly()\r
{\r
- AddCount(609, HttpUtility.ParseQueryString(request)["api_ship_id"].Split(',').Length);\r
+ if (!CrossBoundary(QuarterlyBoundary.AddHours(5)))\r
+ return;\r
+ RemoveQuest(QuestInterval.Quarterly);\r
+ _countList.Remove(QuestInterval.Quarterly);\r
}\r
\r
- public void CountRemodelSlot() => IncrementCount(619);\r
+ private DateTime QuarterlyBoundary =>\r
+ _now.Month / 3 == 0\r
+ ? new DateTime(_now.Year - 1, 12, 1)\r
+ : new DateTime(_now.Year, _now.Month / 3 * 3, 1);\r
\r
- public void InspectDestroyItem(string request, dynamic json)\r
+ private bool CrossBoundary(DateTime boundary)\r
{\r
- var values = HttpUtility.ParseQueryString(request);\r
- var items = values["api_slotitem_ids"].Split(',')\r
- .Select(id => _itemInfo.GetStatus(int.Parse(id)).Spec).ToArray();\r
- IncrementCount(613); // 613: 資源の再利用\r
- foreach (var quest in _quests.Values)\r
- {\r
- var count = quest.Count;\r
- if (!(count.Spec is QuestDestroyItem destroy))\r
- continue;\r
- if (destroy.Count(count, items))\r
- NeedSave = true;\r
- }\r
- if (_quests.TryGetValue(680, out var q680))\r
- {\r
- q680.Count.NowArray[0] += items.Count(spec => spec.Type == 21);\r
- q680.Count.NowArray[1] += items.Count(spec => spec.Type == 12 || spec.Type == 13);\r
- NeedSave = true;\r
- }\r
+ return _lastReset < boundary && boundary <= _now;\r
}\r
\r
- public void InspectPowerUp(dynamic json)\r
+ private void RemoveQuest(QuestInterval interval)\r
{\r
- if ((int)json.api_powerup_flag == 0)\r
- return;\r
- foreach (var quest in _quests.Values)\r
- {\r
- var count = quest.Count;\r
- if (!(count.Spec is QuestPowerUp))\r
- continue;\r
- IncrementCount(count);\r
- }\r
+ foreach (var id in\r
+ (from kv in _quests\r
+ where kv.Value.Count.Spec.Interval == interval || // 輸送5と空母3はカウンタを見ないとデイリーにならない\r
+ kv.Value.Interval == interval\r
+ select kv.Key).ToArray())\r
+ _quests.Remove(id);\r
}\r
\r
public void InspectStop(string request)\r
NeedSave = true;\r
}\r
\r
- public bool NeedSave { get; private set; }\r
+ public bool NeedSave { get; set; }\r
\r
public void SaveState(Status status)\r
{\r
if (_quests != null)\r
status.QuestList = _quests.Values.ToArray();\r
if (_countList != null)\r
- status.QuestCountList = _countList.CountList.ToArray();\r
+ status.QuestCountList = _countList.NonZeroCountList.ToArray();\r
}\r
\r
public void LoadState(Status status)\r
{\r
_lastReset = status.QuestLastReset;\r
if (status.QuestCountList != null)\r
- _countList.CountList = status.QuestCountList;\r
+ _countList.SetCountList(status.QuestCountList);\r
if (status.QuestList != null)\r
{\r
_quests.Clear();\r
- foreach (var q in status.QuestList)\r
- AddQuest(q, false);\r
+ foreach (var quest in status.QuestList)\r
+ SetQuest(quest);\r
}\r
}\r
}\r
+\r
}
\ No newline at end of file