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 == 280 || 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[] {"1-2", "1-3", "1-4", "2-1"}.Zip(NowArray, (map, n) => n >= 1 ? map : "")
\r
213 .Where(s => !string.IsNullOrEmpty(s)));
\r
215 return string.Join(" ",
\r
216 new[] {"警備任務", "対潜警戒任務", "海上護衛任務", "強硬偵察任務"}
\r
217 .Zip(NowArray, (mission, n) => n >= 1 ? mission : "")
\r
218 .Where(s => !string.IsNullOrEmpty(s)));
\r
220 return string.Join(" ",
\r
221 new[] {"対潜警戒任務", "海峡警備行動", "長時間対潜警戒"}.Zip(NowArray, (mission, n) => n >= 1 ? mission + n : "")
\r
222 .Where(s => !string.IsNullOrEmpty(s)));
\r
224 return string.Join(" ",
\r
225 new[] {"2-4", "6-1", "6-3", "6-4"}.Zip(NowArray, (map, n) => n >= 1 ? map : "")
\r
226 .Where(s => !string.IsNullOrEmpty(s)));
\r
228 return string.Join(" ",
\r
229 new[] {"3-1", "3-2", "3-3"}.Zip(NowArray, (map, n) => n >= 1 ? map : "")
\r
230 .Where(s => !string.IsNullOrEmpty(s)));
\r
232 return string.Join(" ",
\r
233 new[] {"5-1", "5-3", "5-4"}.Zip(NowArray, (map, n) => n >= 1 ? map : "")
\r
234 .Where(s => !string.IsNullOrEmpty(s)));
\r
236 return string.Join(" ",
\r
237 new[] {"艦戦", "艦爆", "艦攻", "水偵"}.Zip(NowArray, (type, n) => n >= 1 ? type + n : "")
\r
238 .Where(s => !string.IsNullOrEmpty(s)));
\r
240 return string.Join(" ",
\r
241 new[] {"1-5", "7-1", "7-2G", "7-2M"}.Zip(NowArray, (map, n) => n >= 1 ? $"{map}:{n}" : "")
\r
242 .Where(s => !string.IsNullOrEmpty(s)));
\r
244 return string.Join(" ",
\r
245 new[] {"1-3", "1-4", "2-1", "2-2", "2-3"}.Zip(NowArray, (map, n) => n >= 1 ? map : "")
\r
246 .Where(s => !string.IsNullOrEmpty(s)));
\r
251 public bool Cleared => NowArray?.Zip(Spec.MaxArray, (n, m) => n >= m).All(x => x) ??
\r
252 Spec.Max != 0 && Now >= Spec.Max;
\r
255 public class QuestInfo : IHaveState
\r
257 private readonly SortedDictionary<int, QuestStatus> _quests = new SortedDictionary<int, QuestStatus>();
\r
258 private readonly QuestCountList _countList = new QuestCountList();
\r
259 private readonly ItemInfo _itemInfo;
\r
260 private readonly BattleInfo _battleInfo;
\r
261 private readonly Func<DateTime> _nowFunc = () => DateTime.Now;
\r
262 private DateTime _lastReset;
\r
263 private IEnumerable<QuestStatus> _clearedQuest = new List<QuestStatus>();
\r
265 private readonly Color[] _color =
\r
267 Color.FromArgb(60, 141, 76), Color.FromArgb(232, 57, 41), Color.FromArgb(136, 204, 120),
\r
268 Color.FromArgb(52, 147, 185), Color.FromArgb(220, 198, 126), Color.FromArgb(168, 111, 76),
\r
269 Color.FromArgb(200, 148, 231), Color.FromArgb(232, 57, 41)
\r
272 public int AcceptMax { get; set; } = 5;
\r
274 public QuestStatus[] Quests => _quests.Values.ToArray();
\r
276 public QuestInfo(ItemInfo itemInfo, BattleInfo battleInfo, Func<DateTime> nowFunc = null)
\r
278 _itemInfo = itemInfo;
\r
279 _battleInfo = battleInfo;
\r
280 if (nowFunc != null)
\r
281 _nowFunc = nowFunc;
\r
284 public void GetNotifications(out string[] notify, out string[] stop)
\r
286 var cleared = _quests.Values.Where(q => q.Count.Cleared).ToArray();
\r
287 notify = cleared.Except(_clearedQuest, new QuestComparer()).Select(q => q.Name).ToArray();
\r
288 stop = _clearedQuest.Except(cleared, new QuestComparer()).Select(q => q.Name).ToArray();
\r
289 _clearedQuest = cleared;
\r
292 private class QuestComparer : IEqualityComparer<QuestStatus>
\r
294 public bool Equals(QuestStatus x, QuestStatus y)
\r
296 return x?.Id == y?.Id;
\r
299 public int GetHashCode(QuestStatus obj)
\r
305 private readonly QuestInterval[] _intervals =
\r
307 QuestInterval.Daily, QuestInterval.Weekly, QuestInterval.Monthly,
\r
308 QuestInterval.Other, QuestInterval.Quarterly
\r
311 private readonly int[] _progress = new[] {0, 50, 80};
\r
313 public void InspectQuestList(dynamic json)
\r
316 if (json.api_list == null)
\r
318 for (var i = 0; i < 2; i++)
\r
320 foreach (var entry in json.api_list)
\r
322 if (entry is double) // -1の場合がある。
\r
324 var quest = new QuestStatus
\r
326 Id = (int)entry.api_no,
\r
327 Category = (int)entry.api_category,
\r
328 Progress = _progress[(int)entry.api_progress_flag],
\r
329 Interval = _intervals[(int)entry.api_type - 1],
\r
330 Name = (string)entry.api_title,
\r
331 Detail = ((string)entry.api_detail).Replace("<br>", "\r\n"),
\r
332 Material = (int[])entry.api_get_material
\r
334 var state = (int)entry.api_state;
\r
338 if (_quests.Remove(quest.Id))
\r
342 quest.Progress = 100;
\r
345 AddQuest(quest, true);
\r
349 if (_quests.Count <= AcceptMax)
\r
352 * ほかのPCで任務を達成した場合、任務が消えずに受領した任務の数が_questCountを超えることがある。
\r
353 * その場合はいったん任務をクリアして、現在のページの任務だけを登録し直す。
\r
359 private void AddQuest(QuestStatus quest, bool adjustCount)
\r
361 var count = _countList.GetCount(quest.Id);
\r
364 if (count.AdjustCount(quest.Progress))
\r
366 quest.Material = quest.Material.Concat(count.Spec.Material).ToArray();
\r
368 quest.Count = count;
\r
369 quest.Color = quest.Category <= _color.Length ? _color[quest.Category - 1] : Control.DefaultBackColor;
\r
370 _quests[quest.Id] = quest;
\r
373 public void ClearQuests()
\r
378 private void ResetQuests()
\r
380 var now = _nowFunc();
\r
381 var daily = now.Date.AddHours(5);
\r
383 daily = daily.AddDays(-1);
\r
384 if (!(_lastReset < daily && daily <= now))
\r
386 RemoveQuest(QuestInterval.Daily);
\r
387 _countList.Remove(QuestInterval.Daily);
\r
388 var weekly = now.Date.AddDays(-((6 + (int)now.DayOfWeek) % 7)).AddHours(5);
\r
389 if (_lastReset < weekly && weekly <= now)
\r
391 RemoveQuest(QuestInterval.Weekly);
\r
392 _countList.Remove(QuestInterval.Weekly);
\r
394 var monthly = new DateTime(now.Year, now.Month, 1, 5, 0, 0);
\r
395 if (_lastReset < monthly && monthly <= now)
\r
397 RemoveQuest(QuestInterval.Monthly);
\r
398 _countList.Remove(QuestInterval.Monthly);
\r
400 var season = now.Month / 3;
\r
401 var quarterly = new DateTime(now.Year - (season == 0 ? 1 : 0), (season == 0 ? 12 : season * 3), 1, 5, 0, 0);
\r
402 if (_lastReset < quarterly && quarterly <= now)
\r
404 RemoveQuest(QuestInterval.Quarterly);
\r
405 _countList.Remove(QuestInterval.Quarterly);
\r
411 private void RemoveQuest(QuestInterval interval)
\r
414 (from kv in _quests
\r
415 where kv.Value.Count.Spec.Interval == interval || // 輸送5と空母3はカウンタを見ないとデイリーにならない
\r
416 kv.Value.Interval == interval
\r
417 select kv.Key).ToArray())
\r
418 _quests.Remove(id);
\r
423 private bool _boss;
\r
425 public void InspectMapStart(dynamic json)
\r
427 if (_quests.TryGetValue(214, out var ago)) // あ号
\r
428 ago.Count.NowArray[0]++;
\r
429 InspectMapNext(json);
\r
432 public void InspectMapNext(dynamic json)
\r
434 _map = (int)json.api_maparea_id * 10 + (int)json.api_mapinfo_no;
\r
435 _cell = json.api_no() ? (int)json.api_no : 0;
\r
436 _boss = (int)json.api_event_id == 5;
\r
438 if (_quests.TryGetValue(861, out var q861))
\r
440 if (_map == 16 && (int)json.api_event_id == 8)
\r
442 var fleet = _battleInfo.Result.Friend.Main.Where(s => s.NowHp > 0).Select(s => s.Spec.ShipType)
\r
444 if (fleet.Count(s => s == 10 || s == 22) == 2)
\r
445 IncrementCount(q861.Count);
\r
450 public void InspectBattleResult(dynamic json)
\r
452 var rank = json.api_win_rank;
\r
453 foreach (var quest in _quests.Values)
\r
455 var count = quest.Count;
\r
456 switch (count.Spec)
\r
458 case QuestSortie sortie:
\r
459 if (count.Id == 216 && !_boss || sortie.Check(rank, _map, _boss))
\r
460 IncrementCount(count);
\r
462 case QuestEnemyType enemyType:
\r
463 var num = enemyType.CountResult(
\r
464 _battleInfo.Result.Enemy.Main.Concat(_battleInfo.Result.Enemy.Guard));
\r
466 AddCount(count, num);
\r
470 if (_quests.TryGetValue(214, out var ago))
\r
472 var count = ago.Count;
\r
475 IncrementNowArray(count, 2);
\r
476 if (QuestSortie.CompareRank(rank, "B") <= 0)
\r
477 IncrementNowArray(count, 3);
\r
480 IncrementNowArray(count, 1);
\r
482 if (_quests.TryGetValue(249, out var q249))
\r
484 if (_map == 25 && _boss && QuestSortie.CompareRank(rank, "S") == 0)
\r
486 var fleet = _battleInfo.Result.Friend.Main.Where(s => s.NowHp > 0).Select(s => s.Spec.Id)
\r
488 if (fleet.Intersect(new[] {62, 63, 64, 265, 266, 268, 319, 192, 194}).Count() == 3)
\r
489 IncrementCount(q249.Count);
\r
492 if (_quests.TryGetValue(257, out var q257))
\r
494 if (_map == 14 && _boss && QuestSortie.CompareRank(rank, "S") == 0)
\r
496 var fleet = _battleInfo.Result.Friend.Main.Where(s => s.NowHp > 0).Select(s => s.Spec.ShipType)
\r
498 if (fleet[0] == 3 && fleet.Count(s => s == 3) <= 3 && fleet.All(s => s == 2 || s == 3))
\r
499 IncrementCount(q257.Count);
\r
502 if (_quests.TryGetValue(259, out var q259))
\r
504 if (_map == 51 && _boss && QuestSortie.CompareRank(rank, "S") == 0)
\r
506 var fleet = _battleInfo.Result.Friend.Main.Where(s => s.NowHp > 0).Select(s => s.Spec).ToArray();
\r
507 // ReSharper disable once IdentifierTypo
\r
515 if (fleet.Select(s => s.ShipClass).Count(c => ctype.Contains(c)) == 3 &&
\r
516 fleet.Count(s => s.ShipType == 3) > 0)
\r
518 IncrementCount(q259.Count);
\r
522 if (_quests.TryGetValue(264, out var q264))
\r
524 if (_map == 42 && _boss && QuestSortie.CompareRank(rank, "S") == 0)
\r
526 var fleet = _battleInfo.Result.Friend.Main.Where(s => s.NowHp > 0).Select(s => s.Spec)
\r
528 if (fleet.Count(spec => spec.ShipType == 2) >= 2 &&
\r
529 fleet.Count(spec => spec.IsAircraftCarrier) >= 2)
\r
530 IncrementCount(q264.Count);
\r
533 if (_quests.TryGetValue(266, out var q266))
\r
535 if (_map == 25 && _boss && QuestSortie.CompareRank(rank, "S") == 0)
\r
537 var fleet = _battleInfo.Result.Friend.Main.Where(s => s.NowHp > 0).Select(s => s.Spec.ShipType)
\r
539 if (fleet[0] == 2 && fleet.OrderBy(x => x).SequenceEqual(new[] {2, 2, 2, 2, 3, 5}))
\r
540 IncrementCount(q266.Count);
\r
543 if (_quests.TryGetValue(280, out var q280))
\r
545 if (!(_boss && QuestSortie.CompareRank(rank, "S") == 0))
\r
547 var count = q280.Count;
\r
551 IncrementNowArray(count, 0);
\r
554 IncrementNowArray(count, 1);
\r
557 IncrementNowArray(count, 2);
\r
560 IncrementNowArray(count, 3);
\r
564 if (_quests.TryGetValue(854, out var opz) && _boss)
\r
566 var count = opz.Count;
\r
569 case 24 when QuestSortie.CompareRank(rank, "A") <= 0:
\r
570 IncrementNowArray(count, 0);
\r
572 case 61 when QuestSortie.CompareRank(rank, "A") <= 0:
\r
573 IncrementNowArray(count, 1);
\r
575 case 63 when QuestSortie.CompareRank(rank, "A") <= 0:
\r
576 IncrementNowArray(count, 2);
\r
579 case 64 when QuestSortie.CompareRank(rank, "S") <= 0:
\r
580 IncrementNowArray(count, 3);
\r
584 if (_quests.TryGetValue(862, out var q862))
\r
586 if (_map == 63 && _boss && QuestSortie.CompareRank(rank, "A") <= 0)
\r
588 var fleet = _battleInfo.Result.Friend.Main.Where(s => s.NowHp > 0).Select(s => s.Spec.ShipType)
\r
590 if (fleet.Count(s => s == 3) >= 2 && fleet.Count(s => s == 16) >= 1)
\r
591 IncrementCount(q862.Count);
\r
594 if (_quests.TryGetValue(873, out var q873))
\r
596 if (_battleInfo.Result.Friend.Main.Count(s => s.NowHp > 0 && s.Spec.ShipType == 3) >= 1 &&
\r
597 _boss && QuestSortie.CompareRank(rank, "A") <= 0)
\r
599 var count = q873.Count;
\r
603 IncrementNowArray(count, 0);
\r
606 IncrementNowArray(count, 1);
\r
609 IncrementNowArray(count, 2);
\r
614 if (_quests.TryGetValue(875, out var q875))
\r
616 if (_map == 54 && _boss && QuestSortie.CompareRank(rank, "S") == 0)
\r
618 var fleet = _battleInfo.Result.Friend.Main.Where(s => s.NowHp > 0).Select(s => s.Spec.Id).ToArray();
\r
619 if (fleet.Contains(543) && fleet.Intersect(new[] {344, 345, 359}).Any())
\r
620 IncrementCount(q875.Count);
\r
623 if (_quests.TryGetValue(888, out var q888))
\r
625 if (!_boss || QuestSortie.CompareRank(rank, "S") != 0)
\r
627 var fleet = from ship in _battleInfo.Result.Friend.Main where ship.NowHp > 0 select ship.Spec.Id;
\r
630 69, 272, 427, // 鳥海
\r
632 123, 295, 142, // 衣笠
\r
633 59, 262, 416, // 古鷹
\r
634 60, 263, 417, // 加古
\r
635 51, 213, 477, // 天龍
\r
638 if (fleet.Intersect(member).Count() < 4)
\r
640 var count = q888.Count;
\r
644 IncrementNowArray(count, 0);
\r
647 IncrementNowArray(count, 1);
\r
650 IncrementNowArray(count, 2);
\r
654 if (_quests.TryGetValue(893, out var q893))
\r
656 if (!_boss || QuestSortie.CompareRank(rank, "S") != 0)
\r
658 var count = q893.Count;
\r
662 IncrementNowArray(count, 0);
\r
665 IncrementNowArray(count, 1);
\r
670 IncrementNowArray(count, 2);
\r
673 IncrementNowArray(count, 3);
\r
677 if (_quests.TryGetValue(894, out var q894))
\r
680 QuestSortie.CompareRank(rank, "S") != 0 ||
\r
681 !_battleInfo.Result.Friend.Main.Any(s => s.Spec.IsAircraftCarrier && s.NowHp > 0))
\r
683 var count = q894.Count;
\r
687 IncrementNowArray(count, 0);
\r
690 IncrementNowArray(count, 1);
\r
693 IncrementNowArray(count, 2);
\r
696 IncrementNowArray(count, 3);
\r
699 IncrementNowArray(count, 4);
\r
705 private int _questFleet;
\r
707 public void StartPractice(string request)
\r
709 var values = HttpUtility.ParseQueryString(request);
\r
710 _questFleet = int.Parse(values["api_deck_id"]) - 1;
\r
713 public void InspectPracticeResult(dynamic json)
\r
715 foreach (var quest in _quests.Values)
\r
717 var count = quest.Count;
\r
718 if (!(count.Spec is QuestPractice practice))
\r
720 if (practice.Check(json.api_win_rank))
\r
721 IncrementCount(count);
\r
723 if (_quests.TryGetValue(318, out var q318))
\r
725 if (_questFleet == 0 && QuestSortie.CompareRank(json.api_win_rank, "B") <= 0 &&
\r
726 _battleInfo.Result.Friend.Main.Count(s => s.Spec.ShipType == 3) >= 2)
\r
728 IncrementCount(q318.Count);
\r
731 if (_quests.TryGetValue(330, out var q330))
\r
733 var fleet = _battleInfo.Result.Friend.Main;
\r
734 if (QuestSortie.CompareRank(json.api_win_rank, "B") <= 0 &&
\r
735 fleet.Count(s => s.Spec.IsAircraftCarrier) >= 2 &&
\r
736 fleet.Count(s => s.Spec.ShipType == 2) >= 2 &&
\r
737 fleet[0].Spec.IsAircraftCarrier)
\r
739 IncrementCount(q330.Count);
\r
744 private readonly int[] _missionId = new int[ShipInfo.FleetCount];
\r
746 public void InspectDeck(dynamic json)
\r
748 foreach (var entry in json)
\r
749 _missionId[(int)entry.api_id - 1] = (int)entry.api_mission[1];
\r
752 public void InspectMissionResult(string request, dynamic json)
\r
754 var values = HttpUtility.ParseQueryString(request);
\r
755 var deck = int.Parse(values["api_deck_id"]);
\r
756 if ((int)json.api_clear_result == 0)
\r
758 var mid = _missionId[deck - 1];
\r
759 foreach (var quest in _quests.Values)
\r
761 var count = quest.Count;
\r
762 if (!(count.Spec is QuestMission mission))
\r
764 if (mission.Check(mid))
\r
765 IncrementCount(count);
\r
767 if (_quests.TryGetValue(426, out var q426))
\r
769 var count = q426.Count;
\r
773 IncrementNowArray(count, 0);
\r
776 IncrementNowArray(count, 1);
\r
779 IncrementNowArray(count, 2);
\r
782 IncrementNowArray(count, 3);
\r
786 if (_quests.TryGetValue(428, out var q428))
\r
788 var count = q428.Count;
\r
792 IncrementNowArray(count, 0);
\r
795 IncrementNowArray(count, 1);
\r
798 IncrementNowArray(count, 2);
\r
804 private void IncrementCount(QuestCount count)
\r
810 private void AddCount(QuestCount count, int value)
\r
812 count.Now += value;
\r
816 private void IncrementCount(int id)
\r
821 private void AddCount(int id, int value)
\r
823 if (_quests.TryGetValue(id, out var quest))
\r
825 quest.Count.Now += value;
\r
830 private void IncrementNowArray(QuestCount count, int n)
\r
832 count.NowArray[n]++;
\r
836 public void CountNyukyo() => IncrementCount(503);
\r
838 public void CountCharge() => IncrementCount(504);
\r
840 public void CountCreateItem()
\r
842 IncrementCount(605);
\r
843 IncrementCount(607);
\r
846 public void CountCreateShip()
\r
848 IncrementCount(606);
\r
849 IncrementCount(608);
\r
852 public void InspectDestroyShip(string request)
\r
854 AddCount(609, HttpUtility.ParseQueryString(request)["api_ship_id"].Split(',').Length);
\r
857 public void CountRemodelSlot() => IncrementCount(619);
\r
859 public void InspectDestroyItem(string request, dynamic json)
\r
861 var values = HttpUtility.ParseQueryString(request);
\r
862 var items = values["api_slotitem_ids"].Split(',')
\r
863 .Select(id => _itemInfo.GetStatus(int.Parse(id)).Spec).ToArray();
\r
864 IncrementCount(613); // 613: 資源の再利用
\r
865 foreach (var quest in _quests.Values)
\r
867 var count = quest.Count;
\r
868 if (!(count.Spec is QuestDestroyItem destroy))
\r
870 if (destroy.Count(count, items))
\r
873 if (_quests.TryGetValue(680, out var q680))
\r
875 q680.Count.NowArray[0] += items.Count(spec => spec.Type == 21);
\r
876 q680.Count.NowArray[1] += items.Count(spec => spec.Type == 12 || spec.Type == 13);
\r
881 public void InspectPowerUp(dynamic json)
\r
883 if ((int)json.api_powerup_flag == 0)
\r
885 foreach (var quest in _quests.Values)
\r
887 var count = quest.Count;
\r
888 if (!(count.Spec is QuestPowerUp))
\r
890 IncrementCount(count);
\r
894 public void InspectStop(string request)
\r
896 var values = HttpUtility.ParseQueryString(request);
\r
897 _quests.Remove(int.Parse(values["api_quest_id"]));
\r
901 public void InspectClearItemGet(string request)
\r
903 var values = HttpUtility.ParseQueryString(request);
\r
904 var id = int.Parse(values["api_quest_id"]);
\r
905 _countList.Remove(id);
\r
906 _quests.Remove(id);
\r
910 public bool NeedSave { get; private set; }
\r
912 public void SaveState(Status status)
\r
915 status.QuestLastReset = _lastReset;
\r
916 if (_quests != null)
\r
917 status.QuestList = _quests.Values.ToArray();
\r
918 if (_countList != null)
\r
919 status.QuestCountList = _countList.CountList.ToArray();
\r
922 public void LoadState(Status status)
\r
924 _lastReset = status.QuestLastReset;
\r
925 if (status.QuestCountList != null)
\r
926 _countList.CountList = status.QuestCountList;
\r
927 if (status.QuestList != null)
\r
930 foreach (var q in status.QuestList)
\r
931 AddQuest(q, false);
\r