1#include "Game/MapObj/BenefitItemObj.hpp"
2#include "JSystem/JGeometry/TUtil.hpp"
7namespace NrvBenefitItemObj {
8 INIT_NERVE(HostTypeNrvWait);
9 INIT_NERVE(HostTypeNrvShoot);
10 INIT_NERVE(HostTypeNrvCatch);
11 INIT_NERVE(HostTypeNrvAppearGround);
12 INIT_NERVE(HostTypeNrvPreEscape);
13 INIT_NERVE(HostTypeNrvEscape);
17 const f32 cAppearThrowFwdSpd = 5.0f;
18 const f32 cBoundUpSpd = 20.0f;
19 const f32 cAppearThrowUpSpd = 10.0f;
20 const f32 cAppearThrowUpSpd2 = 15.0f;
21 const f32 cGravity = 0.5f;
22 const f32 cReflectWallX = 0.30000001f;
23 static f32 cSpdRotateY = JGeometry::TUtil<f32>::PI() / 60.0f;
26void ShadowClipActor::endClipped() {
27 LiveActor::endClipped();
28 if (MR::isClipped(_8C)) {
33void ShadowClipActor::control() {
34 if (!MR::isClipped(
this)) {
39BenefitItemObj::BenefitItemObj(
const char *pName,
const char *pPowerUp) :
LiveActor(pName) {
51 mCameraInfo =
nullptr;
52 mHitSensorActor =
nullptr;
60void BenefitItemObj::initModelAndEfx() {
61 initModelManagerWithAnm(_120,
nullptr,
false);
62 initEffectKeeper(5, _120,
false);
63 initBinder(50.0f, 50.0f, 0);
65 MR::addHitSensor(
this,
"body", 77, 4, 50.0f, TVec3f(0.0f, 50.0f, 0.0f));
70 if (MR::isValidInfo(rIter)) {
71 MR::initDefaultPos(
this, rIter);
75 MR::connectToSceneItemStrongLight(
this);
76 MR::offCalcGravity(
this);
84 if (MR::isValidInfo(rIter)) {
85 _E3 = MR::isConnectedWithRail(rIter);
91 if (_E3 && MR::getJMapInfoRailArg0NoInit(
this, &railArg)) {
92 _E8 = railArg / 10.0f;
96 MR::setClippingFar100m(
this);
97 MR::setClippingTypeSphere(
this, 100.0f);
98 initNerve(&NrvBenefitItemObj::HostTypeNrvWait::sInstance);
112 if (MR::isValidInfo(rIter)) {
113 MR::getJMapInfoArg0NoInit(rIter, &arg0);
114 MR::getJMapInfoArg1NoInit(rIter, &arg1);
115 MR::getJMapInfoArg2NoInit(rIter, &arg2);
116 MR::getJMapInfoArg3NoInit(rIter, &arg3);
117 MR::getJMapInfoArg4NoInit(rIter, &arg4);
118 MR::getJMapInfoArg5NoInit(rIter, &arg5);
119 MR::getJMapInfoArg6NoInit(rIter, &arg6);
120 MR::getJMapInfoArg7NoInit(rIter, &arg7);
148 if (arg1 != -1 && (arg1 & 0x80) != 0) {
164 bool setClipType =
false;
186 if (arg5 == 1 && MR::isValidInfo(rIter)) {
187 MR::initActorCamera(
this, rIter, &mCameraInfo);
196 f32 shadowDist = 2000.0f;
202 if (MR::isValidInfo(rIter)) {
203 MR::useStageSwitchWriteDead(
this, rIter);
205 if (MR::useStageSwitchReadAppear(
this, rIter)) {
207 MR::listenStageSwitchOnAppear(
this, appearFunc);
221 MR::invalidateHitSensors(
this);
235 if (!MR::isDead(
this) && MR::isValidInfo(rIter)) {
236 MR::useStageSwitchSleep(
this, rIter);
239 TVec3f rotate_axis_y;
240 MR::getRotatedAxisY(&rotate_axis_y,
mRotation);
241 _A4.set<f32>(rotate_axis_y);
244 MR::initShadowVolumeCylinder(
this, 50.0f);
245 MR::setShadowDropLength(
this,
nullptr, shadowDist);
248 MR::onShadowVolumeCutDropLength(
this,
nullptr);
249 MR::setShadowVolumeEndDropOffset(
this,
nullptr, 50.0f);
252 if ((_DC & 0x1) != 0) {
253 if ((_DC & 0x2) != 0) {
254 MR::onCalcShadowDropPrivateGravity(
this,
nullptr);
255 MR::onCalcShadow(
this,
nullptr);
258 MR::onCalcShadowDropPrivateGravityOneTime(
this,
nullptr);
259 MR::onCalcShadowOneTime(
this,
nullptr);
262 else if ((_DC & 0x2) != 0) {
263 MR::onCalcShadow(
this,
nullptr);
266 MR::onCalcShadowOneTime(
this,
nullptr);
270 MR::setClippingTypeSphere(
this, shadowDist);
276void BenefitItemObj::initAfterPlacement() {
278 MR::moveCoordAndTransToNearestRailPos(
this);
282void BenefitItemObj::makeActorAppeared() {
283 LiveActor::makeActorAppeared();
287void BenefitItemObj::appear() {
295 setNerve(&NrvBenefitItemObj::HostTypeNrvPreEscape::sInstance);
297 MR::validateHitSensors(
this);
306 appearThrowUpQuestionBox();
315 MR::invalidateClipping(
this);
319 MR::invalidateClipping(
this);
323 MR::emitEffect(
this,
"AppearPicture");
327void BenefitItemObj::appearGround() {
328 MR::startSystemSE(
"SE_SY_ITEM_APPEAR", -1, -1);
329 setNerve(&NrvBenefitItemObj::HostTypeNrvAppearGround::sInstance);
331 MR::invalidateClipping(
this);
334void BenefitItemObj::appearThrowUp() {
335 MR::startSystemSE(
"SE_SY_ITEM_APPEAR", -1, -1);
338 MR::getRotatedAxisY(&rotated_axis,
mRotation);
339 _A4.set<f32>(rotated_axis);
340 setNerve(&NrvBenefitItemObj::HostTypeNrvShoot::sInstance);
343 f32 speed = cAppearThrowUpSpd;
344 mVelocity = MR::createVecAndScale(rotated_axis, speed);
347 f32 speed = cAppearThrowUpSpd2;
348 mVelocity = MR::createVecAndScale(rotated_axis, speed);
351 MR::invalidateClipping(
this);
354void BenefitItemObj::shoot(
const TVec3f &a2,
const TVec3f &a3,
bool a4) {
367void BenefitItemObj::appearThrowUpQuestionBox() {
371void BenefitItemObj::control() {
373 if (MR::tryStartDemoWithoutCinemaFrame(
this,
"出現")) {
375 MR::startActorCameraTargetSelf(
this, mCameraInfo, -1);
376 MR::requestMovementOn(
this);
377 MR::pauseOffCameraDirector();
378 _12C = MR::getActorCameraFrames(
this, mCameraInfo);
387 MR::calcGravityOrZero(
this);
388 calcAndSetBaseMtxInMovement();
397 MR::endActorCamera(
this, mCameraInfo,
false, -1);
398 MR::endDemo(
this,
"出現");
399 MR::validateClipping(
this);
405 if (MR::isBindedGroundDamageFire(
this)) {
410 if (!MR::isNearZero(
mVelocity, 0.001f)) {
411 if (MR::isInDeath(
this, TVec3f(0.0f, 0.0f, 0.0f))) {
421void BenefitItemObj::exeWait() {
444void BenefitItemObj::doRotateY() {
445 if (isNerve(&NrvBenefitItemObj::HostTypeNrvAppearGround::sInstance)) {
449 _EC = (f32)fmod((6.2831855f + ((_EC + cSpdRotateY) - zero)), 6.283185482025146) + zero;
453void BenefitItemObj::exeShoot() {
454 f32 reflect, v2, gravity, v4;
456 if (MR::isFirstStep(
this)) {
461 v2 = MR::vecKillElement(v9,
mGravity, &v9);
462 if (MR::isBindedGround(
this)) {
464 MR::validateHitSensors(
this);
467 if (MR::isGreaterStep(
this, 10)) {
468 setNerve(&NrvBenefitItemObj::HostTypeNrvWait::sInstance);
472 setNerve(&NrvBenefitItemObj::HostTypeNrvEscape::sInstance);
477 if (getNerveStep() == 60) {
478 MR::validateHitSensors(
this);
481 if (MR::isBindedWall(
this)) {
482 v4 = MR::vecKillElement(v9, *MR::getWallNormal(
this), &v9);
483 reflect = cReflectWallX;
484 v9 -= MR::createVecAndScale(MR::createVecAndScale(*MR::getWallNormal(
this), v4), reflect);
487 v9 += MR::createVecAndScale(
mGravity, gravity);
492void BenefitItemObj::exeCatch() {
493 if (MR::isFirstStep(
this)) {
498 MR::explainOneUpIfAtFirst();
509 return MR::isMsgStarPieceReflect(msg);
513 if (MR::isDead(
this)) {
517 if (MR::receiveItemShowMsg(msg, a2, a3)) {
521 if (MR::receiveItemHideMsg(msg, a2, a3)) {
525 if (MR::isMsgItemStartMove(msg)) {
530 if (MR::isMsgItemEndMove(msg)) {
536 if (mHitSensorActor) {
540 if (isNerve(&NrvBenefitItemObj::HostTypeNrvWait::sInstance)
541 || isNerve(&NrvBenefitItemObj::HostTypeNrvShoot::sInstance)
542 || isNerve(&NrvBenefitItemObj::HostTypeNrvAppearGround::sInstance)
543 || isNerve(&NrvBenefitItemObj::HostTypeNrvEscape::sInstance)) {
544 mHitSensorActor = a2->mActor;
545 setNerve(&NrvBenefitItemObj::HostTypeNrvCatch::sInstance);
546 MR::tryRumblePadWeak(
this, 0);
554void BenefitItemObj::exeAppearGround() {
555 if (MR::isFirstStep(
this)) {
559 if (getNerveStep() >= 60) {
560 if (getNerveStep() == 60) {
563 MR::startSound(
this,
"SE_OJ_KINOKO_1UP_GROW", -1, -1);
566 if (MR::isBckStopped(
this)) {
568 setNerve(&NrvBenefitItemObj::HostTypeNrvPreEscape::sInstance);
571 setNerve(&NrvBenefitItemObj::HostTypeNrvWait::sInstance);
574 MR::validateHitSensors(
this);
579void BenefitItemObj::exePreEscape() {
580 if (getNerveStep() >= 30) {
581 setNerve(&NrvBenefitItemObj::HostTypeNrvEscape::sInstance);
585void BenefitItemObj::initEscape() {
593 TVec3f stack_8(axis_z);
596 MR::startSound(
this,
"SE_OJ_KINOKO_1UP_RUN_START", -1, -1);
599void BenefitItemObj::doEscape() {
600 MR::startLevelSound(
this,
"SE_OJ_LV_KINOKO_1UP_RUN", -1, -1, -1);
606 if (MR::isBindedGround(
this)) {
607 f32 mag = PSVECMag(_BC.toCVec());
608 MR::vecKillElement(_BC,
mGravity, &_BC);
612 TVec3f* player_pos = MR::getPlayerPos();
615 MR::vecKillElement(v22,
mGravity, &v22);
616 MR::normalizeOrZero(&v22);
617 if (_BC.dot(v22) < 0.0f) {
618 _BC += MR::createVecAndScale(v22, 0.2f);
624 _BC += MR::createVecAndScale(v22, 0.0099999998f);
625 _BC.x *= 0.0099999998f;
626 _BC.y *= 0.0099999998f;
627 _BC.z *= 0.0099999998f;
631 if (PSVECMag(_BC.toCVec()) > 7.0f) {
640 _C8 = MR::createVecAndScale(
mGravity, 5.0f);
645 _BC.x *= 0.94999999f;
646 _BC.y *= 0.94999999f;
647 _BC.z *= 0.94999999f;
648 _C8 += MR::createVecAndScale(
mGravity, 1.0f);
650 if (PSVECMag(_C8.toCVec()) > 20.0f) {
651 _C8.setLength(20.0f);
657 if (MR::isBindedWall(
this) && !_E5) {
658 if (MR::getWallNormal(
this)->dot(
mGravity) < 0.0f) {
659 f32 scalar = MR::vecKillElement(_BC, *MR::getWallNormal(
this), &_BC);
660 _BC += -*MR::getWallNormal(
this) % scalar;
667void BenefitItemObj::exeEscape() {
668 if (MR::isFirstStep(
this)) {
669 MR::invalidateClipping(
this);
701 else if (_B0 == 0x78) {
705 else if (_B0 == 0xB4) {
719 MR::moveCoord(
this, _E8);
720 TVec3f railPos(MR::getRailPos(
this));
728 if ((_DB & 0x4) != 0) {
732 if (_DC && (_DC & 0x2) == 0) {
733 if ((_DC & 0x1) != 0) {
734 MR::onCalcShadowOneTime(
this,
nullptr);
737 MR::onCalcShadowDropPrivateGravityOneTime(
this,
nullptr);
746void BenefitItemObj::calcAndSetBaseMtxInMovement() {
747 if (isNerve(&NrvBenefitItemObj::HostTypeNrvWait::sInstance)) {
751 PSMTXCopy(mFollowMtx, _F0);
752 MR::extractMtxTrans(mFollowMtx, &
mPosition);
755 MtxPtr mtx = MR::tmpMtxRotYRad(_EC);
759 if (MR::isBindedGround(
this)) {
760 _A4 = *MR::getGroundNormal(
this);
762 else if (MR::isBindedWall(
this)) {
763 _A4 = *MR::getWallNormal(
this);
767 MR::normalizeOrZero(&stack_8);
768 if (isNerve(&NrvBenefitItemObj::HostTypeNrvPreEscape::sInstance)) {
769 MR::vecBlendSphere(_98, stack_8, &stack_8, 0.1f);
773 if (!MR::isNearZero(stack_8, 0.001f)) {
774 if (MR::isSameDirection(_A4, stack_8, 0.0099999998f)) {
779 MR::makeMtxUpFrontPos(&pos, _A4, stack_8,
mPosition);
780 MR::blendMtx(_F0, pos.toMtxPtr(), 0.2f, _F0);
781 MtxPtr mtx = MR::tmpMtxRotYRad(_EC);
789void BenefitItemObj::setFollowMtx(MtxPtr mtx) {
794void BenefitItemObj::runBck(
const char *pBckName) {
795 MR::startBck(
this, pBckName,
nullptr);
798void BenefitItemObj::runEfx(
const char *pEfxName) {
799 MR::emitEffect(
this, pEfxName);
802void BenefitItemObj::stopEfx(
const char *pEfxName) {
803 MR::deleteEffect(
this, pEfxName);
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 mRotation
3D vector of the actor's rotation.
TVec3f mPosition
3D vector of the actor's position.
TVec3f mVelocity
3D vector of the actor's velocity.
virtual void init(JMapInfoIter const &)
Intializes the NameObj and can set various settings and construct necessary classes.
virtual void calcAndSetBaseMtx()
Calculates and sets the base matrix of the actor.
TVec3f mGravity
3D vector of the actor's gravity.
virtual MtxPtr getBaseMtx() const
Gets the base matrix of the model used for the actor.