1#include "Amiibo/HelpAmiiboCoinCollect.h"
2
3#include "Library/Area/AreaObj.h"
4#include "Library/Area/AreaObjUtil.h"
5#include "Library/Area/IUseAreaObj.h"
6#include "Library/LiveActor/ActorFlagFunction.h"
7#include "Library/LiveActor/ActorInitInfo.h"
8#include "Library/LiveActor/ActorInitUtil.h"
9#include "Library/LiveActor/ActorMovementFunction.h"
10#include "Library/LiveActor/ActorPoseUtil.h"
11#include "Library/Nfp/NfpFunction.h"
12#include "Library/Placement/PlacementFunction.h"
13#include "Library/Placement/PlacementInfo.h"
14#include "Library/Scene/SceneObjUtil.h"
15#include "Library/Se/SeFunction.h"
16
17#include "Amiibo/HelpAmiiboDirector.h"
18#include "Item/CoinCollect.h"
19#include "Item/CoinCollect2D.h"
20#include "Item/CoinCollectDummy.h"
21#include "Item/CoinCollectHolder.h"
22#include "System/GameDataFunction.h"
23#include "Util/PlayerUtil.h"
24
25HelpAmiiboCoinCollect::HelpAmiiboCoinCollect(HelpAmiiboDirector* director,
26 al::LiveActor* amiiboActor)
27 : HelpAmiiboExecutor(director, amiiboActor, "コレクトコインお助け") {}
28
29void HelpAmiiboCoinCollect::initAfterPlacement(const al::ActorInitInfo& actorInitInfo) {
30 HelpAmiiboExecutor::initAfterPlacement(actorInitInfo);
31
32 mCoinCollectDummy = new CoinCollectDummy("コレクトコインお助け");
33 al::initCreateActorNoPlacementInfo(actor: mCoinCollectDummy, initInfo: actorInitInfo);
34}
35
36bool HelpAmiiboCoinCollect::isTriggerTouch(const al::NfpInfo& nfpInfo) const {
37 return al::isCharacterIdBaseKoopa(nfpInfo);
38}
39
40bool HelpAmiiboCoinCollect::isEnableUse() {
41 CoinCollectHolder* coinHolder = al::tryGetSceneObj<CoinCollectHolder>(user: getActor());
42 if (coinHolder == nullptr)
43 return false;
44
45 if (mCoinCollect2D != nullptr && al::isAlive(actor: mCoinCollect2D))
46 return false;
47
48 if (mCoinCollect != nullptr && al::isAlive(actor: mCoinCollect))
49 return false;
50
51 const sead::Vector3f& playerPos = rs::getPlayerPos(getActor());
52 if (coinHolder->tryFindAliveCoinCollect(playerPos, true) != nullptr)
53 return true;
54 if (coinHolder->tryFindAliveCoinCollect2D(playerPos, true) != nullptr)
55 return true;
56 if (coinHolder->tryFindDeadButHintEnableCoinCollect() != nullptr)
57 return true;
58
59 if (al::tryFindAreaObj(areaUser: mCoinCollectDummy, name: "InvalidateStageMapArea", position: playerPos) == nullptr) {
60 sead::Vector3f stagePos = sead::Vector3f::zero;
61 const char* stageName = nullptr;
62 if (GameDataFunction::tryFindExistCoinCollectStagePosExcludeHomeStageInCurrentWorld(
63 pos: &stagePos, &stageName, accessor: getActor())) {
64 if (GameDataFunction::isMainStage(accessor: mCoinCollectDummy) ||
65 coinHolder->tryFindExStageHintObjTrans(&stagePos, stageName))
66 return true;
67 }
68 }
69
70 return false;
71}
72
73bool HelpAmiiboCoinCollect::execute() {
74 const sead::Vector3f& playerPos = rs::getPlayerPos(getActor());
75
76 al::AreaObj* areaObj =
77 al::tryFindAreaObj(areaUser: mCoinCollectDummy, name: "InvalidateStageMapArea", position: playerPos);
78 if (areaObj != mStartInvalidateStageMapArea) {
79 deleteHintEffect();
80 return true;
81 }
82
83 if (mCoinCollect != nullptr) {
84 if (mCoinCollect->isEnableHint()) {
85 mCoinCollect = nullptr;
86 return true;
87 }
88 return false;
89 }
90
91 if (mCoinCollect2D != nullptr) {
92 if (mCoinCollect2D->isEnableHint()) {
93 mCoinCollect2D = nullptr;
94 return true;
95 }
96 return false;
97 }
98
99 return !al::isAlive(actor: mCoinCollectDummy);
100}
101
102void HelpAmiiboCoinCollect::activate() {
103 HelpAmiiboExecutor::activate();
104
105 al::LiveActor* actor = getActor();
106 const sead::Vector3f& playerPos = rs::getPlayerPos(actor);
107 CoinCollectHolder* coinHolder = al::tryGetSceneObj<CoinCollectHolder>(user: actor);
108 mStartInvalidateStageMapArea =
109 al::tryFindAreaObj(areaUser: mCoinCollectDummy, name: "InvalidateStageMapArea", position: playerPos);
110
111 CoinCollect* aliveCoinCollect =
112 coinHolder->tryFindAliveCoinCollect(playerPos, 5000.0f, 10000.0f, true);
113 if (aliveCoinCollect != nullptr) {
114 al::startSe(getDirector(), "AmiiboKoopa");
115 if (isUseDummyModel(actor: aliveCoinCollect)) {
116 sead::Vector3f dummyEffectEmitPos = sead::Vector3f::zero;
117 getDummyEffectEmitPos(position: &dummyEffectEmitPos, actor: aliveCoinCollect);
118 mCoinCollectDummy->appearHint(position: dummyEffectEmitPos);
119 return;
120 }
121 aliveCoinCollect->appearHelpAmiiboEffect();
122 mCoinCollect = aliveCoinCollect;
123 return;
124 }
125
126 CoinCollect2D* aliveCoinCollect2D =
127 coinHolder->tryFindAliveCoinCollect2D(playerPos, 5000.0f, 10000.0f, true);
128 if (aliveCoinCollect2D != nullptr) {
129 al::startSe(getDirector(), "AmiiboKoopa");
130 if (isUseDummyModel(actor: aliveCoinCollect2D)) {
131 sead::Vector3f dummyEffectEmitPos = sead::Vector3f::zero;
132 getDummyEffectEmitPos(position: &dummyEffectEmitPos, actor: aliveCoinCollect2D);
133 mCoinCollectDummy->appearHint(position: dummyEffectEmitPos);
134 return;
135 }
136 aliveCoinCollect2D->appearHintEffect();
137 mCoinCollect2D = aliveCoinCollect2D;
138 return;
139 }
140
141 CoinCollect* coinCollect = coinHolder->tryFindAliveCoinCollect(playerPos, true);
142 if (coinCollect != nullptr) {
143 al::startSe(getDirector(), "AmiiboKoopa");
144 if (isUseDummyModel(actor: coinCollect)) {
145 sead::Vector3f dummyEffectEmitPos = sead::Vector3f::zero;
146 getDummyEffectEmitPos(position: &dummyEffectEmitPos, actor: coinCollect);
147 mCoinCollectDummy->appearHint(position: dummyEffectEmitPos);
148 return;
149 }
150 coinCollect->appearHelpAmiiboEffect();
151 mCoinCollect = coinCollect;
152 return;
153 }
154
155 CoinCollect2D* coinCollect2D = coinHolder->tryFindAliveCoinCollect2D(playerPos, true);
156 if (coinCollect2D != nullptr) {
157 al::startSe(getDirector(), "AmiiboKoopa");
158 if (isUseDummyModel(actor: coinCollect2D)) {
159 sead::Vector3f dummyEffectEmitPos = sead::Vector3f::zero;
160 getDummyEffectEmitPos(position: &dummyEffectEmitPos, actor: coinCollect2D);
161 mCoinCollectDummy->appearHint(position: dummyEffectEmitPos);
162 return;
163 }
164 coinCollect2D->appearHintEffect();
165 mCoinCollect2D = coinCollect2D;
166 return;
167 }
168
169 CoinCollect* deadCoinCollect = coinHolder->tryFindDeadButHintEnableCoinCollect();
170 if (deadCoinCollect != nullptr) {
171 al::startSe(getDirector(), "AmiiboKoopa");
172 if (isUseDummyModel(actor: deadCoinCollect)) {
173 sead::Vector3f dummyEffectEmitPos = sead::Vector3f::zero;
174 getDummyEffectEmitPos(position: &dummyEffectEmitPos, actor: deadCoinCollect);
175 mCoinCollectDummy->appearHint(position: dummyEffectEmitPos);
176 return;
177 }
178 deadCoinCollect->appearHelpAmiiboEffect();
179 mCoinCollect = deadCoinCollect;
180 return;
181 }
182
183 if (al::tryFindAreaObj(areaUser: mCoinCollectDummy, name: "InvalidateStageMapArea", position: playerPos) == nullptr) {
184 sead::Vector3f stagePos = sead::Vector3f::zero;
185 const char* stageName = nullptr;
186 if (GameDataFunction::tryFindExistCoinCollectStagePosExcludeHomeStageInCurrentWorld(
187 pos: &stagePos, &stageName, accessor: actor)) {
188 if (GameDataFunction::isMainStage(accessor: actor) ||
189 coinHolder->tryFindExStageHintObjTrans(&stagePos, stageName)) {
190 mCoinCollectDummy->appearHint(position: stagePos);
191 al::startSe(getDirector(), "AmiiboKoopa");
192 }
193 }
194 }
195}
196
197void HelpAmiiboCoinCollect::deleteHintEffect() {
198 if (mCoinCollect != nullptr) {
199 mCoinCollect->deleteHelpAmiiboEffect();
200 mCoinCollect = nullptr;
201 return;
202 }
203
204 if (mCoinCollect2D != nullptr) {
205 mCoinCollect2D->deleteHintEffect();
206 mCoinCollect2D = nullptr;
207 return;
208 }
209
210 if (al::isAlive(actor: mCoinCollectDummy))
211 mCoinCollectDummy->kill();
212}
213
214void HelpAmiiboCoinCollect::appearEffect() {
215 if (mCoinCollect != nullptr) {
216 mCoinCollect->reappearHelpAmiiboEffect();
217 return;
218 }
219
220 if (mCoinCollect2D != nullptr) {
221 mCoinCollect2D->reappearHintEffect();
222 return;
223 }
224
225 if (al::isAlive(actor: mCoinCollectDummy))
226 mCoinCollectDummy->reappearHint();
227}
228
229void HelpAmiiboCoinCollect::killEffect() {
230 if (mCoinCollect != nullptr) {
231 mCoinCollect->deleteHelpAmiiboEffect();
232 return;
233 }
234
235 if (mCoinCollect2D != nullptr)
236 mCoinCollect2D->deleteHintEffect();
237
238 if (al::isAlive(actor: mCoinCollectDummy))
239 mCoinCollectDummy->deleteHint();
240}
241
242bool HelpAmiiboCoinCollect::isUseDummyModel(al::LiveActor* actor) {
243 const sead::Vector3f& playerPos = rs::getPlayerPos(mCoinCollectDummy);
244 al::AreaObj* dummyAreaObj =
245 al::tryFindAreaObj(areaUser: mCoinCollectDummy, name: "InvalidateStageMapArea", position: playerPos);
246 al::AreaObj* actorAreaObj =
247 al::tryFindAreaObj(areaUser: actor, name: "InvalidateStageMapArea", position: al::getTrans(actor));
248
249 return dummyAreaObj != actorAreaObj;
250}
251
252void HelpAmiiboCoinCollect::getDummyEffectEmitPos(sead::Vector3f* position, al::LiveActor* actor) {
253 al::AreaObj* areaObj = al::tryFindAreaObj(areaUser: actor, name: "InvalidateStageMapArea", position: al::getTrans(actor));
254 if (areaObj != nullptr)
255 al::tryGetLinksTrans(trans: position, placementInfo: *areaObj->getPlacementInfo(), linkName: "PlayerPoint");
256}
257