1#include "Npc/AchievementHolder.h"
2
3#include "Library/Base/StringUtil.h"
4
5#include "Npc/Achievement.h"
6#include "Npc/AchievementInfoReader.h"
7#include "System/GameDataFunction.h"
8#include "System/GameDataUtil.h"
9#include "Util/AchievementUtil.h"
10#include "Util/ClothUtil.h"
11
12AchievementHolder::AchievementHolder() = default;
13
14void AchievementHolder::init(const al::ActorInitInfo&) {
15 mAchievementInfoReader = new AchievementInfoReader();
16 mAchievementInfoReader->init();
17 mArray.allocBuffer(ptrNumMax: mAchievementInfoReader->size(), heap: nullptr);
18
19 for (s32 i = 0; i < mArray.capacity(); i++)
20 mArray.pushBack(ptr: new Achievement(mAchievementInfoReader->get(index: i)));
21}
22
23void AchievementHolder::init() {
24 mAchievementInfoReader = new AchievementInfoReader();
25 mAchievementInfoReader->init();
26 mArray.allocBuffer(ptrNumMax: mAchievementInfoReader->size(), heap: nullptr);
27
28 for (s32 i = 0; i < mArray.capacity(); i++)
29 mArray.pushBack(ptr: new Achievement(mAchievementInfoReader->get(index: i)));
30}
31
32bool AchievementHolder::isGetMoon(s32 index, GameDataHolderAccessor accessor) const {
33 return mArray[index]->isGet(accessor);
34}
35
36bool AchievementHolder::isAchieve(s32 index, GameDataHolderAccessor accessor) const {
37 return getAchievementProgressCurrent(index, accessor) >=
38 mAchievementInfoReader->get(index)->num;
39}
40
41s32 AchievementHolder::getAchievementProgressCurrent(s32 index,
42 GameDataHolderAccessor accessor) const {
43 s32 progressCurrentRow = getAchievementProgressCurrentRow(index, accessor);
44 auto* infoItem = mAchievementInfoReader->get(index);
45 const char** name = infoItem ? &infoItem->name : nullptr;
46
47 if (al::isEqualSubString(str: *name, subStr: "Shine_")) {
48 s32 max = 999;
49
50 if (progressCurrentRow <= 999)
51 max = progressCurrentRow;
52
53 return progressCurrentRow < 0 ? 0 : max;
54 }
55 if (!al::isEqualSubString(str: *name, subStr: "Other_Coin_") && !al::isEqualString(str1: *name, str2: "Other_Jump") &&
56 !al::isEqualString(str1: *name, str2: "Other_CapThrow"))
57 return progressCurrentRow;
58
59 s32 max = 999999999;
60
61 if (progressCurrentRow <= max)
62 max = progressCurrentRow;
63
64 return progressCurrentRow < 0 ? 0 : max;
65}
66
67s32 AchievementHolder::getAchievementProgressMax(s32 index, GameDataHolderAccessor) const {
68 return mAchievementInfoReader->get(index)->num;
69}
70
71s32 AchievementHolder::getAchievementProgressCurrentRow(s32 index,
72 GameDataHolderAccessor accessor) const {
73 auto* infoItem = mAchievementInfoReader->get(index);
74 const char** name = infoItem ? &infoItem->name : nullptr;
75
76 if (al::isEqualString(str1: *name, str2: "Scenario_Ending"))
77 return 1;
78 if (al::isEqualString(str1: *name, str2: "Scenario_WorldAll"))
79 return rs::calcClearWorldNum(holder: accessor);
80 if (al::isEqualString(str1: *name, str2: "Shine_Gather_1") || al::isEqualString(str1: *name, str2: "Shine_Gather_2") ||
81 al::isEqualString(str1: *name, str2: "Shine_Gather_3"))
82 return GameDataFunction::getTotalShineNum(accessor);
83 if (al::isEqualString(str1: *name, str2: "Shine_CollectCoinShop"))
84 return rs::calcBuyItemNumForCoinCollectByWorld(holder: accessor);
85 if (al::isEqualString(str1: *name, str2: "Shine_Shine2D_1") || al::isEqualString(str1: *name, str2: "Shine_Shine2D_2"))
86 return rs::calcGetShineNumDot(holder: accessor);
87 if (al::isEqualString(str1: *name, str2: "Shine_TreasureBox_1") ||
88 al::isEqualString(str1: *name, str2: "Shine_TreasureBox_2"))
89 return rs::calcGetShineNumTreasureBox(holder: accessor);
90 if (al::isEqualString(str1: *name, str2: "Shine_MusicNote_1") ||
91 al::isEqualString(str1: *name, str2: "Shine_MusicNote_2"))
92 return rs::calcGetShineNumNoteObj(holder: accessor);
93 if (al::isEqualString(str1: *name, str2: "Shine_TimerAthretic_1") ||
94 al::isEqualString(str1: *name, str2: "Shine_TimerAthretic_2"))
95 return rs::calcGetShineNumTimerAthletic(holder: accessor);
96 if (al::isEqualString(str1: *name, str2: "Shine_CaptainKinopio_1") ||
97 al::isEqualString(str1: *name, str2: "Shine_CaptainKinopio_2"))
98 return rs::calcGetShineNumKinopioBrigade(holder: accessor);
99 if (al::isEqualString(str1: *name, str2: "Shine_TravelingPeach_1") ||
100 al::isEqualString(str1: *name, str2: "Shine_TravelingPeach_2"))
101 return rs::calcGetShineNumWorldTravelingPeach(holder: accessor);
102 if (al::isEqualString(str1: *name, str2: "Shine_CollectAnimalAll"))
103 return rs::calcGetShineNumCollectAnimal(holder: accessor);
104 if (al::isEqualString(str1: *name, str2: "Shine_KuriboGirl"))
105 return rs::calcGetShineNumKuriboGirl(holder: accessor);
106 if (al::isEqualString(str1: *name, str2: "Shine_Jugem"))
107 return rs::calcGetShineNumJugemFish(holder: accessor);
108 if (al::isEqualString(str1: *name, str2: "Shine_Seed_1") || al::isEqualString(str1: *name, str2: "Shine_Seed_2"))
109 return rs::calcGetShineNumGrowPlant(holder: accessor);
110 if (al::isEqualString(str1: *name, str2: "Shine_Rabbit_1") || al::isEqualString(str1: *name, str2: "Shine_Rabbit_2"))
111 return rs::calcGetShineNumRabbit(holder: accessor);
112 if (al::isEqualString(str1: *name, str2: "Shine_DigPoint_1") ||
113 al::isEqualString(str1: *name, str2: "Shine_DigPoint_2"))
114 return rs::calcGetShineNumDigPoint(holder: accessor);
115 if (al::isEqualString(str1: *name, str2: "Shine_CapHanger_1") ||
116 al::isEqualString(str1: *name, str2: "Shine_CapHanger_2"))
117 return rs::calcGetShineNumCapHanger(holder: accessor);
118 if (al::isEqualString(str1: *name, str2: "Shine_Bird"))
119 return rs::calcGetShineNumBird(holder: accessor);
120 if (al::isEqualString(str1: *name, str2: "Shine_CostumeRoom_1") ||
121 al::isEqualString(str1: *name, str2: "Shine_CostumeRoom_2") ||
122 al::isEqualString(str1: *name, str2: "Shine_CostumeRoom_3"))
123 return rs::calcGetShineNumCostumeRoom(holder: accessor);
124 if (al::isEqualString(str1: *name, str2: "Shine_CapThrottle"))
125 return rs::calcGetShineNumSlot(holder: accessor);
126 if (al::isEqualString(str1: *name, str2: "Shine_HideAndSeekCapMan"))
127 return rs::calcGetShineNumHideAndSeekCapMan(holder: accessor);
128 if (al::isEqualString(str1: *name, str2: "Shine_CollectBgm"))
129 return rs::calcGetShineNumCollectedBgm(accessor);
130 if (al::isEqualString(str1: *name, str2: "Shine_HintPhoto_1") ||
131 al::isEqualString(str1: *name, str2: "Shine_HintPhoto_2"))
132 return rs::calcGetShineNumHintPhoto(holder: accessor);
133 if (al::isEqualString(str1: *name, str2: "MiniGame_RaceMan_1") ||
134 al::isEqualString(str1: *name, str2: "MiniGame_RaceMan_2"))
135 return rs::calcGetShineNumRace(holder: accessor);
136 if (al::isEqualString(str1: *name, str2: "MiniGame_FigureWalker"))
137 return rs::calcGetShineNumFigureWalking(holder: accessor);
138 if (al::isEqualString(str1: *name, str2: "MiniGame_SphinxQuiz"))
139 return rs::calcSphinxQuizCompleteNum(accessor);
140 if (al::isEqualString(str1: *name, str2: "Souvenir_Count_1") ||
141 al::isEqualString(str1: *name, str2: "Souvenir_Count_2") ||
142 al::isEqualString(str1: *name, str2: "Souvenir_Count_3"))
143 return rs::calcHaveStickerNum(accessor) + rs::calcHaveGiftNum(accessor);
144 if (al::isEqualString(str1: *name, str2: "Capture_Count_1") ||
145 al::isEqualString(str1: *name, str2: "Capture_Count_2") || al::isEqualString(str1: *name, str2: "Capture_Count_3"))
146 return rs::calcHackObjNum(accessor);
147 if (al::isEqualString(str1: *name, str2: "Costume_Cap_1") || al::isEqualString(str1: *name, str2: "Costume_Cap_2"))
148 return rs::calcHaveCapNum(accessor);
149 if (al::isEqualString(str1: *name, str2: "Costume_Clothes_1") ||
150 al::isEqualString(str1: *name, str2: "Costume_Clothes_2"))
151 return rs::calcHaveClothNum(accessor);
152 if (al::isEqualString(str1: *name, str2: "Other_MoonStoneAll"))
153 return rs::calcUnlockMoonRockNum(accessor);
154 if (al::isEqualString(str1: *name, str2: "Other_WorldWarpHoleAll"))
155 return rs::calcWorldWarpHoleThroughNum(holder: accessor);
156 if (al::isEqualString(str1: *name, str2: "Other_CheckPoint_1") ||
157 al::isEqualString(str1: *name, str2: "Other_CheckPoint_2"))
158 return rs::calcGetCheckpointNum(holder: accessor);
159 if (al::isEqualString(str1: *name, str2: "Other_Coin_1") || al::isEqualString(str1: *name, str2: "Other_Coin_2") ||
160 al::isEqualString(str1: *name, str2: "Other_Coin_3"))
161 return rs::getTotalCoinNum(holder: accessor);
162 if (al::isEqualString(str1: *name, str2: "Other_Jump"))
163 return rs::getPlayerJumpCount(holder: accessor);
164 if (al::isEqualString(str1: *name, str2: "Other_CapThrow"))
165 return rs::getPlayerThrowCapCount(holder: accessor);
166
167 return 0;
168}
169
170s32 AchievementHolder::calcAchieveTotalNum(GameDataHolderAccessor accessor) const {
171 s32 count = 0;
172
173 for (s32 i = 0; i < mArray.capacity(); i++)
174 if (getAchievementProgressCurrent(index: i, accessor) >= mAchievementInfoReader->get(index: i)->num)
175 count++;
176
177 return count;
178}
179
180s32 AchievementHolder::calcMoonGetTotalNum(GameDataHolderAccessor accessor) const {
181 s32 count = 0;
182
183 for (s32 i = 0; i < mArray.capacity(); i++)
184 if (mArray[i]->isGet(accessor))
185 count++;
186
187 return count;
188}
189
190Achievement* AchievementHolder::tryGetNewAchievement(GameDataHolderAccessor accessor) const {
191 for (s32 i = 0; i < mArray.capacity(); i++)
192 if (!mArray[i]->isGet(accessor) &&
193 getAchievementProgressCurrent(index: i, accessor) >= mAchievementInfoReader->unsafeAt(index: i)->num)
194 return mArray[i];
195 return nullptr;
196}
197