diff --git a/.gitignore b/.gitignore index 9bc17b380..460106770 100644 --- a/.gitignore +++ b/.gitignore @@ -37,3 +37,6 @@ compile_commands.json /*.txt *.exe tools/mwcc_compiler + +# Apple +.DS_Store diff --git a/include/Enemy/BossWanwan.hpp b/include/Enemy/BossWanwan.hpp index 7bd1f1d4b..8dfd6621c 100644 --- a/include/Enemy/BossWanwan.hpp +++ b/include/Enemy/BossWanwan.hpp @@ -2,8 +2,113 @@ #define ENEMY_BOSS_WANWAN_HPP #include +#include +#include +#include +#include +#include class TLiveActor; +class TBossWanwan; + +class TBWHit : public THitActor { +public: + TBWHit(TBossWanwan* owner, int joint_index, + const char* name = "idk"); // yeah + + virtual void perform(u32 cue, JDrama::TGraphics* graphics); + virtual BOOL receiveMessage(THitActor* sender, u32 message); + +private: + TBossWanwan* mOwner; + u32 mJointIndex; +}; + +class TBWPicket : public THitActor { +public: + virtual void perform(u32 cue, JDrama::TGraphics* graphics); + virtual BOOL receiveMessage(THitActor* sender, u32 message); +}; + +class TBWBinder : public TBinder { +public: + TBWBinder(); + virtual void bind(TLiveActor*); +}; + +class TBWLeash : public THitActor { +public: + TBWLeash(int, const char*); + + virtual void perform(u32 cue, JDrama::TGraphics* graphics); +}; + +class TBWLeashNode : public THitActor { +public: + TBWLeashNode(int, const char*); + + virtual void perform(u32 cue, JDrama::TGraphics* graphics); + virtual void calcMatrix(); + virtual void calcTemperature(); +}; + +class TBWParams : public TSpineEnemyParams { +public: + /* * TSpineEnemyParams ends at 0xA8. * + * Every TParamRT occupies 0x14 bytes: + * * +0x00 : TParam / base data + * * +0x04 : ... + * * +0x0C : ... + * * +0x10 : actual parameter value + * * * Therefore: * parameter start = X * parameter value = X + 0x10 */ + TBWParams(const char*); + + /* 0x0A8 */ TParamRT mSLMarchSpeed; + /* 0x0BC */ TParamRT mSLTurnSpeed; + /* 0x0D0 */ TParamRT mSLLeashNodeLen; + /* 0x0E4 */ TParamRT mSLPicketHeight; + /* 0x0F8 */ TParamRT mSLPicketRadius; + /* 0x10C */ TParamRT mSLChainHitHeight; + /* 0x120 */ TParamRT mSLChainHitRadius; + /* 0x134 */ TParamRT mSLChainGroundRadius; + /* 0x148 */ TParamRT mSLPullLimit; + /* 0x15C */ TParamRT mSLAttackSpeed; + /* 0x170 */ TParamRT mSLStunTimer; + /* 0x184 */ TParamRT mSLSearchLength; + /* 0x198 */ TParamRT mSLSearchAngle; + /* 0x1AC */ TParamRT mSLBWHitPointMax; + /* 0x1C0 */ TParamRT mSLHeadGap; + /* 0x1D4 */ TParamRT mSLShakeLengthMax; + /* 0x1E8 */ TParamRT mSLShakeLengthMaxHP0; +}; + +// TBossWanwan size: 0x1b8 +class TBossWanwan : public TSpineEnemy { +public: + TBossWanwan(const char* name = "ボスワンワン"); + + virtual void kill(); + virtual void init(TLiveManager*); + BOOL receiveMessage(THitActor* sender, u32 message); + virtual void shakeCamera(int shakeType); + +private: + /* 0x1A0 */ BOOL unk0; + /* 0x1A8 */ u32 mWaterHitCount; + /* 0x1AC */ u32 mDistToMarioSquared; + /* 0x1B0 */ TBWParams* mParams; + /* 0x18C */ u8 msInvincible; +}; + +class TBossWanwanManager : public TEnemyManager { +public: + TBossWanwanManager(const char* name = "ボスワンワンマネージャ"); + + virtual void load(JSUMemoryInputStream&); + + TSpineEnemy* createEnemyInstance(); + void createModelData(); +}; DECLARE_NERVE(TNerveBWGraphWander, TLiveActor); DECLARE_NERVE(TNerveBWRoll, TLiveActor); diff --git a/include/System/Particles.hpp b/include/System/Particles.hpp index 9629ff185..c7ee07aac 100644 --- a/include/System/Particles.hpp +++ b/include/System/Particles.hpp @@ -144,6 +144,7 @@ enum E_SMS_EFFECT_ONETIME_NORMAL /* 0 */ { PARTICLE_MS_POPO_BOMB_B = 0xA2, GATEKEEPER_JPA_MS_GKPA_DEAD = 0xA7, GATEKEEPER_JPA_MS_GKPA_DEADSMOKE = 0xA8, + BWAN_JPA_MS_DOWNYUGE = 0xB0, PARTICLE_MS_SMB_AP_ROCK = 0xB6, PARTICLE_MS_SMB_AP_SMOKE = 0xB7, PARTICLE_MS_GESO_OSENHIT_A = 0xBC, diff --git a/src/Enemy/bosswanwan.cpp b/src/Enemy/bosswanwan.cpp index 8b1378917..e9514c1f7 100644 --- a/src/Enemy/bosswanwan.cpp +++ b/src/Enemy/bosswanwan.cpp @@ -1 +1,130 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +void TBossWanwan::kill() { return; } + +BOOL TBossWanwan::receiveMessage(THitActor* sender, u32 message) +{ + u32 actorType = sender->getActorType(); + if (actorType == 0x80000001) { + return false; + } else if (actorType == 0x1000001) { + // fabricated + if (!this->msInvincible) { + gpMarioParticleManager->emit(PARTICLE_MS_ENM_WATHIT, + &sender->mPosition, 0, 0); + if (this->mHitPoints == 0) { + + SMSGetMSound()->startSoundActor(0x28d1, &this->mPosition, 0, + nullptr, 0, 4); + } else if (this->mHitPoints == 1) { + MtxPtr iVar3 = this->getModel()->getAnmMtx(1); + gpMarioParticleManager->emitAndBindToMtxPtr( + 0xb0, (iVar3 + 0x58) + 0x30, 0, 0); + SMSGetMSound()->startSoundActor(0x28c5, &this->mPosition, 0, + nullptr, 0, 4); + + } else { + SMSGetMSound()->startSoundActor(0x28be, &this->mPosition, 0, + nullptr, 0, 4); + } + + if (this->mHitPoints != 0) { + this->mHitPoints--; + } + + this->mWaterHitCount++; + return true; + } else { + return true; + } + + } else { + if (actorType == 0x4000005a) { + sender->receiveMessage(this, HIT_MESSAGE_HIP_DROP); + this->mHitPoints = 0; + this->mWaterHitCount++; + if (!this->unk0) { + this->unk0 = true; + } + + MtxPtr mtx = this->getModel()->getAnmMtx(1); + gpMarioParticleManager->emitAndBindToMtxPtr(BWAN_JPA_MS_DOWNYUGE, + mtx, 0, nullptr); + + SMSGetMSound()->startSoundActor(0x28c5, &this->mPosition, 0, + nullptr, 0, 4); + } + } + + return TSpineEnemy::receiveMessage(sender, message); +} + +void TBossWanwan::shakeCamera(int shakeType) +{ + if (!SMS_IsMarioTouchGround4cm()) { + return; + } + + f32 dist = this->mDistToMarioSquared; + + dist = MsSqrtf(dist); + + TBWParams* params = (TBWParams*)this->getSaveParam(); + f32 shakeLengthMax = params->mSLShakeLengthMax.get(); + + TBWParams* params2 = (TBWParams*)this->getSaveParam(); + f32 shakeLengthMaxHP0 = params2->mSLShakeLengthMaxHP0.get(); + + f32 ratio = 1.0; + if (this->mMActor->checkCurBckFromIndex(0) == 0) { + TBWParams* params3 = (TBWParams*)this->getSaveParam(); + ratio = (f32)this->mHitPoints / (f32)params3->mSLBWHitPointMax.get(); + } + + f32 effectiveDist + = shakeLengthMax * ratio + shakeLengthMaxHP0 * (1.0f - ratio); + + f32 delta = effectiveDist - dist; + + if (delta < 0.0f) { + return; + } + + f32 power = delta / effectiveDist; + if (1.0f < power) { + power = 1.0f; + } + + power *= ratio; + + gpCameraShake->startShake((EnumCamShakeMode)shakeType, power); + SMSRumbleMgr->start(8, &this->mPosition); +} + +TSpineEnemy* TBossWanwanManager::createEnemyInstance() +{ + return new TBossWanwan(); +} + +void TBossWanwanManager::createModelData() { }