From d218c9be2313fa900b518310d8c9b715425455ef Mon Sep 17 00:00:00 2001 From: Tom Overton Date: Mon, 6 Dec 2021 15:52:18 -0800 Subject: [PATCH] En_Stream (unused water vortex from OoT) OK (#480) * En_Stream (unused water vortex from OoT) OK * Better names in EnStream_PlayerIsInRange * Enum for whether the player is in range --- spec | 3 +- .../actors/ovl_En_Stream/z_en_stream.c | 124 +++++++++++++++--- .../actors/ovl_En_Stream/z_en_stream.h | 25 +++- tools/disasm/functions.txt | 6 +- 4 files changed, 134 insertions(+), 24 deletions(-) diff --git a/spec b/spec index 5f1ca2c3fb..0008a93347 100644 --- a/spec +++ b/spec @@ -1723,8 +1723,7 @@ beginseg name "ovl_En_Stream" compress include "build/src/overlays/actors/ovl_En_Stream/z_en_stream.o" - include "build/data/ovl_En_Stream/ovl_En_Stream.data.o" - include "build/data/ovl_En_Stream/ovl_En_Stream.reloc.o" + include "build/src/overlays/actors/ovl_En_Stream/ovl_En_Stream_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_En_Stream/z_en_stream.c b/src/overlays/actors/ovl_En_Stream/z_en_stream.c index 8e72ac31c7..6f20e1bd5b 100644 --- a/src/overlays/actors/ovl_En_Stream/z_en_stream.c +++ b/src/overlays/actors/ovl_En_Stream/z_en_stream.c @@ -1,7 +1,7 @@ /* * File: z_en_stream.c * Overlay: ovl_En_Stream - * Description: + * Description: Unused water vortex from OoT */ #include "z_en_stream.h" @@ -15,9 +15,8 @@ void EnStream_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnStream_Update(Actor* thisx, GlobalContext* globalCtx); void EnStream_Draw(Actor* thisx, GlobalContext* globalCtx); -void EnStream_SetupAction(EnStream* this, EnStreamActionFunc actionFunc); +void EnStream_WaitForPlayer(EnStream* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Stream_InitVars = { ACTOR_EN_STREAM, ACTORCAT_BG, @@ -30,29 +29,122 @@ const ActorInit En_Stream_InitVars = { (ActorFunc)EnStream_Draw, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80965B20[] = { +static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 20, ICHAIN_STOP), }; -#endif +extern Gfx D_06000950[]; -extern InitChainEntry D_80965B20[]; +void EnStream_SetupAction(EnStream* this, EnStreamActionFunc actionFunc) { + this->actionFunc = actionFunc; +} -extern UNK_TYPE D_06000950; +void EnStream_Init(Actor* thisx, GlobalContext* globalCtx) { + EnStream* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Stream/EnStream_SetupAction.s") + this->size = EN_STREAM_SIZE(&this->actor); + Actor_ProcessInitChain(&this->actor, sInitChain); + if (this->size != EN_STREAM_SIZE_NORMAL && this->size == EN_STREAM_SIZE_SMALL) { + this->actor.scale.y = 0.01f; + } + EnStream_SetupAction(this, EnStream_WaitForPlayer); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Stream/EnStream_Init.s") +void EnStream_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Stream/EnStream_Destroy.s") +s32 EnStream_PlayerIsInRange(Vec3f* vortexWorldPos, Vec3f* playerWorldPos, Vec3f* posDifference, f32 vortexYScale) { + s32 ret = EN_STREAM_PLAYER_OUTSIDE_RANGE; + f32 smallConstant = 28.0f; + f32 upperBounds = 160 * vortexYScale * 50.0f; + f32 lowerBounds = 0 * vortexYScale * 50.0f; + f32 xzDist; + f32 range; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Stream/func_809656D4.s") + posDifference->x = playerWorldPos->x - vortexWorldPos->x; + posDifference->y = playerWorldPos->y - vortexWorldPos->y; + posDifference->z = playerWorldPos->z - vortexWorldPos->z; + xzDist = sqrtf(SQ(posDifference->x) + SQ(posDifference->z)); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Stream/func_809657F4.s") + if (lowerBounds <= posDifference->y && posDifference->y <= upperBounds) { + posDifference->y -= lowerBounds; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Stream/func_8096597C.s") + range = ((75.0f - smallConstant) * (posDifference->y / (upperBounds - lowerBounds))) + 28.0f; + if (xzDist <= range) { + ret = EN_STREAM_PLAYER_WITHIN_RANGE_INSIDE_VORTEX; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Stream/EnStream_Update.s") + if (posDifference->y <= lowerBounds && xzDist <= 28.0f) { + ret = EN_STREAM_PLAYER_WITHIN_RANGE_BELOW_VORTEX; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Stream/EnStream_Draw.s") + return ret; +} + +void EnStream_SuckPlayer(EnStream* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 pad48; + Vec3f posDifference; + f32 xzDist; + f32 yDistWithOffset; + s32 pad30[2]; + + if (EnStream_PlayerIsInRange(&this->actor.world.pos, &player->actor.world.pos, &posDifference, + this->actor.scale.y) != EN_STREAM_PLAYER_OUTSIDE_RANGE) { + xzDist = sqrtf(SQ(posDifference.x) + SQ(posDifference.z)); + yDistWithOffset = player->actor.world.pos.y - (this->actor.world.pos.y - 90.0f); + player->unk_B84 = Math_Atan2S(-posDifference.x, -posDifference.z); + if (xzDist > 3.0f) { + Math_SmoothStepToF(&player->unk_B80, 3.0f, 0.5f, xzDist, 0.0f); + } else { + player->unk_B80 = 0.0f; + Math_SmoothStepToF(&player->actor.world.pos.x, this->actor.world.pos.x, 0.5f, 3.0f, 0.0f); + Math_SmoothStepToF(&player->actor.world.pos.z, this->actor.world.pos.z, 0.5f, 3.0f, 0.0f); + } + if (yDistWithOffset > 0.0f) { + Math_SmoothStepToF(&player->actor.velocity.y, -3.0f, 0.7f, yDistWithOffset, 0.0f); + if (posDifference.y < -70.0f) { + player->stateFlags2 |= 0x80000000; + } + } + } else { + EnStream_SetupAction(this, EnStream_WaitForPlayer); + } +} + +void EnStream_WaitForPlayer(EnStream* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 pad; + Vec3f temp; + + if (EnStream_PlayerIsInRange(&this->actor.world.pos, &player->actor.world.pos, &temp, this->actor.scale.y) != + EN_STREAM_PLAYER_OUTSIDE_RANGE) { + EnStream_SetupAction(this, EnStream_SuckPlayer); + } +} + +void EnStream_Update(Actor* thisx, GlobalContext* globalCtx) { + EnStream* this = THIS; + + this->actionFunc(this, globalCtx); + func_800B8FE8(&this->actor, NA_SE_EV_WHIRLPOOL - SFX_FLAG); +} + +void EnStream_Draw(Actor* thisx, GlobalContext* globalCtx) { + u32 multipliedFrames; + u32 frames = globalCtx->gameplayFrames; + Gfx* gfx; + + OPEN_DISPS(globalCtx->state.gfxCtx); + func_8012C2DC(globalCtx->state.gfxCtx); + gfx = POLY_XLU_DISP; + gSPMatrix(&gfx[0], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + multipliedFrames = frames * 20; + gSPSegment(&gfx[1], 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, frames * 30, -multipliedFrames, 64, 64, 1, multipliedFrames, + -multipliedFrames, 64, 64)); + gSPDisplayList(&gfx[2], D_06000950); + POLY_XLU_DISP = &gfx[3]; + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Stream/z_en_stream.h b/src/overlays/actors/ovl_En_Stream/z_en_stream.h index 3166c4aa2e..3948b70c9a 100644 --- a/src/overlays/actors/ovl_En_Stream/z_en_stream.h +++ b/src/overlays/actors/ovl_En_Stream/z_en_stream.h @@ -3,14 +3,33 @@ #include "global.h" +/** + * Even in OoT, where this actor was used, every single instance of it had + * a params of 0x0000, so it's hard to know how they intended to use this. + * In the final game, only an EN_STREAM_SIZE of 1 does anything different. + */ +#define EN_STREAM_SIZE(thisx) ((thisx)->params & 0xFF) + +typedef enum { + /* 0 */ EN_STREAM_SIZE_NORMAL, + /* 1 */ EN_STREAM_SIZE_SMALL, +} EnStreamSize; + +typedef enum { + /* 0 */ EN_STREAM_PLAYER_OUTSIDE_RANGE, + /* 1 */ EN_STREAM_PLAYER_WITHIN_RANGE_INSIDE_VORTEX, + /* 2 */ EN_STREAM_PLAYER_WITHIN_RANGE_BELOW_VORTEX, +} EnStreamPlayerLocation; + struct EnStream; typedef void (*EnStreamActionFunc)(struct EnStream*, GlobalContext*); typedef struct EnStream { - /* 0x0000 */ Actor actor; - /* 0x0144 */ EnStreamActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x8]; + /* 0x000 */ Actor actor; + /* 0x144 */ EnStreamActionFunc actionFunc; + /* 0x148 */ s32 size; + /* 0x14C */ UNK_TYPE1 unk_14C[0x4]; } EnStream; // size = 0x150 extern const ActorInit En_Stream_InitVars; diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index 080711b1b3..5d062ebb9c 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -7888,9 +7888,9 @@ 0x80965650:("EnStream_SetupAction",), 0x8096565C:("EnStream_Init",), 0x809656C4:("EnStream_Destroy",), - 0x809656D4:("func_809656D4",), - 0x809657F4:("func_809657F4",), - 0x8096597C:("func_8096597C",), + 0x809656D4:("EnStream_PlayerIsInRange",), + 0x809657F4:("EnStream_SuckPlayer",), + 0x8096597C:("EnStream_WaitForPlayer",), 0x809659D0:("EnStream_Update",), 0x80965A04:("EnStream_Draw",), 0x80965BB0:("EnMm_SetupAction",),