2#include "Game/MapObj/PunchingKinoko.hpp"
4PunchingKinoko::PunchingKinoko(
const char *pName) :
LiveActor(pName),
5 mGroundChecker(nullptr), mScaleController(nullptr), mDelegator(nullptr), _98(-1), _9C(0, 0, 0), _A8(0, 1, 0) {
6 mStarPointerHitCoolDown = 0;
8 mInvincibleHitCoolDown = -1;
12 MR::initDefaultPos(
this, rIter);
13 initModelManagerWithAnm(
"PunchingKinoko",
nullptr,
false);
14 MR::connectToSceneNoSilhouettedMapObj(
this);
15 MR::calcGravity(
this);
19 MR::calcPositionUpOffset(&mGroundChecker->
mPosition,
this, 130.0f);
20 MR::resetPosition(mGroundChecker);
21 MR::onCalcGravity(mGroundChecker);
25 TVec3f *groundCheckerPos = &mGroundChecker->
mPosition;
26 MR::initStarPointerTargetAtPos(
this, 70.0f, groundCheckerPos, TVec3f(0, 0, 0));
30 initEffectKeeper(0,
nullptr,
false);
34 initNerve(&NrvPunchingKinoko::PunchingKinokoNrvWait::sInstance);
38 if (MR::useStageSwitchReadB(
this, rIter) != 0) {
40 MR::listenStageSwitchOnB(
this, functor);
42 MR::useStageSwitchSleep(
this, rIter);
45void PunchingKinoko::initSensor() {
47 MR::addHitSensorAtJointEnemy(
this,
"Head",
"Ball", 0x10, 9.18355e-41f, TVec3f(0.0174533f, 0.0174533f, 0.0174533f));
48 MR::addHitSensorEnemy(
this,
"Body", 0x10, 9.18355e-41f, TVec3f(0.0174533f, 9.18355e-41f, 0.0174533f));
51void PunchingKinoko::initShadow() {
52 MR::initShadowController(
this, 3);
53 MR::addShadowVolumeSphere(
this,
"体", 10.0f);
54 MR::onCalcShadowOneTime(
this,
"体");
55 MR::addShadowVolumeSphere(
this,
"頭", 10.0f);
56 MR::setShadowDropPositionPtr(
this,
"頭", &mGroundChecker->
mPosition);
57 MR::setShadowDropDirectionPtr(
this,
"頭", &mGroundChecker->
mGravity);
58 MR::addShadowVolumeLine(
this,
"つた",
this,
"体", 10.0f,
this,
"頭", 10.0f);
61void PunchingKinoko::initCamera(
const JMapInfoIter &rIter) {
62 MR::getJMapInfoArg7WithInit(rIter, &_98);
64 MR::declareCameraRegisterVec(
this, _98, &_9C);
68void PunchingKinoko::initJointControl() {
69 mDelegator = MR::createJointDelegatorWithNullChildFunc(
this, &PunchingKinoko::ballMtxCallBack,
"Ball");
74 PSVECSubtract(mGroundChecker->
mPosition.toCVec(),
mPosition.toCVec(), stack_8.toVec());
75 MR::orthogonalize(a1);
76 if (!MR::normalizeOrZero(&stack_8)) {
77 MR::turnMtxToYDirRate(a1, stack_8, 1.0f);
83 MR::scaleMtxToDir(&stack_14, _A8, mScaleController->_C);
84 a1->concat(stack_14, *a1);
86 TVec3f *groundCheckerPos = &mGroundChecker->
mPosition;
87 a1->mMtx[0][0] = groundCheckerPos->x;
88 a1->mMtx[1][1] = groundCheckerPos->y;
89 a1->mMtx[2][2] = groundCheckerPos->z;
94void PunchingKinoko::makeActorAppeared() {
95 LiveActor::makeActorAppeared();
96 mGroundChecker->makeActorAppeared();
99void PunchingKinoko::kill() {
103void PunchingKinoko::makeActorDead() {
104 LiveActor::makeActorDead();
105 mGroundChecker->makeActorDead();
108void PunchingKinoko::control() {
109 if (mStarPointerHitCoolDown > 0) {
110 mStarPointerHitCoolDown -= 1;
112 mScaleController->update();
113 mGroundChecker->movement();
114 MR::reboundVelocityFromCollision(mGroundChecker, 0.0f, 0.0f, 1.0f);
115 if (mInvincibleHitCoolDown > -1) {
116 mInvincibleHitCoolDown -= 1;
124 MR::makeMtxUpNoSupportPos(&stack_14, stack_8,
mPosition);
125 MR::setBaseTRMtx(
this, stack_14);
126 mDelegator->registerCallBack();
132 if (isNerve(&NrvPunchingKinoko::PunchingKinokoNrvWait::sInstance)) {
133 MR::sendMsgPush(pOtherSensor, pMySensor);
136 else if (!isNerve(&NrvPunchingKinoko::PunchingKinokoNrvCrushedEnd::sInstance) || !MR::isSensorPlayer(pOtherSensor) || !MR::sendMsgEnemyAttackFlipWeakJump(pOtherSensor, pMySensor)) {
140 MR::separateScalarAndDirection(&stack_8, &stack_3C, mGroundChecker->
mVelocity);
142 if (MR::isSensorPlayer(pOtherSensor)) {
143 if (isEnableHitPlayer()) {
144 if (stack_8 >= 30.0f) {
145 if (stack_8 >= 45.0f) {
146 TVec3f stack_24(stack_3C);
147 stack_24.scaleInline(70.0f);
148 hit = MR::sendMsgEnemyAttackFlipMaximumToDir(pOtherSensor, pMySensor, stack_24);
151 TVec3f stack_18(stack_3C);
152 stack_18.scale(70.0f);
153 hit = MR::sendMsgEnemyAttackFlipToDir(pOtherSensor, pMySensor, stack_18);
156 MR::startSoundPlayer(
"SE_PM_WALL_HIT_BODY", -1);
157 MR::scatterStarPiecePlayer(10);
161 if (stack_8 >= 15.0f) {
162 hit = MR::sendMsgEnemyAttackFlipWeak(pOtherSensor, pMySensor);
164 MR::sendMsgPush(pOtherSensor, pMySensor);
169 MR::sendMsgPush(pOtherSensor, pMySensor);
173 if (isEnableEnemyAttack()) {
174 hit = MR::sendMsgToEnemyAttackBlow(pOtherSensor, pMySensor);
177 MR::sendMsgPush(pOtherSensor, pMySensor);
181 MR::emitEffectHitBetweenSensors(
this, pMySensor, pOtherSensor, 0.0f,
"Hit");
182 MR::calcSensorDirectionNormalize(&stack_30, pOtherSensor, pMySensor);
183 f32 dot = mGroundChecker->
mVelocity.dot(stack_30) * 1.6f;
184 TVec3f stack_C(stack_30);
186 TVec3f *groundvel = &mGroundChecker->
mVelocity;
187 PSVECSubtract(groundvel->toCVec(), stack_C.toVec(), groundvel->toVec());
188 mGroundChecker->
mVelocity.scaleInline(0.3f);
189 setNerve(&NrvPunchingKinoko::PunchingKinokoNrvWait::sInstance);
195bool PunchingKinoko::receiveMsgPlayerAttack(u32 a1,
HitSensor *pOtherSensor,
HitSensor *pMySensor) {
204 if (MR::isMsgInvincibleAttack(a1)) {
205 if (mInvincibleHitCoolDown < 0) {
206 MR::startBlowHitSound(
this);
207 mInvincibleHitCoolDown = 10;
209 return requestEnemyBlow(pOtherSensor, pMySensor);
212 if (MR::isMsgPlayerHipDrop(a1)) {
213 return requestCrush();
216 if (MR::isMsgLockOnStarPieceShoot(a1)) {
220 if (MR::isMsgStarPieceAttack(a1)) {
222 MR::calcSensorDirectionNormalize(&stack_14, pOtherSensor, pMySensor);
223 f32 dot = mGroundChecker->
mVelocity.dot(stack_14);
225 TVec3f stack_8(stack_14);
226 stack_8.scale(15.0f);
229 MR::startSound(
this,
"SE_OJ_PNC_KINOKO_BOUND", -1, -1);
233 if (MR::isMsgPlayerSpinAttack(a1)) {
234 return requestPunch(pOtherSensor, pMySensor);
237 if (MR::isMsgPlayerTrample(a1)) {
238 return requestTrample(pOtherSensor, pMySensor);
244bool PunchingKinoko::receiveMsgEnemyAttack(u32 a1,
HitSensor *pOtherSensor,
HitSensor *pMySensor) {
253 if (MR::isMsgToEnemyAttackTrample(a1)) {
254 return requestCrush();
257 if (MR::isMsgToEnemyAttackBlow(a1)) {
258 return requestEnemyBlow(pOtherSensor, pMySensor);
274 MR::calcSensorHorizonNormalize(&stack_14,
mGravity, pOtherSensor, pMySensor);
275 f32 fVar1 = stack_14.dot(mGroundChecker->
mVelocity);
280 fVar1 = 3.0f - fVar1;
284 TVec3f stack_8(stack_14);
285 stack_8.scale(fVar1);
302 if (isEnablePunched()) {
303 MR::invalidateClipping(
this);
305 MR::calcSensorHorizonNormalize(&stack_14,
mGravity, pOtherSensor, pMySensor);
306 TVec3f stack_8(stack_14);
307 stack_8.scale(50.0f);
309 MR::startSpinHitSound(
this);
310 MR::startBlowHitSound(
this);
311 MR::tryRumblePadStrong(
this, 0);
313 setNerve(&NrvPunchingKinoko::PunchingKinokoNrvPunched::sInstance);
322 if (!isEnableBlowed()) {
326 MR::invalidateClipping(
this);
328 MR::calcSensorHorizonNormalize(&stack_14,
mGravity, pOtherSensor, pMySensor);
329 TVec3f stack_8(stack_14);
330 stack_8.scale(25.0f);
332 MR::startSound(
this,
"SE_OJ_PNC_KINOKO_HIT_SELF", -1, -1);
333 setNerve(&NrvPunchingKinoko::PunchingKinokoNrvWait::sInstance);
339 if (isEnableTrample()) {
341 MR::calcSensorDirectionNormalize(&stack_14, pOtherSensor, pMySensor);
343 TVec3f stack_8(stack_14);
352bool PunchingKinoko::requestCrush() {
353 if (isEnableCrushed()) {
354 MR::invalidateClipping(
this);
355 setNerve(&NrvPunchingKinoko::PunchingKinokoNrvCrushed::sInstance);
361void PunchingKinoko::exeWait() {
362 if (MR::isFirstStep(
this)) {
363 MR::startBrk(
this,
"Normal");
364 MR::validateClipping(
this);
370 MR::calcPositionUpOffset(&stack_38,
this, 130.0f);
372 TVec3f *groundCheckerPos = &mGroundChecker->
mPosition;
374 TVec3f stack_14(stack_38);
375 PSVECSubtract(stack_14.toCVec(), groundCheckerPos->toCVec(), stack_14.toVec());
378 stack_20.scale(0.008f);
379 MR::addVelocity(mGroundChecker, stack_20);
380 MR::attenuateVelocity(mGroundChecker, 0.94f);
382 if (MR::isStarPointerPointing2POnPressButton(
this,
nullptr,
false,
false)) {
383 if (mStarPointerHitCoolDown == 0 && !_B8 && MR::getStarPointerScreenSpeed(1) > 5.0f) {
384 stack_2C.set(0.0f, 0.0f, 0.0f);
385 if (MR::calcStarPointerWorldVelocityDirectionOnPlane(&stack_2C, mGroundChecker->
mPosition,
mGravity, 1)) {
386 TVec3f stack_8(stack_2C);
387 stack_8.scale(35.0f);
389 MR::startBlowHitSound(
this);
390 MR::start2PAttackAssistSound();
391 MR::tryRumblePadWeak(
this, 1);
392 mStarPointerHitCoolDown = 30;
393 setNerve(&NrvPunchingKinoko::PunchingKinokoNrvPointSnaped::sInstance);
402 MR::vecBlend(_9C,
mPosition, &_9C, 0.05f);
405void PunchingKinoko::exeSwing() {
406 float var2 = MR::calcVelocityLength(mGroundChecker);
408 MR::calcPositionUpOffset(&stack_20,
this, 130.0f);
410 TVec3f *groundCheckerPos = &mGroundChecker->
mPosition;
411 TVec3f stack_14(stack_20);
412 PSVECSubtract(stack_14.toCVec(), groundCheckerPos->toCVec(), stack_14.toVec());
414 TVec3f stack_8(stack_14);
415 stack_8.scale(0.008f);
417 MR::addVelocity(mGroundChecker, stack_8);
418 MR::attenuateVelocity(mGroundChecker, 0.97f);
419 float var3 = MR::calcVelocityLength(mGroundChecker);
421 const float f0 = 20.0f;
422 if (var2 < f0 && var3 >= f0) {
423 MR::startSound(
this,
"SE_OJ_PNC_KINOKO_BOUND", -1, -1);
426 MR::vecBlend(_9C,
mPosition, &_9C, 0.05f);
428 if (var3 < 40.0f && PSVECMag(stack_14.toCVec()) < 50.0f) {
429 setNerve(&NrvPunchingKinoko::PunchingKinokoNrvWait::sInstance);
433void PunchingKinoko::exePointSnaped() {
434 MR::startLevelSound(
this,
"SE_OJ_LV_PNC_KINOKO_PUNCHED", -1, -1, -1);
435 addVelocityKeepHeight();
436 MR::attenuateVelocity(mGroundChecker, 0.99f);
437 if (MR::isGreaterStep(
this, 6)) {
438 setNerve(&NrvPunchingKinoko::PunchingKinokoNrvSwing::sInstance);
442void PunchingKinoko::exePunched() {
443 MR::isFirstStep(
this);
444 MR::startLevelSound(
this,
"SE_OJ_LV_PNC_KINOKO_PUNCHED", -1, -1, -1);
445 addVelocityKeepHeight();
446 MR::attenuateVelocity(mGroundChecker, 0.99f);
448 MR::sendMsgEnemyAttackToBindedSensor(mGroundChecker, sensor);
450 if (MR::isGreaterStep(
this, 5)) {
451 setNerve(&NrvPunchingKinoko::PunchingKinokoNrvPunchedBrake::sInstance);
455void PunchingKinoko::exePunchedBrake() {
456 addVelocityKeepHeight();
457 MR::attenuateVelocity(mGroundChecker, 0.9f);
458 MR::startLevelSound(
this,
"SE_OJ_LV_PNC_KINOKO_PUNCHED", -1, -1, -1);
460 if (!MR::isGreaterStep(
this, 40)) {
462 if (!MR::sendMsgEnemyAttackToBindedSensor(mGroundChecker, sensor)) {
466 MR::startSound(
this,
"SE_OJ_PNC_KINOKO_RETURN", -1, -1);
467 setNerve(&NrvPunchingKinoko::PunchingKinokoNrvSwing::sInstance);
470void PunchingKinoko::exeHitted() {
471 if (MR::isFirstStep(
this)) {
472 MR::startSound(
this,
"SE_OJ_PNC_KINOKO_HIT_SELF", -1, -1);
474 addVelocityKeepHeight();
475 MR::attenuateVelocity(mGroundChecker, 0.99f);
476 if (MR::isGreaterStep(
this, 5)) {
477 setNerve(&NrvPunchingKinoko::PunchingKinokoNrvWait::sInstance);
481void PunchingKinoko::exeCrushed() {
482 if (MR::isFirstStep(
this)) {
483 MR::startBrk(
this,
"Press");
484 if (MR::isShadowProjected(
this,
"頭")) {
485 MR::getShadowProjectionNormal(
this,
"頭", &_A8);
486 MR::getShadowProjectionPos(
this,
"頭", &mGroundChecker->
mPosition);
488 stack_8.scale(20.0f);
494 MR::offBind(mGroundChecker);
495 mScaleController->startCrush();
496 MR::startSound(
this,
"SE_OJ_PNC_KINOKO_CRASH", -1, -1);
498 MR::zeroVelocity(mGroundChecker);
499 if (MR::isGreaterStep(
this, 180)) {
500 setNerve(&NrvPunchingKinoko::PunchingKinokoNrvCrushedEnd::sInstance);
504void PunchingKinoko::exeCrushedEnd() {
505 MR::isFirstStep(
this);
506 if (MR::isStep(
this, 10)) {
507 MR::startBrk(
this,
"Revival");
508 mScaleController->startAnim();
509 MR::startSound(
this,
"SE_OJ_PNC_KINOKO_RECOVER", -1, -1);
512 MR::calcPositionUpOffset(&stack_20,
this, 130.0f);
513 TVec3f *groundCheckerPos = &mGroundChecker->
mPosition;
515 TVec3f stack_8(stack_20);
516 PSVECSubtract(stack_8.toCVec(), groundCheckerPos->toCVec(), stack_8.toVec());
518 stack_14.scale(0.008f);
519 MR::addVelocity(mGroundChecker, stack_14);
520 MR::attenuateVelocity(mGroundChecker, 0.94f);
521 if (MR::isGreaterStep(
this, 60)) {
522 setNerve(&NrvPunchingKinoko::PunchingKinokoNrvWait::sInstance);
523 MR::onBind(mGroundChecker);
527void PunchingKinoko::addVelocityKeepHeight() {
528 if (MR::isShadowProjected(
this,
"頭")) {
530 MR::getShadowProjectionPos(
this,
"頭", &stack_8);
531 MR::addVelocityKeepHeight(mGroundChecker, stack_8, 130.0f, 0.5f, 60.0f);
535bool PunchingKinoko::isEnablePunched()
const {
536 if (isNerve(&NrvPunchingKinoko::PunchingKinokoNrvWait::sInstance) ||
537 isNerve(&NrvPunchingKinoko::PunchingKinokoNrvSwing::sInstance)) {
543bool PunchingKinoko::isEnableHitPlayer()
const {
544 return isNerve(&NrvPunchingKinoko::PunchingKinokoNrvSwing::sInstance);
547bool PunchingKinoko::isEnableEnemyAttack()
const {
548 if (isNerve(&NrvPunchingKinoko::PunchingKinokoNrvSwing::sInstance) ||
549 isNerve(&NrvPunchingKinoko::PunchingKinokoNrvPunched::sInstance) ||
550 isNerve(&NrvPunchingKinoko::PunchingKinokoNrvPunchedBrake::sInstance) ||
551 isNerve(&NrvPunchingKinoko::PunchingKinokoNrvPointSnaped::sInstance)) {
557bool PunchingKinoko::isEnableCrushed()
const {
558 if (isNerve(&NrvPunchingKinoko::PunchingKinokoNrvWait::sInstance) ||
559 isNerve(&NrvPunchingKinoko::PunchingKinokoNrvCrushedEnd::sInstance)) {
565bool PunchingKinoko::isEnableTrample()
const {
566 if (isNerve(&NrvPunchingKinoko::PunchingKinokoNrvCrushed::sInstance) ||
567 isNerve(&NrvPunchingKinoko::PunchingKinokoNrvCrushedEnd::sInstance)) {
573bool PunchingKinoko::isEnableBlowed()
const {
574 return isNerve(&NrvPunchingKinoko::PunchingKinokoNrvWait::sInstance);
577bool PunchingKinoko::isCrushed()
const {
578 return isNerve(&NrvPunchingKinoko::PunchingKinokoNrvCrushed::sInstance);
581namespace NrvPunchingKinoko {
582 INIT_NERVE(PunchingKinokoNrvWait);
583 INIT_NERVE(PunchingKinokoNrvSwing);
584 INIT_NERVE(PunchingKinokoNrvPunched);
585 INIT_NERVE(PunchingKinokoNrvPunchedBrake);
586 INIT_NERVE(PunchingKinokoNrvHitted);
587 INIT_NERVE(PunchingKinokoNrvPointSnaped);
588 INIT_NERVE(PunchingKinokoNrvCrushed);
589 INIT_NERVE(PunchingKinokoNrvCrushedEnd);
591 void PunchingKinokoNrvWait::execute(
Spine *pSpine)
const {
595 void PunchingKinokoNrvSwing::execute(
Spine *pSpine)
const {
599 void PunchingKinokoNrvPunched::execute(
Spine *pSpine)
const {
601 kinoko->exePunched();
603 void PunchingKinokoNrvPunchedBrake::execute(
Spine *pSpine)
const {
605 kinoko->exePunchedBrake();
607 void PunchingKinokoNrvHitted::execute(
Spine *pSpine)
const {
611 void PunchingKinokoNrvPointSnaped::execute(
Spine *pSpine)
const {
613 kinoko->exePointSnaped();
615 void PunchingKinokoNrvCrushed::execute(
Spine *pSpine)
const {
617 kinoko->exeCrushed();
619 void PunchingKinokoNrvCrushedEnd::execute(
Spine *pSpine)
const {
621 kinoko->exeCrushedEnd();
625PunchingKinoko::~PunchingKinoko() {
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.
HitSensor * getSensor(const char *pSensorName) const
Gets a sensor.
virtual void init(const JMapInfoIter &)
Intializes the NameObj and can set various settings and construct necessary classes.
virtual void calcAndSetBaseMtx()
Calculates and sets the base matrix of the actor.