diff --git a/assets/xml/objects/gameplay_keep.xml b/assets/xml/objects/gameplay_keep.xml index 121dcfe5e5..ca0aaeb3cc 100644 --- a/assets/xml/objects/gameplay_keep.xml +++ b/assets/xml/objects/gameplay_keep.xml @@ -1377,8 +1377,8 @@ - - + + diff --git a/include/functions.h b/include/functions.h index c79fc333f5..9d21eca01c 100644 --- a/include/functions.h +++ b/include/functions.h @@ -558,7 +558,7 @@ void EffectSsHitmark_SpawnFixedScale(PlayState* play, s32 type, Vec3f* pos); void EffectSsHitmark_SpawnCustomScale(PlayState* play, s32 type, s16 scale, Vec3f* pos); void EffectSsFhgFlash_SpawnShock(PlayState* play, Actor* actor, Vec3f* pos, s16 scale, u8 params); // void EffectSsKFire_Spawn(UNK_TYPE4 uParm1, Vec3f* pzParm2, Vec3f* pzParm3, Vec3f* pzParm4, UNK_TYPE2 param_5, UNK_TYPE1 param_6); -void EffectSsSolderSrchBall_Spawn(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 unused, s16* linkDetected, s16 drawFlag); +void EffectSsSolderSrchBall_Spawn(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale, s16* playerDetected, s16 params); void EffectSsKakera_Spawn(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* arg3, s16 gravity, s16 arg5, s16 arg6, s16 arg7, s16 arg8, s16 scale, s16 arg10, s16 arg11, s32 life, s16 colorIdx, s16 objId, Gfx* dList); // void EffectSsIcePiece_Spawn(UNK_TYPE4 uParm1, Vec3f* pzParm2, UNK_TYPE4 uParm3, Vec3f* pzParm4, Vec3f* param_5, UNK_TYPE4 param_6); // void EffectSsIcePiece_SpawnBurst(void); diff --git a/include/z64effect.h b/include/z64effect.h index dde996eb76..b4574592a0 100644 --- a/include/z64effect.h +++ b/include/z64effect.h @@ -257,7 +257,6 @@ typedef struct { /* 0x18 */ u8 unk18; // Always 1? } EffectSsOverlay; // size = 0x1C -//! TODO: Review reuse of vec/gfx/actor fields across all effects typedef struct EffectSs { /* 0x00 */ Vec3f pos; /* 0x0C */ Vec3f velocity; diff --git a/spec b/spec index 80141af9c4..2dce298d5b 100644 --- a/spec +++ b/spec @@ -1869,8 +1869,7 @@ beginseg name "ovl_Effect_Ss_Solder_Srch_Ball" compress include "build/src/overlays/effects/ovl_Effect_Ss_Solder_Srch_Ball/z_eff_ss_solder_srch_ball.o" - include "build/data/ovl_Effect_Ss_Solder_Srch_Ball/ovl_Effect_Ss_Solder_Srch_Ball.data.o" - include "build/data/ovl_Effect_Ss_Solder_Srch_Ball/ovl_Effect_Ss_Solder_Srch_Ball.reloc.o" + include "build/src/overlays/effects/ovl_Effect_Ss_Solder_Srch_Ball/ovl_Effect_Ss_Solder_Srch_Ball_reloc.o" endseg beginseg diff --git a/src/code/z_effect_soft_sprite_old_init.c b/src/code/z_effect_soft_sprite_old_init.c index 5fc51b0c33..bbdd528a4a 100644 --- a/src/code/z_effect_soft_sprite_old_init.c +++ b/src/code/z_effect_soft_sprite_old_init.c @@ -702,16 +702,16 @@ void EffectSsKFire_Spawn(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* ac // EffectSsSolderSrchBall Spawn Functions -void EffectSsSolderSrchBall_Spawn(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 unused, - s16* linkDetected, s16 drawFlag) { +void EffectSsSolderSrchBall_Spawn(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale, + s16* playerDetected, s16 flags) { EffectSsSolderSrchBallInitParams initParams; Math_Vec3f_Copy(&initParams.pos, pos); Math_Vec3f_Copy(&initParams.velocity, velocity); Math_Vec3f_Copy(&initParams.accel, accel); - initParams.unused = unused; - initParams.linkDetected = linkDetected; - initParams.drawFlag = drawFlag; + initParams.scale = scale; + initParams.playerDetected = playerDetected; + initParams.flags = flags; EffectSs_Spawn(play, EFFECT_SS_SOLDER_SRCH_BALL, 128, &initParams); } diff --git a/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c b/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c index 12da392887..10b72634a2 100644 --- a/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c +++ b/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c @@ -508,7 +508,7 @@ void DemoKakyo_DrawLostWoodsSparkle(Actor* thisx, PlayState* play2) { POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 20); gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(gSun1Tex)); - gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_07AB10); + gSPDisplayList(POLY_XLU_DISP++, gSunSparkleMaterialDL); for (i = 0; i < play->envCtx.unk_F2[3]; i++) { worldPos.x = this->effects[i].posBase.x + this->effects[i].posOffset.x; @@ -575,7 +575,7 @@ void DemoKakyo_DrawLostWoodsSparkle(Actor* thisx, PlayState* play2) { gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_07AB58); + gSPDisplayList(POLY_XLU_DISP++, gSunSparkleModelDL); } } diff --git a/src/overlays/actors/ovl_En_Encount2/z_en_encount2.c b/src/overlays/actors/ovl_En_Encount2/z_en_encount2.c index d771f3511c..b7c698376a 100644 --- a/src/overlays/actors/ovl_En_Encount2/z_en_encount2.c +++ b/src/overlays/actors/ovl_En_Encount2/z_en_encount2.c @@ -279,14 +279,14 @@ void EnEncount2_DrawEffects(EnEncount2* this, PlayState* play) { Matrix_Scale(sPtr->scale, sPtr->scale, sPtr->scale, MTXMODE_APPLY); POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 20); gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(gSun1Tex)); - gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_07AB10); + gSPDisplayList(POLY_XLU_DISP++, gSunSparkleMaterialDL); gDPPipeSync(POLY_XLU_DISP++); gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, 255); gDPSetEnvColor(POLY_XLU_DISP++, 250, 180, 255, sPtr->alpha); Matrix_Mult(&play->billboardMtxF, MTXMODE_APPLY); Matrix_RotateZF(DEGF_TO_RADF(play->state.frames * 20.0f), MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_07AB58); + gSPDisplayList(POLY_XLU_DISP++, gSunSparkleModelDL); } } CLOSE_DISPS(gfxCtx); diff --git a/src/overlays/actors/ovl_En_Hanabi/z_en_hanabi.c b/src/overlays/actors/ovl_En_Hanabi/z_en_hanabi.c index f9085e8253..0f016f3004 100644 --- a/src/overlays/actors/ovl_En_Hanabi/z_en_hanabi.c +++ b/src/overlays/actors/ovl_En_Hanabi/z_en_hanabi.c @@ -146,7 +146,7 @@ void func_80B22FA8(EnHanabiStruct* arg0, PlayState* play2) { POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 20); gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(gSun1Tex)); - gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_07AB10); + gSPDisplayList(POLY_XLU_DISP++, gSunSparkleMaterialDL); sp53 = 0xFF; if (sp53) {} @@ -181,7 +181,7 @@ void func_80B22FA8(EnHanabiStruct* arg0, PlayState* play2) { D_80B23C2C[arg0->unk_02 + 2], 255); } - gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_07AB58); + gSPDisplayList(POLY_XLU_DISP++, gSunSparkleModelDL); } } diff --git a/src/overlays/actors/ovl_En_Look_Nuts/z_en_look_nuts.c b/src/overlays/actors/ovl_En_Look_Nuts/z_en_look_nuts.c index de053c46a8..6fd949febe 100644 --- a/src/overlays/actors/ovl_En_Look_Nuts/z_en_look_nuts.c +++ b/src/overlays/actors/ovl_En_Look_Nuts/z_en_look_nuts.c @@ -5,6 +5,7 @@ */ #include "z_en_look_nuts.h" +#include "overlays/effects/ovl_Effect_Ss_Solder_Srch_Ball/z_eff_ss_solder_srch_ball.h" #define FLAGS (ACTOR_FLAG_80000000) @@ -340,13 +341,14 @@ void EnLookNuts_Update(Actor* thisx, PlayState* play) { Matrix_MultVec3f(&effectVelOffset, &effectVel); Matrix_Pop(); if (!this->isPlayerDetected) { - s16 drawFlag = 1; + s16 effectFlags = SOLDERSRCHBALL_INVISIBLE; + if (gSaveContext.save.isNight) { - drawFlag = 0; + effectFlags = 0; } if (Player_GetMask(play) != PLAYER_MASK_STONE) { EffectSsSolderSrchBall_Spawn(play, &effectPos, &effectVel, &gZeroVec3f, 50, &this->isPlayerDetected, - drawFlag); + effectFlags); } } diff --git a/src/overlays/actors/ovl_En_Suttari/z_en_suttari.c b/src/overlays/actors/ovl_En_Suttari/z_en_suttari.c index bbce2ee6ca..4f3882aa7f 100644 --- a/src/overlays/actors/ovl_En_Suttari/z_en_suttari.c +++ b/src/overlays/actors/ovl_En_Suttari/z_en_suttari.c @@ -7,6 +7,7 @@ #include "z_en_suttari.h" #include "overlays/actors/ovl_En_Elf/z_en_elf.h" #include "overlays/actors/ovl_En_Door/z_en_door.h" +#include "overlays/effects/ovl_Effect_Ss_Solder_Srch_Ball/z_eff_ss_solder_srch_ball.h" #include "objects/object_boj/object_boj.h" #define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) @@ -444,12 +445,13 @@ void func_80BAAFDC(EnSuttari* this, PlayState* play) { effectVelOffset.z = 20.0f; Matrix_MultVec3f(&effectVelOffset, &effectVel); Matrix_Pop(); - if (this->unk3F0 == 0) { - EffectSsSolderSrchBall_Spawn(play, &effectPos, &effectVel, &gZeroVec3f, 50, &this->unk3F0, 1); + if (!this->playerDetected) { + EffectSsSolderSrchBall_Spawn(play, &effectPos, &effectVel, &gZeroVec3f, 50, &this->playerDetected, + SOLDERSRCHBALL_INVISIBLE); } - if (this->unk3F0 == 1) { + if (this->playerDetected == true) { play_sound(NA_SE_SY_FOUND); - this->unk3F0 = 0; + this->playerDetected = false; this->actor.speedXZ = 0.0f; if (this->unk1F4[0] != 0) { this->unk1F4[0]--; @@ -476,12 +478,13 @@ void func_80BAB1A0(EnSuttari* this, PlayState* play) { effectVelOffset.z = 20.0f; Matrix_MultVec3f(&effectVelOffset, &effectVel); Matrix_Pop(); - if (this->unk3F0 == 0) { - EffectSsSolderSrchBall_Spawn(play, &effectPos, &effectVel, &gZeroVec3f, 50, &this->unk3F0, 1); + if (!this->playerDetected) { + EffectSsSolderSrchBall_Spawn(play, &effectPos, &effectVel, &gZeroVec3f, 50, &this->playerDetected, + SOLDERSRCHBALL_INVISIBLE); } - if (this->unk3F0 == 1) { + if (this->playerDetected == true) { play_sound(NA_SE_SY_FOUND); - this->unk3F0 = 0; + this->playerDetected = false; this->actor.speedXZ = 0.0f; if (this->unk1F4[0] != 0) { this->unk1F4[0]--; diff --git a/src/overlays/actors/ovl_En_Suttari/z_en_suttari.h b/src/overlays/actors/ovl_En_Suttari/z_en_suttari.h index 35a9b6e2e4..427f74988f 100644 --- a/src/overlays/actors/ovl_En_Suttari/z_en_suttari.h +++ b/src/overlays/actors/ovl_En_Suttari/z_en_suttari.h @@ -34,7 +34,7 @@ typedef struct EnSuttari { /* 0x2FA */ s16 unk2FA[16]; /* 0x31A */ s16 unk31A[16]; /* 0x33A */ UNK_TYPE1 unk_33A[0xB6]; - /* 0x3F0 */ s16 unk3F0; + /* 0x3F0 */ s16 playerDetected; /* 0x3F2 */ s16 unk3F2; /* 0x3F4 */ s16 unk3F4; /* 0x3F6 */ s16 unk3F6; diff --git a/src/overlays/effects/ovl_Effect_Ss_Solder_Srch_Ball/z_eff_ss_solder_srch_ball.c b/src/overlays/effects/ovl_Effect_Ss_Solder_Srch_Ball/z_eff_ss_solder_srch_ball.c index 04afcba3f5..01224dd329 100644 --- a/src/overlays/effects/ovl_Effect_Ss_Solder_Srch_Ball/z_eff_ss_solder_srch_ball.c +++ b/src/overlays/effects/ovl_Effect_Ss_Solder_Srch_Ball/z_eff_ss_solder_srch_ball.c @@ -1,27 +1,93 @@ /* * File: z_eff_ss_solder_srch_ball.c * Overlay: ovl_Effect_Ss_Solder_Srch_Ball - * Description: + * Description: Vision sphere */ #include "z_eff_ss_solder_srch_ball.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define rFlags regs[0] #define PARAMS ((EffectSsSolderSrchBallInitParams*)initParamsx) -s32 EffectSsSolderSrchBall_Init(PlayState* play, u32 index, EffectSs* this, void* initParamsx); +u32 EffectSsSolderSrchBall_Init(PlayState* play, u32 index, EffectSs* this, void* initParamsx); void EffectSsSolderSrchBall_Update(PlayState* play, u32 index, EffectSs* this); void EffectSsSolderSrchBall_Draw(PlayState* play, u32 index, EffectSs* this); -#if 0 const EffectSsInit Effect_Ss_Solder_Srch_Ball_InitVars = { EFFECT_SS_SOLDER_SRCH_BALL, EffectSsSolderSrchBall_Init, }; -#endif +u32 EffectSsSolderSrchBall_Init(PlayState* play, u32 index, EffectSs* this, void* initParamsx) { + EffectSsSolderSrchBallInitParams* initParams = PARAMS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Solder_Srch_Ball/EffectSsSolderSrchBall_Init.s") + this->pos = initParams->pos; + this->velocity = initParams->velocity; + this->accel = initParams->accel; + this->update = EffectSsSolderSrchBall_Update; + if (!(initParams->flags & SOLDERSRCHBALL_INVISIBLE)) { + this->draw = EffectSsSolderSrchBall_Draw; + } + this->life = 10; + this->rgScale = initParams->scale; + this->rFlags = initParams->flags; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Solder_Srch_Ball/EffectSsSolderSrchBall_Draw.s") + //! @bug actor field used to store an s16* + // This bug is purely cosmetic. Nothing external will ever read this as an Actor, so there are no unintended + // side-effects. + this->actor = (Actor*)initParams->playerDetected; + return 1; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Solder_Srch_Ball/EffectSsSolderSrchBall_Update.s") +void EffectSsSolderSrchBall_Draw(PlayState* play, u32 index, EffectSs* this) { + s32 pad; + GraphicsContext* gfxCtx = play->state.gfxCtx; + f32 scale = this->rgScale / 100.0f; + + func_8012C28C(gfxCtx); + func_8012C2DC(play->state.gfxCtx); + + OPEN_DISPS(gfxCtx); + + Matrix_Translate(this->pos.x, this->pos.y, this->pos.z, MTXMODE_NEW); + Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); + POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 20); + gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(gSun1Tex)); + gSPDisplayList(POLY_XLU_DISP++, gSunSparkleMaterialDL); + gDPPipeSync(POLY_XLU_DISP++); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, 255); + gDPSetEnvColor(POLY_XLU_DISP++, 250, 180, 255, 255); + Matrix_Mult(&play->billboardMtxF, MTXMODE_APPLY); + Matrix_RotateZF(DEGF_TO_RADF(20.0f * play->state.frames), MTXMODE_APPLY); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gSunSparkleModelDL); + + CLOSE_DISPS(gfxCtx); +} + +void EffectSsSolderSrchBall_Update(PlayState* play, u32 index, EffectSs* this) { + s32 pad; + f32 diffX; + f32 diffY; + f32 diffZ; + s16* playerDetected = (s16*)this->actor; + Player* player = GET_PLAYER(play); + + diffX = player->actor.world.pos.x - this->pos.x; + diffY = player->actor.world.pos.y - this->pos.y; + diffZ = player->actor.world.pos.z - this->pos.z; + + if (this->rFlags >= SOLDERSRCHBALL_SMALL_DETECT_RADIUS) { + if ((sqrtf(SQ(diffX) + SQ(diffZ)) < 10.0f) && (sqrtf(SQ(diffY)) < 10.0f)) { + *playerDetected = true; + } + } else if (!BgCheck_SphVsFirstWall(&play->colCtx, &this->pos, 30.0f)) { + if ((sqrtf(SQ(diffX) + SQ(diffZ)) < 40.0f) && (sqrtf(SQ(diffY)) < 80.0f)) { + *playerDetected = true; + } + } else if (this->life > 1) { + this->life = 1; + } +} diff --git a/src/overlays/effects/ovl_Effect_Ss_Solder_Srch_Ball/z_eff_ss_solder_srch_ball.h b/src/overlays/effects/ovl_Effect_Ss_Solder_Srch_Ball/z_eff_ss_solder_srch_ball.h index 24b9f47fcc..fb4fb4159c 100644 --- a/src/overlays/effects/ovl_Effect_Ss_Solder_Srch_Ball/z_eff_ss_solder_srch_ball.h +++ b/src/overlays/effects/ovl_Effect_Ss_Solder_Srch_Ball/z_eff_ss_solder_srch_ball.h @@ -3,13 +3,16 @@ #include "global.h" +#define SOLDERSRCHBALL_INVISIBLE (1 << 0) +#define SOLDERSRCHBALL_SMALL_DETECT_RADIUS (1 << 1) + typedef struct { /* 0x00 */ Vec3f pos; /* 0x0C */ Vec3f velocity; /* 0x18 */ Vec3f accel; - /* 0x24 */ s16 unused; - /* 0x28 */ s16* linkDetected; - /* 0x2C */ s16 drawFlag; + /* 0x24 */ s16 scale; + /* 0x28 */ s16* playerDetected; + /* 0x2C */ s16 flags; } EffectSsSolderSrchBallInitParams; // size = 0x30 extern const EffectSsInit Effect_Ss_Solder_Srch_Ball_InitVars;