Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,6 @@ compile_commands.json
/*.txt
*.exe
tools/mwcc_compiler

# Apple
.DS_Store
105 changes: 105 additions & 0 deletions include/Enemy/BossWanwan.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,113 @@
#define ENEMY_BOSS_WANWAN_HPP

#include <Strategic/Nerve.hpp>
#include <Strategic/Spine.hpp>
#include <Strategic/LiveManager.hpp>
#include <Strategic/Binder.hpp>
#include <Enemy/EnemyManager.hpp>
#include <Enemy/Enemy.hpp>

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<T> 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<f32> mSLMarchSpeed;
/* 0x0BC */ TParamRT<f32> mSLTurnSpeed;
/* 0x0D0 */ TParamRT<f32> mSLLeashNodeLen;
/* 0x0E4 */ TParamRT<f32> mSLPicketHeight;
/* 0x0F8 */ TParamRT<f32> mSLPicketRadius;
/* 0x10C */ TParamRT<f32> mSLChainHitHeight;
/* 0x120 */ TParamRT<f32> mSLChainHitRadius;
/* 0x134 */ TParamRT<f32> mSLChainGroundRadius;
/* 0x148 */ TParamRT<f32> mSLPullLimit;
/* 0x15C */ TParamRT<f32> mSLAttackSpeed;
/* 0x170 */ TParamRT<s32> mSLStunTimer;
/* 0x184 */ TParamRT<f32> mSLSearchLength;
/* 0x198 */ TParamRT<f32> mSLSearchAngle;
/* 0x1AC */ TParamRT<u8> mSLBWHitPointMax;
/* 0x1C0 */ TParamRT<f32> mSLHeadGap;
/* 0x1D4 */ TParamRT<f32> mSLShakeLengthMax;
/* 0x1E8 */ TParamRT<f32> 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);
Expand Down
1 change: 1 addition & 0 deletions include/System/Particles.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
129 changes: 129 additions & 0 deletions src/Enemy/bosswanwan.cpp
Original file line number Diff line number Diff line change
@@ -1 +1,130 @@
#include <MSound/MSSetSound.hpp>
#include <MSound/MSoundBGM.hpp>
#include <MSound/MSound.hpp>
#include <MSound/MSoundSE.hpp>
#include <MSound/SoundEffects.hpp>
#include <M3DUtil/InfectiousStrings.hpp>
#include <Enemy/BossWanwan.hpp>
#include <Camera/CameraShake.hpp>
#include <MarioUtil/RumbleMgr.hpp>
#include <MarioUtil/MathUtil.hpp>
#include <MarioUtil/RandomUtil.hpp>
#include <Player/MarioAccess.hpp>
#include <M3DUtil/MActor.hpp>
#include <M3DUtil/MActorAnm.hpp>
#include <Strategic/ObjManager.hpp>
#include <Player/ModelWaterManager.hpp>
#include <System/FlagManager.hpp>
#include <System/MarDirector.hpp>
#include <System/EmitterViewObj.hpp>
#include <System/Application.hpp>
#include <System/Particles.hpp>
#include <JSystem/JGeometry/JGUtil.hpp>

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() { }