Enemy/Bosswanwan TU (#159)

* feat: TBW started, shakeCamera done

* feat: progress TBW, first started shakeCamera

* feat: TBossWanwaReceiveMessage, 92%

* fix: misc...
- fixed to SMSGetSound instead of other API
- used Particles.hpp enum and created a new one based off modders tables
- used msSqrtf instead of fabricated match

* feat: added calcRootMatrix()

* fix: improve calcRootMatrix to 100%

* feat: TBWLeash(Node) progress

* feat: TBWLeashNode::calcTemperature 100%

* feat: some progress and TBossWanwanManager::createModelData() 100%

* feat: progress emitEffects() 97%

* declaring stuff

* progress TBWPicket, TBWHit

* progress TBWPicket::moveRequest

* more progress

* fixing some issues, progressing a lil

* feat: sliteToCurPathNode

* control

* feat: TNerveBWJumpToBath

* a bunch of stuff

* fucking destructors

* bunch of stuff 2.0

* changeBck unused function

* inline shenanigans

* anotha nerve

* feat: other nerves

* why I decided to do this

* 90ing all functions??????

* adjust after rebasing

* adjust after rebasing

* fix particles.hpp

* fixing some stuff

* fix: use enums for sound, animations, etc; update particles and actor types for wanwan

* create enum flags for wanwan

* fix: reorder symbol by val script + some adjusting
This commit is contained in:
Paolo Imbriani authored and GitHub committed 2026-10-26 14:33:58 +03:00
1 parent 8c847193f3
commit 01b2fce78d
12 files changed
+2181 -22

No files matched your search

+3
View File
@@ -37,3 +37,6 @@ compile_commands.json
/*.txt
*.exe
tools/mwcc_compiler
# Apple
.DS_Store
+243 -1
View File
@@ -2,8 +2,250 @@
#define ENEMY_BOSS_WANWAN_HPP
#include <Strategic/Nerve.hpp>
#include <Strategic/HitActor.hpp>
#include <Strategic/TakeActor.hpp>
#include <Strategic/Spine.hpp>
#include <Strategic/Binder.hpp>
#include <Strategic/LiveManager.hpp>
#include <Strategic/ObjModel.hpp>
#include <Strategic/LiveActor.hpp>
#include <M3DUtil/M3UJoint.hpp>
#include <M3DUtil/MActorData.hpp>
#include <M3DUtil/MActor.hpp>
#include <Enemy/EnemyManager.hpp>
#include <Enemy/Enemy.hpp>
#include <JSystem/JDrama/JDRViewObj.hpp>
#include <JSystem/J3D/J3DGraphAnimator/J3DJoint.hpp>
#include <JSystem/J3D/J3DGraphAnimator/J3DAnimation.hpp>
#include <MarioUtil/MtxUtil.hpp>
#include <GC2D/GCConsole2.hpp>
#include <System/EmitterViewObj.hpp>
#include <System/Particles.hpp>
#include <Enemy/Graph.hpp>
#include <Player/MarioAccess.hpp>
#include <System/MarDirector.hpp>
class TLiveActor;
class TBossWanwan;
class TBWParams;
class TBWLeash;
class TBWLeashNode;
class TRope;
class TBossWanwanMtxCalc;
class TBWHit : public THitActor {
public:
TBWHit(TBossWanwan* owner, int jointIndex,
const char* name = "ボスワンワンヒット");
virtual void perform(u32 cue, JDrama::TGraphics* graphics);
virtual BOOL receiveMessage(THitActor* sender, u32 message);
private:
/* 0x68 */ TBossWanwan* mOwner;
/* 0x6C */ s32 mJointIndex;
};
class TBWPicket : public TTakeActor {
public:
TBWPicket(TBossWanwan* owner, const char* name = "ボスワンワン杭");
virtual void perform(u32 cue, JDrama::TGraphics* graphics);
virtual BOOL receiveMessage(THitActor* sender, u32 message);
virtual MtxPtr getTakingMtx();
virtual BOOL moveRequest(const JGeometry::TVec3<float>&);
private:
/* 0x70 */ TBossWanwan* mOwner;
/* 0x74 */ TMtx34f unk74;
/* 0xA8 */ MActor* mActor;
};
class TBWBinder : public TBinder {
public:
TBWBinder();
virtual ~TBWBinder() { };
virtual void bind(TLiveActor*);
};
class TBWLeash : public JDrama::TViewObj {
public:
TBWLeash(TBossWanwan* owner, int nodeCount,
const char* name = "ボスワンワンリーシュ");
virtual ~TBWLeash() { };
void perform(u32 cue, JDrama::TGraphics* graphics);
TBWLeashNode* getNode(s32 idx) const { return mNodes[idx]; } // fabricated
// UNUSED
void pullTail(const JGeometry::TVec3<f32>& pos);
void invalidateAllCollision();
/* 0x10 */ TBossWanwan* mOwner;
/* 0x14 */ TRope* mRope;
/* 0x18 */ TBWLeashNode** mNodes;
};
class TBWLeashNode : public THitActor {
public:
TBWLeashNode(TBWLeash*, int, const char*);
virtual void perform(u32 cue, JDrama::TGraphics* graphics);
void calcMatrix();
void calcTemperature();
TBWLeash* mLeash; // +0x68
MActor* mMActor; // +0x6C
f32 mTemperature; // +0x70
int mIndex; // +0x74
};
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;
};
class TBossWanwanMtxCalc : public M3UMtxCalcSIAnmBlendQuat {
public:
TBossWanwanMtxCalc(TBossWanwan*);
virtual ~TBossWanwanMtxCalc() { };
void calc(u16);
void joinAnm(int i);
public:
/* 0x64 */ TBossWanwan* mOwner;
};
// TBossWanwan size: 0x1b8
class TBossWanwan : public TSpineEnemy {
public:
TBossWanwan(const char* name = "ボスワンワン");
virtual void kill() { };
virtual void init(TLiveManager*);
void shakeCamera(int shakeType);
virtual BOOL receiveMessage(THitActor* sender, u32 message);
virtual void calcRootMatrix();
void slideToCurPathNode(float, float);
virtual void control();
void emitEffects();
virtual void perform(u32 cue, JDrama::TGraphics* graphics);
f32 getUnk168() const { return unk168; }
// fabricated
TBWParams* getSaveParam() const { return (TBWParams*)getSaveParam(); }
// fabricated
f32 getHeadHeight() const { return mHeadHeight * mBodyScale; }
// UNUSED
BOOL isHeadPulled();
bool isMarioInSight();
bool isTailBurning();
bool isBurning();
void startGoldBrk();
void releasePicket();
void takeBath();
void rollNextGraphNode();
void reverseNextGraphNode();
void showMessage(u32 msg);
void changeBck(int);
// fabricated
const TNerveBase<TLiveActor>* getLatestNerve()
{
return mSpine->getLatestNerve();
}
// fabricated
void setBckFromIndex(int idx)
{
mMtxCalc->joinAnm(idx);
getMActor()->getAnmBck()->setFrameCtrl(idx);
}
// fabricated
static inline void setRotDirY(JGeometry::TVec3<f32>& dir, f32 rot,
f32 scale)
{
u16 angle = (int)(rot * 182.04445f);
dir.set(scale * JMASSin(angle), 0.0f, scale * JMASCos(angle));
}
// fabricated
JGeometry::TVec3<f32> getRotDirY(f32 rot) const
{
JGeometry::TVec3<f32> dir;
setRotDirY(dir, rot, 1.0f);
return dir;
}
enum {
BOSS_WANWAN_FLAGS_UNK1 = 0xE001A,
BOSS_WANWAN_FLAGS_UNK2 = 0xE001B,
BOSS_WANWAN_FLAGS_UNK3 = 0xE001C,
BOSS_WANWAN_FLAGS_UNK4 = 0xE001D,
};
/* 0x150 */ TBossWanwanMtxCalc* mMtxCalc;
/* 0x154 */ TBWLeash* mLeash;
/* 0x158 */ TBWPicket* mPicket;
/* 0x15C */ JGeometry::TVec3<f32> mPicketPullDelta;
/* 0x168 */ f32 unk168;
/* 0x16C */ s32 unk16C;
/* 0x170 */ TBWHit* mHits[2];
/* 0x178 */ f32 unk178;
/* 0x17C */ BOOL unk17C;
/* 0x180 */ u32 unk180;
/* 0x184 */ u32 unk184;
/* 0x188 */ BOOL unk188;
/* 0x18C */ s8 msInvincible;
/* 0x18D */ u8 unk18D;
/* 0x190 */ s32 unk190;
/* 0x194 */ s8 unk194;
/* 0x195 */ u8 mHasSpawnedWater;
/* 0x198 */ u32 unk198;
/* 0x19C */ u32 unk19C;
/* 0x1A0 */ u8 unk1A0;
/* 0x1A4 */ JGeometry::TVec3<f32> unk1A4;
/* 0x1A8 */ s8 mWaterHitCount;
/* 0x1AC */ f32 unk1AC;
/* 0x1B0 */ TBWParams* mParams;
/* 0x1B4 */ u16 unk1B4;
};
class TBossWanwanManager : public TEnemyManager {
public:
TBossWanwanManager(const char* name = "ボスワンワンマネージャ");
virtual void load(JSUMemoryInputStream&);
virtual TSpineEnemy* createEnemyInstance();
virtual void createModelData();
void initJParticle();
};
DECLARE_NERVE(TNerveBWGraphWander, TLiveActor);
DECLARE_NERVE(TNerveBWRoll, TLiveActor);
+3
View File
@@ -318,6 +318,9 @@ public:
mMtxCalcType = MActorMtxCalcType_User;
}
// fabricated for bosswanwan.cpp
void setCalcType(u8 type) { mMtxCalcType = type; }
void setJointIndex(u16 value) { mJointIndex = value; }
private:
+3 -1
View File
@@ -179,12 +179,14 @@ public:
void moveHeadAndTail(const JGeometry::TVec3<f32>&,
const JGeometry::TVec3<f32>&);
private:
/* 0x00 */ u16 mNumPoints;
/* 0x04 */ TRopePoint* mPoints;
/* 0x08 */ f32 unk8;
/* 0x0C */ f32 unkC;
/* 0x10 */ f32 unk10;
public:
// Made attributes public to match bosswanwan.cpp
};
void SMS_GetActorMtx(const THitActor&, MtxPtr);
+1 -1
View File
@@ -336,7 +336,7 @@ enum TActorType {
ACTOR_TYPE_BOSS_GESSO_BEAK = HIT_CATEGORY_BOSS | 0x9,
ACTOR_TYPE_BOSS_UNKB = HIT_CATEGORY_BOSS | 0xB,
ACTOR_TYPE_BOSS_UNKC = HIT_CATEGORY_BOSS | 0xC,
ACTOR_TYPE_BOSS_UNKD = HIT_CATEGORY_BOSS | 0xD,
ACTOR_TYPE_BOSS_WANWAN = HIT_CATEGORY_BOSS | 0xD,
ACTOR_TYPE_BOSS_UNKE = HIT_CATEGORY_BOSS | 0xE,
ACTOR_TYPE_BOSS_PAKKUN = HIT_CATEGORY_BOSS | 0xF,
ACTOR_TYPE_BOSS_PAKKUN_ATTACK = HIT_CATEGORY_BOSS | 0x10,
+6
View File
@@ -169,6 +169,10 @@ enum E_SMS_EFFECT_ONETIME_NORMAL /* 0 */ {
SCENE_BOSSPAKKUN_JPA_MS_BOPA_DOWN = 0xAA,
SCENE_BOSSPAKKUN_JPA_MS_BOPA_SWING1 = 0xAB,
SCENE_BOSSPAKKUN_JPA_MS_BOPA_SWING2 = 0xAC,
BWAN_JPA_JUMP_ROCK = 0xAD,
BWAN_JPA_JUMP_SMOKE = 0xAE,
BWAN_JPA_MS_HIBANA = 0xAF,
BWAN_JPA_MS_DOWNYUGE = 0xB0,
PARTICLE_MS_SMB_KAFUN_OW = 0xB2,
PARTICLE_MS_SMB_KAFUN_OA = 0xB3,
PARTICLE_MS_SMB_AP_ROCK = 0xB6,
@@ -330,6 +334,7 @@ enum E_SMS_EFFECT_LOOP_NORMAL /* 1 */ {
SCENE_BOSSPAKKUN_JPA_MS_BOPA_TR_WEED = 0x164,
PARTICLE_MS_GESO_KISEKI = 0x165,
CANNON_JPA_MS_CANNON_SMOKE = 0x166,
BWANWAN_JPA_MS_BWAN_HITYUGE = 0x167,
BWANWAN_JPA_MS_BWAN_KIRA = 0x168,
PARTICLE_MS_BOHA_JOUKI2_R_A = 0x169,
PARTICLE_MS_BOHA_JOUKI2_R_B = 0x16A,
@@ -464,6 +469,7 @@ enum E_SMS_EFFECT_LOOP_INDIRECT /* 3 */ {
PARTICLE_MS_GESOSURF_A = 0x1E7,
PARTICLE_MS_M_WATSLIDE_A = 0x1EA,
PARTICLE_MS_MOE_FIRE_C = 0x1ED,
BWAN_JPA_MS_YUGAMI = 0x1EE,
};
// NOTE: doing this makes inlining work out, specializations DON'T.
+12 -14
View File
@@ -828,9 +828,9 @@ BOOL TBossEelTooth::receiveMessage(THitActor* sender, u32 message)
actor->setFrameRate(SMSGetAnmFrameRate(), ANM_TYPE_BCK);
mOwner->mToothDamaged = true;
mColor.a = static_cast<u8>(
static_cast<f32>(mHitPoints * 0xFF)
/ static_cast<f32>(
mOwner->getBossEelParams().mSLToothMaxHitPoint.get()));
static_cast<f32>(mHitPoints * 0xFF)
/ static_cast<f32>(
mOwner->getBossEelParams().mSLToothMaxHitPoint.get()));
if (mToothType == 1 && mHitPoints % 20 == 1)
mOwner->forceShedTears(mCanShedTears);
@@ -1043,7 +1043,7 @@ void TBossEelVortex::perform(u32 cue, JDrama::TGraphics* graphics)
f32 power = mOwner->mSaveParams->mSLBreathInPower.get();
f32 wave = fabsf(JMASSin(
static_cast<s16>(182.04445f * (0.9f * mTimer))));
static_cast<s16>(182.04445f * (0.9f * mTimer))));
if (wave > 1.0f)
wave = 1.0f;
else if (wave < 0.1f)
@@ -1187,15 +1187,13 @@ void TBossEelHeartCoin::perform(u32 cue, JDrama::TGraphics* graphics)
u32 calcAnim = cue & CUE_CALC_ANIM;
if (calcAnim) {
s32 jointIndex = mOwner->getMActor()
->getModel()
->getModelData()
->getJointName()
->getIndex("ha7");
MtxPtr jointMtx
= mOwner->getMActor()->getModel()->getAnmMtx(jointIndex);
if (mOwner->getMActor()->checkCurBckFromIndex(3)
&& mOwner->getMActor()->getFrameCtrl(ANM_TYPE_BCK)->getFrame()
s32 jointIndex = mOwner->mMActor->getModel()
->getModelData()
->getJointName()
->getIndex("ha7");
MtxPtr jointMtx = mOwner->mMActor->getModel()->getAnmMtx(jointIndex);
if (mOwner->mMActor->checkCurBckFromIndex(3)
&& mOwner->mMActor->getFrameCtrl(ANM_TYPE_BCK)->getFrame()
< 700.0f) {
mPosition.set(jointMtx[0][3], jointMtx[1][3], jointMtx[2][3]);
}
@@ -1531,7 +1529,7 @@ void TBossEel::init(TLiveManager* manager)
= { "headcol1", "headcol2", "sebone5", "sebone5" };
static const char* sCollisionFileTable[]
= { "/bosseel/meoto_head", "/bosseel/meoto_head2",
"/bosseel/meoto_camera", "/bosseel/meoto_out_loop" };
"/bosseel/meoto_camera", "/bosseel/meoto_out_loop" };
for (s32 i = 0; i < 4; ++i) {
mMapCollisionJointIndices[i]
File diff suppressed because it is too large. Load diff
View File
Whitespace-only changes.
+1 -1
View File
@@ -411,7 +411,7 @@ void TMario::checkCollision()
case ACTOR_TYPE_BOSS_GESSO_TENTACLE:
case ACTOR_TYPE_BOSS_UNK8:
case ACTOR_TYPE_BOSS_UNKD:
case ACTOR_TYPE_BOSS_WANWAN:
case ACTOR_TYPE_YOSHI_TONGUE:
case ACTOR_TYPE_FIRE_WANWAN_TAIL_HIT:
hitNoKeepPull(mCollisions[i]);
+1 -1
View File
@@ -665,7 +665,7 @@ BOOL TMario::receiveMessage(THitActor* sender, u32 message)
case ACTOR_TYPE_BOSS_UNKB:
case ACTOR_TYPE_BOSS_UNKC:
case ACTOR_TYPE_BOSS_UNKD:
case ACTOR_TYPE_BOSS_WANWAN:
case ACTOR_TYPE_BOSS_UNKE:
if (message == HIT_MESSAGE_BURN && !isInvincible()) {
damageExec(sender, mDmgParamsFire.mDamage.get(),
+3 -3
View File
@@ -537,7 +537,7 @@ BOOL TMario::hanging()
for (int j = 0; j < record4.mResultWallsNum; j++) {
TBGCheckData* w = record4.mResultWalls[j];
s16 ang = matan(w->mNormal.z, w->mNormal.x)
- (mFaceAngle.y + 0x8000);
- (mFaceAngle.y + 0x8000);
if (ang > -0x2000 && ang < 0x2000) {
JGeometry::TVec3<f32> pos = mPosition;
f32 d = w->mNormal.x * pos.x + w->mNormal.y * pos.y
@@ -1144,7 +1144,7 @@ void TMario::getCurrentPullParams(f32* outV, f32* outH)
case ACTOR_TYPE_BOSS_GESSO_TENTACLE:
params = &mPullParamsBGTentacle;
break;
case ACTOR_TYPE_BOSS_UNKD:
case ACTOR_TYPE_BOSS_WANWAN:
params = &mPullParamsBGFireWanWanBossTail;
break;
case ACTOR_TYPE_FIRE_WANWAN_TAIL_HIT:
@@ -1233,7 +1233,7 @@ BOOL TMario::pulling()
JGeometry::TVec3<f32> delta;
if ((mHeldObject->getActorType() == ACTOR_TYPE_BOSS_GESSO_TENTACLE
? true
: false)
: false)
|| (mHeldObject->getActorType() == ACTOR_TYPE_BOSS_UNK8 ? true
: false)) {
delta = pos - mPrevPosition;