2023-12-13 00:40:16 -05:00
|
|
|
#include "Game/MapObj/SpinDriver.hpp"
|
|
|
|
|
#include "Game/MapObj/SpinDriverUtil.hpp"
|
2022-09-15 21:19:51 -04:00
|
|
|
#include <cstdio>
|
|
|
|
|
#include <cstring>
|
2024-04-14 21:02:28 -04:00
|
|
|
#include "math_types.hpp"
|
2022-07-11 08:17:22 -04:00
|
|
|
|
|
|
|
|
SpinDriver::SpinDriver(const char *pName) : LiveActor(pName),
|
2023-02-13 03:33:10 -05:00
|
|
|
_8C(nullptr), mShootPath(nullptr), mSpinDriverCamera(nullptr), _98(0, 0, 0, 1), _A8(0, 0, 0, 1),
|
2022-07-11 08:17:22 -04:00
|
|
|
_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) {
|
|
|
|
|
|
|
|
|
|
_11C = 0.0f;
|
|
|
|
|
_120 = -1.0f;
|
|
|
|
|
_124 = 300;
|
|
|
|
|
_128 = -1;
|
|
|
|
|
_12C = 240;
|
|
|
|
|
_130 = 270;
|
|
|
|
|
_134 = 0.0;
|
|
|
|
|
_138 = 1;
|
|
|
|
|
_13C = 0;
|
|
|
|
|
_140 = 0;
|
|
|
|
|
_141 = 1;
|
|
|
|
|
_142 = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SpinDriver::init(const JMapInfoIter &rIter) {
|
|
|
|
|
MR::initDefaultPos(this, rIter);
|
2023-02-13 03:33:10 -05:00
|
|
|
initModelManagerWithAnm("SpinDriver", nullptr, false);
|
2022-07-11 08:17:22 -04:00
|
|
|
MR::connectToSceneNoSilhouettedMapObjStrongLight(this);
|
|
|
|
|
initShootPath(rIter);
|
|
|
|
|
MR::offCalcGravity(this);
|
|
|
|
|
TVec3f gravityVector;
|
2023-02-13 03:33:10 -05:00
|
|
|
MR::calcGravityVectorOrZero(this, &gravityVector, nullptr, 0);
|
2022-07-11 08:17:22 -04:00
|
|
|
if (MR::isNearZero(gravityVector, 0.001f)) {
|
|
|
|
|
gravityVector.set(0.0f, -1.0f, 0.0f);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mGravity.set(gravityVector);
|
|
|
|
|
initHitSensor(1);
|
|
|
|
|
TVec3f sensorOffs;
|
|
|
|
|
sensorOffs.x = 0.0f;
|
|
|
|
|
sensorOffs.y = 0.0f;
|
|
|
|
|
sensorOffs.z = 0.0f;
|
|
|
|
|
MR::addHitSensor(this, "body", 0x64, 0x10, 300.0f, sensorOffs);
|
2023-02-13 03:33:10 -05:00
|
|
|
initEffectKeeper(0, nullptr, false);
|
2022-07-11 08:17:22 -04:00
|
|
|
initSound(6, false);
|
|
|
|
|
initEventCamera(rIter);
|
|
|
|
|
initNerve(&NrvSpinDriver::SpinDriverNrvWait::sInstance);
|
|
|
|
|
MR::initShadowVolumeFlatModel(this, "SpinDriverShadow", MR::getJointMtx(this, "SpinDriver"));
|
|
|
|
|
initParamFromJMapInfo(rIter);
|
|
|
|
|
MR::setClippingFar200m(this);
|
|
|
|
|
|
|
|
|
|
if (MR::useStageSwitchReadAppear(this, rIter)) {
|
|
|
|
|
MR::syncStageSwitchAppear(this);
|
|
|
|
|
makeActorDead();
|
|
|
|
|
mSpinDriverCamera->initAppearCamera(rIter, this);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
makeActorAppeared();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MR::useStageSwitchSleep(this, rIter);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SpinDriver::initAfterPlacement() {
|
|
|
|
|
SpinDriverUtil::setShadowAndClipping(this, &_10C, _120, 300.0f, &_118);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SpinDriver::initParamFromJMapInfo(const JMapInfoIter &rIter) {
|
|
|
|
|
if (!mShootPath) {
|
|
|
|
|
MR::getJMapInfoArg0NoInit(rIter, &_100);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
MR::getJMapInfoArg0NoInit(rIter, &_124);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_120 = -1.0f;
|
|
|
|
|
MR::getJMapInfoArg1NoInit(rIter, &_120);
|
|
|
|
|
s32 arg2 = 0;
|
|
|
|
|
if (MR::getJMapInfoArg2NoInit(rIter, &arg2)) {
|
|
|
|
|
_138 = arg2 != 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s32 arg4 = 0;
|
|
|
|
|
if (MR::getJMapInfoArg4NoInit(rIter, &arg4)) {
|
|
|
|
|
_142 = !(arg4 - 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SpinDriver::initShootPath(const JMapInfoIter &rIter) {
|
|
|
|
|
if (MR::isConnectedWithRail(rIter)) {
|
|
|
|
|
mShootPath = new SpinDriverShootPath();
|
|
|
|
|
_134 = 0.0f;
|
|
|
|
|
MR::getJMapInfoArg5NoInit(rIter, &_134);
|
|
|
|
|
mShootPath->initUsingParabolic(rIter, mPosition);
|
|
|
|
|
mShootPath->calcInitPose(&_E8, &_D0, &_DC, _134);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
Mtx mtx;
|
|
|
|
|
MR::makeMtxRotate(mtx, mRotation);
|
|
|
|
|
f32 z = mtx[2][0];
|
|
|
|
|
f32 y = mtx[1][0];
|
|
|
|
|
f32 x = mtx[0][0];
|
|
|
|
|
_DC.set(x, y, z);
|
|
|
|
|
z = mtx[2][1];
|
|
|
|
|
y = mtx[1][1];
|
|
|
|
|
x = mtx[0][1];
|
|
|
|
|
_E8.set(x, y, z);
|
|
|
|
|
z = mtx[2][2];
|
|
|
|
|
y = mtx[1][2];
|
|
|
|
|
x = mtx[0][2];
|
|
|
|
|
_D0.set(x, y, z);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SpinDriver::initEventCamera(const JMapInfoIter &rIter) {
|
|
|
|
|
mSpinDriverCamera = new SpinDriverCamera();
|
|
|
|
|
mSpinDriverCamera->init(rIter, this);
|
|
|
|
|
MR::isConnectedWithRail(rIter);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SpinDriver::appear() {
|
|
|
|
|
LiveActor::appear();
|
|
|
|
|
MR::invalidateClipping(this);
|
|
|
|
|
if (mSpinDriverCamera->isUseAppearCamera(this)) {
|
|
|
|
|
MR::requestStartDemo(this, "出現", &NrvSpinDriver::SpinDriverNrvAppear::sInstance, &NrvSpinDriver::SpinDriverNrvTryDemo::sInstance);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
setNerve(&NrvSpinDriver::SpinDriverNrvAppear::sInstance);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SpinDriver::makeActorAppeared() {
|
|
|
|
|
LiveActor::makeActorAppeared();
|
|
|
|
|
setNerve(&NrvSpinDriver::SpinDriverNrvWait::sInstance);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SpinDriver::makeActorDead() {
|
|
|
|
|
if (_8C) {
|
|
|
|
|
cancelBind();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LiveActor::makeActorDead();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SpinDriver::control() {
|
|
|
|
|
if (!_141) {
|
|
|
|
|
TVec3f* pos = MR::getPlayerPos();
|
|
|
|
|
if (mPosition.squared(*pos) > 122500.0f) {
|
|
|
|
|
_141 = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_13C) {
|
|
|
|
|
_13C--;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
f32 v4 = _104 + _108;
|
|
|
|
|
f32 v5 = ((_104 + _108) - -PI);
|
|
|
|
|
_140 = _13C > 0;
|
|
|
|
|
_104 = v4;
|
|
|
|
|
f32 v6 = fmod((TWO_PI + v5), TWO_PI_D);
|
|
|
|
|
_104 = -PI + v6;
|
|
|
|
|
_108 *= 0.94999999f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SpinDriver::calcAndSetBaseMtx() {
|
|
|
|
|
TPos3f position;
|
|
|
|
|
MR::makeMtxUpFrontPos(&position, _E8, _D0, mPosition);
|
|
|
|
|
TMtx34f mtx;
|
|
|
|
|
mtx.identity();
|
|
|
|
|
f32 var = _104;
|
|
|
|
|
f32 _sin = sin(var);
|
|
|
|
|
f32 _cos = cos(var);
|
|
|
|
|
mtx.mMtx[0][2] = _sin;
|
|
|
|
|
mtx.mMtx[1][1] = 1.0f;
|
|
|
|
|
mtx.mMtx[0][0] = _cos;
|
|
|
|
|
mtx.mMtx[2][0] = -_sin;
|
|
|
|
|
mtx.mMtx[2][2] = mtx.mMtx[0][0];
|
|
|
|
|
mtx.mMtx[2][1] = 0.0f;
|
|
|
|
|
mtx.mMtx[1][2] = 0.0f;
|
|
|
|
|
mtx.mMtx[1][0] = 0.0f;
|
|
|
|
|
mtx.mMtx[0][1] = 0.0f;
|
|
|
|
|
position.concat(position, mtx);
|
|
|
|
|
MR::setBaseTRMtx(this, position);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool SpinDriver::receiveOtherMsg(u32 msg, HitSensor *a2, HitSensor *a3) {
|
|
|
|
|
if (msg == 152) {
|
|
|
|
|
_13C = 60;
|
|
|
|
|
return canBind(a2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (msg == 146) {
|
|
|
|
|
_13C = 60;
|
|
|
|
|
if (startBind(a2)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (msg == 147) {
|
|
|
|
|
if (isNerve(&NrvSpinDriver::SpinDriverNrvShootStart::sInstance)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_8C) {
|
|
|
|
|
_8C = 0;
|
|
|
|
|
cancelCamera();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (msg == 148 && _8C) {
|
|
|
|
|
_8C = 0;
|
|
|
|
|
cancelCamera();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (msg == 161 && _8C) {
|
|
|
|
|
calcBindActorMatrix();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool SpinDriver::tryStartShoot() {
|
|
|
|
|
bool isSwingOrPointed = MR::isPadSwing(0) || MR::isPlayerPointedBy2POnTriggerButton();
|
|
|
|
|
|
|
|
|
|
if (isSwingOrPointed) {
|
|
|
|
|
MR::startSound(_8C, "SE_PM_SPIN_ATTACK", -1, -1);
|
|
|
|
|
if (MR::isInAreaObj("Water", mPosition)) {
|
|
|
|
|
MR::startSound(this, "SE_PMSPIN_DRV_IN_WATER_1", -1, -1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setNerve(&NrvSpinDriver::SpinDriverNrvShootStart::sInstance);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool SpinDriver::tryEndCapture() {
|
|
|
|
|
if (MR::isGreaterStep(this, 40) && PSVECDistance(_B8.toCVec(), mPosition.toCVec()) < 15.0f) {
|
|
|
|
|
cancelBind();
|
|
|
|
|
_141 = 0;
|
|
|
|
|
setNerve(&NrvSpinDriver::SpinDriverNrvWait::sInstance);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool SpinDriver::tryShoot() {
|
|
|
|
|
if (MR::isGreaterStep(this, 20)) {
|
|
|
|
|
setNerve(&NrvSpinDriver::SpinDriverNrvShoot::sInstance);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool SpinDriver::tryEndShoot() {
|
|
|
|
|
if (!mShootPath || MR::isGreaterStep(this, _124)) {
|
|
|
|
|
MR::endBindAndSpinDriverJump(this, _C4);
|
|
|
|
|
_8C = 0;
|
|
|
|
|
endCamera();
|
|
|
|
|
setNerve(&NrvSpinDriver::SpinDriverNrvCoolDown::sInstance);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool SpinDriver::tryForceCancel() {
|
|
|
|
|
if (!_8C) {
|
|
|
|
|
setNerve(&NrvSpinDriver::SpinDriverNrvCoolDown::sInstance);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool SpinDriver::tryEndCoolDown() {
|
|
|
|
|
if (MR::isGreaterStep(this, 60)) {
|
|
|
|
|
setNerve(&NrvSpinDriver::SpinDriverNrvWait::sInstance);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool SpinDriver::trySwitchOff() {
|
|
|
|
|
if (MR::isValidSwitchAppear(this) && !MR::isOnSwitchAppear(this)) {
|
|
|
|
|
kill();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SpinDriver::exeNonActive() {
|
|
|
|
|
if (MR::isFirstStep(this)) {
|
|
|
|
|
MR::validateClipping(this);
|
2023-02-13 03:33:10 -05:00
|
|
|
MR::startBck(this, "Wait", nullptr);
|
2022-07-11 08:17:22 -04:00
|
|
|
MR::startBpk(this, "Wait");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool isSwingOrPointed = MR::isPadSwing(0) || MR::isPlayerPointedBy2POnTriggerButton();
|
|
|
|
|
|
|
|
|
|
if (isSwingOrPointed) {
|
|
|
|
|
f32 v3 = _108;
|
|
|
|
|
_108 += 0.050000001f;
|
|
|
|
|
if (v3 > 0.15000001f) {
|
|
|
|
|
_108 = 0.15000001f;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SpinDriver::exeAppear() {
|
|
|
|
|
if (MR::isFirstStep(this)) {
|
|
|
|
|
if (!_142) {
|
|
|
|
|
MR::startSystemSE("SE_SY_SPIN_DRIVER_APPEAR", -1, -1);
|
|
|
|
|
MR::startSound(this, "SE_OJ_SPIN_DRV_APPEAR", -1, -1);
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-13 03:33:10 -05:00
|
|
|
MR::startBck(this, "Appear", nullptr);
|
2022-07-11 08:17:22 -04:00
|
|
|
mSpinDriverCamera->startAppearCamera(this, _E8, _D0, mPosition);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (MR::isBckStopped(this)) {
|
|
|
|
|
if (MR::isGreaterStep(this, mSpinDriverCamera->getAppearCameraFrames())) {
|
|
|
|
|
setNerve(&NrvSpinDriver::SpinDriverNrvWait::sInstance);
|
|
|
|
|
|
|
|
|
|
if (mSpinDriverCamera->isUseAppearCamera(this)) {
|
|
|
|
|
MR::endDemoWaitCameraInterpolating(this, "出現");
|
|
|
|
|
mSpinDriverCamera->endAppearCamera(this);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SpinDriver::exeWait() {
|
|
|
|
|
if (MR::isFirstStep(this)) {
|
|
|
|
|
MR::validateClipping(this);
|
2023-02-13 03:33:10 -05:00
|
|
|
MR::startBck(this, "Wait", nullptr);
|
2022-07-11 08:17:22 -04:00
|
|
|
MR::startBpk(this, "Wait");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool isSwingOrPointed = MR::isPadSwing(0) || MR::isPlayerPointedBy2POnTriggerButton();
|
|
|
|
|
|
|
|
|
|
if (isSwingOrPointed) {
|
|
|
|
|
_108 += 0.050000001f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_13C > 0) {
|
|
|
|
|
_108 += 0.0080000004f;
|
|
|
|
|
MR::startLevelSound(this, "SE_OJ_LV_SPIN_DRV_SHINE", -1, -1, -1);
|
|
|
|
|
if (!_140) {
|
|
|
|
|
MR::emitEffect(this, "SpinDriverLight");
|
2023-02-13 03:33:10 -05:00
|
|
|
MR::startCSSound("CS_SPIN_BIND", nullptr, 0);
|
2022-07-11 08:17:22 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
MR::deleteEffect(this, "SpinDriverLight");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (trySwitchOff()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SpinDriver::exeCapture() {
|
|
|
|
|
if (tryForceCancel()) {
|
|
|
|
|
MR::deleteEffect(this, "SpinDriverLight");
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if (MR::isFirstStep(this)) {
|
|
|
|
|
MR::startBckPlayer("SpinDriverWait", "SpinDriverCapture");
|
2023-02-13 03:33:10 -05:00
|
|
|
MR::startBck(this, "Active", nullptr);
|
2022-07-11 08:17:22 -04:00
|
|
|
MR::emitEffect(this, "SpinDriverLight");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MR::startLevelSound(this, "SE_OJ_LV_SPIN_DRV_SHINE", -1, -1, -1);
|
|
|
|
|
MR::startLevelSound(this, "SE_OJ_LV_SPIN_DRV_CAPTURE", -1, -1, -1);
|
|
|
|
|
moveBindPosToCenter();
|
|
|
|
|
_11C = MR::calcNerveRate(this, 40);
|
|
|
|
|
updateBindActorMatrix(_11C);
|
|
|
|
|
_108 += 0.0080000004f;
|
|
|
|
|
MR::tryRumblePadWeak(this, 0);
|
|
|
|
|
_13C = 60;
|
|
|
|
|
|
|
|
|
|
if (!tryStartShoot()) {
|
|
|
|
|
if (tryEndCapture()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SpinDriver::exeShootStart() {
|
|
|
|
|
if (!tryForceCancel()) {
|
|
|
|
|
if (MR::isFirstStep(this)) {
|
|
|
|
|
_F4 = _B8;
|
|
|
|
|
MR::deleteEffect(this, "SpinDriverLight");
|
|
|
|
|
MR::emitEffect(this, "SpinDriverStart");
|
|
|
|
|
MR::startBckPlayer("Spin", "SpinDriverShoot");
|
2023-02-13 03:33:10 -05:00
|
|
|
MR::startBck(this, "Active", nullptr);
|
2022-07-11 08:17:22 -04:00
|
|
|
MR::startBpk(this, "Active");
|
|
|
|
|
startCamera();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (MR::isStep(this, 4)) {
|
|
|
|
|
MR::startCSSound("CS_SPIN_DRIVE_SHORT", "SE_SY_CS_SPIN_DRV_START", 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
f32 clamp = MR::clamp(getNerveStep() / 20.0f, 0.0f, 1.0f);
|
|
|
|
|
f32 v3 = ((2.0f * (clamp - 0.5f)) * (2.0f * (clamp - 0.5f)));
|
|
|
|
|
f32 dot = v3 * v3;
|
|
|
|
|
TVec3f upVec;
|
|
|
|
|
MR::calcUpVec(&upVec, this);
|
|
|
|
|
TVec3f stack_50;
|
|
|
|
|
stack_50.set(mPosition - MR::multVec(MR::multVec(upVec, 200.0f), 1.0f - dot));
|
|
|
|
|
f32 v5 = MR::clamp((2.0f * clamp), 0.0f, 1.0f);
|
|
|
|
|
_B8.set(MR::multAndAddVec(stack_50, _F4, v5, 1.0f - v5));
|
|
|
|
|
updateBindActorMatrix((v5 + (_11C * (1.0f - v5))));
|
|
|
|
|
_108 += 0.039999999f;
|
|
|
|
|
MR::tryRumblePadMiddle(this, 0);
|
|
|
|
|
if (tryShoot()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SpinDriver::exeShoot() {
|
|
|
|
|
if (!tryForceCancel()) {
|
|
|
|
|
if (MR::isFirstStep(this)) {
|
|
|
|
|
calcShootMotionTime();
|
|
|
|
|
|
|
|
|
|
if (MR::hasME()) {
|
|
|
|
|
MR::startSystemME("ME_MAGIC");
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
MR::startSystemSE("SE_SY_S_SPIN_DRV_ME_ALT", -1, -1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MR::startSound(this, "SE_OJ_SPIN_DRV_JUMP", -1, -1);
|
|
|
|
|
MR::startSound(_8C, "SE_PV_JUMP_JOY", -1, -1);
|
|
|
|
|
|
|
|
|
|
if (MR::isInAreaObj("Water", mPosition)) {
|
|
|
|
|
MR::startSound(this, "SE_PM_SIN_DIV_IN_WATER_2", -1, -1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MR::startBckPlayer("SpaceFlyShortStart", "SpinDriverFlyStart");
|
|
|
|
|
MR::shakeCameraNormal();
|
|
|
|
|
MR::tryRumblePadVeryStrong(this, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mShootPath) {
|
|
|
|
|
updateBindPosition();
|
|
|
|
|
updateCamera();
|
|
|
|
|
calcParabolicBindPose();
|
|
|
|
|
|
|
|
|
|
if (MR::isStep(this, _128)) {
|
|
|
|
|
MR::startBckPlayer("SpaceFlyShort", "SpinDriverFlyLoop");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (MR::isStep(this, _12C)) {
|
|
|
|
|
MR::startBckPlayer("SpaceFlyEnd", "SpinDriverFlyEnd");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (MR::isLessStep(this, _130)) {
|
|
|
|
|
MR::startLevelSound(_8C, "SE_PM_LV_SPIN_DRV_FLY", -1, -1, -1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (MR::isStep(this, _130)) {
|
|
|
|
|
MR::startBckPlayer("Fall", "SpinDriverFall");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
f32 v3 = _100;
|
|
|
|
|
TVec3f v5(_E8);
|
|
|
|
|
v5 *= v3;
|
|
|
|
|
_C4 = v5;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (tryEndShoot()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SpinDriver::exeCoolDown() {
|
|
|
|
|
if (MR::isFirstStep(this)) {
|
|
|
|
|
MR::startBpk(this, "Wait");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!tryEndCoolDown()) {
|
|
|
|
|
if (trySwitchOff()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool SpinDriver::startBind(HitSensor *pSensor) {
|
|
|
|
|
if (!canStartBind()) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool isSwingOrPointed = MR::isPadSwing(0) || MR::isPlayerPointedBy2POnTriggerButton();
|
|
|
|
|
|
|
|
|
|
if (isSwingOrPointed) {
|
|
|
|
|
if (MR::hasME()) {
|
|
|
|
|
MR::startSystemME("ME_MAGIC");
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
MR::startSystemSE("SE_SY_S_SPIN_DRV_ME_ALT", -1, -1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MR::startSound(pSensor->mActor, "SE_PM_SPIN_ATTACK", -1, -1);
|
|
|
|
|
|
|
|
|
|
if (MR::isInAreaObj("Water", mPosition)) {
|
|
|
|
|
MR::startSound(this, "SE_PM_SPIN_DRV_IN_WATER_1", -1, -1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setNerve(&NrvSpinDriver::SpinDriverNrvShootStart::sInstance);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if (_138 && _141 && mPosition.squared(pSensor->mPosition) < 57600.0f) {
|
|
|
|
|
setNerve(&NrvSpinDriver::SpinDriverNrvCapture::sInstance);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_8C = pSensor->mActor;
|
|
|
|
|
_B8 = mPosition;
|
|
|
|
|
_C4 = *MR::getPlayerLastMove();
|
|
|
|
|
f32 mag = PSVECMag(_C4.toCVec());
|
|
|
|
|
if (mag > 40.0f) {
|
|
|
|
|
_C4 *= 40.0f / mag;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_11C = 0.0f;
|
|
|
|
|
MtxPtr mtx = _8C->getBaseMtx();
|
|
|
|
|
TRot3f rotation;
|
|
|
|
|
rotation.setInline(mtx);
|
|
|
|
|
rotation.getQuat(_98);
|
|
|
|
|
_A8 = _98;
|
|
|
|
|
cSpaceFlyStartFrame = MR::getBckFrameMax(_8C, "SpaceFlyStart");
|
|
|
|
|
cSpaceFlyEndFrame = MR::getBckFrameMax(_8C, "SpaceFlyEnd");
|
|
|
|
|
MR::validateClipping(this);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SpinDriver::cancelBind() {
|
|
|
|
|
if (_8C) {
|
|
|
|
|
MR::endBindAndPlayerJump(this, _C4, 0);
|
2023-02-13 03:33:10 -05:00
|
|
|
_8C = nullptr;
|
2022-07-11 08:17:22 -04:00
|
|
|
endCamera();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SpinDriver::updateBindPosition() {
|
|
|
|
|
f32 step = getNerveStep() / (f32)_124;
|
|
|
|
|
TVec3f stack_20(_B8);
|
|
|
|
|
TVec3f position;
|
|
|
|
|
mShootPath->calcPosition(&position, step);
|
|
|
|
|
_B8 = position;
|
|
|
|
|
_C4 = position - stack_20;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SpinDriver::moveBindPosToCenter() {
|
|
|
|
|
_B8 += _C4;
|
|
|
|
|
TVec3f stack_24(mPosition - _B8);
|
|
|
|
|
f32 scalar;
|
|
|
|
|
MR::separateScalarAndDirection(&scalar, &stack_24, stack_24);
|
|
|
|
|
f32 v3 = scalar / 120.0f;
|
|
|
|
|
_C4 += MR::multVec(stack_24, 1.5f, v3);
|
|
|
|
|
_C4.x *= 0.80000001f;
|
|
|
|
|
_C4.y *= 0.80000001f;
|
|
|
|
|
_C4.z *= 0.80000001f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SpinDriver::updateBindActorMatrix(f32 a1) {
|
|
|
|
|
TPos3f rotation;
|
|
|
|
|
MR::makeMtxUpFrontPos(&rotation, _E8, _D0, mPosition);
|
|
|
|
|
TQuat4f quat;
|
|
|
|
|
rotation.makeQuat(quat);
|
|
|
|
|
_A8.x = _98.x;
|
|
|
|
|
_A8.y = _98.y;
|
|
|
|
|
_A8.z = _98.z;
|
|
|
|
|
_A8.w = _98.w;
|
|
|
|
|
_A8.slerp(quat, a1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
void SpinDriver::calcBindActorMatrix() {
|
|
|
|
|
f32 v3 = (2.0f * _A8.y);
|
|
|
|
|
f32 v4 = _A8.z;
|
|
|
|
|
f32 v5 = (2.0f * _A8.x);
|
|
|
|
|
f32 v6 = (2.0f * _A8.y) * _A8.y;
|
|
|
|
|
f32 v7 = (2.0f * _A8.w);
|
|
|
|
|
f32 v8 = (1.0f - ((2.0f * _A8.x) * _A8.x));
|
|
|
|
|
f32 v9 = ((1.0f - ((2.0f * _A8.x) * _A8.x)) - ((2.0f * _A8.z) * _A8.z));
|
|
|
|
|
f32 v10 = (((2.0f * _A8.x) * _A8.y) - ((2.0f * _A8.w) * _A8.z));
|
|
|
|
|
f32 v11 = (((2.0f * _A8.x) * _A8.y) + ((2.0f * _A8.w) * _A8.z));
|
|
|
|
|
TPos3f pos;
|
|
|
|
|
pos.mMtx[0][0] = (1.0f - ((2.0f * _A8.y) * _A8.y)) - ((2.0f * _A8.z) * _A8.z);
|
|
|
|
|
pos.mMtx[0][1] = v10;
|
|
|
|
|
f32 v12 = (v7 * _A8.y);
|
|
|
|
|
pos.mMtx[1][1] = v9;
|
|
|
|
|
f32 v13 = (v7 * _A8.x);
|
|
|
|
|
pos.mMtx[1][0] = v11;
|
|
|
|
|
pos.mMtx[2][2] = v8 - v6;
|
|
|
|
|
pos.mMtx[0][2] = (v5 * v4) + v12;
|
|
|
|
|
pos.mMtx[1][2] = (v3 * v4) - v13;
|
|
|
|
|
pos.mMtx[2][0] = (v5 * v4) - v12;
|
|
|
|
|
pos.mMtx[2][1] = (v3 * v4) + v13;
|
|
|
|
|
pos.mMtx[0][3] = _B8.x;
|
|
|
|
|
pos.mMtx[1][3] = _B8.y;
|
|
|
|
|
pos.mMtx[2][3] = _B8.z;
|
|
|
|
|
MR::setBaseTRMtx(_8C, pos);
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
// SpinDriver::calcParabolicBindPose
|
|
|
|
|
// SpinDriver::turnBindHead
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
void SpinDriver::calcShootMotionTime() {
|
|
|
|
|
s32 v1 = _124;
|
|
|
|
|
if (v1 < cSpaceFlyEndFrame) {
|
|
|
|
|
_128 = -1;
|
|
|
|
|
_12C = 0;
|
|
|
|
|
_130 = v1;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
_12C = v1 - 70;
|
|
|
|
|
_130 = v1 - 20;
|
|
|
|
|
_128 = (v1 - 70) / 5;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
void SpinDriver::startCamera() {
|
|
|
|
|
if (mSpinDriverCamera) {
|
|
|
|
|
mSpinDriverCamera->start(_E8, _D0, mPosition);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SpinDriver::updateCamera() {
|
|
|
|
|
if (mSpinDriverCamera) {
|
|
|
|
|
mSpinDriverCamera->update(_C4, _B8);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SpinDriver::cancelCamera() {
|
|
|
|
|
if (mSpinDriverCamera) {
|
|
|
|
|
mSpinDriverCamera->cancel();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SpinDriver::endCamera() {
|
|
|
|
|
if (mSpinDriverCamera) {
|
|
|
|
|
mSpinDriverCamera->end();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool SpinDriver::canStartBind() const {
|
|
|
|
|
return isNerve(&NrvSpinDriver::SpinDriverNrvWait::sInstance);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool SpinDriver::canBind(HitSensor *pSensor) const {
|
|
|
|
|
if (!canStartBind()) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool isSwingOrPointed = MR::isPadSwing(0) || MR::isPlayerPointedBy2POnTriggerButton();
|
|
|
|
|
|
|
|
|
|
if (isSwingOrPointed) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_138 && _141 && mPosition.squared(pSensor->mPosition) < 457600.0f) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SpinDriver::~SpinDriver() {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
namespace NrvSpinDriver {
|
|
|
|
|
INIT_NERVE(SpinDriverNrvTryDemo);
|
|
|
|
|
INIT_NERVE(SpinDriverNrvNonActive);
|
|
|
|
|
INIT_NERVE(SpinDriverNrvAppear);
|
|
|
|
|
INIT_NERVE(SpinDriverNrvWait);
|
|
|
|
|
INIT_NERVE(SpinDriverNrvCapture);
|
|
|
|
|
INIT_NERVE(SpinDriverNrvShootStart);
|
|
|
|
|
INIT_NERVE(SpinDriverNrvShoot);
|
|
|
|
|
INIT_NERVE(SpinDriverNrvCoolDown);
|
|
|
|
|
|
|
|
|
|
void SpinDriverNrvCoolDown::execute(Spine *pSpine) const {
|
|
|
|
|
SpinDriver* spinDriver = reinterpret_cast<SpinDriver*>(pSpine->mExecutor);
|
|
|
|
|
spinDriver->exeCoolDown();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SpinDriverNrvShoot::execute(Spine *pSpine) const {
|
|
|
|
|
SpinDriver* spinDriver = reinterpret_cast<SpinDriver*>(pSpine->mExecutor);
|
|
|
|
|
spinDriver->exeShoot();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SpinDriverNrvShootStart::execute(Spine *pSpine) const {
|
|
|
|
|
SpinDriver* spinDriver = reinterpret_cast<SpinDriver*>(pSpine->mExecutor);
|
|
|
|
|
spinDriver->exeShootStart();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SpinDriverNrvCapture::execute(Spine *pSpine) const {
|
|
|
|
|
SpinDriver* spinDriver = reinterpret_cast<SpinDriver*>(pSpine->mExecutor);
|
|
|
|
|
spinDriver->exeCapture();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SpinDriverNrvWait::execute(Spine *pSpine) const {
|
|
|
|
|
SpinDriver* spinDriver = reinterpret_cast<SpinDriver*>(pSpine->mExecutor);
|
|
|
|
|
spinDriver->exeWait();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SpinDriverNrvAppear::execute(Spine *pSpine) const {
|
|
|
|
|
SpinDriver* spinDriver = reinterpret_cast<SpinDriver*>(pSpine->mExecutor);
|
|
|
|
|
spinDriver->exeAppear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SpinDriverNrvNonActive::execute(Spine *pSpine) const {
|
|
|
|
|
SpinDriver* spinDriver = reinterpret_cast<SpinDriver*>(pSpine->mExecutor);
|
|
|
|
|
spinDriver->exeNonActive();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SpinDriverNrvTryDemo::execute(Spine *pSpine) const {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
};
|