1#include "Amiibo/HelpAmiiboCountUpCoin.h"
2
3#include <math/seadQuat.h>
4#include <math/seadVector.h>
5
6#include "Library/LiveActor/ActorInitUtil.h"
7#include "Library/LiveActor/ActorMovementFunction.h"
8#include "Library/LiveActor/ActorPoseUtil.h"
9#include "Library/Math/MathUtil.h"
10#include "Library/Nerve/NerveSetupUtil.h"
11#include "Library/Nerve/NerveUtil.h"
12#include "Library/Nfp/NfpFunction.h"
13
14#include "Amiibo/HelpAmiiboFunction.h"
15#include "Item/Coin.h"
16#include "Item/Coin2D.h"
17#include "Item/LifeUpItem.h"
18#include "Item/LifeUpItem2D.h"
19#include "Util/PlayerUtil.h"
20
21namespace {
22NERVE_IMPL(HelpAmiiboCountUpCoin, End);
23NERVE_IMPL(HelpAmiiboCountUpCoin, Delay);
24NERVE_IMPL(HelpAmiiboCountUpCoin, AppearCoin);
25
26NERVES_MAKE_NOSTRUCT(HelpAmiiboCountUpCoin, AppearCoin);
27NERVES_MAKE_STRUCT(HelpAmiiboCountUpCoin, End, Delay);
28} // namespace
29
30HelpAmiiboCountUpCoin::HelpAmiiboCountUpCoin(HelpAmiiboDirector* director, al::LiveActor* actor)
31 : HelpAmiiboExecutor(director, actor, "ランダムアイテムお助け") {
32 mNerveKeeper = new al::NerveKeeper(this, &NrvHelpAmiiboCountUpCoin.End, 0);
33}
34
35void HelpAmiiboCountUpCoin::initAfterPlacement(const al::ActorInitInfo& initInfo) {
36 HelpAmiiboExecutor::initAfterPlacement(initInfo);
37 mLifeUpItem = new LifeUpItem("ライフアップアイテム[amiibo]");
38 al::initCreateActorNoPlacementInfo(actor: mLifeUpItem, initInfo);
39 mLifeUpItem->setBool145(true);
40 mLifeUpItem->makeActorDead();
41
42 mLifeUpItem2D = new LifeUpItem2D("ライフアップアイテム2D[amiibo]");
43 al::initCreateActorNoPlacementInfo(actor: mLifeUpItem2D, initInfo);
44 mLifeUpItem2D->makeActorDead();
45 mLifeUpItem2D->setBool130(true);
46 mCoinBuffer.allocBuffer(ptrNumMax: 3, heap: nullptr);
47 mCoin2DBuffer.allocBuffer(ptrNumMax: 3, heap: nullptr);
48
49 for (u32 i = 0; i < 3; i++) {
50 Coin* coin = new Coin("コイン[amiibo]", false);
51 al::initCreateActorNoPlacementInfo(actor: coin, initInfo);
52 coin->makeActorDead();
53
54 Coin2D* coin2D = new Coin2D("コイン2D[amiibo]");
55 al::initCreateActorNoPlacementInfo(actor: coin2D, initInfo);
56 coin2D->makeActorDead();
57
58 mCoinBuffer.pushBack(ptr: coin);
59 mCoin2DBuffer.pushBack(ptr: coin2D);
60 }
61}
62
63bool HelpAmiiboCountUpCoin::isTriggerTouch(const al::NfpInfo& nfpInfo) const {
64 if (!al::isCharacterIdBaseKoopa(nfpInfo) && !al::isCharacterIdBasePeach(nfpInfo) &&
65 !al::isCharacterIdBaseMario(nfpInfo))
66 return true;
67
68 return false;
69}
70
71bool HelpAmiiboCountUpCoin::isEnableUse() {
72 return !HelpAmiiboFunction::calcIsHitArrowItemAppearPos(getActor());
73}
74
75bool HelpAmiiboCountUpCoin::execute() {
76 getNerveKeeper()->update();
77 return al::isNerve(user: this, nerve: &NrvHelpAmiiboCountUpCoin.End);
78}
79
80void HelpAmiiboCountUpCoin::activate() {
81 HelpAmiiboExecutor::activate();
82
83 mNumberOfCoins = al::getRandom(max: 4);
84 if (mNumberOfCoins != 0) {
85 mCoinsSpawned = 0;
86 al::setNerve(user: this, nerve: &NrvHelpAmiiboCountUpCoin.Delay);
87 return;
88 }
89
90 al::LiveActor* actor = getActor();
91 sead::Vector3f offset = sead::Vector3f::zero;
92 HelpAmiiboFunction::calcLifeUpItemAppearOffset(&offset, actor);
93
94 if (rs::isPlayer2D(getActor())) {
95 al::resetPosition(actor: mLifeUpItem2D, trans: rs::getPlayerPos(actor) + offset);
96 mLifeUpItem2D->appearAmiiboTouch();
97 } else {
98 if (!rs::isPlayerHack(actor)) {
99 al::resetPosition(actor: mLifeUpItem, trans: rs::getPlayerPos(actor) + offset);
100 } else {
101 sead::Vector3f basePos = sead::Vector3f::zero;
102 rs::calcPlayerAmiiboPeachAppearBasePos(&basePos, actor);
103 al::resetPosition(actor: mLifeUpItem);
104 }
105 mLifeUpItem->appearAmiiboTouch();
106 }
107
108 al::setNerve(user: this, nerve: &NrvHelpAmiiboCountUpCoin.End);
109}
110
111void HelpAmiiboCountUpCoin::updateItemQT(al::LiveActor* actor) {
112 sead::Quatf pose = sead::Quatf::unit;
113 sead::Vector3f position = sead::Vector3f::zero;
114
115 HelpAmiiboFunction::calcCoinAppearQT(&pose, &position, actor);
116
117 al::updatePoseQuat(actor, quat: pose);
118 al::resetPosition(actor, trans: position);
119}
120
121void HelpAmiiboCountUpCoin::exeEnd() {}
122
123void HelpAmiiboCountUpCoin::exeDelay() {
124 if (al::isGreaterEqualStep(user: this, step: 60))
125 al::setNerve(user: this, nerve: &AppearCoin);
126}
127
128void HelpAmiiboCountUpCoin::exeAppearCoin() {
129 if (al::getNerveStep(user: this) % 10 != 0)
130 return;
131
132 if (rs::isPlayer2D(getActor())) {
133 Coin2D* coin2D = mCoin2DBuffer[mCoinsSpawned];
134 updateItemQT(actor: coin2D);
135 coin2D->appearCountUp();
136
137 } else {
138 Coin* coin = mCoinBuffer[mCoinsSpawned];
139 updateItemQT(actor: coin);
140 coin->appearCountUp();
141 }
142
143 s32 mLastCoinIndex = (mNumberOfCoins == 1) ? 0 :
144 (mNumberOfCoins == 2) ? 1 :
145 (mNumberOfCoins == 3) ? 2 :
146 -1;
147
148 if ((s32)mCoinsSpawned == mLastCoinIndex) {
149 al::setNerve(user: this, nerve: &NrvHelpAmiiboCountUpCoin.End);
150 return;
151 }
152
153 mCoinsSpawned++;
154}
155