mirror of
https://github.com/encounter/Petari.git
synced 2026-03-30 11:34:15 -07:00
322 lines
8.5 KiB
C++
322 lines
8.5 KiB
C++
#include "Game/MapObj/WaterPressureBullet.hpp"
|
|
#include "Game/LiveActor/ActorCameraInfo.hpp"
|
|
#include "JSystem/JMath/JMath.hpp"
|
|
|
|
WaterPressureBullet::WaterPressureBullet(const char *pName) : LiveActor(pName) {
|
|
_8C.x = 0.0f;
|
|
_8C.y = 0.0f;
|
|
_8C.z = 0.0f;
|
|
_98.x = 0.0f;
|
|
_98.y = 0.0f;
|
|
_98.z = 0.0f;
|
|
_A4 = 0;
|
|
_A8 = 0.0f;
|
|
mHostActor = nullptr;
|
|
_B0 = false;
|
|
_B1 = false;
|
|
_B2 = false;
|
|
mCameraInfo = nullptr;
|
|
}
|
|
|
|
void WaterPressureBullet::init(const JMapInfoIter &rIter) {
|
|
initModelManagerWithAnm("WaterBullet", nullptr, false);
|
|
MR::connectToSceneMapObjStrongLight(this);
|
|
initHitSensor(2);
|
|
MR::addHitSensor(this, "body", 24, 4, 100.0f, TVec3f(0.0f, 0.0f, 0.0f));
|
|
MR::addHitSensor(this, "binder", 106, 4, 100.0f, TVec3f(0.0f, 0.0f, 0.0f));
|
|
initBinder(100.0f, 0.0f, 0);
|
|
initEffectKeeper(0, nullptr, false);
|
|
initSound(6, false);
|
|
TVec3f offs;
|
|
offs.x = 0.0f;
|
|
offs.y = 0.0f;
|
|
offs.z = 0.0f;
|
|
MR::initStarPointerTarget(this, 100.0f, offs);
|
|
MR::initShadowVolumeSphere(this, 75.0f);
|
|
MR::setShadowDropLength(this, nullptr, 1500.0f);
|
|
MR::registerDemoSimpleCastAll(this);
|
|
initNerve(&NrvWaterPressureBullet::WaterPressureBulletNrvFly::sInstance);
|
|
makeActorDead();
|
|
}
|
|
|
|
void WaterPressureBullet::kill() {
|
|
if (MR::isPlayerInRush() && mHostActor) {
|
|
MR::startBckPlayer("GCaptureBreak", (const char*)nullptr);
|
|
MR::endBindAndPlayerJumpWithRollLanding(this, mVelocity, 0);
|
|
mHostActor = nullptr;
|
|
endHostCamera();
|
|
}
|
|
|
|
MR::emitEffect(this, "Break");
|
|
MR::startSound(this, "SE_OJ_W_PRESS_BUBBLE_BREAK", -1, -1);
|
|
LiveActor::kill();
|
|
}
|
|
|
|
#ifdef NON_MATCHING
|
|
void WaterPressureBullet::control() {
|
|
bool v1 = true;
|
|
bool v2 = false;
|
|
|
|
if (_B2 && mHostActor == nullptr) {
|
|
v2 = true;
|
|
}
|
|
|
|
if (!v2 && _B2) {
|
|
v1 = false;
|
|
}
|
|
|
|
if (v1 && MR::isStarPointerPointing2POnTriggerButton(this, "弱", true, false)) {
|
|
kill();
|
|
}
|
|
else {
|
|
TVec3f stack_8;
|
|
if (MR::isNearZero(mVelocity, 0.001)) {
|
|
stack_8.set(mGravity);
|
|
}
|
|
else {
|
|
stack_8.set(mVelocity);
|
|
}
|
|
|
|
f32 val = (45.511112f * MR::negFloat(2.5f));
|
|
MR::turnVecToVecCosOnPlane(&_8C, stack_8, _98, JMASCos(val));
|
|
}
|
|
}
|
|
#endif
|
|
|
|
void WaterPressureBullet::calcAndSetBaseMtx() {
|
|
TPos3f pos;
|
|
MR::makeMtxFrontSidePos(&pos, _8C, _98, mPosition);
|
|
MR::setBaseTRMtx(this, pos);
|
|
}
|
|
|
|
void WaterPressureBullet::shotWaterBullet(LiveActor *pActor, const TPos3f &rPos, f32 a3, bool a4, bool a5, bool a6, ActorCameraInfo **pInfo) {
|
|
f32 z = rPos.mMtx[2][2];
|
|
f32 y = rPos.mMtx[1][2];
|
|
f32 x = rPos.mMtx[0][2];
|
|
_A8 = a3;
|
|
_A4 = pActor;
|
|
_B0 = a4;
|
|
_B1 = a5;
|
|
_B2 = a6;
|
|
mCameraInfo = pInfo;
|
|
_8C.set<f32>(x, y, z);
|
|
mVelocity.scale(_A8, _8C);
|
|
z = rPos.mMtx[2][3];
|
|
y = rPos.mMtx[1][3];
|
|
x = rPos.mMtx[0][3];
|
|
mPosition.set<f32>(x, y, z);
|
|
z = rPos.mMtx[2][0];
|
|
y = rPos.mMtx[1][0];
|
|
x = rPos.mMtx[0][0];
|
|
_98.set<f32>(x, y, z);
|
|
mRotation.zero();
|
|
makeActorAppeared();
|
|
MR::validateHitSensors(this);
|
|
MR::invalidateClipping(this);
|
|
MR::setShadowDropLength(this, nullptr, 1500.0f);
|
|
|
|
if (!_B0) {
|
|
MR::onCalcGravity(this);
|
|
}
|
|
|
|
setNerve(&NrvWaterPressureBullet::WaterPressureBulletNrvFly::sInstance);
|
|
}
|
|
|
|
void WaterPressureBullet::exeFly() {
|
|
if (MR::isFirstStep(this)) {
|
|
MR::startBck(this, "Shot", nullptr);
|
|
}
|
|
|
|
if (MR::isBckOneTimeAndStopped(this)) {
|
|
MR::startBck(this, "Move", nullptr);
|
|
}
|
|
|
|
if (mHostActor != nullptr && MR::isBckOneTimeAndStopped(mHostActor)) {
|
|
MR::startBckPlayer("WaterBulletWait", (const char*)nullptr);
|
|
}
|
|
|
|
if (mHostActor != nullptr) {
|
|
MR::startLevelSound(this, "SE_OJ_LV_W_PRESS_BUBBLE_SUS", -1, -1, -1);
|
|
}
|
|
|
|
if (!_B0) {
|
|
JMAVECScaleAdd(mGravity.toCVec(), mVelocity.toCVec(), mVelocity.toVec(), 0.40000001f);
|
|
}
|
|
|
|
if (MR::isPadSwing(0) && mHostActor != nullptr && !_B2) {
|
|
MR::startSound(mHostActor, "SE_PV_TWIST_START", -1, -1);
|
|
MR::startSound(mHostActor, "SE_PM_SPIN_ATTACK", -1, -1);
|
|
MR::tryRumblePadMiddle(this, 0);
|
|
setNerve(&NrvWaterPressureBullet::WaterPressureBulletNrvSpinKill::sInstance);
|
|
return;
|
|
}
|
|
|
|
bool v2 = false;
|
|
|
|
if (MR::isBinded(this) || MR::isInWater(this, TVec3f(0.0f, 0.0f, 0.0f))) {
|
|
v2 = true;
|
|
}
|
|
|
|
if (v2) {
|
|
if (!_B1 || mHostActor == nullptr || MR::isBindedGroundSand(this)) {
|
|
kill();
|
|
return;
|
|
}
|
|
|
|
TVec3f* vel = &mVelocity;
|
|
TVec3f* grav = &mGravity;
|
|
f32 dot = grav->dot(mVelocity);
|
|
JMAVECScaleAdd(grav->toCVec(), vel->toCVec(), vel->toVec(), -dot);
|
|
}
|
|
|
|
if (!_B2 && MR::isGreaterEqualStep(this, 180) || _B2 && MR::isGreaterEqualStep(this, 300)) {
|
|
kill();
|
|
}
|
|
}
|
|
|
|
void WaterPressureBullet::exeSpinKill() {
|
|
if (MR::isFirstStep(this)) {
|
|
MR::startBckPlayer("Spin2nd", (const char*)nullptr);
|
|
mVelocity.zero();
|
|
MR::invalidateHitSensors(this);
|
|
|
|
if (MR::isPlayerInRush()) {
|
|
if (mHostActor != nullptr) {
|
|
MR::endBindAndPlayerJump(this, mVelocity, 0);
|
|
mHostActor = nullptr;
|
|
endHostCamera();
|
|
}
|
|
}
|
|
}
|
|
|
|
kill();
|
|
}
|
|
|
|
void WaterPressureBullet::attackSensor(HitSensor *a1, HitSensor *a2) {
|
|
if (MR::isSensorMapObj(a2)) {
|
|
kill();
|
|
}
|
|
}
|
|
|
|
bool WaterPressureBullet::receiveMsgPlayerAttack(u32 msg, HitSensor *, HitSensor *) {
|
|
if (MR::isMsgFireBallAttack(msg)) {
|
|
kill();
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool WaterPressureBullet::receiveOtherMsg(u32 msg, HitSensor *a2, HitSensor *a3) {
|
|
if (MR::isDead(this)) {
|
|
return false;
|
|
}
|
|
|
|
if (MR::isMsgAutoRushBegin(msg) && MR::isSensorPlayer(a2) && mHostActor == nullptr) {
|
|
if (MR::isDemoActive()) {
|
|
kill();
|
|
return false;
|
|
}
|
|
|
|
if (!inviteMario(a2)) {
|
|
return false;
|
|
}
|
|
else {
|
|
MR::startSound(this, "SE_OJ_W_PRESS_BUBBLE_IN", -1, -1);
|
|
MR::startSound(mHostActor, "SE_PV_CATCH", -1, -1);
|
|
return true;
|
|
}
|
|
}
|
|
else if (msg == 152) {
|
|
return true;
|
|
}
|
|
else if (msg == 147) {
|
|
kill();
|
|
return true;
|
|
}
|
|
else if (msg == 161 && mHostActor != nullptr) {
|
|
updateSuffererMtx();
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool WaterPressureBullet::startHostCamera() const {
|
|
if (_A4 != nullptr && mCameraInfo != nullptr) {
|
|
MR::startActorCameraNoTarget(_A4, *mCameraInfo, -1);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool WaterPressureBullet::endHostCamera() const {
|
|
if (_A4 != nullptr && mCameraInfo != nullptr) {
|
|
MR::endActorCamera(_A4, *mCameraInfo, true, -1);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool WaterPressureBullet::inviteMario(HitSensor *pSensor) {
|
|
MR::tryRumblePadMiddle(this, 0);
|
|
|
|
if (MR::isOnGroundPlayer() && MR::isNearAngleDegree(mVelocity, mGravity, 60.0f)) {
|
|
if (_B1) {
|
|
TVec3f* vel = &mVelocity;
|
|
TVec3f* grav = &mGravity;
|
|
f32 dot = grav->dot(mVelocity);
|
|
JMAVECScaleAdd(grav->toCVec(), vel->toCVec(), vel->toVec(), -dot);
|
|
}
|
|
else {
|
|
kill();
|
|
MR::sendArbitraryMsg(76, pSensor, getSensor("body"));
|
|
return false;
|
|
}
|
|
}
|
|
|
|
mHostActor = pSensor->mActor;
|
|
MR::startBckWithInterpole(this, "Touch", 0);
|
|
MR::startBckPlayer("WaterBulletStart", 2);
|
|
startHostCamera();
|
|
MR::setShadowDropLength(this, nullptr, 2000.0f);
|
|
return true;
|
|
}
|
|
|
|
void WaterPressureBullet::updateSuffererMtx() {
|
|
TPos3f pos;
|
|
pos.identity();
|
|
|
|
if (isNerve(&NrvWaterPressureBullet::WaterPressureBulletNrvSpinKill::sInstance)) {
|
|
TVec3f front;
|
|
MR::calcFrontVec(&front, mHostActor);
|
|
MR::calcMtxFromGravityAndZAxis(&pos, mHostActor, mGravity, front);
|
|
}
|
|
else {
|
|
MtxPtr mtx = getBaseMtx();
|
|
pos.setInline(mtx);
|
|
}
|
|
|
|
MR::setBaseTRMtx(this, pos);
|
|
}
|
|
|
|
WaterPressureBullet::~WaterPressureBullet() {
|
|
|
|
}
|
|
|
|
namespace NrvWaterPressureBullet {
|
|
INIT_NERVE(WaterPressureBulletNrvFly);
|
|
INIT_NERVE(WaterPressureBulletNrvSpinKill);
|
|
|
|
void WaterPressureBulletNrvSpinKill::execute(Spine *pSpine) const {
|
|
WaterPressureBullet* bullet = reinterpret_cast<WaterPressureBullet*>(pSpine->mExecutor);
|
|
bullet->exeSpinKill();
|
|
}
|
|
|
|
void WaterPressureBulletNrvFly::execute(Spine *pSpine) const {
|
|
WaterPressureBullet* bullet = reinterpret_cast<WaterPressureBullet*>(pSpine->mExecutor);
|
|
bullet->exeFly();
|
|
}
|
|
}; |