OSDN Git Service

戦果拡張任務!「Z作戦」後段作戦のカウンターを実装する
[kancollesniffer/KancolleSniffer.git] / KancolleSniffer / Model / QuestCounter.cs
1 // Copyright (C) 2019 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.Collections.Generic;\r
17 using System.Linq;\r
18 using System.Xml.Serialization;\r
19 using KancolleSniffer.Util;\r
20 \r
21 namespace KancolleSniffer.Model\r
22 {\r
23     public class QuestCount\r
24     {\r
25         public int Id { get; set; }\r
26         public int Now { get; set; }\r
27         public int[] NowArray { get; set; }\r
28 \r
29         [XmlIgnore]\r
30         public QuestSpec Spec { get; set; }\r
31 \r
32         public bool AdjustCount(int progress)\r
33         {\r
34             if (!Spec.AdjustCount)\r
35                 return false;\r
36             if (NowArray != null)\r
37             {\r
38                 if (progress != 100)\r
39                     return false;\r
40                 NowArray = NowArray.Zip(Spec.MaxArray, Math.Max).ToArray();\r
41                 return true;\r
42             }\r
43             var next = 0;\r
44             switch (progress)\r
45             {\r
46                 case 0:\r
47                     next = 50;\r
48                     break;\r
49                 case 50:\r
50                     next = 80;\r
51                     break;\r
52                 case 80:\r
53                     next = 100;\r
54                     break;\r
55                 case 100:\r
56                     next = 100000;\r
57                     break;\r
58             }\r
59             var now = Now + Spec.Shift;\r
60             var max = Spec.Max + Spec.Shift;\r
61             var low = (int)Math.Ceiling(max * progress / 100.0);\r
62             if (low >= max && progress != 100)\r
63                 low = max - 1;\r
64             var high = (int)Math.Ceiling(max * next / 100.0);\r
65             if (now < low)\r
66             {\r
67                 Now = low - Spec.Shift;\r
68                 return true;\r
69             }\r
70             if (now >= high)\r
71             {\r
72                 Now = high - 1 - Spec.Shift;\r
73                 return true;\r
74             }\r
75             return false;\r
76         }\r
77 \r
78         public override string ToString()\r
79         {\r
80             if (Id == 280 || Id == 426 || Id == 854 || Id == 872 || Id == 873 || Id == 888 || Id == 894)\r
81                 return $"{NowArray.Count(n => n >= 1)}/{Spec.MaxArray.Length}";\r
82             return NowArray != null\r
83                 ? string.Join(" ", NowArray.Zip(Spec.MaxArray, (n, m) => $"{n}/{m}"))\r
84                 : $"{Now}/{Spec.Max}";\r
85         }\r
86 \r
87         public QuestCount Clone()\r
88         {\r
89             var clone = (QuestCount)MemberwiseClone();\r
90             if (NowArray != null)\r
91                 clone.NowArray = (int[])NowArray.Clone();\r
92             return clone;\r
93         }\r
94 \r
95         public bool Equals(QuestCount other)\r
96         {\r
97             if (Id != other.Id)\r
98                 return false;\r
99             if (NowArray == null)\r
100                 return Now == other.Now;\r
101             return NowArray.SequenceEqual(other.NowArray);\r
102         }\r
103 \r
104         public string ToToolTip()\r
105         {\r
106             switch (Id)\r
107             {\r
108                 case 280:\r
109                     return string.Join(" ",\r
110                         new[] {"1-2", "1-3", "1-4", "2-1"}.Zip(NowArray, (map, n) => n >= 1 ? map : "")\r
111                             .Where(s => !string.IsNullOrEmpty(s)));\r
112                 case 426:\r
113                     return string.Join(" ",\r
114                         new[] {"警備任務", "対潜警戒任務", "海上護衛任務", "強硬偵察任務"}\r
115                             .Zip(NowArray, (mission, n) => n >= 1 ? mission : "")\r
116                             .Where(s => !string.IsNullOrEmpty(s)));\r
117                 case 428:\r
118                     return string.Join(" ",\r
119                         new[] {"対潜警戒任務", "海峡警備行動", "長時間対潜警戒"}.Zip(NowArray, (mission, n) => n >= 1 ? mission + n : "")\r
120                             .Where(s => !string.IsNullOrEmpty(s)));\r
121                 case 854:\r
122                     return string.Join(" ",\r
123                         new[] {"2-4", "6-1", "6-3", "6-4"}.Zip(NowArray, (map, n) => n >= 1 ? map : "")\r
124                             .Where(s => !string.IsNullOrEmpty(s)));\r
125                 case 872:\r
126                     return string.Join(" ",\r
127                         new[] {"7-2M", "5-5", "6-2", "6-5"}.Zip(NowArray, (map, n) => n >= 1 ? map : "")\r
128                             .Where(s => !string.IsNullOrEmpty(s)));\r
129                 case 873:\r
130                     return string.Join(" ",\r
131                         new[] {"3-1", "3-2", "3-3"}.Zip(NowArray, (map, n) => n >= 1 ? map : "")\r
132                             .Where(s => !string.IsNullOrEmpty(s)));\r
133                 case 888:\r
134                     return string.Join(" ",\r
135                         new[] {"5-1", "5-3", "5-4"}.Zip(NowArray, (map, n) => n >= 1 ? map : "")\r
136                             .Where(s => !string.IsNullOrEmpty(s)));\r
137                 case 688:\r
138                     return string.Join(" ",\r
139                         new[] {"艦戦", "艦爆", "艦攻", "水偵"}.Zip(NowArray, (type, n) => n >= 1 ? type + n : "")\r
140                             .Where(s => !string.IsNullOrEmpty(s)));\r
141                 case 893:\r
142                     return string.Join(" ",\r
143                         new[] {"1-5", "7-1", "7-2G", "7-2M"}.Zip(NowArray, (map, n) => n >= 1 ? $"{map}:{n}" : "")\r
144                             .Where(s => !string.IsNullOrEmpty(s)));\r
145                 case 894:\r
146                     return string.Join(" ",\r
147                         new[] {"1-3", "1-4", "2-1", "2-2", "2-3"}.Zip(NowArray, (map, n) => n >= 1 ? map : "")\r
148                             .Where(s => !string.IsNullOrEmpty(s)));\r
149             }\r
150             return "";\r
151         }\r
152 \r
153         public bool Cleared => NowArray?.Zip(Spec.MaxArray, (n, m) => n >= m).All(x => x) ??\r
154                                Spec.Max != 0 && Now >= Spec.Max;\r
155     }\r
156 \r
157     public class QuestCounter\r
158     {\r
159         private readonly QuestInfo _questInfo;\r
160         private readonly ItemInfo _itemInfo;\r
161         private readonly BattleInfo _battleInfo;\r
162         private readonly SortedDictionary<int, QuestStatus> _quests;\r
163         private int _map;\r
164         private int _cell;\r
165         private bool _boss;\r
166 \r
167         private class ResultShipSpecs\r
168         {\r
169             public ResultShipSpecs(BattleInfo battleInfo)\r
170             {\r
171                 Specs = battleInfo.Result?.Friend.Main.Where(s => s.NowHp > 0).Select(ship => ship.Spec).ToArray() ??\r
172                         new ShipSpec[0];\r
173                 Ids = Specs.Select(spec => spec.Id).ToArray();\r
174                 Types = Specs.Select(spec => spec.ShipType).ToArray();\r
175                 Classes = Specs.Select(spec => spec.ShipClass).ToArray();\r
176                 Flagship = Specs.FirstOrDefault();\r
177                 FlagshipType = Types.FirstOrDefault();\r
178             }\r
179 \r
180             public ShipSpec[] Specs { get; }\r
181             public int[] Ids { get; }\r
182             public int[] Types { get; }\r
183             public int[] Classes { get; }\r
184             public ShipSpec Flagship { get; }\r
185             public int FlagshipType { get; }\r
186         }\r
187 \r
188         public QuestCounter(QuestInfo questInfo, ItemInfo itemInfo, BattleInfo battleInfo)\r
189         {\r
190             _questInfo = questInfo;\r
191             _quests = questInfo.QuestDictionary;\r
192             _itemInfo = itemInfo;\r
193             _battleInfo = battleInfo;\r
194         }\r
195 \r
196         private bool NeedSave\r
197         {\r
198             set => _questInfo.NeedSave = value;\r
199         }\r
200 \r
201         public void InspectMapStart(dynamic json)\r
202         {\r
203             if (_quests.TryGetValue(214, out var ago)) // あ号\r
204                 ago.Count.NowArray[0]++;\r
205             InspectMapNext(json);\r
206         }\r
207 \r
208         public void InspectMapNext(dynamic json)\r
209         {\r
210             _map = (int)json.api_maparea_id * 10 + (int)json.api_mapinfo_no;\r
211             _cell = json.api_no() ? (int)json.api_no : 0;\r
212             _boss = (int)json.api_event_id == 5;\r
213 \r
214             if (_quests.TryGetValue(861, out var q861) && _map == 16 && (int)json.api_event_id == 8)\r
215             {\r
216                 if (new ResultShipSpecs(_battleInfo).Types.Count(s => s == 10 || s == 22) == 2)\r
217                     Increment(q861.Count);\r
218             }\r
219         }\r
220 \r
221         private class Rank\r
222         {\r
223             private readonly string _rank;\r
224 \r
225             public Rank(string rank)\r
226             {\r
227                 _rank = rank;\r
228             }\r
229 \r
230             public bool S => QuestSortie.CompareRank(_rank, "S") == 0;\r
231             public bool A => QuestSortie.CompareRank(_rank, "A") <= 0;\r
232             public bool B => QuestSortie.CompareRank(_rank, "B") <= 0;\r
233         }\r
234 \r
235         public void InspectBattleResult(dynamic json)\r
236         {\r
237             var rawRak = json.api_win_rank;\r
238             var rank = new Rank(rawRak);\r
239             var specs = new ResultShipSpecs(_battleInfo);\r
240             foreach (var quest in _quests.Values)\r
241             {\r
242                 var count = quest.Count;\r
243                 switch (count.Spec)\r
244                 {\r
245                     case QuestSortie sortie:\r
246                         if (count.Id == 216 && !_boss || sortie.Check(rawRak, _map, _boss))\r
247                             Increment(count);\r
248                         continue;\r
249                     case QuestEnemyType enemyType:\r
250                         var num = enemyType.CountResult(\r
251                             _battleInfo.Result.Enemy.Main.Concat(_battleInfo.Result.Enemy.Guard));\r
252                         if (num > 0)\r
253                             Add(count, num);\r
254                         continue;\r
255                 }\r
256                 switch (quest.Id)\r
257                 {\r
258                     case 214:\r
259                         if (rank.S)\r
260                             IncrementNth(count, 1);\r
261                         if (_boss)\r
262                         {\r
263                             IncrementNth(count, 2);\r
264                             if (rank.B)\r
265                                 IncrementNth(count, 3);\r
266                         }\r
267                         break;\r
268                     case 249:\r
269                         if (_map == 25 && _boss && rank.S &&\r
270                             specs.Ids.Intersect(new[] {62, 63, 64, 265, 266, 268, 319, 192, 194}).Count() == 3)\r
271                         {\r
272                             Increment(count);\r
273                         }\r
274                         break;\r
275                     case 257:\r
276                         if (_map == 14 && _boss && rank.S &&\r
277                             specs.FlagshipType == 3 &&\r
278                             specs.Types.Count(s => s == 3) <= 3 &&\r
279                             specs.Types.All(s => s == 2 || s == 3))\r
280                         {\r
281                             Increment(count);\r
282                         }\r
283                         break;\r
284                     case 259:\r
285                         if (_map == 51 && _boss && rank.S &&\r
286                             specs.Types.Count(type => type == 3) > 0 &&\r
287                             specs.Classes.Count(c => new[]\r
288                             {\r
289                                 2, // 伊勢型\r
290                                 19, // 長門型\r
291                                 26, // 扶桑型\r
292                                 37 // 大和型\r
293                             }.Contains(c)) == 3)\r
294                         {\r
295                             Increment(count);\r
296                         }\r
297                         break;\r
298                     case 264:\r
299                         if (_map == 42 && _boss && rank.S &&\r
300                             specs.Types.Count(type => type == 2) >= 2 &&\r
301                             specs.Specs.Count(spec => spec.IsAircraftCarrier) >= 2)\r
302                         {\r
303                             Increment(count);\r
304                         }\r
305                         break;\r
306                     case 266:\r
307                         if (_map == 25 && _boss && rank.S &&\r
308                             specs.FlagshipType == 2 &&\r
309                             specs.Types.OrderBy(x => x).SequenceEqual(new[] {2, 2, 2, 2, 3, 5}))\r
310                         {\r
311                             Increment(count);\r
312                         }\r
313                         break;\r
314                     case 280:\r
315                         if (_boss && rank.S &&\r
316                             specs.Types.Count(type => type == 1 || type == 2) >= 3 &&\r
317                             specs.Types.Intersect(new[] {3, 4, 7, 21}).Any())\r
318                         {\r
319                             switch (_map)\r
320                             {\r
321                                 case 12:\r
322                                     IncrementNth(count, 0);\r
323                                     break;\r
324                                 case 13:\r
325                                     IncrementNth(count, 1);\r
326                                     break;\r
327                                 case 14:\r
328                                     IncrementNth(count, 2);\r
329                                     break;\r
330                                 case 21:\r
331                                     IncrementNth(count, 3);\r
332                                     break;\r
333                             }\r
334                         }\r
335                         break;\r
336                     case 854:\r
337                         if (_boss)\r
338                         {\r
339                             switch (_map)\r
340                             {\r
341                                 case 24 when rank.A:\r
342                                     IncrementNth(count, 0);\r
343                                     break;\r
344                                 case 61 when rank.A:\r
345                                     IncrementNth(count, 1);\r
346                                     break;\r
347                                 case 63 when rank.A:\r
348                                     IncrementNth(count, 2);\r
349                                     break;\r
350                                 case 64 when rank.S:\r
351                                     IncrementNth(count, 3);\r
352                                     break;\r
353                             }\r
354                         }\r
355                         break;\r
356                     case 862:\r
357                         if (_map == 63 && _boss && rank.A &&\r
358                             specs.Types.Count(s => s == 3) >= 2 &&\r
359                             specs.Types.Count(s => s == 16) >= 1)\r
360                         {\r
361                             Increment(count);\r
362                         }\r
363                         break;\r
364                     case 872:\r
365                         if (_boss && rank.S)\r
366                         {\r
367                             switch (_map)\r
368                             {\r
369                                 case 72:\r
370                                     if (_cell != 7)\r
371                                         IncrementNth(count, 0);\r
372                                     break;\r
373                                 case 55:\r
374                                     IncrementNth(count, 1);\r
375                                     break;\r
376                                 case 62:\r
377                                     IncrementNth(count, 2);\r
378                                     break;\r
379                                 case 65:\r
380                                     IncrementNth(count, 3);\r
381                                     break;\r
382                             }\r
383                         }\r
384                         break;\r
385                     case 873:\r
386                         if (_boss && rank.A &&\r
387                             specs.Types.Count(type => type == 3) >= 1)\r
388                         {\r
389                             switch (_map)\r
390                             {\r
391                                 case 31:\r
392                                     IncrementNth(count, 0);\r
393                                     break;\r
394                                 case 32:\r
395                                     IncrementNth(count, 1);\r
396                                     break;\r
397                                 case 33:\r
398                                     IncrementNth(count, 2);\r
399                                     break;\r
400                             }\r
401                         }\r
402                         break;\r
403                     case 875:\r
404                         if (_map == 54 && _boss && rank.S &&\r
405                             specs.Ids.Contains(543) &&\r
406                             specs.Ids.Intersect(new[] {344, 345, 359}).Any())\r
407                         {\r
408                             Increment(count);\r
409                         }\r
410                         break;\r
411                     case 888:\r
412                         if (_boss && rank.S &&\r
413                             specs.Ids.Intersect(new[]\r
414                             {\r
415                                 69, 272, 427, // 鳥海\r
416                                 61, 264, // 青葉\r
417                                 123, 295, 142, // 衣笠\r
418                                 59, 262, 416, // 古鷹\r
419                                 60, 263, 417, // 加古\r
420                                 51, 213, 477, // 天龍\r
421                                 115, 293 // 夕張\r
422                             }).Count() >= 4)\r
423                         {\r
424                             switch (_map)\r
425                             {\r
426                                 case 51:\r
427                                     IncrementNth(count, 0);\r
428                                     break;\r
429                                 case 53:\r
430                                     IncrementNth(count, 1);\r
431                                     break;\r
432                                 case 54:\r
433                                     IncrementNth(count, 2);\r
434                                     break;\r
435                             }\r
436                         }\r
437                         break;\r
438                     case 893:\r
439                         if (_boss && rank.S)\r
440                         {\r
441                             switch (_map)\r
442                             {\r
443                                 case 15:\r
444                                     IncrementNth(count, 0);\r
445                                     break;\r
446                                 case 71:\r
447                                     IncrementNth(count, 1);\r
448                                     break;\r
449                                 case 72:\r
450                                     if (_cell == 7)\r
451                                     {\r
452                                         IncrementNth(count, 2);\r
453                                         break;\r
454                                     }\r
455                                     IncrementNth(count, 3);\r
456                                     break;\r
457                             }\r
458                             break;\r
459                         }\r
460                         return;\r
461                     case 894:\r
462                         if (_boss && rank.S &&\r
463                             specs.Specs.Any(spec => spec.IsAircraftCarrier))\r
464                         {\r
465                             switch (_map)\r
466                             {\r
467                                 case 13:\r
468                                     IncrementNth(count, 0);\r
469                                     break;\r
470                                 case 14:\r
471                                     IncrementNth(count, 1);\r
472                                     break;\r
473                                 case 21:\r
474                                     IncrementNth(count, 2);\r
475                                     break;\r
476                                 case 22:\r
477                                     IncrementNth(count, 3);\r
478                                     break;\r
479                                 case 23:\r
480                                     IncrementNth(count, 4);\r
481                                     break;\r
482                             }\r
483                         }\r
484                         break;\r
485                 }\r
486             }\r
487         }\r
488 \r
489         private int _questFleet;\r
490 \r
491         public void StartPractice(string request)\r
492         {\r
493             var values = HttpUtility.ParseQueryString(request);\r
494             _questFleet = int.Parse(values["api_deck_id"]) - 1;\r
495         }\r
496 \r
497         public void InspectPracticeResult(dynamic json)\r
498         {\r
499             var rank = new Rank(json.api_win_rank);\r
500             var specs = new ResultShipSpecs(_battleInfo);\r
501             foreach (var quest in _quests.Values)\r
502             {\r
503                 var count = quest.Count;\r
504                 if (count.Spec is QuestPractice practice)\r
505                 {\r
506                     if (practice.Check(json.api_win_rank))\r
507                         Increment(count);\r
508                     continue;\r
509                 }\r
510                 switch (quest.Id)\r
511                 {\r
512                     case 318:\r
513                         if (_questFleet == 0 && rank.B &&\r
514                             specs.Types.Count(type => type == 3) >= 2)\r
515                         {\r
516                             Increment(count);\r
517                         }\r
518                         break;\r
519                     case 330:\r
520                         if (rank.B &&\r
521                             specs.Flagship.IsAircraftCarrier &&\r
522                             specs.Specs.Count(spec => spec.IsAircraftCarrier) >= 2 &&\r
523                             specs.Types.Count(type => type == 2) >= 2)\r
524                         {\r
525                             Increment(count);\r
526                         }\r
527                         break;\r
528                 }\r
529             }\r
530         }\r
531 \r
532         private readonly int[] _missionId = new int[ShipInfo.FleetCount];\r
533 \r
534         public void InspectDeck(dynamic json)\r
535         {\r
536             foreach (var entry in json)\r
537                 _missionId[(int)entry.api_id - 1] = (int)entry.api_mission[1];\r
538         }\r
539 \r
540         public void InspectMissionResult(string request, dynamic json)\r
541         {\r
542             var values = HttpUtility.ParseQueryString(request);\r
543             var deck = int.Parse(values["api_deck_id"]);\r
544             if ((int)json.api_clear_result == 0)\r
545                 return;\r
546             var mid = _missionId[deck - 1];\r
547             foreach (var quest in _quests.Values)\r
548             {\r
549                 var count = quest.Count;\r
550                 if (count.Spec is QuestMission mission)\r
551                 {\r
552                     if (mission.Check(mid))\r
553                         Increment(count);\r
554                     continue;\r
555                 }\r
556                 switch (quest.Id)\r
557                 {\r
558                     case 426:\r
559                         switch (mid)\r
560                         {\r
561                             case 3:\r
562                                 IncrementNth(count, 0);\r
563                                 break;\r
564                             case 4:\r
565                                 IncrementNth(count, 1);\r
566                                 break;\r
567                             case 5:\r
568                                 IncrementNth(count, 2);\r
569                                 break;\r
570                             case 10:\r
571                                 IncrementNth(count, 3);\r
572                                 break;\r
573                         }\r
574                         break;\r
575                     case 428:\r
576                         switch (mid)\r
577                         {\r
578                             case 4:\r
579                                 IncrementNth(count, 0);\r
580                                 break;\r
581                             case 101:\r
582                                 IncrementNth(count, 1);\r
583                                 break;\r
584                             case 102:\r
585                                 IncrementNth(count, 2);\r
586                                 break;\r
587                         }\r
588                         break;\r
589                 }\r
590             }\r
591         }\r
592 \r
593         public void CountNyukyo() => Increment(503);\r
594 \r
595         public void CountCharge() => Increment(504);\r
596 \r
597         public void InspectCreateItem(string request)\r
598         {\r
599             var values = HttpUtility.ParseQueryString(request);\r
600             var count = values["api_multiple_flag"] == "1" ? 3 : 1;\r
601             Add(605, count);\r
602             Add(607, count);\r
603         }\r
604 \r
605         public void CountCreateShip()\r
606         {\r
607             Increment(606);\r
608             Increment(608);\r
609         }\r
610 \r
611         public void InspectDestroyShip(string request)\r
612         {\r
613             Add(609, HttpUtility.ParseQueryString(request)["api_ship_id"].Split(',').Length);\r
614         }\r
615 \r
616         public void CountRemodelSlot() => Increment(619);\r
617 \r
618         public void InspectDestroyItem(string request, dynamic json)\r
619         {\r
620             var values = HttpUtility.ParseQueryString(request);\r
621             var items = values["api_slotitem_ids"].Split(',')\r
622                 .Select(id => _itemInfo.GetStatus(int.Parse(id)).Spec).ToArray();\r
623             Increment(613); // 613: 資源の再利用\r
624             foreach (var quest in _quests.Values)\r
625             {\r
626                 var count = quest.Count;\r
627                 if (count.Spec is QuestDestroyItem destroy)\r
628                 {\r
629                     if (destroy.Count(count, items))\r
630                         NeedSave = true;\r
631                     continue;\r
632                 }\r
633                 if (quest.Id == 680)\r
634                 {\r
635                     count.NowArray[0] += items.Count(spec => spec.Type == 21);\r
636                     count.NowArray[1] += items.Count(spec => spec.Type == 12 || spec.Type == 13);\r
637                     NeedSave = true;\r
638                 }\r
639             }\r
640         }\r
641 \r
642         public void InspectPowerUp(dynamic json)\r
643         {\r
644             if ((int)json.api_powerup_flag == 0)\r
645                 return;\r
646             foreach (var quest in _quests.Values)\r
647             {\r
648                 var count = quest.Count;\r
649                 if (!(count.Spec is QuestPowerUp))\r
650                     continue;\r
651                 Increment(count);\r
652             }\r
653         }\r
654 \r
655         public void Increment(QuestCount count)\r
656         {\r
657             Add(count, 1);\r
658         }\r
659 \r
660         public void Add(QuestCount count, int value)\r
661         {\r
662             count.Now += value;\r
663             NeedSave = true;\r
664         }\r
665 \r
666         public void Increment(int id)\r
667         {\r
668             Add(id, 1);\r
669         }\r
670 \r
671         public void Add(int id, int value)\r
672         {\r
673             if (!_quests.TryGetValue(id, out var quest))\r
674                 return;\r
675             quest.Count.Now += value;\r
676             NeedSave = true;\r
677         }\r
678 \r
679         public void IncrementNth(QuestCount count, int n)\r
680         {\r
681             count.NowArray[n]++;\r
682             NeedSave = true;\r
683         }\r
684     }\r
685 }