1#include "Game/MapObj/Coin.hpp"
2#include "Game/MapObj/CoinHolder.hpp"
3#include "Game/MapObj/CoinRotater.hpp"
4#include "Game/MapObj/PurpleCoinHolder.hpp"
5#include "Game/Util.hpp"
6#include "JSystem/JMath/JMath.hpp"
8Coin::Coin(
const char *pName) :
LiveActor(pName) {
12 mDropPosition.x = 0.0f;
13 mDropPosition.y = 0.0f;
14 mDropPosition.z = 0.0f;
15 mClippingRange.x = 0.0f;
16 mClippingRange.y = 0.0f;
17 mClippingRange.z = 0.0f;
23 mIsPurpleCoin =
false;
24 mIsNeedBubble =
false;
28 MR::initDefaultPos(
this, rIter);
29 initModelManagerWithAnm(mIsPurpleCoin ?
"PurpleCoin" :
"Coin",
nullptr,
false);
30 MR::connectToSceneItemStrongLight(
this);
32 MR::addHitSensor(
this,
"coin", 0x4A, 4, 55.0f, TVec3f(0.0f, 70.0f, 0.0f));
33 initBinder(55.0f, 70.0f, 0);
34 MR::setBinderExceptSensorType(
this, &
mPosition, 10.0f);
35 MR::setClippingFar100m(
this);
36 initEffectKeeper(0,
nullptr,
false);
39 if (MR::isValidInfo(rIter)) {
40 setShadowAndPoseModeFromJMapIter(rIter);
45 MR::calcActorAxisY(&axis,
this);
52 mAirBubble = MR::createPartsModelNoSilhouettedMapObj(
this,
"アワ",
"AirBubble",
nullptr);
53 mAirBubble->initFixedPosition(TVec3f(0.0f, 70.0f, 0.0f), TVec3f(0.0f, 0.0f, 0.0f),
nullptr);
54 mAirBubble->makeActorDead();
55 MR::registerDemoSimpleCastAll(mAirBubble);
56 MR::startBck(mAirBubble,
"Move",
nullptr);
60 MR::tryCreateMirrorActor(
this, mIsPurpleCoin ?
"PurpleCoin" :
"Coin");
61 initNerve(&NrvCoin::CoinNrvFix::sInstance);
63 if (MR::isValidInfo(rIter)) {
64 if (MR::useStageSwitchReadAppear(
this, rIter)) {
65 MR::syncStageSwitchAppear(
this);
72 if (MR::useStageSwitchReadB(
this, rIter)) {
74 MR::listenStageSwitchOnB(
this, deadFunc);
81 MR::useStageSwitchSleep(
this, rIter);
84void Coin::initAfterPlacement() {
85 MR::setClippingRangeIncludeShadow(
this, &mClippingRange, 150.0f);
92 if (MR::isValidInfo(rIter)) {
93 MR::getJMapInfoArg5NoInit(rIter, &arg_5);
94 MR::getJMapInfoArg6NoInit(rIter, &arg_6);
99 MR::initShadowSurfaceCircle(
this, 50.0f);
102 MR::initShadowVolumeCylinder(
this, 50.0f);
105 MR::initShadowVolumeSphere(
this, 50.0f);
109 MR::setShadowDropPositionPtr(
this,
nullptr, &mDropPosition);
112 MR::setShadowDropLength(
this,
nullptr, arg_5);
116void Coin::setShadowAndPoseModeFromJMapIter(
const JMapInfoIter &rIter) {
118 MR::getJMapInfoArg3WithInit(rIter, &arg_3);
121 MR::getJMapInfoArg4WithInit(rIter, &arg_4);
123 mIsNeedBubble = Coin::isNeedBubble(rIter);
126void Coin::makeActorAppeared() {
127 MR::offCalcGravity(
this);
130 MR::calcGravityOrZero(
this);
133 if (!mIsPurpleCoin && MR::isGalaxyDarkCometAppearInCurrentStage()) {
134 LiveActor::makeActorDead();
137 LiveActor::makeActorAppeared();
140 mAirBubble->makeActorAppeared();
141 MR::setSensorRadius(
this,
"coin", 150.0f);
144 MR::setSensorRadius(
this,
"coin", 55.0f);
149 MR::validateShadow(
this,
nullptr);
151 if (!mIsPurpleCoin) {
159void Coin::makeActorDead() {
160 LiveActor::makeActorDead();
162 mAirBubble->makeActorDead();
168 another_vec.set<f32>(MR::isNearZero(
mGravity, 0.001f) ? TVec3f(0.0f, 1.0f, 0.0f) : -
mGravity);
169 JMAVECScaleAdd(another_vec.toCVec(),
mPosition.toCVec(), mDropPosition.toVec(), 70.0f);
174 MR::makeMtxTR(pos.toMtxPtr(),
this);
177 MR::makeMtxUpNoSupportPos(&pos, another_vec,
mPosition);
180 if (isNerve(&NrvCoin::CoinNrvSpinDrained::sInstance)) {
181 pos.concat(pos, MR::getCoinHiSpeedRotateYMatrix());
185 pos.concat(pos, MR::getCoinInWaterRotateYMatrix());
188 pos.concat(pos, MR::getCoinRotateYMatrix());
192 MR::setBaseTRMtx(
this, pos);
198 if (MR::isMsgItemGet(msg)) {
200 MR::emitEffect(
this,
"CoinGet");
205 else if (MR::isMsgItemPull(msg)) {
206 result = requestSpinDrain();
208 else if (MR::isMsgItemShow(msg)) {
209 result = requestShow();
211 else if (MR::isMsgItemHide(msg)) {
212 result = requestHide();
214 else if (MR::isMsgItemStartMove(msg)) {
215 result = requestStartControl();
217 else if (MR::isMsgItemEndMove(msg)) {
218 result = requestEndControl();
220 else if (MR::isMsgInhaleBlackHole(msg)) {
231void Coin::exeNonActive() {
232 if (MR::isFirstStep(
this) || _B9) {
233 MR::setClippingRangeIncludeShadow(
this, &mClippingRange, 150.0f);
238 if (MR::isFirstStep(
this) || _B9) {
239 MR::setClippingRangeIncludeShadow(
this, &mClippingRange, 150.0f);
243void Coin::exeFixTimer() {
244 if (MR::isFirstStep(
this)) {
245 mFlashCtrl->start(_B0);
246 MR::invalidateClipping(
this);
250 if (MR::isStep(
this, mCannotTime)) {
251 MR::validateHitSensors(
this);
254 if (mFlashCtrl->mIsEnded) {
259void Coin::exeMove() {
260 if (MR::isFirstStep(
this)) {
261 mFlashCtrl->start(_B0);
262 MR::onCalcShadow(
this,
nullptr);
263 MR::onCalcShadowDropPrivateGravity(
this,
nullptr);
266 if (MR::isStep(
this, mCannotTime)) {
267 MR::validateHitSensors(
this);
270 if (MR::isGreaterEqualStep(
this, mCannotTime) && MR::isBindedGroundDamageFire(
this)) {
271 MR::emitEffect(
this,
"LavaFall");
272 MR::startSound(
this,
"SE_OJ_FALL_IN_MAGMA_S", -1, -1);
276 if (MR::isInDeath(
this, TVec3f(0.0f, 0.0f, 0.0f))) {
280 MR::calcGravityOrZero(
this);
282 if (MR::isPressedRoofAndGround(
this)) {
284 MR::zeroVelocity(
this);
287 if (!MR::isNoBind(
this)) {
293 if (mFlashCtrl->mIsEnded) {
300void Coin::exeControled() {
301 if (MR::isFirstStep(
this)) {
302 MR::onCalcShadow(
this,
nullptr);
303 MR::onCalcShadowDropPrivateGravity(
this,
nullptr);
306 MR::zeroVelocity(
this);
309void Coin::exeSpinDrained() {
310 if (MR::isFirstStep(
this)) {
311 MR::onCalcShadow(
this,
nullptr);
312 MR::onCalcShadowDropPrivateGravity(
this,
nullptr);
315 MR::emitEffect(
this,
"CoinSpinBlur");
319 if (MR::isFirstStep(
this)) {
325 if (MR::isGreaterStep(
this, 30)) {
326 MR::emitEffect(
this,
"CoinGet");
336void Coin::appearFixInit() {
338 MR::validateClipping(
this);
339 MR::validateHitSensors(
this);
342 setNerve(&NrvCoin::CoinNrvFix::sInstance);
345void Coin::appearFix() {
347 MR::validateClipping(
this);
348 MR::validateHitSensors(
this);
351 setNerve(&NrvCoin::CoinNrvFix::sInstance);
354void Coin::appearControlPose() {
356 MR::validateClipping(
this);
357 MR::validateHitSensors(
this);
359 MR::calcGravityOrZero(
this);
361 setNerve(&NrvCoin::CoinNrvControled::sInstance);
364void Coin::appearNonActive() {
366 MR::validateClipping(
this);
367 MR::invalidateHitSensors(
this);
370 setNerve(&NrvCoin::CoinNrvNonActive::sInstance);
373void Coin::appearFixTimer(s32 a1, s32 a2) {
375 MR::invalidateClipping(
this);
376 MR::invalidateHitSensors(
this);
380 setNerve(&NrvCoin::CoinNrvFixTimer::sInstance);
383void Coin::appearMove(
const TVec3f &a1,
const TVec3f &a2, s32 a3, s32 a4) {
386 MR::invalidateClipping(
this);
387 MR::invalidateHitSensors(
this);
389 MR::onCalcShadow(
this,
nullptr);
393 if (MR::normalizeOrZero(a2, &stack_14)) {
402 MR::calcGravityOrZero(
this);
405 setNerve(&NrvCoin::CoinNrvMove::sInstance);
408void Coin::appearHop(
const TVec3f &a1,
const TVec3f &a2) {
409 if (MR::isNearZero(a2, 0.001f)) {
420 MR::invalidateClipping(
this);
421 MR::invalidateHitSensors(
this);
423 MR::invalidateShadow(
this,
nullptr);
426 setNerve(&NrvCoin::CoinNrvHop::sInstance);
429bool Coin::requestActive() {
430 if (isNerve(&NrvCoin::CoinNrvNonActive::sInstance)) {
431 MR::invalidateHitSensors(
this);
432 setNerve(&NrvCoin::CoinNrvFix::sInstance);
439bool Coin::requestActiveWithGravity() {
440 if (isNerve(&NrvCoin::CoinNrvNonActive::sInstance)) {
441 MR::invalidateClipping(
this);
442 MR::validateHitSensors(
this);
444 MR::calcGravityOrZero(
this);
446 setNerve(&NrvCoin::CoinNrvMove::sInstance);
453bool Coin::requestDeactive() {
454 if (!MR::isDead(
this) && isNerve(&NrvCoin::CoinNrvFix::sInstance)) {
455 MR::invalidateHitSensors(
this);
456 setNerve(&NrvCoin::CoinNrvNonActive::sInstance);
463bool Coin::requestStartControl() {
464 if (MR::isDead(
this)) {
468 if (!isNerve(&NrvCoin::CoinNrvFix::sInstance) && !isNerve(&NrvCoin::CoinNrvFixHide::sInstance)) {
472 if (isNerve(&NrvCoin::CoinNrvFixHide::sInstance)) {
476 MR::validateClipping(
this);
477 MR::invalidateHitSensors(
this);
479 MR::onCalcShadow(
this,
nullptr);
480 setNerve(&NrvCoin::CoinNrvControled::sInstance);
485bool Coin::requestEndControl() {
486 if (MR::isDead(
this) || !isNerve(&NrvCoin::CoinNrvControled::sInstance)) {
490 MR::validateClipping(
this);
491 MR::validateHitSensors(
this);
493 MR::offCalcShadow(
this,
nullptr);
496 setNerve(&NrvCoin::CoinNrvFix::sInstance);
500bool Coin::requestSpinDrain() {
501 if (isNerve(&NrvCoin::CoinNrvSpinDrained::sInstance)) {
509 MR::invalidateClipping(
this);
511 MR::validateHitSensors(
this);
512 setNerve(&NrvCoin::CoinNrvSpinDrained::sInstance);
517bool Coin::requestShow() {
518 if (isNerve(&NrvCoin::CoinNrvFixHide::sInstance) && !MR::isDead(
this)) {
520 MR::validateHitSensors(
this);
521 setNerve(&NrvCoin::CoinNrvFix::sInstance);
527bool Coin::requestHide() {
528 if (isNerve(&NrvCoin::CoinNrvFix::sInstance) && !MR::isDead(
this)) {
530 MR::invalidateHitSensors(
this);
531 setNerve(&NrvCoin::CoinNrvFixHide::sInstance);
537void Coin::noticeGetCoin() {
539 MR::emitEffect(mAirBubble,
"RecoveryBubbleBreak");
540 MR::incPlayerOxygen(8);
542 mIsNeedBubble =
false;
547 MR::startSystemSE(
"SE_SY_PURPLE_COIN", -1, -1);
551 MR::startSystemSE(
"SE_SY_COIN", -1, -1);
556void Coin::setLife(s32 life) {
569void Coin::setCalcShadowMode() {
571 MR::onCalcShadow(
this,
nullptr);
572 MR::onCalcShadowDropPrivateGravity(
this,
nullptr);
575 MR::onCalcShadowOneTime(
this,
nullptr);
576 MR::onCalcShadowDropPrivateGravityOneTime(
this,
nullptr);
580void Coin::setCannotTime(s32 time) {
589void Coin::calcRebouond() {
590 if (MR::isBindedRoof(
this)) {
591 MR::calcReboundVelocity(&
mVelocity, *MR::getRoofNormal(
this), 0.60000002f, 0.5f);
594 if (MR::isBindedWall(
this)) {
595 MR::calcReboundVelocity(&
mVelocity, *MR::getWallNormal(
this), 0.60000002f, 0.5f);
598 if (MR::isBindedGround(
this)) {
599 f32 dot =
mVelocity.dot(-*MR::getGroundNormal(
this));
608 int what = (100.0f * dot) / 30.0f;
611 MR::startSound(
this,
"SE_OJ_COIN_BOUND", what, -1);
621void Coin::attenuateVelocity() {
625 velocity = 0.80000001f;
627 else if (MR::isOnGround(
this)) {
628 velocity = 0.89999998f;
634 MR::attenuateVelocity(
this, velocity);
638 if (!MR::isValidInfo(rIter)) {
643 MR::getJMapInfoArg7WithInit(rIter, &arg);
648 if (Coin::isNeedBubble(rIter)) {
649 pList->addArchive(
"AirBubble");
654 NameObj* createDirectSetCoin(
const char *pName) {
656 MR::createCoinHolder();
657 MR::createCoinRotater();
658 MR::addToCoinHolder(coin, coin);
664 MR::createCoinHolder();
665 MR::createCoinRotater();
666 MR::addToCoinHolder(pObj, coin);
670 NameObj* createDirectSetPurpleCoin(
const char *pName) {
672 coin->mIsPurpleCoin =
true;
673 MR::createPurpleCoinHolder();
674 MR::createCoinRotater();
675 MR::addToPurpleCoinHolder(coin, coin);
679 NameObj* createPurpleCoin(
const NameObj *pObj,
const char *pName) {
681 coin->mIsPurpleCoin =
true;
682 MR::createPurpleCoinHolder();
683 MR::createCoinRotater();
684 MR::addToPurpleCoinHolder(pObj, coin);
690 INIT_NERVE(CoinNrvNonActive);
691 INIT_NERVE(CoinNrvFix);
692 INIT_NERVE(CoinNrvFixHide);
693 INIT_NERVE(CoinNrvFixTimer);
694 INIT_NERVE(CoinNrvControled);
695 INIT_NERVE(CoinNrvSpinDrained);
696 INIT_NERVE(CoinNrvMove);
697 INIT_NERVE(CoinNrvHop);
699 void CoinNrvHop::execute(
Spine *pSpine)
const {
700 Coin* coin =
reinterpret_cast<Coin*
>(pSpine->mExecutor);
704 void CoinNrvMove::execute(
Spine *pSpine)
const {
705 Coin* coin =
reinterpret_cast<Coin*
>(pSpine->mExecutor);
709 void CoinNrvSpinDrained::execute(
Spine *pSpine)
const {
710 Coin* coin =
reinterpret_cast<Coin*
>(pSpine->mExecutor);
711 coin->exeSpinDrained();
714 void CoinNrvControled::execute(
Spine *pSpine)
const {
715 Coin* coin =
reinterpret_cast<Coin*
>(pSpine->mExecutor);
716 coin->exeControled();
719 void CoinNrvFixTimer::execute(
Spine *pSpine)
const {
720 Coin* coin =
reinterpret_cast<Coin*
>(pSpine->mExecutor);
724 void CoinNrvFixHide::execute(
Spine *pSpine)
const {
728 void CoinNrvFix::execute(
Spine *pSpine)
const {
729 Coin* coin =
reinterpret_cast<Coin*
>(pSpine->mExecutor);
733 void CoinNrvNonActive::execute(
Spine *pSpine)
const {
734 Coin* coin =
reinterpret_cast<Coin*
>(pSpine->mExecutor);
735 coin->exeNonActive();
virtual void calcAndSetBaseMtx()
Calculates and sets the base matrix of the actor.
virtual void init(const JMapInfoIter &)
Intializes the NameObj and can set various settings and construct necessary classes.
The basis of a drawable actor that can contain states (see: Nerve)
TVec3f mPosition
3D vector of the actor's position.
TVec3f mVelocity
3D vector of the actor's velocity.
TVec3f mGravity
3D vector of the actor's gravity.
Stores archive names of NameObjs.
The most basic form of an object.