From 858d10a38b20cf4288c0044c2fe93a5b49746a40 Mon Sep 17 00:00:00 2001 From: Derek Hensley Date: Mon, 15 May 2023 23:37:33 -0700 Subject: [PATCH] Documents EnEncount1 (Dragonfly, Wallmaster, and Skullfish spawner) (#1206) * Document everything * missed some () * PR * format * spawnActiveCount * spawnTotalCount --- .../actors/ovl_En_Encount1/z_en_encount1.c | 139 ++++++++++-------- .../actors/ovl_En_Encount1/z_en_encount1.h | 39 +++-- .../ovl_En_Grasshopper/z_en_grasshopper.h | 2 + src/overlays/actors/ovl_En_Pr2/z_en_pr2.c | 6 +- src/overlays/actors/ovl_En_Pr2/z_en_pr2.h | 2 + .../actors/ovl_En_Wallmas/z_en_wallmas.c | 4 +- .../actors/ovl_En_Wallmas/z_en_wallmas.h | 2 + tools/disasm/functions.txt | 2 +- 8 files changed, 110 insertions(+), 86 deletions(-) diff --git a/src/overlays/actors/ovl_En_Encount1/z_en_encount1.c b/src/overlays/actors/ovl_En_Encount1/z_en_encount1.c index a39a035674..834a6449f1 100644 --- a/src/overlays/actors/ovl_En_Encount1/z_en_encount1.c +++ b/src/overlays/actors/ovl_En_Encount1/z_en_encount1.c @@ -5,6 +5,9 @@ */ #include "z_en_encount1.h" +#include "overlays/actors/ovl_En_Grasshopper/z_en_grasshopper.h" +#include "overlays/actors/ovl_En_Wallmas/z_en_wallmas.h" +#include "overlays/actors/ovl_En_Pr2/z_en_pr2.h" #define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_100000 | ACTOR_FLAG_CANT_LOCK_ON) @@ -13,7 +16,7 @@ void EnEncount1_Init(Actor* thisx, PlayState* play); void EnEncount1_Update(Actor* thisx, PlayState* play); -void func_808E0954(EnEncount1* this, PlayState* play); +void EnEncount1_SpawnActor(EnEncount1* this, PlayState* play); ActorInit En_Encount1_InitVars = { ACTOR_EN_ENCOUNT1, @@ -27,14 +30,19 @@ ActorInit En_Encount1_InitVars = { (ActorFunc)NULL, }; -static s16 sActorList[] = { - ACTOR_EN_GRASSHOPPER, - ACTOR_EN_WALLMAS, - ACTOR_EN_PR2, - ACTOR_EN_PR2, +static s16 sActorIds[] = { + ACTOR_EN_GRASSHOPPER, // EN_ENCOUNT1_GRASSHOPPER + ACTOR_EN_WALLMAS, // EN_ENCOUNT1_WALLMASTER + ACTOR_EN_PR2, // EN_ENCOUNT1_SKULLFISH + ACTOR_EN_PR2, // EN_ENCOUNT1_SKULLFISH_2 }; -static s16 sActorParams[] = { 1, 0, 1, 3 }; +static s16 sActorParams[] = { + EN_GRASSHOPPER_PARAMS(EN_GRASSHOPPER_TYPE_GROWS_WHEN_SPAWNED), // EN_ENCOUNT1_GRASSHOPPER + WALLMASTER_PARAMS(WALLMASTER_TYPE_TIMER_ONLY, 0, false), // EN_ENCOUNT1_WALLMASTER + ENPR2_PARAMS(1, 0), // EN_ENCOUNT1_SKULLFISH + ENPR2_PARAMS(3, 0) // EN_ENCOUNT1_SKULLFISH_2 +}; void EnEncount1_Init(Actor* thisx, PlayState* play) { EnEncount1* this = THIS; @@ -44,69 +52,72 @@ void EnEncount1_Init(Actor* thisx, PlayState* play) { return; } - this->actorType = ENENCOUNT1_GET_TYPE(&this->actor); - this->unk_14C = ENENCOUNT1_GET_7C0(&this->actor); - this->unk_154 = ENENCOUNT1_GET_PATH(&this->actor); - this->unk_158 = this->actor.world.rot.x; - this->unk_15C = this->actor.world.rot.y; - this->unk_160 = (this->actor.world.rot.z * 40.0f) + 120.0f; + this->type = ENENCOUNT1_GET_TYPE(&this->actor); + this->spawnActiveMax = ENENCOUNT1_GET_SPAWN_ACTIVE_MAX(&this->actor); + this->spawnTotalMax = ENENCOUNT1_GET_SPAWN_TOTAL_MAX(&this->actor); + this->spawnTimeMin = ENENCOUNT1_GET_SPAWN_TIME_MIN(&this->actor); + this->spawnUnusedProp = ENENCOUNT1_GET_SPAWN_UNUSED_PROP(&this->actor); + this->spawnDistanceMax = (ENENCOUNT1_GET_SPAWN_DISTANCE_MAX(&this->actor) * 40.0f) + 120.0f; - if (this->unk_154 >= 0x3F) { - this->unk_154 = -1; + if (this->spawnTotalMax >= ENENCOUNT1_SPAWNS_TOTAL_MAX_INFINITE) { + this->spawnTotalMax = -1; } - if (this->actor.world.rot.z < 0) { - this->unk_160 = -1.0f; + if (ENENCOUNT1_GET_SPAWN_DISTANCE_MAX(&this->actor) < 0) { + this->spawnDistanceMax = -1.0f; } - if (this->actorType == EN_ENCOUNT1_SKULLFISH_2) { - this->unk_15A = ENENCOUNT1_GET_PATH(&this->actor); - this->path = SubS_GetPathByIndex(play, this->unk_15A, 0x3F); - this->unk_154 = -1; - this->unk_160 = -1.0f; + if (this->type == EN_ENCOUNT1_SKULLFISH_2) { + this->pathIndex = ENENCOUNT1_GET_PATH_INDEX(&this->actor); + this->path = SubS_GetPathByIndex(play, this->pathIndex, 0x3F); + this->spawnTotalMax = -1; + this->spawnDistanceMax = -1.0f; } this->actor.flags &= ~ACTOR_FLAG_1; - this->actionFunc = func_808E0954; + this->actionFunc = EnEncount1_SpawnActor; } -void func_808E0954(EnEncount1* this, PlayState* play) { +void EnEncount1_SpawnActor(EnEncount1* this, PlayState* play) { Player* player = GET_PLAYER(play); Vec3f spawnPos; - f32 sp64; - f32 temp_fv0_2; - s16 sp5E; - s16 actorList; + f32 scale; + f32 floorHeight; + s16 rotY; + s16 actorId; s32 actorParams; - CollisionPoly* sp54; - s32 sp50; + CollisionPoly* floorPoly; + s32 bgId; - if (((this->unk_14E >= this->unk_14C) || ((this->unk_160 > 0.0f) && (this->unk_160 < this->actor.xzDistToPlayer)) || - ((this->unk_154 > 0) && (this->unk_154 <= this->unk_152)))) { + if (((this->spawnActiveCount >= this->spawnActiveMax) || + ((this->spawnDistanceMax > 0.0f) && (this->spawnDistanceMax < this->actor.xzDistToPlayer)) || + ((this->spawnTotalMax > 0) && (this->spawnTotalMax <= this->spawnTotalCount)))) { return; - } else if (this->unk_156 != 0) { - this->unk_156++; - if (this->unk_156 < this->unk_158) { + } + + if (this->timer != 0) { + this->timer++; + if (this->timer < this->spawnTimeMin) { return; } } - this->unk_156 = 0; - switch (this->actorType) { + this->timer = 0; + switch (this->type) { case EN_ENCOUNT1_GRASSHOPPER: - sp64 = randPlusMinusPoint5Scaled(40.0f) + 200.0f; - sp5E = player->actor.shape.rot.y; - if (this->unk_14E & 1) { - sp5E = -sp5E; - sp64 = randPlusMinusPoint5Scaled(20.0f) + 100.0f; + scale = randPlusMinusPoint5Scaled(40.0f) + 200.0f; + rotY = player->actor.shape.rot.y; + if (this->spawnActiveCount & 1) { + rotY = -rotY; + scale = randPlusMinusPoint5Scaled(20.0f) + 100.0f; } - spawnPos.x = player->actor.world.pos.x + (Math_SinS(sp5E) * sp64) + randPlusMinusPoint5Scaled(40.0f); + spawnPos.x = player->actor.world.pos.x + (Math_SinS(rotY) * scale) + randPlusMinusPoint5Scaled(40.0f); spawnPos.y = player->actor.floorHeight + 120.0f; - spawnPos.z = player->actor.world.pos.z + (Math_CosS(sp5E) * sp64) + randPlusMinusPoint5Scaled(40.0f); - temp_fv0_2 = BgCheck_EntityRaycastFloor5(&play->colCtx, &sp54, &sp50, &this->actor, &spawnPos); - if ((temp_fv0_2 <= BGCHECK_Y_MIN) || + spawnPos.z = player->actor.world.pos.z + (Math_CosS(rotY) * scale) + randPlusMinusPoint5Scaled(40.0f); + floorHeight = BgCheck_EntityRaycastFloor5(&play->colCtx, &floorPoly, &bgId, &this->actor, &spawnPos); + if ((floorHeight <= BGCHECK_Y_MIN) || ((player->actor.depthInWater != BGCHECK_Y_MIN) && - (temp_fv0_2 < (player->actor.world.pos.y - player->actor.depthInWater)))) { + (floorHeight < (player->actor.world.pos.y - player->actor.depthInWater)))) { return; } - spawnPos.y = temp_fv0_2; + spawnPos.y = floorHeight; break; case EN_ENCOUNT1_WALLMASTER: @@ -114,36 +125,36 @@ void func_808E0954(EnEncount1* this, PlayState* play) { break; case EN_ENCOUNT1_SKULLFISH: - sp64 = randPlusMinusPoint5Scaled(250.0f) + 500.0f; - sp5E = player->actor.shape.rot.y; - spawnPos.x = player->actor.world.pos.x + Math_SinS(sp5E) * sp64 + randPlusMinusPoint5Scaled(40.0f); + scale = randPlusMinusPoint5Scaled(250.0f) + 500.0f; + rotY = player->actor.shape.rot.y; + spawnPos.x = player->actor.world.pos.x + (Math_SinS(rotY) * scale) + randPlusMinusPoint5Scaled(40.0f); spawnPos.y = player->actor.world.pos.y - Rand_ZeroFloat(20.0f); - spawnPos.z = player->actor.world.pos.z + (Math_CosS(sp5E) * sp64) + randPlusMinusPoint5Scaled(40.0f); - temp_fv0_2 = BgCheck_EntityRaycastFloor5(&play->colCtx, &sp54, &sp50, &this->actor, &spawnPos); - if ((!(player->stateFlags1 & 0x8000000) || (temp_fv0_2 <= (BGCHECK_Y_MIN)) || - (player->actor.depthInWater < temp_fv0_2))) { + spawnPos.z = player->actor.world.pos.z + (Math_CosS(rotY) * scale) + randPlusMinusPoint5Scaled(40.0f); + floorHeight = BgCheck_EntityRaycastFloor5(&play->colCtx, &floorPoly, &bgId, &this->actor, &spawnPos); + if (!(player->stateFlags1 & PLAYER_STATE1_8000000) || (floorHeight <= BGCHECK_Y_MIN) || + (player->actor.depthInWater < floorHeight)) { return; } break; case EN_ENCOUNT1_SKULLFISH_2: - if ((this->path != NULL) && (!SubS_CopyPointFromPath(this->path, 0, &spawnPos))) { + if ((this->path != NULL) && !SubS_CopyPointFromPath(this->path, 0, &spawnPos)) { Actor_Kill(&this->actor); } break; } - actorList = sActorList[this->actorType]; - actorParams = sActorParams[this->actorType]; - if (Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, actorList, spawnPos.x, spawnPos.y, spawnPos.z, 0, 0, 0, + actorId = sActorIds[this->type]; + actorParams = sActorParams[this->type]; + if (Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, actorId, spawnPos.x, spawnPos.y, spawnPos.z, 0, 0, 0, actorParams) != NULL) { - this->unk_14E++; - if (this->unk_154 > 0) { - this->unk_152++; + this->spawnActiveCount++; + if (this->spawnTotalMax > 0) { + this->spawnTotalCount++; } - if ((this->unk_14E >= this->unk_14C) && (this->unk_158 != 0)) { - this->unk_156 = 1; + if ((this->spawnActiveCount >= this->spawnActiveMax) && (this->spawnTimeMin != 0)) { + this->timer = 1; } } } diff --git a/src/overlays/actors/ovl_En_Encount1/z_en_encount1.h b/src/overlays/actors/ovl_En_Encount1/z_en_encount1.h index 52e0fb30c3..5c8e6db834 100644 --- a/src/overlays/actors/ovl_En_Encount1/z_en_encount1.h +++ b/src/overlays/actors/ovl_En_Encount1/z_en_encount1.h @@ -3,15 +3,22 @@ #include "global.h" +#define ENENCOUNT1_SPAWNS_TOTAL_MAX_INFINITE 63 // aka 0x3F, All bits set + #define ENENCOUNT1_GET_TYPE(thisx) (((thisx)->params >> 11) & 0x1F) -#define ENENCOUNT1_GET_7C0(thisx) (((thisx)->params >> 6) & 0x1F) -#define ENENCOUNT1_GET_PATH(thisx) ((thisx)->params & 0x3F) +#define ENENCOUNT1_GET_SPAWN_ACTIVE_MAX(thisx) (((thisx)->params >> 6) & 0x1F) +#define ENENCOUNT1_GET_SPAWN_TOTAL_MAX(thisx) ((thisx)->params & 0x3F) +#define ENENCOUNT1_GET_PATH_INDEX(thisx) ((thisx)->params & 0x3F) // Used only by EN_ENCOUNT1_SKULLFISH_2 which doesn't use SpawnTotalMax + +#define ENENCOUNT1_GET_SPAWN_TIME_MIN(thisx) ((thisx)->world.rot.x) // Time to wait between spawning +#define ENENCOUNT1_GET_SPAWN_UNUSED_PROP(thisx) ((thisx)->world.rot.y) // Unused spawn property +#define ENENCOUNT1_GET_SPAWN_DISTANCE_MAX(thisx) ((thisx)->world.rot.z) // Negative means infinite distance typedef enum EnEncount1Enemy { - /* 0x0 */ EN_ENCOUNT1_GRASSHOPPER, - /* 0x1 */ EN_ENCOUNT1_WALLMASTER, - /* 0x2 */ EN_ENCOUNT1_SKULLFISH, - /* 0x3 */ EN_ENCOUNT1_SKULLFISH_2, + /* 0 */ EN_ENCOUNT1_GRASSHOPPER, + /* 1 */ EN_ENCOUNT1_WALLMASTER, + /* 2 */ EN_ENCOUNT1_SKULLFISH, + /* 3 */ EN_ENCOUNT1_SKULLFISH_2, } EnEncount1Enemy; struct EnEncount1; @@ -22,16 +29,16 @@ typedef struct EnEncount1 { /* 0x000 */ Actor actor; /* 0x144 */ EnEncount1ActionFunc actionFunc; /* 0x148 */ Path* path; - /* 0x14C */ s16 unk_14C; - /* 0x14E */ s16 unk_14E; - /* 0x150 */ s16 actorType; - /* 0x152 */ s16 unk_152; - /* 0x154 */ s16 unk_154; - /* 0x156 */ s16 unk_156; - /* 0x158 */ s16 unk_158; - /* 0x15A */ s16 unk_15A; - /* 0x15C */ s32 unk_15C; - /* 0x160 */ f32 unk_160; + /* 0x14C */ s16 spawnActiveMax; + /* 0x14E */ s16 spawnActiveCount; + /* 0x150 */ s16 type; + /* 0x152 */ s16 spawnTotalCount; + /* 0x154 */ s16 spawnTotalMax; + /* 0x156 */ s16 timer; + /* 0x158 */ s16 spawnTimeMin; + /* 0x15A */ s16 pathIndex; + /* 0x15C */ s32 spawnUnusedProp; + /* 0x160 */ f32 spawnDistanceMax; } EnEncount1; // size = 0x164 #endif // Z_EN_ENCOUNT1_H diff --git a/src/overlays/actors/ovl_En_Grasshopper/z_en_grasshopper.h b/src/overlays/actors/ovl_En_Grasshopper/z_en_grasshopper.h index 8056253f63..11ed8a1308 100644 --- a/src/overlays/actors/ovl_En_Grasshopper/z_en_grasshopper.h +++ b/src/overlays/actors/ovl_En_Grasshopper/z_en_grasshopper.h @@ -6,6 +6,8 @@ #define EN_GRASSHOPPER_GET_TYPE(thisx) ((thisx)->params) +#define EN_GRASSHOPPER_PARAMS(type) (type) + struct EnGrasshopper; typedef void (*EnGrasshopperActionFunc)(struct EnGrasshopper*, PlayState*); diff --git a/src/overlays/actors/ovl_En_Pr2/z_en_pr2.c b/src/overlays/actors/ovl_En_Pr2/z_en_pr2.c index a1c2f3f4d4..1c76d59853 100644 --- a/src/overlays/actors/ovl_En_Pr2/z_en_pr2.c +++ b/src/overlays/actors/ovl_En_Pr2/z_en_pr2.c @@ -151,7 +151,7 @@ void EnPr2_Init(Actor* thisx, PlayState* play) { Actor* parent = this->actor.parent; if (parent->update != NULL) { - this->unk_1C8 = ((EnEncount1*)parent)->unk_15A; + this->unk_1C8 = ((EnEncount1*)parent)->pathIndex; this->path = SubS_GetPathByIndex(play, this->unk_1C8, 0x3F); this->unk_208 = parent->world.rot.z * 20.0f; if (this->unk_208 < 20.0f) { @@ -190,8 +190,8 @@ void EnPr2_Destroy(Actor* thisx, PlayState* play) { if (this->actor.parent != NULL) { EnEncount1* encount1 = (EnEncount1*)this->actor.parent; - if ((encount1->actor.update != NULL) && (encount1->unk_14E > 0)) { - encount1->unk_14E--; + if ((encount1->actor.update != NULL) && (encount1->spawnActiveCount > 0)) { + encount1->spawnActiveCount--; } } } diff --git a/src/overlays/actors/ovl_En_Pr2/z_en_pr2.h b/src/overlays/actors/ovl_En_Pr2/z_en_pr2.h index 617a5cc73b..bbcd28afd8 100644 --- a/src/overlays/actors/ovl_En_Pr2/z_en_pr2.h +++ b/src/overlays/actors/ovl_En_Pr2/z_en_pr2.h @@ -10,6 +10,8 @@ typedef void (*EnPr2ActionFunc)(struct EnPr2*, PlayState*); #define ENPR2_GET_F(thisx) ((thisx)->params & 0xF) #define ENPR2_GET_FF0(thisx) (((thisx)->params >> 4) & 0xFF) +#define ENPR2_PARAMS(paramF, paramFF0) (((paramF) & 0xF) | (((paramFF0) << 4) & 0xFF0)) + typedef struct EnPr2 { /* 0x000 */ Actor actor; /* 0x144 */ SkelAnime skelAnime; diff --git a/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.c b/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.c index 11860c20d5..a4b3f7cc69 100644 --- a/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.c +++ b/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.c @@ -191,8 +191,8 @@ void EnWallmas_Destroy(Actor* thisx, PlayState* play) { if (this->actor.parent != NULL) { EnEncount1* encount1 = (EnEncount1*)this->actor.parent; - if ((encount1->actor.update != NULL) && (encount1->unk_14E > 0)) { - encount1->unk_14E--; + if ((encount1->actor.update != NULL) && (encount1->spawnActiveCount > 0)) { + encount1->spawnActiveCount--; } } } diff --git a/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.h b/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.h index ceb1d18231..93dd632450 100644 --- a/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.h +++ b/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.h @@ -8,6 +8,8 @@ #define WALLMASTER_GET_SWITCH_FLAG(thisx) (((thisx)->params >> 8) & 0xFF) #define WALLMASTER_IS_FROZEN(thisx) ((thisx)->params & 0x80) +#define WALLMASTER_PARAMS(type, switchFlag, isFrozen) ((type) | (((switchFlag) << 8) & 0xFF) | (((isFrozen) << 7) & 0x80)) + /** * This type determines under what conditions the Wallmaster will drop from the ceiling. * - WALLMASTER_TYPE_TIMER_ONLY: These Wallmasters don't check for anything to determine diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index 4cb29f0dca..06d43ccade 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -6504,7 +6504,7 @@ 0x808E06B0:("DoorAna_Update",), 0x808E0704:("DoorAna_Draw",), 0x808E0830:("EnEncount1_Init",), - 0x808E0954:("func_808E0954",), + 0x808E0954:("EnEncount1_SpawnActor",), 0x808E0DA8:("EnEncount1_Update",), 0x808E0E40:("DemoTreLgt_Init",), 0x808E0EBC:("DemoTreLgt_Destroy",),