mirror of
https://github.com/zeldaret/mm.git
synced 2026-08-28 00:02:04 -04:00
Boss01 (Odolwa) OK and documented (#1452)
* Boss01 (Odolwa) OK and documented * Unify existing InitRand implementations * Remove newlines after `// fallthrough` * Respond to the rest of engineer's review * Respond to most of anon's review * Try to comment the shadow thing correctly * Fix boss_01 after merge * SEGMENTED_TO_VIRTUAL -> SEGMENTED_TO_K0 * Review * Use DMG_SWORD_BEAM and update the comment in z64collision_check.h * Respond to engineer's review
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -2,16 +2,153 @@
|
||||
#define Z_BOSS_01_H
|
||||
|
||||
#include "global.h"
|
||||
#include "assets/objects/object_boss01/object_boss01.h"
|
||||
|
||||
struct Boss01;
|
||||
|
||||
#define ODOLWA_GET_TYPE(thisx) ((thisx)->params)
|
||||
#define ODOLWA_GET_AFTERIMAGE_DESPAWN_TIMER(thisx) ((thisx)->world.rot.z)
|
||||
|
||||
#define ODOLWA_SHADOW_TEX_WIDTH 64
|
||||
#define ODOLWA_SHADOW_TEX_HEIGHT 64
|
||||
#define ODOLWA_SHADOW_TEX_SIZE ((s32)sizeof(u8[ODOLWA_SHADOW_TEX_HEIGHT][ODOLWA_SHADOW_TEX_WIDTH]))
|
||||
|
||||
typedef void (*Boss01ActionFunc)(struct Boss01*, PlayState*);
|
||||
|
||||
typedef enum OdolwaType {
|
||||
/* 0 */ ODOLWA_TYPE_ODOLWA,
|
||||
/* 10 */ ODOLWA_TYPE_BUG = 10,
|
||||
/* 35 */ ODOLWA_TYPE_AFTERIMAGE = 35
|
||||
} OdolwaType;
|
||||
|
||||
typedef enum OdolwaBodyPart {
|
||||
/* 0 */ ODOLWA_BODYPART_HEAD,
|
||||
/* 1 */ ODOLWA_BODYPART_TORSO,
|
||||
/* 2 */ ODOLWA_BODYPART_PELVIS,
|
||||
/* 3 */ ODOLWA_BODYPART_LEFT_UPPER_ARM,
|
||||
/* 4 */ ODOLWA_BODYPART_LEFT_FOREARM,
|
||||
/* 5 */ ODOLWA_BODYPART_SHIELD,
|
||||
/* 6 */ ODOLWA_BODYPART_RIGHT_UPPER_ARM,
|
||||
/* 7 */ ODOLWA_BODYPART_RIGHT_FOREARM,
|
||||
/* 8 */ ODOLWA_BODYPART_SWORD,
|
||||
/* 9 */ ODOLWA_BODYPART_RIGHT_THIGH,
|
||||
/* 10 */ ODOLWA_BODYPART_RIGHT_SHIN,
|
||||
/* 11 */ ODOLWA_BODYPART_RIGHT_FOOT,
|
||||
/* 12 */ ODOLWA_BODYPART_LEFT_THIGH,
|
||||
/* 13 */ ODOLWA_BODYPART_LEFT_SHIN,
|
||||
/* 14 */ ODOLWA_BODYPART_LEFT_FOOT,
|
||||
/* 15 */ ODOLWA_BODYPART_MAX
|
||||
} OdolwaBodyPart;
|
||||
|
||||
typedef enum OdolwaColliderBodyPart {
|
||||
/* 0 */ ODOLWA_COLLIDER_BODYPART_HEAD,
|
||||
/* 1 */ ODOLWA_COLLIDER_BODYPART_TORSO,
|
||||
/* 2 */ ODOLWA_COLLIDER_BODYPART_PELVIS,
|
||||
/* 3 */ ODOLWA_COLLIDER_BODYPART_LEFT_UPPER_ARM,
|
||||
/* 4 */ ODOLWA_COLLIDER_BODYPART_LEFT_FOREARM,
|
||||
/* 5 */ ODOLWA_COLLIDER_BODYPART_RIGHT_UPPER_ARM,
|
||||
/* 6 */ ODOLWA_COLLIDER_BODYPART_RIGHT_FOREARM,
|
||||
/* 7 */ ODOLWA_COLLIDER_BODYPART_LEFT_THIGH,
|
||||
/* 8 */ ODOLWA_COLLIDER_BODYPART_LEFT_SHIN,
|
||||
/* 9 */ ODOLWA_COLLIDER_BODYPART_RIGHT_THIGH,
|
||||
/* 10 */ ODOLWA_COLLIDER_BODYPART_RIGHT_SHIN,
|
||||
/* 11 */ ODOLWA_COLLIDER_BODYPART_MAX
|
||||
} OdolwaColliderBodyPart;
|
||||
|
||||
typedef enum OdolwaSwordCollider {
|
||||
/* 0 */ ODOLWA_SWORD_COLLIDER_SWORD_BASE,
|
||||
/* 1 */ ODOLWA_SWORD_COLLIDER_SWORD_TIP,
|
||||
/* 2 */ ODOLWA_SWORD_COLLIDER_PELVIS,
|
||||
/* 3 */ ODOLWA_SWORD_COLLIDER_MAX
|
||||
} OdolwaSwordCollider;
|
||||
|
||||
typedef enum OdolwaShieldCollider {
|
||||
/* 0 */ ODOLWA_SHIELD_COLLIDER_SHIELD,
|
||||
/* 1 */ ODOLWA_SHIELD_COLLIDER_MAX
|
||||
} OdolwaShieldCollider;
|
||||
|
||||
typedef enum OdolwaKickAndShieldBashCollider {
|
||||
/* 0 */ ODOLWA_KICK_AND_SHIELD_BASH_COLLIDER_SHIELD,
|
||||
/* 1 */ ODOLWA_KICK_AND_SHIELD_BASH_COLLIDER_LEFT_FOOT,
|
||||
/* 2 */ ODOLWA_KICK_AND_SHIELD_BASH_COLLIDER_MAX
|
||||
} OdolwaKickAndShieldBashCollider;
|
||||
|
||||
typedef struct Boss01 {
|
||||
/* 0x000 */ Actor actor;
|
||||
/* 0x144 */ char unk_144[0x320];
|
||||
/* 0x144 */ s16 frameCounter;
|
||||
/* 0x148 */ s32 phaseFrameCounter;
|
||||
/* 0x14C */ union {
|
||||
u8 jumpIfPlayerIsClose;
|
||||
u8 shouldPerformFallingSlash;
|
||||
u8 bugDrawDmgEffType;
|
||||
};
|
||||
/* 0x14E */ s16 timers[3];
|
||||
/* 0x154 */ f32 animMorphFrames1;
|
||||
/* 0x158 */ f32 animMorphFrames2;
|
||||
/* 0x15C */ s16 damageTimer;
|
||||
/* 0x15E */ s16 damageFlashTimer;
|
||||
/* 0x160 */ u8 isPerformingVerticalSlash; // set, but never checked
|
||||
/* 0x160 */ u8 landedFromJump;
|
||||
/* 0x162 */ u8 waitType;
|
||||
/* 0x163 */ u8 lookAtPlayer;
|
||||
/* 0x164 */ SkelAnime skelAnime;
|
||||
/* 0x1A8 */ f32 animEndFrame;
|
||||
/* 0x1AC */ f32 prevJumpVelocityY;
|
||||
/* 0x1B0 */ f32 runTargetPosAngularVelocityY;
|
||||
/* 0x1B4 */ f32 runTargetPosRotY;
|
||||
/* 0x1B8 */ u8 swordState;
|
||||
/* 0x1B9 */ u8 kickAndShieldBashCollisionEnabled;
|
||||
/* 0x1BA */ u8 swordAndShieldCollisionEnabled;
|
||||
/* 0x1BB */ u8 canGuardOrEvade;
|
||||
/* 0x1BC */ u8 bodyInvincibilityTimer;
|
||||
/* 0x1BE */ s16 disableCollisionTimer;
|
||||
/* 0x1C0 */ u8 afterimageSpawnFrameMask; // used as a bitmask with frameCounter to control how often to spawn afterimages
|
||||
/* 0x1C1 */ u8 hasPlayedSummonBugCs;
|
||||
/* 0x1C4 */ f32 additionalVelocityX;
|
||||
/* 0x1C8 */ f32 additionalVelocityZ;
|
||||
/* 0x1CC */ s16 headRotY;
|
||||
/* 0x1CE */ s16 headRotX;
|
||||
/* 0x1D0 */ Vec3s jointTable[ODOLWA_LIMB_MAX];
|
||||
/* 0x308 */ Vec3s morphTable[ODOLWA_LIMB_MAX];
|
||||
/* 0x440 */ Vec3f feetPos[2];
|
||||
/* 0x458 */ Vec3f pelvisPos;
|
||||
/* 0x464 */ Boss01ActionFunc actionFunc;
|
||||
/* 0x468 */ char unk_468[0x674];
|
||||
/* 0x468 */ ColliderJntSph swordCollider;
|
||||
/* 0x488 */ ColliderJntSphElement swordColliderElements[ODOLWA_SWORD_COLLIDER_MAX];
|
||||
/* 0x548 */ ColliderJntSph shieldCollider;
|
||||
/* 0x568 */ ColliderJntSphElement shieldColliderElements[ODOLWA_SHIELD_COLLIDER_MAX];
|
||||
/* 0x5A8 */ ColliderJntSph bodyCollider;
|
||||
/* 0x5C8 */ ColliderJntSphElement bodyColliderElements[ODOLWA_COLLIDER_BODYPART_MAX];
|
||||
/* 0x888 */ ColliderJntSph kickAndShieldBashCollider;
|
||||
/* 0x8A8 */ ColliderJntSphElement kickAndShieldBashColliderElements[ODOLWA_KICK_AND_SHIELD_BASH_COLLIDER_MAX];
|
||||
/* 0x928 */ Vec3f bodyPartsPos[ODOLWA_BODYPART_MAX];
|
||||
/* 0x9DC */ union {
|
||||
u32 cutsceneTimer;
|
||||
u32 waitTimer;
|
||||
u32 summonMothsTimer;
|
||||
};
|
||||
/* 0x9E0 */ s16 cutsceneState;
|
||||
/* 0x9E2 */ s16 subCamId;
|
||||
/* 0x9E4 */ Vec3f subCamEye;
|
||||
/* 0x9F0 */ Vec3f subCamAt;
|
||||
/* 0x9FC */ Vec3f subCamUp;
|
||||
/* 0xA08 */ Vec3f subCamEyeNext;
|
||||
/* 0xA14 */ f32 deathCsInitialSubCamRot;
|
||||
/* 0xA18 */ f32 deathCsSubCamRot;
|
||||
/* 0xA1C */ f32 subCamVelocity;
|
||||
/* 0xA20 */ f32 deathShrinkSpeed;
|
||||
/* 0xA24 */ f32 screenShakeOffsetY;
|
||||
/* 0xA28 */ f32 screenShakeMagnitude;
|
||||
/* 0xA2C */ ColliderCylinder bugACCollider;
|
||||
/* 0xA78 */ ColliderCylinder bugATCollider;
|
||||
/* 0xAC4 */ f32 bugDrawDmgEffScale;
|
||||
/* 0xAC8 */ f32 bugDrawDmgEffAlpha;
|
||||
/* 0xACC */ f32 drawDmgEffScale;
|
||||
/* 0xAD0 */ f32 drawDmgEffFrozenSteamScale;
|
||||
/* 0xAD4 */ f32 drawDmgEffAlpha;
|
||||
/* 0xAD8 */ u8 drawDmgEffType;
|
||||
/* 0xAD9 */ u8 drawDmgEffState;
|
||||
/* 0xADA */ s16 drawDmgEffTimer;
|
||||
} Boss01; // size = 0xADC
|
||||
|
||||
#endif // Z_BOSS_01_H
|
||||
|
||||
@@ -69,9 +69,9 @@ u8 sIsInGiantMode;
|
||||
Boss02* sRedTwinmold;
|
||||
Boss02* sBlueTwinmold;
|
||||
Boss02* sTwinmoldStatic;
|
||||
u8 sMusicStartTimer;
|
||||
u8 sTwinmoldMusicStartTimer;
|
||||
DoorWarp1* sBlueWarp;
|
||||
TwinmoldEffect sEffects[TWINMOLD_EFFECT_COUNT];
|
||||
TwinmoldEffect sTwinmoldEffects[TWINMOLD_EFFECT_COUNT];
|
||||
|
||||
static DamageTable sBlueTwinmoldDamageTable = {
|
||||
/* Deku Nut */ DMG_ENTRY(0, 0x0),
|
||||
@@ -588,7 +588,7 @@ void Boss02_Init(Actor* thisx, PlayState* play) {
|
||||
if (CHECK_WEEKEVENTREG(WEEKEVENTREG_CLEARED_STONE_TOWER_TEMPLE) &&
|
||||
(TWINMOLD_GET_TYPE(&this->actor) == TWINMOLD_TYPE_RED)) {
|
||||
sBlueWarp = (DoorWarp1*)Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DOOR_WARP1, 0.0f, 60.0f,
|
||||
0.0f, 0, 0, 0, 1);
|
||||
0.0f, 0, 0, 0, ENDOORWARP1_FF_1);
|
||||
Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, 0.0f, 30.0f, -150.0f, 0, 1, 0, BHEART_PARAM_NORMAL);
|
||||
}
|
||||
|
||||
@@ -597,14 +597,14 @@ void Boss02_Init(Actor* thisx, PlayState* play) {
|
||||
this->subCamUp.y = 1.0f;
|
||||
if (TWINMOLD_GET_TYPE(&this->actor) == TWINMOLD_TYPE_STATIC) {
|
||||
sTwinmoldStatic = this;
|
||||
play->specialEffects = (void*)sEffects;
|
||||
play->specialEffects = (void*)sTwinmoldEffects;
|
||||
this->actor.update = Boss02_Static_Update;
|
||||
this->actor.draw = Boss02_Static_Draw;
|
||||
this->actor.flags &= ~ACTOR_FLAG_TARGETABLE;
|
||||
this->playerScale = 0.01f;
|
||||
if ((KREG(64) != 0) || CHECK_EVENTINF(EVENTINF_55) || (sBlueWarp != NULL)) {
|
||||
this->unk_1D20 = 0;
|
||||
sMusicStartTimer = KREG(15) + 20;
|
||||
sTwinmoldMusicStartTimer = KREG(15) + 20;
|
||||
} else {
|
||||
this->unk_1D20 = 1;
|
||||
}
|
||||
@@ -1346,9 +1346,9 @@ void Boss02_Static_Update(Actor* thisx, PlayState* play) {
|
||||
}
|
||||
|
||||
if (sBlueWarp == NULL) {
|
||||
if (sMusicStartTimer != 0) {
|
||||
sMusicStartTimer--;
|
||||
if (sMusicStartTimer == 0) {
|
||||
if (sTwinmoldMusicStartTimer != 0) {
|
||||
sTwinmoldMusicStartTimer--;
|
||||
if (sTwinmoldMusicStartTimer == 0) {
|
||||
SEQCMD_PLAY_SEQUENCE(SEQ_PLAYER_BGM_MAIN, 0, NA_BGM_BOSS | SEQ_FLAG_ASYNC);
|
||||
}
|
||||
}
|
||||
@@ -2173,7 +2173,7 @@ void func_809DEAC4(Boss02* this, PlayState* play) {
|
||||
|
||||
if (this->unk_1D1C == 45) {
|
||||
func_800B7298(play, &this->actor, PLAYER_CSACTION_21);
|
||||
sMusicStartTimer = KREG(91) + 43;
|
||||
sTwinmoldMusicStartTimer = KREG(91) + 43;
|
||||
}
|
||||
|
||||
if (this->unk_1D1C == 85) {
|
||||
@@ -2304,7 +2304,7 @@ void func_809DEAC4(Boss02* this, PlayState* play) {
|
||||
phi_f0 = 3155.0f;
|
||||
}
|
||||
sBlueWarp = (DoorWarp1*)Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DOOR_WARP1,
|
||||
0.0f, phi_f0, 0.0f, 0, 0, 0, 1);
|
||||
0.0f, phi_f0, 0.0f, 0, 0, 0, ENDOORWARP1_FF_1);
|
||||
|
||||
if (!sIsInGiantMode) {
|
||||
sBlueWarp->unk_203 = 0;
|
||||
|
||||
@@ -231,30 +231,30 @@ void Boss03_UpdateSphereElement(s32 index, ColliderJntSph* collider, Vec3f* sphe
|
||||
|
||||
/* Start of RNG section */
|
||||
|
||||
static s32 sRandSeed0;
|
||||
static s32 sRandSeed1;
|
||||
static s32 sRandSeed2;
|
||||
s32 sGyorgRandSeed1;
|
||||
s32 sGyorgRandSeed2;
|
||||
s32 sGyorgRandSeed3;
|
||||
|
||||
void Boss03_SeedRand(s32 seed0, s32 seed1, s32 seed2) {
|
||||
sRandSeed0 = seed0;
|
||||
sRandSeed1 = seed1;
|
||||
sRandSeed2 = seed2;
|
||||
void Boss03_InitRand(s32 seedInit1, s32 seedInit2, s32 seedInit3) {
|
||||
sGyorgRandSeed1 = seedInit1;
|
||||
sGyorgRandSeed2 = seedInit2;
|
||||
sGyorgRandSeed3 = seedInit3;
|
||||
}
|
||||
|
||||
f32 Boss03_RandZeroOne(void) {
|
||||
f32 rand;
|
||||
|
||||
// Wichmann-Hill algorithm
|
||||
sRandSeed0 = (sRandSeed0 * 171) % 30269;
|
||||
sRandSeed1 = (sRandSeed1 * 172) % 30307;
|
||||
sRandSeed2 = (sRandSeed2 * 170) % 30323;
|
||||
f32 randFloat;
|
||||
|
||||
rand = (sRandSeed0 / 30269.0f) + (sRandSeed1 / 30307.0f) + (sRandSeed2 / 30323.0f);
|
||||
while (rand >= 1.0f) {
|
||||
rand -= 1.0f;
|
||||
sGyorgRandSeed1 = (sGyorgRandSeed1 * 171) % 30269;
|
||||
sGyorgRandSeed2 = (sGyorgRandSeed2 * 172) % 30307;
|
||||
sGyorgRandSeed3 = (sGyorgRandSeed3 * 170) % 30323;
|
||||
|
||||
randFloat = (sGyorgRandSeed1 / 30269.0f) + (sGyorgRandSeed2 / 30307.0f) + (sGyorgRandSeed3 / 30323.0f);
|
||||
while (randFloat >= 1.0f) {
|
||||
randFloat -= 1.0f;
|
||||
}
|
||||
|
||||
return fabsf(rand);
|
||||
return fabsf(randFloat);
|
||||
}
|
||||
|
||||
/* End of RNG section */
|
||||
@@ -483,7 +483,7 @@ void Boss03_Init(Actor* thisx, PlayState* play2) {
|
||||
this->actor.world.pos = sGyorgInitialPos;
|
||||
|
||||
// Since Boss03_RandZeroOne is only used on this Init function, the resulting values end up being deterministic
|
||||
Boss03_SeedRand(1, 29093, 9786);
|
||||
Boss03_InitRand(1, 29093, 9786);
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
f32 rand;
|
||||
|
||||
@@ -147,9 +147,9 @@ f32 sSubCamVelFactor;
|
||||
f32 D_80911F50;
|
||||
Vec3f sSinkingLureBasePos;
|
||||
f32 D_80911F64;
|
||||
s32 sRandSeed0;
|
||||
s32 sRandSeed1;
|
||||
s32 sRandSeed2;
|
||||
s32 sFishingRandSeed1;
|
||||
s32 sFishingRandSeed2;
|
||||
s32 sFishingRandSeed3;
|
||||
FishingProp sPondProps[POND_PROP_COUNT];
|
||||
FishingGroupFish sGroupFishes[GROUP_FISH_COUNT];
|
||||
f32 sFishGroupAngle1;
|
||||
@@ -404,26 +404,26 @@ void EnFishing_SetColliderElement(s32 index, ColliderJntSph* collider, Vec3f* po
|
||||
collider->elements[index].dim.modelSphere.radius * collider->elements[index].dim.scale * scale * 1.6f;
|
||||
}
|
||||
|
||||
void EnFishing_SeedRand(s32 seed0, s32 seed1, s32 seed2) {
|
||||
sRandSeed0 = seed0;
|
||||
sRandSeed1 = seed1;
|
||||
sRandSeed2 = seed2;
|
||||
void EnFishing_InitRand(s32 seedInit1, s32 seedInit2, s32 seedInit3) {
|
||||
sFishingRandSeed1 = seedInit1;
|
||||
sFishingRandSeed2 = seedInit2;
|
||||
sFishingRandSeed3 = seedInit3;
|
||||
}
|
||||
|
||||
f32 EnFishing_RandZeroOne(void) {
|
||||
f32 rand;
|
||||
|
||||
// Wichmann-Hill algorithm
|
||||
sRandSeed0 = (sRandSeed0 * 171) % 30269;
|
||||
sRandSeed1 = (sRandSeed1 * 172) % 30307;
|
||||
sRandSeed2 = (sRandSeed2 * 170) % 30323;
|
||||
f32 randFloat;
|
||||
|
||||
rand = (sRandSeed0 / 30269.0f) + (sRandSeed1 / 30307.0f) + (sRandSeed2 / 30323.0f);
|
||||
while (rand >= 1.0f) {
|
||||
rand -= 1.0f;
|
||||
sFishingRandSeed1 = (sFishingRandSeed1 * 171) % 30269;
|
||||
sFishingRandSeed2 = (sFishingRandSeed2 * 172) % 30307;
|
||||
sFishingRandSeed3 = (sFishingRandSeed3 * 170) % 30323;
|
||||
|
||||
randFloat = (sFishingRandSeed1 / 30269.0f) + (sFishingRandSeed2 / 30307.0f) + (sFishingRandSeed3 / 30323.0f);
|
||||
while (randFloat >= 1.0f) {
|
||||
randFloat -= 1.0f;
|
||||
}
|
||||
|
||||
return fabsf(rand);
|
||||
return fabsf(randFloat);
|
||||
}
|
||||
|
||||
s16 EnFishing_SmoothStepToS(s16* pValue, s16 target, s16 scale, s16 step) {
|
||||
@@ -730,7 +730,7 @@ void EnFishing_InitPondProps(EnFishing* this, PlayState* play) {
|
||||
Vec3f colliderPos;
|
||||
s16 i;
|
||||
|
||||
EnFishing_SeedRand(1, 29100, 9786);
|
||||
EnFishing_InitRand(1, 29100, 9786);
|
||||
|
||||
for (i = 0; i < POND_PROP_COUNT; i++) {
|
||||
if (sPondPropInits[i].type == FS_PROP_INIT_STOP) {
|
||||
|
||||
Reference in New Issue
Block a user