1#include "Game/MapObj/SpinDriver.hpp"
2#include "Game/MapObj/SpinDriverUtil.hpp"
6SpinDriver::SpinDriver(
const char *pName) :
LiveActor(pName),
7 _8C(nullptr), mShootPath(nullptr), mSpinDriverCamera(nullptr), _98(0, 0, 0, 1), _A8(0, 0, 0, 1),
8 _B8(0, 0, 0), _C4(0, 0, 0), _D0(0, 0, 1), _DC(0, 0, 0), _E8(0, 1, 0), _F4(0, 0, 0), _104(0.0f), _100(40.0f), _108(0.0f), _10C(0, 0, 0) {
25 MR::initDefaultPos(
this, rIter);
26 initModelManagerWithAnm(
"SpinDriver",
nullptr,
false);
27 MR::connectToSceneNoSilhouettedMapObjStrongLight(
this);
29 MR::offCalcGravity(
this);
31 MR::calcGravityVectorOrZero(
this, &gravityVector,
nullptr, 0);
32 if (MR::isNearZero(gravityVector, 0.001f)) {
33 gravityVector.set(0.0f, -1.0f, 0.0f);
42 MR::addHitSensor(
this,
"body", 0x64, 0x10, 300.0f, sensorOffs);
43 initEffectKeeper(0,
nullptr,
false);
45 initEventCamera(rIter);
46 initNerve(&NrvSpinDriver::SpinDriverNrvWait::sInstance);
47 MR::initShadowVolumeFlatModel(
this,
"SpinDriverShadow", MR::getJointMtx(
this,
"SpinDriver"));
48 initParamFromJMapInfo(rIter);
49 MR::setClippingFar200m(
this);
51 if (MR::useStageSwitchReadAppear(
this, rIter)) {
52 MR::syncStageSwitchAppear(
this);
54 mSpinDriverCamera->initAppearCamera(rIter,
this);
61 MR::useStageSwitchSleep(
this, rIter);
64void SpinDriver::initAfterPlacement() {
65 SpinDriverUtil::setShadowAndClipping(
this, &_10C, _120, 300.0f, &_118);
68void SpinDriver::initParamFromJMapInfo(
const JMapInfoIter &rIter) {
70 MR::getJMapInfoArg0NoInit(rIter, &_100);
73 MR::getJMapInfoArg0NoInit(rIter, &_124);
77 MR::getJMapInfoArg1NoInit(rIter, &_120);
79 if (MR::getJMapInfoArg2NoInit(rIter, &arg2)) {
84 if (MR::getJMapInfoArg4NoInit(rIter, &arg4)) {
89void SpinDriver::initShootPath(
const JMapInfoIter &rIter) {
90 if (MR::isConnectedWithRail(rIter)) {
93 MR::getJMapInfoArg5NoInit(rIter, &_134);
94 mShootPath->initUsingParabolic(rIter,
mPosition);
95 mShootPath->calcInitPose(&_E8, &_D0, &_DC, _134);
115void SpinDriver::initEventCamera(
const JMapInfoIter &rIter) {
117 mSpinDriverCamera->init(rIter,
this);
118 MR::isConnectedWithRail(rIter);
121void SpinDriver::appear() {
123 MR::invalidateClipping(
this);
124 if (mSpinDriverCamera->isUseAppearCamera(
this)) {
125 MR::requestStartDemo(
this,
"出現", &NrvSpinDriver::SpinDriverNrvAppear::sInstance, &NrvSpinDriver::SpinDriverNrvTryDemo::sInstance);
128 setNerve(&NrvSpinDriver::SpinDriverNrvAppear::sInstance);
132void SpinDriver::makeActorAppeared() {
133 LiveActor::makeActorAppeared();
134 setNerve(&NrvSpinDriver::SpinDriverNrvWait::sInstance);
137void SpinDriver::makeActorDead() {
142 LiveActor::makeActorDead();
145void SpinDriver::control() {
147 TVec3f* pos = MR::getPlayerPos();
148 if (
mPosition.squared(*pos) > 122500.0f) {
157 f32 v4 = _104 + _108;
158 f32 v5 = ((_104 + _108) - -PI);
161 f32 v6 = fmod((TWO_PI + v5), TWO_PI_D);
168 MR::makeMtxUpFrontPos(&position, _E8, _D0,
mPosition);
174 mtx.mMtx[0][2] = _sin;
175 mtx.mMtx[1][1] = 1.0f;
176 mtx.mMtx[0][0] = _cos;
177 mtx.mMtx[2][0] = -_sin;
178 mtx.mMtx[2][2] = mtx.mMtx[0][0];
179 mtx.mMtx[2][1] = 0.0f;
180 mtx.mMtx[1][2] = 0.0f;
181 mtx.mMtx[1][0] = 0.0f;
182 mtx.mMtx[0][1] = 0.0f;
183 position.concat(position, mtx);
184 MR::setBaseTRMtx(
this, position);
201 if (isNerve(&NrvSpinDriver::SpinDriverNrvShootStart::sInstance)) {
212 if (msg == 148 && _8C) {
218 if (msg == 161 && _8C) {
219 calcBindActorMatrix();
226bool SpinDriver::tryStartShoot() {
227 bool isSwingOrPointed = MR::isPadSwing(0) || MR::isPlayerPointedBy2POnTriggerButton();
229 if (isSwingOrPointed) {
230 MR::startSound(_8C,
"SE_PM_SPIN_ATTACK", -1, -1);
231 if (MR::isInAreaObj(
"Water",
mPosition)) {
232 MR::startSound(
this,
"SE_PMSPIN_DRV_IN_WATER_1", -1, -1);
235 setNerve(&NrvSpinDriver::SpinDriverNrvShootStart::sInstance);
242bool SpinDriver::tryEndCapture() {
243 if (MR::isGreaterStep(
this, 40) && PSVECDistance(_B8.toCVec(),
mPosition.toCVec()) < 15.0f) {
246 setNerve(&NrvSpinDriver::SpinDriverNrvWait::sInstance);
253bool SpinDriver::tryShoot() {
254 if (MR::isGreaterStep(
this, 20)) {
255 setNerve(&NrvSpinDriver::SpinDriverNrvShoot::sInstance);
262bool SpinDriver::tryEndShoot() {
263 if (!mShootPath || MR::isGreaterStep(
this, _124)) {
264 MR::endBindAndSpinDriverJump(
this, _C4);
267 setNerve(&NrvSpinDriver::SpinDriverNrvCoolDown::sInstance);
274bool SpinDriver::tryForceCancel() {
276 setNerve(&NrvSpinDriver::SpinDriverNrvCoolDown::sInstance);
283bool SpinDriver::tryEndCoolDown() {
284 if (MR::isGreaterStep(
this, 60)) {
285 setNerve(&NrvSpinDriver::SpinDriverNrvWait::sInstance);
292bool SpinDriver::trySwitchOff() {
293 if (MR::isValidSwitchAppear(
this) && !MR::isOnSwitchAppear(
this)) {
301void SpinDriver::exeNonActive() {
302 if (MR::isFirstStep(
this)) {
303 MR::validateClipping(
this);
304 MR::startBck(
this,
"Wait",
nullptr);
305 MR::startBpk(
this,
"Wait");
308 bool isSwingOrPointed = MR::isPadSwing(0) || MR::isPlayerPointedBy2POnTriggerButton();
310 if (isSwingOrPointed) {
312 _108 += 0.050000001f;
313 if (v3 > 0.15000001f) {
319void SpinDriver::exeAppear() {
320 if (MR::isFirstStep(
this)) {
322 MR::startSystemSE(
"SE_SY_SPIN_DRIVER_APPEAR", -1, -1);
323 MR::startSound(
this,
"SE_OJ_SPIN_DRV_APPEAR", -1, -1);
326 MR::startBck(
this,
"Appear",
nullptr);
327 mSpinDriverCamera->startAppearCamera(
this, _E8, _D0,
mPosition);
330 if (MR::isBckStopped(
this)) {
331 if (MR::isGreaterStep(
this, mSpinDriverCamera->getAppearCameraFrames())) {
332 setNerve(&NrvSpinDriver::SpinDriverNrvWait::sInstance);
334 if (mSpinDriverCamera->isUseAppearCamera(
this)) {
335 MR::endDemoWaitCameraInterpolating(
this,
"出現");
336 mSpinDriverCamera->endAppearCamera(
this);
342void SpinDriver::exeWait() {
343 if (MR::isFirstStep(
this)) {
344 MR::validateClipping(
this);
345 MR::startBck(
this,
"Wait",
nullptr);
346 MR::startBpk(
this,
"Wait");
349 bool isSwingOrPointed = MR::isPadSwing(0) || MR::isPlayerPointedBy2POnTriggerButton();
351 if (isSwingOrPointed) {
352 _108 += 0.050000001f;
356 _108 += 0.0080000004f;
357 MR::startLevelSound(
this,
"SE_OJ_LV_SPIN_DRV_SHINE", -1, -1, -1);
359 MR::emitEffect(
this,
"SpinDriverLight");
360 MR::startCSSound(
"CS_SPIN_BIND",
nullptr, 0);
364 MR::deleteEffect(
this,
"SpinDriverLight");
367 if (trySwitchOff()) {
372void SpinDriver::exeCapture() {
373 if (tryForceCancel()) {
374 MR::deleteEffect(
this,
"SpinDriverLight");
377 if (MR::isFirstStep(
this)) {
378 MR::startBckPlayer(
"SpinDriverWait",
"SpinDriverCapture");
379 MR::startBck(
this,
"Active",
nullptr);
380 MR::emitEffect(
this,
"SpinDriverLight");
383 MR::startLevelSound(
this,
"SE_OJ_LV_SPIN_DRV_SHINE", -1, -1, -1);
384 MR::startLevelSound(
this,
"SE_OJ_LV_SPIN_DRV_CAPTURE", -1, -1, -1);
385 moveBindPosToCenter();
386 _11C = MR::calcNerveRate(
this, 40);
387 updateBindActorMatrix(_11C);
388 _108 += 0.0080000004f;
389 MR::tryRumblePadWeak(
this, 0);
392 if (!tryStartShoot()) {
393 if (tryEndCapture()) {
400void SpinDriver::exeShootStart() {
401 if (!tryForceCancel()) {
402 if (MR::isFirstStep(
this)) {
404 MR::deleteEffect(
this,
"SpinDriverLight");
405 MR::emitEffect(
this,
"SpinDriverStart");
406 MR::startBckPlayer(
"Spin",
"SpinDriverShoot");
407 MR::startBck(
this,
"Active",
nullptr);
408 MR::startBpk(
this,
"Active");
412 if (MR::isStep(
this, 4)) {
413 MR::startCSSound(
"CS_SPIN_DRIVE_SHORT",
"SE_SY_CS_SPIN_DRV_START", 0);
416 f32 clamp = MR::clamp(getNerveStep() / 20.0f, 0.0f, 1.0f);
417 f32 v3 = ((2.0f * (clamp - 0.5f)) * (2.0f * (clamp - 0.5f)));
420 MR::calcUpVec(&upVec,
this);
422 stack_50.set(
mPosition - MR::multVec(MR::multVec(upVec, 200.0f), 1.0f - dot));
423 f32 v5 = MR::clamp((2.0f * clamp), 0.0f, 1.0f);
424 _B8.set(MR::multAndAddVec(stack_50, _F4, v5, 1.0f - v5));
425 updateBindActorMatrix((v5 + (_11C * (1.0f - v5))));
426 _108 += 0.039999999f;
427 MR::tryRumblePadMiddle(
this, 0);
434void SpinDriver::exeShoot() {
435 if (!tryForceCancel()) {
436 if (MR::isFirstStep(
this)) {
437 calcShootMotionTime();
440 MR::startSystemME(
"ME_MAGIC");
443 MR::startSystemSE(
"SE_SY_S_SPIN_DRV_ME_ALT", -1, -1);
446 MR::startSound(
this,
"SE_OJ_SPIN_DRV_JUMP", -1, -1);
447 MR::startSound(_8C,
"SE_PV_JUMP_JOY", -1, -1);
449 if (MR::isInAreaObj(
"Water",
mPosition)) {
450 MR::startSound(
this,
"SE_PM_SIN_DIV_IN_WATER_2", -1, -1);
453 MR::startBckPlayer(
"SpaceFlyShortStart",
"SpinDriverFlyStart");
454 MR::shakeCameraNormal();
455 MR::tryRumblePadVeryStrong(
this, 0);
459 updateBindPosition();
461 calcParabolicBindPose();
463 if (MR::isStep(
this, _128)) {
464 MR::startBckPlayer(
"SpaceFlyShort",
"SpinDriverFlyLoop");
467 if (MR::isStep(
this, _12C)) {
468 MR::startBckPlayer(
"SpaceFlyEnd",
"SpinDriverFlyEnd");
471 if (MR::isLessStep(
this, _130)) {
472 MR::startLevelSound(_8C,
"SE_PM_LV_SPIN_DRV_FLY", -1, -1, -1);
475 if (MR::isStep(
this, _130)) {
476 MR::startBckPlayer(
"Fall",
"SpinDriverFall");
492void SpinDriver::exeCoolDown() {
493 if (MR::isFirstStep(
this)) {
494 MR::startBpk(
this,
"Wait");
497 if (!tryEndCoolDown()) {
498 if (trySwitchOff()) {
504bool SpinDriver::startBind(
HitSensor *pSensor) {
505 if (!canStartBind()) {
509 bool isSwingOrPointed = MR::isPadSwing(0) || MR::isPlayerPointedBy2POnTriggerButton();
511 if (isSwingOrPointed) {
513 MR::startSystemME(
"ME_MAGIC");
516 MR::startSystemSE(
"SE_SY_S_SPIN_DRV_ME_ALT", -1, -1);
519 MR::startSound(pSensor->mActor,
"SE_PM_SPIN_ATTACK", -1, -1);
521 if (MR::isInAreaObj(
"Water",
mPosition)) {
522 MR::startSound(
this,
"SE_PM_SPIN_DRV_IN_WATER_1", -1, -1);
525 setNerve(&NrvSpinDriver::SpinDriverNrvShootStart::sInstance);
528 if (_138 && _141 &&
mPosition.squared(pSensor->mPosition) < 57600.0f) {
529 setNerve(&NrvSpinDriver::SpinDriverNrvCapture::sInstance);
536 _8C = pSensor->mActor;
538 _C4 = *MR::getPlayerLastMove();
539 f32 mag = PSVECMag(_C4.toCVec());
547 rotation.setInline(mtx);
548 rotation.getQuat(_98);
550 cSpaceFlyStartFrame = MR::getBckFrameMax(_8C,
"SpaceFlyStart");
551 cSpaceFlyEndFrame = MR::getBckFrameMax(_8C,
"SpaceFlyEnd");
552 MR::validateClipping(
this);
556void SpinDriver::cancelBind() {
558 MR::endBindAndPlayerJump(
this, _C4, 0);
564void SpinDriver::updateBindPosition() {
565 f32 step = getNerveStep() / (f32)_124;
566 TVec3f stack_20(_B8);
568 mShootPath->calcPosition(&position, step);
570 _C4 = position - stack_20;
573void SpinDriver::moveBindPosToCenter() {
577 MR::separateScalarAndDirection(&scalar, &stack_24, stack_24);
578 f32 v3 = scalar / 120.0f;
579 _C4 += MR::multVec(stack_24, 1.5f, v3);
580 _C4.x *= 0.80000001f;
581 _C4.y *= 0.80000001f;
582 _C4.z *= 0.80000001f;
585void SpinDriver::updateBindActorMatrix(f32 a1) {
587 MR::makeMtxUpFrontPos(&rotation, _E8, _D0,
mPosition);
589 rotation.makeQuat(quat);
646void SpinDriver::startCamera() {
647 if (mSpinDriverCamera) {
648 mSpinDriverCamera->start(_E8, _D0,
mPosition);
652void SpinDriver::updateCamera() {
653 if (mSpinDriverCamera) {
654 mSpinDriverCamera->update(_C4, _B8);
658void SpinDriver::cancelCamera() {
659 if (mSpinDriverCamera) {
660 mSpinDriverCamera->cancel();
664void SpinDriver::endCamera() {
665 if (mSpinDriverCamera) {
666 mSpinDriverCamera->end();
670bool SpinDriver::canStartBind()
const {
671 return isNerve(&NrvSpinDriver::SpinDriverNrvWait::sInstance);
674bool SpinDriver::canBind(
HitSensor *pSensor)
const {
675 if (!canStartBind()) {
679 bool isSwingOrPointed = MR::isPadSwing(0) || MR::isPlayerPointedBy2POnTriggerButton();
681 if (isSwingOrPointed) {
685 if (_138 && _141 &&
mPosition.squared(pSensor->mPosition) < 457600.0f) {
692SpinDriver::~SpinDriver() {
696namespace NrvSpinDriver {
697 INIT_NERVE(SpinDriverNrvTryDemo);
698 INIT_NERVE(SpinDriverNrvNonActive);
699 INIT_NERVE(SpinDriverNrvAppear);
700 INIT_NERVE(SpinDriverNrvWait);
701 INIT_NERVE(SpinDriverNrvCapture);
702 INIT_NERVE(SpinDriverNrvShootStart);
703 INIT_NERVE(SpinDriverNrvShoot);
704 INIT_NERVE(SpinDriverNrvCoolDown);
706 void SpinDriverNrvCoolDown::execute(
Spine *pSpine)
const {
708 spinDriver->exeCoolDown();
711 void SpinDriverNrvShoot::execute(
Spine *pSpine)
const {
713 spinDriver->exeShoot();
716 void SpinDriverNrvShootStart::execute(
Spine *pSpine)
const {
718 spinDriver->exeShootStart();
721 void SpinDriverNrvCapture::execute(
Spine *pSpine)
const {
723 spinDriver->exeCapture();
726 void SpinDriverNrvWait::execute(
Spine *pSpine)
const {
728 spinDriver->exeWait();
731 void SpinDriverNrvAppear::execute(
Spine *pSpine)
const {
733 spinDriver->exeAppear();
736 void SpinDriverNrvNonActive::execute(
Spine *pSpine)
const {
738 spinDriver->exeNonActive();
741 void SpinDriverNrvTryDemo::execute(
Spine *pSpine)
const {
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 mGravity
3D vector of the actor's gravity.
virtual MtxPtr getBaseMtx() const
Gets the base matrix of the model used for the actor.
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.