diff --git a/assets/xml/overlays/ovl_En_Clear_Tag/ovl_En_Clear_Tag.xml b/assets/xml/overlays/ovl_En_Clear_Tag/ovl_En_Clear_Tag.xml new file mode 100644 index 0000000000..cc2ea94dbd --- /dev/null +++ b/assets/xml/overlays/ovl_En_Clear_Tag/ovl_En_Clear_Tag.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/extract_assets.py b/extract_assets.py index cc77f08b17..24e4b66535 100755 --- a/extract_assets.py +++ b/extract_assets.py @@ -34,8 +34,11 @@ def ExtractFunc(fullPath): objectName = os.path.splitext(xmlName)[0] outPath = os.path.join("assets", *pathList[2:-1], objectName) - basromPath = os.path.join("baserom", "assets", *pathList[2:-1]) outSourcePath = outPath + if "overlays" in pathList: + basromPath = os.path.join("baserom", *pathList[2:-1]) + else: + basromPath = os.path.join("baserom", "assets", *pathList[2:-1]) ## MM doesn't have _scene prefixed files, so this check is not necessary. ## This _may_ change in the future, so I wont delete this for now. diff --git a/include/PR/mbi.h b/include/PR/mbi.h index 0f8503d1f6..2f88d6ef46 100644 --- a/include/PR/mbi.h +++ b/include/PR/mbi.h @@ -49,8 +49,6 @@ #define _SHIFTR(v, s, w) \ ((unsigned int)(((unsigned int)(v) >> (s)) & ((0x01 << (w)) - 1))) -#define _SHIFT _SHIFTL /* old, for compatibility only */ - #define G_ON (1) #define G_OFF (0) diff --git a/include/functions.h b/include/functions.h index 14c3fc257c..39251b16cf 100644 --- a/include/functions.h +++ b/include/functions.h @@ -787,7 +787,7 @@ float func_800B6FC8(Player* player); u32 func_800B7200(s32 param_1); // void func_800B722C(void); void func_800B724C(GlobalContext* globalCtx, Actor* actor, u8 param_3); -u32 func_800B7298(GlobalContext* globalCtx, UNK_TYPE4 param_2, u8 param_3); +u32 func_800B7298(GlobalContext* globalCtx, Actor* actor, u8 param_3); void func_800B72E0(s32 param_1); void func_800B72F8(DynaPolyActor* dpactor, f32 a1, s16 a2); s32 Actor_IsLinkFacingActor(Actor* actor, s16 tolerance, GlobalContext* globalCtx); @@ -1007,7 +1007,7 @@ f32 func_800C411C(CollisionContext* colCtx, CollisionPoly** arg1, s32* arg2, Act // void func_800C4488(void); // void func_800C44F0(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); // void func_800C455C(void); -s32 func_800C45C4(CollisionContext* colCtx, u32 param_2, Vec3f* param_3, Vec3f* param_4, Vec3f* param_5, f32 param_6, s32* param_7, s32* param_8, DynaPolyActor* param_9, f32 param_10, u8 param_11); +s32 func_800C45C4(CollisionContext* colCtx, u32 arg1, Vec3f* arg2, Vec3f* arg3, Vec3f* arg4, f32 arg5, s32* arg6, s32* arg7, DynaPolyActor* arg8, f32 arg9, u8 arg10); // void func_800C4C74(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6, UNK_TYPE4 param_7); // void func_800C4CD8(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6, UNK_TYPE4 param_7, UNK_TYPE4 param_8); // void func_800C4D3C(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6, UNK_TYPE4 param_7, UNK_TYPE4 param_8, UNK_TYPE4 param_9); @@ -1019,23 +1019,23 @@ s32 func_800C45C4(CollisionContext* colCtx, u32 param_2, Vec3f* param_3, Vec3f* // void func_800C5464(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); // void func_800C54AC(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6, UNK_TYPE4 param_7, UNK_TYPE4 param_8, UNK_TYPE4 param_9, UNK_TYPE4 param_10); // void func_800C5538(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6, UNK_TYPE4 param_7, UNK_TYPE4 param_8, UNK_TYPE4 param_9, UNK_TYPE4 param_10); -s32 func_800C55C4(CollisionContext*, Vec3f*, Vec3f*, Vec3f*, CollisionPoly**, u32, u32, u32, u32, u32*); +s32 func_800C55C4(CollisionContext* colCtx, Vec3f* arg1, Vec3f* arg2, Vec3f* arg3, CollisionPoly** arg4, u32 arg5, u32 arg6, u32 arg7, u32 arg8, u32* arg9); // void func_800C5650(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6, UNK_TYPE4 param_7, UNK_TYPE4 param_8, UNK_TYPE4 param_9, UNK_TYPE4 param_10, UNK_TYPE4 param_11); // void func_800C56E0(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6, UNK_TYPE4 param_7, UNK_TYPE4 param_8, UNK_TYPE4 param_9, UNK_TYPE4 param_10, UNK_TYPE4 param_11, UNK_TYPE4 param_12); -s32 func_800C576C(CollisionContext*, Vec3f*, Vec3f*, Vec3f*, CollisionPoly**, u32, u32, u32, u32, u32*); +s32 func_800C576C(CollisionContext* colCtx, Vec3f* arg1, Vec3f* arg2, Vec3f* arg3, CollisionPoly** arg4, u32 arg5, u32 arg6, u32 arg7, u32 arg8, u32* arg9); // void func_800C57F8(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6); // void func_800C583C(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6, UNK_TYPE4 param_7, UNK_TYPE4 param_8, UNK_TYPE4 param_9); // void func_800C58C8(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6, UNK_TYPE4 param_7, UNK_TYPE4 param_8, UNK_TYPE4 param_9, UNK_TYPE4 param_10); // void func_800C5954(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6, UNK_TYPE4 param_7, UNK_TYPE2 param_8); -// void func_800C5A20(void); +s32 func_800C5A20(CollisionContext* colCtx, Vec3f* arg1, f32 arg2); // void func_800C5A64(void); -void BgCheck_ScenePolygonListsInit(SSNodeList* param_1); +void BgCheck_ScenePolygonListsInit(SSNodeList* arg0); void BgCheck_ScenePolygonListsAlloc(GlobalContext* globalCtx, SSNodeList* lists, s32 numNodes, u32 numPolygons); -s32 func_800C5B80(u16* param_1); +s32 func_800C5B80(u16* arg0); u16 BgCheck_ScenePolygonListsReserveNode(SSNodeList* lists); void BgCheck_ActorMeshParamsInit(ScaleRotPos* params); void BgCheck_SetActorMeshParams(ScaleRotPos* params, Vec3f* scale, Vec3s* rotation, Vec3f* position); -s32 BgCheck_AreActorMeshParamsEqual(ScaleRotPos* param_1, ScaleRotPos* param_2); +s32 BgCheck_AreActorMeshParamsEqual(ScaleRotPos* arg0, ScaleRotPos* arg1); void BgCheck_ActorMeshPolyListsHeadsInit(DynaLookup* lists); void BgCheck_ActorMeshPolyListsInit(DynaLookup* lists); void BgCheck_ActorMeshVerticesIndexInit(s16* index); @@ -1120,7 +1120,7 @@ u32 func_800C9E18(CollisionContext* colCtx, CollisionPoly* polygon, s32 index); u32 func_800C9E40(CollisionContext* colCtx, CollisionPoly* polygon, s32 index); u32 func_800C9E88(CollisionContext* colCtx, CollisionPoly* polygon, s32 index); // void func_800C9EBC(GlobalContext* globalCtx, CollisionContext* colCtx, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6, UNK_TYPE4 param_7); -// void func_800CA1AC(GlobalContext* globalCtx, CollisionContext* colCtx, f32 param_3, f32 param_4, f32* param_5, UNK_PTR param_6); +s32 func_800CA1AC(GlobalContext* globalCtx, CollisionContext* colCtx, f32 x, f32 z, f32* ySurface, WaterBox** outWaterBox); void func_800CA1E8(GlobalContext* globalCtx, CollisionContext* colCtx, f32 arg2, f32 arg3, f32* arg4, UNK_PTR arg5); // void func_800CA22C(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6); // void func_800CA568(void); @@ -3051,10 +3051,10 @@ s32 func_8016970C(GlobalContext* globalCtx, s16 camId, Vec3f* at, Vec3f* eye); // void func_8016981C(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); // void func_80169940(void); // void func_80169988(void); -void func_801699D4(GlobalContext* globalCtx, s16 param_2, s16 param_3); +void func_801699D4(GlobalContext* globalCtx, s16 arg1, s16 arg2); // void func_80169A50(void); // void func_80169AC0(void); -// void func_80169AFC(void); +void func_80169AFC(GlobalContext* globalCtx, s16 camId, s16 arg2); // void func_80169C64(void); // void func_80169C84(void); // void convert_scene_number_among_shared_scenes(void); @@ -3396,7 +3396,7 @@ void SysMatrix_SetCurrentState(MtxF* matrix); MtxF* SysMatrix_GetCurrentState(void); void SysMatrix_InsertMatrix(MtxF* matrix, s32 appendToState); void SysMatrix_InsertTranslation(f32 x, f32 y, f32 z, s32 appendToState); -void Matrix_Scale(f32 xScale, f32 yScale, f32 zScale, u8 appendToState); +void Matrix_Scale(f32 xScale, f32 yScale, f32 zScale, s32 appendToState); void SysMatrix_InsertXRotation_s(s16 rotation, s32 appendToState); void SysMatrix_InsertXRotation_f(f32 rotation, s32 appendToState); void SysMatrix_RotateStateAroundXAxis(f32 rotation); @@ -3876,7 +3876,7 @@ void func_8019FAD8(Vec3f* param_1, u16 param_2, f32 param_3); // void func_8019FC20(void); // void func_8019FCB8(void); // void func_8019FD90(void); -// void func_8019FDC8(void); +void func_8019FDC8(UNK_PTR arg0, u16 sfxId, UNK_TYPE arg2); // void func_8019FE1C(void); // void func_8019FE74(void); // void func_8019FEDC(void); diff --git a/include/variables.h b/include/variables.h index e95d3d7af1..7f62cae1a0 100644 --- a/include/variables.h +++ b/include/variables.h @@ -1878,7 +1878,7 @@ extern UNK_PTR D_801DB478[7]; // extern UNK_TYPE1 D_801DB494; // extern UNK_TYPE1 D_801DB49C; // extern UNK_TYPE2 D_801DB4A0; -// extern UNK_TYPE4 D_801DB4A4; +extern UNK_TYPE D_801DB4A4; // extern UNK_TYPE1 D_801DB4B0; // extern UNK_TYPE1 D_801DB4B8; // extern UNK_TYPE1 D_801DB4C0; diff --git a/include/z64.h b/include/z64.h index 1e67fbffdf..4048080d5b 100644 --- a/include/z64.h +++ b/include/z64.h @@ -490,20 +490,6 @@ typedef struct { /* 0x0 */ Vec3s pos; } BgVertex; // size = 0x6 -typedef struct { - /* 0x0 */ Vec3s minPos; - /* 0x6 */ UNK_TYPE1 xLength; // Created by retype action - /* 0x7 */ UNK_TYPE1 pad7[0x1]; - /* 0x8 */ UNK_TYPE1 zLength; // Created by retype action - /* 0x9 */ UNK_TYPE1 pad9[0x3]; - /* 0xC */ u32 properties; -} BgWaterBox; // size = 0x10 - -typedef struct { - /* 0x0 */ UNK_TYPE1 pad0[0x4]; - /* 0x4 */ BgWaterBox* boxes; -} BgWaterboxList; // size = 0x8 - typedef union { F3DVertexColor color; F3DVertexNormal normal; diff --git a/include/z64actor.h b/include/z64actor.h index 7952ca3e17..71378f7ab9 100644 --- a/include/z64actor.h +++ b/include/z64actor.h @@ -1000,4 +1000,14 @@ typedef enum { /* 0x2B2 */ ACTOR_ID_MAX // originally "ACTOR_DLF_MAX" } ActorID; +typedef enum { + /* 0x00 */ CLEAR_TAG_SMALL_EXPLOSION, + /* 0x01 */ CLEAR_TAG_LARGE_EXPLOSION, + /* 0x02 */ CLEAR_TAG_POP, + /* 0x03 */ CLEAR_TAG_SMALL_LIGHT_RAYS, + /* 0x04 */ CLEAR_TAG_LARGE_LIGHT_RAYS, + /* 0x23 */ CLEAR_TAG_SPLASH = 35, + /* 0xC8 */ CLEAR_TAG_SMOKE = 200, +} ClearTagType; + #endif diff --git a/linker_scripts/code_script.txt b/linker_scripts/code_script.txt index 967e7413db..b81b39eabd 100644 --- a/linker_scripts/code_script.txt +++ b/linker_scripts/code_script.txt @@ -2410,9 +2410,9 @@ SECTIONS ovl_En_Clear_Tag : AT(RomLocation) { build/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.o(.text) - build/asm/overlays/ovl_En_Clear_Tag_data.o(.data) + build/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.o(.data) build/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.o(.rodata) - build/asm/overlays/ovl_En_Clear_Tag_rodata.o(.rodata) + build/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag_overlay.o(.ovl) } SegmentEnd = .; SegmentSize = SegmentEnd - SegmentStart; diff --git a/linker_scripts/object_script.txt b/linker_scripts/object_script.txt index 896e0ddcbf..fdb775b6ef 100644 --- a/linker_scripts/object_script.txt +++ b/linker_scripts/object_script.txt @@ -11,6 +11,16 @@ D_04029CB0 = 0x04029CB0; D_04029CF0 = 0x04029CF0; D_04029CB0 = 0x04029CB0; D_04029CF0 = 0x04029CF0; +D_04030100 = 0x04030100; +D_040378F0 = 0x040378F0; +D_04037DF0 = 0x04037DF0; +D_040382F0 = 0x040382F0; +D_040387F0 = 0x040387F0; +D_04038CF0 = 0x04038CF0; +D_040391F0 = 0x040391F0; +D_040396F0 = 0x040396F0; +D_04039BF0 = 0x04039BF0; +D_0403A0F0 = 0x0403A0F0; D_04058BA0 = 0x04058BA0; D_0405AAB0 = 0x0405AAB0; D_0405BEF0 = 0x0405BEF0; diff --git a/src/overlays/actors/ovl_Dm_Nb/z_dm_nb.c b/src/overlays/actors/ovl_Dm_Nb/z_dm_nb.c index 742b89dc06..7dec3fcf6a 100644 --- a/src/overlays/actors/ovl_Dm_Nb/z_dm_nb.c +++ b/src/overlays/actors/ovl_Dm_Nb/z_dm_nb.c @@ -32,7 +32,7 @@ extern AnimationHeader D_06000990; extern FlexSkeletonHeader D_06008C40; // Probably the same struct as ActorAnimationEntryS, need more info from func_8013BC6C -static ActorAnimationEntryS D_80C1E200[] = { &D_06000990, 1.0f, 0, -1, 0, 0}; +static ActorAnimationEntryS D_80C1E200[] = { &D_06000990, 1.0f, 0, -1, 0, 0 }; s32 func_80C1DED0(DmNb* this, s32 arg1) { s32 ret = 0; diff --git a/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c b/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c index c17cfe4505..43eedf37ca 100644 --- a/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c +++ b/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c @@ -1,3 +1,9 @@ +/* + * File z_en_clear_tag.c + * Overlay: ovl_en_clear_tag + * Description: Various effects: explosions and pops, splashes, light rays + */ + #include "z_en_clear_tag.h" #define FLAGS 0x00000035 @@ -9,7 +15,9 @@ void EnClearTag_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnClearTag_Update(Actor* thisx, GlobalContext* globalCtx); void EnClearTag_Draw(Actor* thisx, GlobalContext* globalCtx); -/* +void EnClearTag_UpdateEffects(EnClearTag* this, GlobalContext* globalCtx); +void EnClearTag_DrawEffects(Actor* thisx, GlobalContext* globalCtx); + const ActorInit En_Clear_Tag_InitVars = { ACTOR_EN_CLEAR_TAG, ACTORCAT_ITEMACTION, @@ -21,34 +29,979 @@ const ActorInit En_Clear_Tag_InitVars = { (ActorFunc)EnClearTag_Update, (ActorFunc)EnClearTag_Draw, }; -*/ -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Clear_Tag_0x80947F60/func_80947F60.asm") +extern Gfx D_04030100[]; // Floor shockwave ring +extern Gfx D_040378F0[]; // gExplosionSplashTex1 +extern Gfx D_04037DF0[]; // gExplosionSplashTex2 +extern Gfx D_040382F0[]; // gExplosionSplashTex3 +extern Gfx D_040387F0[]; // gExplosionSplashTex4 +extern Gfx D_04038CF0[]; // gExplosionSplashTex5 +extern Gfx D_040391F0[]; // gExplosionSplashTex6 +extern Gfx D_040396F0[]; // gExplosionSplashTex7 +extern Gfx D_04039BF0[]; // gExplosionSplashTex8 +extern Gfx D_0403A0F0[]; // gExplosionSplashDL -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Clear_Tag_0x80947F60/func_809480C8.asm") +static Vec3f sZeroVector = { 0.0f, 0.0f, 0.0f }; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Clear_Tag_0x80947F60/func_80948264.asm") +static Vec3f sLightRayEnvColor[] = { + { 255.0f, 255.0f, 0.0f }, + { 255.0f, 100.0f, 100.0f }, + { 100.0f, 255.0f, 100.0f }, + { 100.0f, 100.0f, 255.0f }, +}; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Clear_Tag_0x80947F60/func_809484EC.asm") +static Vec3f sLightRayPrimColor[] = { + { 255.0f, 255.0f, 255.0f }, + { 255.0f, 255.0f, 255.0f }, + { 255.0f, 255.0f, 255.0f }, + { 255.0f, 255.0f, 255.0f }, +}; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Clear_Tag_0x80947F60/func_809485A8.asm") +static f32 sFlashMaxScale[] = { + 6.0f, + 12.0f, + 9.0f, +}; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Clear_Tag_0x80947F60/func_80948788.asm") +static f32 sSmokeScale[] = { + 3.0f, + 6.0f, +}; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Clear_Tag_0x80947F60/func_8094899C.asm") +static f32 sShockwaveMaxScale[] = { + 15.0f, + 30.0f, + 20.0f, +}; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Clear_Tag_0x80947F60/func_80948A54.asm") +static f32 sDebrisScale[] = { + 0.03f, + 0.06f, + 0.04f, +}; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Clear_Tag_0x80947F60/EnClearTag_Destroy.asm") +static f32 sLightRayScale[] = { + 1000.0f, 2000.0f, 1500.0f, 800.0f, 1300.0f, +}; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Clear_Tag_0x80947F60/EnClearTag_Init.asm") +static f32 sLightRayMaxScaleTarget[] = { + 15.0f, 30.0f, 20.0f, 10.0f, 20.0f, +}; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Clear_Tag_0x80947F60/func_80949288.asm") +static f32 sLightRayMaxScale[] = { + 25.0f, 100.0f, 48.0f, 20.0f, 32.0f, +}; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Clear_Tag_0x80947F60/EnClearTag_Update.asm") +static Gfx* sSplashTex[] = { + D_040378F0, D_04037DF0, D_040382F0, D_040387F0, D_04038CF0, D_040391F0, D_040396F0, D_04039BF0, NULL, NULL, NULL, +}; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Clear_Tag_0x80947F60/EnClearTag_Draw.asm") +#include "overlays/ovl_En_Clear_Tag/ovl_En_Clear_Tag.c" -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Clear_Tag_0x80947F60/func_809495F8.asm") +/** + * Creates a debris effect. + * Debris effects are spawned by an explosion. + */ +void EnClearTag_CreateDebrisEffect(EnClearTag* this, Vec3f* position, Vec3f* velocity, Vec3f* acceleration, f32 scale, + f32 rotationZ) { + EnClearTagEffect* effect = this->effect; + s16 i; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Clear_Tag_0x80947F60/func_80949BD4.asm") + // Look for an available effect to allocate a Debris effect to. + for (i = 0; i < ARRAY_COUNT(this->effect) - 1; i++, effect++) { + if (effect->type == CLEAR_TAG_EFFECT_AVAILABLE) { + effect->type = CLEAR_TAG_EFFECT_DEBRIS; + + effect->position = *position; + effect->velocity = *velocity; + effect->acceleration = *acceleration; + + effect->scale = scale; + + // Set the debris effects to spawn in a circle. + effect->rotationY = Rand_ZeroFloat(M_PI * 2); + effect->rotationX = Rand_ZeroFloat(M_PI * 2); + + effect->effectsTimer = effect->bounces = 0; + + effect->rotationZ = rotationZ; + + effect->actionTimer = Rand_ZeroFloat(10.0f); + + break; + } + } +} + +/** + * Creates a smoke effect. + * Smoke effects are spawned by an explosion. + */ +void EnClearTag_CreateSmokeEffect(EnClearTag* this, Vec3f* position, f32 scale) { + s16 i; + EnClearTagEffect* effect = this->effect; + + // Look for an available effect to allocate a smoke effect to. + for (i = 0; i < ARRAY_COUNT(this->effect); i++, effect++) { + if (effect->type == CLEAR_TAG_EFFECT_AVAILABLE) { + effect->actionTimer = Rand_ZeroFloat(100.0f); + effect->type = CLEAR_TAG_EFFECT_SMOKE; + + effect->position = *position; + effect->velocity = sZeroVector; + effect->acceleration = sZeroVector; + + effect->scale = scale; + effect->maxScale = 2.0f * scale; + effect->smokeScaleX = 1.0f; + effect->smokeScaleY = 1.0f; + + effect->primColor.a = 255.0f; + effect->envColor.r = 255.0f; + effect->envColor.b = 255.0f; + effect->primColor.r = 200.0f; + effect->primColor.g = 20.0f; + effect->primColor.b = 0.0f; + effect->envColor.g = 215.0f; + + break; + } + } +} + +/** + * Creates an isolated smoke effect without an explosion. + * Smoke effects are spawned directly. + */ +void EnClearTag_CreateIsolatedSmokeEffect(EnClearTag* this, Vec3f* position, f32 scale) { + s16 i; + EnClearTagEffect* effect = this->effect; + + // Look for an available effect to allocate a smoke effect to. + for (i = 0; i < ARRAY_COUNT(this->effect); i++, effect++) { + if (effect->type == CLEAR_TAG_EFFECT_AVAILABLE) { + effect->actionTimer = Rand_ZeroFloat(100.0f); + effect->type = CLEAR_TAG_EFFECT_ISOLATED_SMOKE; + + effect->position = *position; + effect->velocity = sZeroVector; + effect->acceleration = sZeroVector; + + effect->scale = scale; + effect->maxScale = 2.0f * scale; + effect->smokeScaleX = 1.0f; + effect->smokeScaleY = 1.0f; + + if (scale <= 1.1f) { + effect->scale = ((KREG(23) * 0.1f) + 1.0f) * scale; + effect->primColor.a = KREG(16) + 150.0f; + effect->primColor.r = KREG(17); + effect->primColor.g = KREG(18); + effect->primColor.b = KREG(19); + effect->envColor.r = KREG(20); + effect->envColor.g = KREG(21); + effect->envColor.b = KREG(22); + } else { + effect->envColor.r = effect->envColor.g = effect->envColor.b = 0.0f; + effect->primColor.r = effect->primColor.g = effect->primColor.b = 0.0f; + effect->primColor.a = 255.0f; + } + + break; + } + } +} + +/** + * Creates a flash effect. + * Flash effects are spawned by an explosion or a pop. + * Flash effects have two components: 1) a billboard flash, and 2) a light effect on the ground. + */ +void EnClearTag_CreateFlashEffect(EnClearTag* this, Vec3f* position, f32 scale, f32 floorHeight) { + EnClearTagEffect* effect = this->effect; + s16 i; + + // Look for an available effect to allocate a flash effect to. + for (i = 0; i < ARRAY_COUNT(this->effect) - 1; i++, effect++) { + if (effect->type == CLEAR_TAG_EFFECT_AVAILABLE) { + effect->type = CLEAR_TAG_EFFECT_FLASH; + + effect->position = *position; + effect->velocity = sZeroVector; + effect->acceleration = sZeroVector; + + effect->scale = 0.0f; + effect->maxScale = scale * 3.0f; + + // rotationZ is unused for CLEAR_TAG_EFFECT_FLASH + effect->rotationZ = floorHeight; + + effect->primColor.a = 255.0f; + + break; + } + } +} + +/** + * Creates a light ray effect. + * Light ray effects are spawned by an explosion or pop. + */ +void EnClearTag_CreateLightRayEffect(EnClearTag* this, Vec3f* position, Vec3f* velocity, Vec3f* acceleration, f32 scale, + f32 maxScaleTarget, s16 alphaDecrementSpeed) { + EnClearTagEffect* effect = this->effect; + s16 i; + + // Look for an available effect to allocate a light ray effect to. + for (i = 0; i < ARRAY_COUNT(this->effect) - 1; i++, effect++) { + if (effect->type == CLEAR_TAG_EFFECT_AVAILABLE) { + effect->type = CLEAR_TAG_EFFECT_LIGHT_RAYS; + + effect->position = *position; + effect->velocity = *velocity; + effect->acceleration = *acceleration; + + effect->scale = scale / 1000.0f; + effect->maxScale = 1.0f; + effect->maxScaleTarget = maxScaleTarget; + + effect->lightRayAlpha = Rand_ZeroFloat(100.0f) + 200.0f; + effect->lightRayAlphaDecrementSpeed = alphaDecrementSpeed; + + effect->actionTimer = Rand_ZeroFloat(10.0f); + + effect->rotationY = Math_Acot2F(effect->velocity.z, effect->velocity.x); + effect->rotationX = -Math_Acot2F(sqrtf(SQXZ(effect->velocity)), effect->velocity.y); + + effect->envColor.r = 255.0f; + effect->envColor.g = 255.0f; + effect->envColor.b = 0.0f; + effect->primColor.r = 255.0f; + effect->primColor.g = 255.0f; + effect->primColor.b = 255.0f; + + break; + } + dummy:; + } +} + +/** + * Creates an isolated light ray effect without an explosion or pop. + * Light ray effects are spawned directly. + */ +void EnClearTag_CreateIsolatedLightRayEffect(EnClearTag* this, Vec3f* position, Vec3f* velocity, Vec3f* acceleration, + f32 scale, f32 maxScaleTarget, s16 colorIndex, s16 alphaDecrementSpeed) { + EnClearTagEffect* effect = this->effect; + s16 i; + + // Look for an available effect to allocate a light ray effect to. + for (i = 0; i < ARRAY_COUNT(this->effect) - 1; i++, effect++) { + if (effect->type == CLEAR_TAG_EFFECT_AVAILABLE) { + effect->type = CLEAR_TAG_EFFECT_LIGHT_RAYS; + + effect->position = *position; + effect->velocity = *velocity; + effect->acceleration = *acceleration; + + effect->scale = scale / 1000.0f; + effect->maxScale = 1.0f; + effect->maxScaleTarget = maxScaleTarget; + + effect->lightRayAlpha = Rand_ZeroFloat(100.0f) + 200.0f; + effect->lightRayAlphaDecrementSpeed = alphaDecrementSpeed; + + effect->actionTimer = Rand_ZeroFloat(10.0f); + + effect->rotationY = Math_Acot2F(effect->velocity.z, effect->velocity.x); + effect->rotationX = -Math_Acot2F(sqrtf(SQXZ(effect->velocity)), effect->velocity.y); + + effect->envColor.r = sLightRayEnvColor[colorIndex].x; + effect->envColor.g = sLightRayEnvColor[colorIndex].y; + effect->envColor.b = sLightRayEnvColor[colorIndex].z; + effect->primColor.r = sLightRayPrimColor[colorIndex].x; + effect->primColor.g = sLightRayPrimColor[colorIndex].y; + effect->primColor.b = sLightRayPrimColor[colorIndex].z; + + break; + } + } +} + +/** + * Creates a shockwave effect + * This effect uses concentric ring floor shadows that travel radially outward along the floor poly + */ +void EnClearTag_CreateShockwaveEffect(EnClearTag* this, Vec3f* position, f32 maxScale, s16 actionTimer) { + EnClearTagEffect* effect = this->effect; + s16 i; + + // Look for an available effect to allocate a shockwave effect to. + for (i = 0; i < ARRAY_COUNT(this->effect) - 1; i++, effect++) { + if (effect->type == CLEAR_TAG_EFFECT_AVAILABLE) { + effect->type = CLEAR_TAG_EFFECT_SHOCKWAVE; + + effect->position = *position; + effect->velocity = sZeroVector; + effect->acceleration = sZeroVector; + + effect->maxScale = maxScale; + effect->scale = 0.0f; + + effect->actionTimer = actionTimer; + + effect->primColor.a = 200.0f; + + break; + } + } +} + +/** + * Creates a splash effect + * This effect is used when EnClearTag is spawned above a waterbox + */ +void EnClearTag_CreateSplashEffect(EnClearTag* this, Vec3f* position, s16 effectsTimer) { + s16 i; + EnClearTagEffect* effect = this->effect; + + // Look for an available effect to allocate a splash effect to. + for (i = 0; i < ARRAY_COUNT(this->effect) - 1; i++, effect++) { + if (effect->type == CLEAR_TAG_EFFECT_AVAILABLE) { + // Immediately overwritten and generates a lot of wasted asm (f32 to u8) + effect->actionTimer = Rand_ZeroFloat(100.0f); + effect->type = CLEAR_TAG_EFFECT_SPLASH; + + effect->position = *position; + effect->velocity = sZeroVector; + effect->acceleration = sZeroVector; + + effect->scale = 0.0f; + effect->maxScale = 0.0f; + + effect->actionTimer = 0; + effect->effectsTimer = effectsTimer; + + effect->rotationX = 0.78f; + + break; + } + } +} + +/** + * EnClearTag destructor. + * No Operation takes place. + */ +void EnClearTag_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} + +/** + * EnClearTag constructor. + * This initializes effects, and sets up ClearTag instance data. + */ +void EnClearTag_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad[3]; + EnClearTag* this = THIS; + f32 lightRayMaxScale; + u8 i; + Vec3f pos; + Vec3f vel; + Vec3f accel; + + this->actor.flags &= ~1; + if (thisx->params >= 0) { + this->activeTimer = 70; + Math_Vec3f_Copy(&pos, &this->actor.world.pos); + + // Initialize isolated smoke effect + if (thisx->params == CLEAR_TAG_SMOKE) { + EnClearTag_CreateIsolatedSmokeEffect(this, &pos, this->actor.world.rot.z); + return; + } + + if (thisx->params != CLEAR_TAG_SPLASH) { + // Initialize isolated light ray effect + if (thisx->params == CLEAR_TAG_SMALL_LIGHT_RAYS || thisx->params == CLEAR_TAG_LARGE_LIGHT_RAYS) { + for (i = 0; i < 54; i++) { + lightRayMaxScale = + sLightRayMaxScale[thisx->params] + Rand_ZeroFloat(sLightRayMaxScale[thisx->params]); + SysMatrix_InsertYRotation_f(Rand_ZeroFloat(M_PI * 2), 0); + SysMatrix_RotateStateAroundXAxis(Rand_ZeroFloat(M_PI * 2)); + SysMatrix_GetStateTranslationAndScaledZ(lightRayMaxScale, &vel); + accel.x = vel.x * -0.03f; + accel.y = vel.y * -0.03f; + accel.z = vel.z * -0.03f; + EnClearTag_CreateIsolatedLightRayEffect( + this, &pos, &vel, &accel, + sLightRayScale[thisx->params] + Rand_ZeroFloat(sLightRayScale[thisx->params] * 0.5f), + sLightRayMaxScaleTarget[thisx->params], this->actor.world.rot.z, Rand_ZeroFloat(10.0f) + 20.0f); + } + return; + } + + if ((this->actor.world.rot.x != 0) || (this->actor.world.rot.y != 0) || (this->actor.world.rot.z != 0)) { + this->flashEnvColor.r = this->actor.world.rot.x; + this->flashEnvColor.g = this->actor.world.rot.y; + this->flashEnvColor.b = this->actor.world.rot.z; + } else { + this->flashEnvColor.r = 255; + this->flashEnvColor.g = 0; + } + + // Initialize flash effect + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 50.0f, 30.0f, 100.0f, 4); + pos = this->actor.world.pos; + EnClearTag_CreateFlashEffect(this, &pos, sFlashMaxScale[thisx->params], this->actor.floorHeight); + + // Is not underwater + if (!(this->actor.bgCheckFlags & 0x20)) { + if (thisx->params < 10) { + pos.y = this->actor.world.pos.y - 40.0f; + + // Initialize smoke effect + if (thisx->params != CLEAR_TAG_POP) { + EnClearTag_CreateSmokeEffect(this, &pos, sSmokeScale[thisx->params]); + } + + // Initialize shockwave effect + pos.y = this->actor.floorHeight + 3.0f; + EnClearTag_CreateShockwaveEffect(this, &pos, sShockwaveMaxScale[thisx->params], 0); + EnClearTag_CreateShockwaveEffect(this, &pos, sShockwaveMaxScale[thisx->params], 3); + if (thisx->params == CLEAR_TAG_LARGE_EXPLOSION) { + EnClearTag_CreateShockwaveEffect(this, &pos, sShockwaveMaxScale[thisx->params], 6); + } + } + + // Initialize debris effect + if (thisx->params != CLEAR_TAG_POP) { + pos.y = this->actor.world.pos.y; + for (i = 0; i < 18; i++) { + vel.x = __sinf(i * (33.0f / 40.0f)) * i * .5f; + vel.z = __cosf(i * (33.0f / 40.0f)) * i * .5f; + vel.y = Rand_ZeroFloat(8.0f) + 7.0f; + + vel.x += randPlusMinusPoint5Scaled(0.5f); + vel.z += randPlusMinusPoint5Scaled(0.5f); + + accel.x = 0.0f; + accel.y = -1.0f; + accel.z = 0.0f; + EnClearTag_CreateDebrisEffect(this, &pos, &vel, &accel, + sDebrisScale[thisx->params] + + Rand_ZeroFloat(sDebrisScale[thisx->params]), + this->actor.floorHeight); + } + } + } + + // Initialize light ray effect + pos = this->actor.world.pos; + for (i = 0; i < 44; i++) { + lightRayMaxScale = sLightRayMaxScale[thisx->params] + Rand_ZeroFloat(sLightRayMaxScale[thisx->params]); + SysMatrix_InsertYRotation_f(Rand_ZeroFloat(2 * M_PI), 0); + SysMatrix_RotateStateAroundXAxis(Rand_ZeroFloat(2 * M_PI)); + SysMatrix_GetStateTranslationAndScaledZ(lightRayMaxScale, &vel); + accel.x = vel.x * -0.03f; + accel.y = vel.y * -0.03f; + accel.z = vel.z * -0.03f; + EnClearTag_CreateLightRayEffect(this, &pos, &vel, &accel, + sLightRayScale[thisx->params] + + Rand_ZeroFloat(sLightRayScale[thisx->params] * 0.5f), + sLightRayMaxScaleTarget[thisx->params], Rand_ZeroFloat(10.0f) + 20.0f); + } + } + + // Initialize splash effect + EnClearTag_CreateSplashEffect(this, &pos, 0); + EnClearTag_CreateSplashEffect(this, &pos, 2); + } +} + +void EnClearTag_UpdateCamera(EnClearTag* this, GlobalContext* globalCtx) { + Player* player = PLAYER; + Camera* camera; + s32 pad; + + switch (this->cameraState) { + case 0: + if (((player->actor.world.pos.z > 0.0f) && (player->actor.world.pos.z > 290.0f) && + (fabsf(player->actor.world.pos.x) < 60.0f)) || + ((player->actor.world.pos.z < 0.0f) && (player->actor.world.pos.z < -950.0f) && + (fabsf(player->actor.world.pos.x) < 103.0f))) { + + if (player->actor.world.pos.z > 0.0f) { + player->actor.world.pos.z = 290.0f; + } else { + player->actor.world.pos.z = -950.0f; + } + + player->actor.speedXZ = 0.0f; + if (this->activeTimer == 0) { + this->cameraState = 1; + } + } + break; + case 1: + func_800EA0D4(globalCtx, &globalCtx->csCtx); + this->camId = func_801694DC(globalCtx); + func_80169590(globalCtx, 0, 1); + func_80169590(globalCtx, this->camId, 7); + func_800B7298(globalCtx, &this->actor, 4); + camera = Play_GetCamera(globalCtx, 0); + this->eye.x = camera->eye.x; + this->eye.y = camera->eye.y; + this->eye.z = camera->eye.z; + this->at.x = camera->at.x; + this->at.y = camera->at.y; + this->at.z = camera->at.z; + func_801518B0(globalCtx, 0xF, NULL); + this->cameraState = 2; + func_8019FDC8(&D_801DB4A4, NA_SE_VO_NA_LISTEN, 0x20); + case 2: + if (player->actor.world.pos.z > 0.0f) { + player->actor.world.pos.z = 290.0f; + } else { + player->actor.world.pos.z = -950.0f; + } + + player->actor.speedXZ = 0.0f; + if (func_80152498(&globalCtx->msgCtx) == 0) { + camera = Play_GetCamera(globalCtx, 0); + camera->eye = this->eye; + camera->eyeNext = this->eye; + camera->at = this->at; + func_80169AFC(globalCtx, this->camId, 0); + func_800EA0EC(globalCtx, &globalCtx->csCtx); + func_800B7298(globalCtx, &this->actor, 6); + this->cameraState = 0; + this->camId = 0; + this->activeTimer = 20; + } + break; + } + + if (this->camId != 0) { + func_8016970C(globalCtx, this->camId, &this->at, &this->eye); + } +} + +/** + * EnClear_Tag update function. + * Decides whether to update or to mark for death + */ +void EnClearTag_Update(Actor* thisx, GlobalContext* globalCtx) { + EnClearTag* this = THIS; + + if (this->activeTimer != 0) { + this->activeTimer--; + } + + if (this->actor.params < 0) { + EnClearTag_UpdateCamera(this, globalCtx); + } else if (this->activeTimer != 0) { + EnClearTag_UpdateEffects(this, globalCtx); + } else { + Actor_MarkForDeath(&this->actor); + } +} + +/** + * EnClearTag draw function. + * Setups DrawEffects + */ +void EnClearTag_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnClearTag_DrawEffects(thisx, globalCtx); +} + +/** + * Updates all effects. + * Performs effect physics. + * Moves and bounces debris effects. + * Fades most effects out of view. When effects are completely faded away they are removed. + */ +void EnClearTag_UpdateEffects(EnClearTag* this, GlobalContext* globalCtx) { + EnClearTagEffect* effect = this->effect; + s16 i; + f32 originalYPosition; + Vec3f sphereCenter; + s32 pad; + + for (i = 0; i < ARRAY_COUNT(this->effect); i++, effect++) { + if (effect->type != CLEAR_TAG_EFFECT_AVAILABLE) { + effect->actionTimer++; + + // Perform effect physics. + effect->position.x += effect->velocity.x; + originalYPosition = effect->position.y; + effect->position.y += effect->velocity.y; + effect->position.z += effect->velocity.z; + effect->velocity.x += effect->acceleration.x; + effect->velocity.y += effect->acceleration.y; + effect->velocity.z += effect->acceleration.z; + + if (effect->type == CLEAR_TAG_EFFECT_DEBRIS) { + // Clamp the velocity to -5.0 + if (effect->velocity.y < -5.0f) { + effect->velocity.y = -5.0f; + } + + // While the effect is falling check if it has hit the ground. + if (effect->velocity.y < 0.0f) { + sphereCenter = effect->position; + sphereCenter.y += 5.0f; + + // Check if the debris has hit the ground. + if (func_800C5A20(&globalCtx->colCtx, &sphereCenter, 11.0f)) { + effect->position.y = originalYPosition; + + // Bounce the debris effect. + if (effect->bounces <= 0) { + effect->bounces++; + effect->velocity.y *= -0.5f; + effect->effectsTimer = Rand_ZeroFloat(20.0f) + 25.0f; + } else { + // The Debris effect is done bouncing. Set its velocity and acceleration to 0. + effect->velocity.x = effect->velocity.z = effect->acceleration.y = effect->velocity.y = + 0.0f; + } + } + } + + // Rotate the debris effect. + if (effect->acceleration.y != 0.0f) { + effect->rotationY += 0.5f; + effect->rotationX += 0.35f; + } + + if (effect->effectsTimer == 1) { + effect->type = CLEAR_TAG_EFFECT_AVAILABLE; + } + } else if (effect->type == CLEAR_TAG_EFFECT_FIRE) { + // Fade the fire effect. + Math_ApproachZeroF(&effect->primColor.a, 1.0f, 15.0f); + if (effect->primColor.a <= 0.0f) { + effect->type = CLEAR_TAG_EFFECT_AVAILABLE; + } + } else if (effect->type == CLEAR_TAG_EFFECT_SHOCKWAVE) { + if (effect->actionTimer > 3) { + Math_ApproachF(&effect->scale, effect->maxScale, 0.2f, effect->maxScale * 0.6666666f); + Math_ApproachZeroF(&effect->primColor.a, 1.0f, 15.0f); + if (effect->primColor.a <= 0.0f) { + effect->type = CLEAR_TAG_EFFECT_AVAILABLE; + } + } + } else if (effect->type == CLEAR_TAG_EFFECT_SMOKE) { + // Fade the smoke effects. + Math_ApproachZeroF(&effect->primColor.r, 1.0f, 20.0f); + Math_ApproachZeroF(&effect->primColor.g, 1.0f, 2.0f); + Math_ApproachZeroF(&effect->envColor.r, 1.0f, 25.5f); + Math_ApproachZeroF(&effect->envColor.g, 1.0f, 21.5f); + Math_ApproachZeroF(&effect->envColor.b, 1.0f, 25.5f); + + // Smooth scale the smoke effects. + Math_ApproachF(&effect->scale, effect->maxScale, 0.05f, 0.1f); + + if (effect->primColor.r == 0.0f) { + Math_ApproachF(&effect->smokeScaleX, 3.0f, 0.1f, 0.01f); + Math_ApproachF(&effect->smokeScaleY, 3.0f, 0.1f, 0.02f); + + // Fade the smoke effects. + Math_ApproachZeroF(&effect->primColor.a, 1.0f, 5.f); + + // If the smoke effect has fully faded, unload it. + if (effect->primColor.a <= 0.0f) { + effect->type = CLEAR_TAG_EFFECT_AVAILABLE; + } + } + } else if (effect->type == CLEAR_TAG_EFFECT_ISOLATED_SMOKE) { + // Smooth scale the isolated smoke effects. + Math_ApproachF(&effect->scale, effect->maxScale, 0.05f, 0.1f); + if (effect->actionTimer > 10) { + Math_ApproachF(&effect->smokeScaleX, 3.0f, 0.1f, 0.01f); + Math_ApproachF(&effect->smokeScaleY, 3.0f, 0.1f, 0.02f); + + // Fade the smoke effects. + Math_ApproachZeroF(&effect->primColor.a, 1.0f, 5.f); + if (effect->primColor.a <= 0.0f) { + effect->type = CLEAR_TAG_EFFECT_AVAILABLE; + } + } + } else if (effect->type == CLEAR_TAG_EFFECT_FLASH) { + // Smooth scale the flash effects. + Math_ApproachF(&effect->scale, effect->maxScale, 0.5f, 6.0f); + + // Fade the flash effects. + Math_ApproachZeroF(&effect->primColor.a, 1.0f, 15.0f); + if (effect->primColor.a <= 0.0f) { + effect->type = CLEAR_TAG_EFFECT_AVAILABLE; + } + } else if (effect->type == CLEAR_TAG_EFFECT_LIGHT_RAYS) { + // Rotate the light ray effect. + effect->rotationZ += Rand_ZeroFloat(M_PI / 2) + (M_PI / 2); + + // Fade the light ray effects. + effect->lightRayAlpha -= effect->lightRayAlphaDecrementSpeed; + if (effect->lightRayAlpha <= 0) { + effect->lightRayAlpha = 0; + effect->type = CLEAR_TAG_EFFECT_AVAILABLE; + } + effect->primColor.a = effect->lightRayAlpha; + if (effect->primColor.a > 255.0f) { + effect->primColor.a = 255.0f; + } + + // Smooth scale the light ray effects. + Math_ApproachF(&effect->maxScale, effect->maxScaleTarget, 1.0f, + (effect->maxScaleTarget / 15.0f) * 4.0f); + } else if (effect->type == CLEAR_TAG_EFFECT_SPLASH) { + if (effect->effectsTimer == 0) { + effect->scale = 7.0f; + + // Smooth scale the splash effects. + Math_ApproachF(&effect->maxScale, 500.0f, 1.0f, 50.0f); + Math_ApproachF(&effect->rotationX, 1.5f, 1.0f, 0.12f); + if (effect->actionTimer > 7) { + effect->type = CLEAR_TAG_EFFECT_AVAILABLE; + } + } else { + effect->actionTimer = 0; + } + } + + if (effect->effectsTimer != 0) { + effect->effectsTimer--; + } + } + } +} + +/** + * Draws all effects. + * Each effect type is drawn before the next. The function will apply a material that + * applies to all effects of that type while drawing the first effect of that type. + */ +void EnClearTag_DrawEffects(Actor* thisx, GlobalContext* globalCtx) { + u8 isMaterialApplied = false; + s16 i; + s16 j; + Vec3f vec; + WaterBox* waterBox; + f32 ySurface; + MtxF mtxF; + GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; + EnClearTag* this = THIS; + EnClearTagEffect* effect = this->effect; + EnClearTagEffect* firstEffect = this->effect; + + OPEN_DISPS(gfxCtx); + func_8012C28C(globalCtx->state.gfxCtx); + func_8012C2DC(globalCtx->state.gfxCtx); + + // Draw all Debris effects. + for (i = 0; i < ARRAY_COUNT(this->effect); i++, effect++) { + if (effect->type == CLEAR_TAG_EFFECT_DEBRIS) { + // Apply the debris effect material if it has not already been applied. + if (!isMaterialApplied) { + isMaterialApplied++; + gSPDisplayList(POLY_OPA_DISP++, gClearTagDebrisEffectMaterialDL); + } + + // Draw the debris effect. + SysMatrix_InsertTranslation(effect->position.x, effect->position.y, effect->position.z, MTXMODE_NEW); + Matrix_Scale(effect->scale, effect->scale, effect->scale, MTXMODE_APPLY); + SysMatrix_InsertYRotation_f(effect->rotationY, MTXMODE_APPLY); + SysMatrix_RotateStateAroundXAxis(effect->rotationX); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gClearTagDebrisEffectDL); + } + } + + // Draw all Shockwave effects. + effect = firstEffect; + if (this->actor.floorPoly != NULL) { + for (i = 0; i < ARRAY_COUNT(this->effect); i++, effect++) { + if (effect->type == CLEAR_TAG_EFFECT_SHOCKWAVE) { + // Draw the shockwave effect. + gDPPipeSync(POLY_XLU_DISP++); + gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 255, (s8)effect->primColor.a); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (s8)effect->primColor.a); + func_800C0094(this->actor.floorPoly, effect->position.x, effect->position.y, effect->position.z, &mtxF); + SysMatrix_SetCurrentState(&mtxF); + Matrix_Scale(effect->scale, 1.0f, effect->scale, MTXMODE_APPLY); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, D_04030100); + } + } + } + + // Draw all ground flash effects. + effect = firstEffect; + isMaterialApplied = false; + if (this->actor.floorPoly != NULL) { + for (i = 0; i < ARRAY_COUNT(this->effect); i++, effect++) { + if (effect->type == CLEAR_TAG_EFFECT_FLASH) { + // Apply the flash ground effect material if it has not already been applied. + if (!isMaterialApplied) { + gDPPipeSync(POLY_XLU_DISP++); + gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 200, 0); + isMaterialApplied++; + } + + // Draw the ground flash effect. + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 200, (s8)(effect->primColor.a * 0.7f)); + func_800C0094(this->actor.floorPoly, effect->position.x, this->actor.floorHeight, effect->position.z, + &mtxF); + SysMatrix_SetCurrentState(&mtxF); + Matrix_Scale(effect->scale * 3.0f, 1.0f, effect->scale * 3.0f, MTXMODE_APPLY); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gClearTagFlashEffectGroundDL); + } + } + } + + // Draw all smoke effects. + effect = firstEffect; + isMaterialApplied = false; + for (i = 0; i < ARRAY_COUNT(this->effect); i++, effect++) { + if ((effect->type == CLEAR_TAG_EFFECT_SMOKE) || (effect->type == CLEAR_TAG_EFFECT_ISOLATED_SMOKE)) { + // Apply the smoke effect material if it has not already been applied. + if (!isMaterialApplied) { + gSPDisplayList(POLY_XLU_DISP++, gClearTagFireEffectMaterialDL); + isMaterialApplied++; + } + + // Draw the smoke effect. + gDPPipeSync(POLY_XLU_DISP++); + gDPSetEnvColor(POLY_XLU_DISP++, (s8)effect->envColor.r, (s8)effect->envColor.g, (s8)effect->envColor.b, + 128); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, (s8)effect->primColor.r, (s8)effect->primColor.g, + (s8)effect->primColor.b, (s8)effect->primColor.a); + gSPSegment( + POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, -effect->actionTimer * 5, 32, 64, 1, 0, 0, 32, 32)); + SysMatrix_InsertTranslation(effect->position.x, effect->position.y, effect->position.z, MTXMODE_NEW); + SysMatrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_Scale(effect->smokeScaleX * effect->scale, effect->smokeScaleY * effect->scale, 1.0f, MTXMODE_APPLY); + SysMatrix_InsertTranslation(0.0f, 20.0f, 0.0f, MTXMODE_APPLY); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gClearTagFireEffectDL); + } + } + + // Draw all fire effects. + effect = firstEffect; + isMaterialApplied = false; + for (i = 0; i < ARRAY_COUNT(this->effect); i++, effect++) { + if (effect->type == CLEAR_TAG_EFFECT_FIRE) { + // Apply the fire effect material if it has not already been applied. + if (!isMaterialApplied) { + gSPDisplayList(POLY_XLU_DISP++, gClearTagFireEffectMaterialDL); + gDPSetEnvColor(POLY_XLU_DISP++, 255, 215, 255, 128); + isMaterialApplied++; + } + + // Draw the fire effect. + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 200, 20, 0, (s8)effect->primColor.a); + gSPSegment( + POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, -effect->actionTimer * 15, 32, 64, 1, 0, 0, 32, 32)); + SysMatrix_InsertTranslation(effect->position.x, effect->position.y, effect->position.z, MTXMODE_NEW); + SysMatrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_Scale(effect->scale, effect->scale, 1.0f, MTXMODE_APPLY); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gClearTagFireEffectDL); + } + } + + // Draw all flash billboard effects. + effect = firstEffect; + isMaterialApplied = false; + for (i = 0; i < ARRAY_COUNT(this->effect); i++, effect++) { + if (effect->type == CLEAR_TAG_EFFECT_FLASH) { + // Apply the flash billboard effect material if it has not already been applied. + if (!isMaterialApplied) { + gDPPipeSync(POLY_XLU_DISP++); + gDPSetEnvColor(POLY_XLU_DISP++, this->flashEnvColor.r, this->flashEnvColor.g, this->flashEnvColor.b, 0); + isMaterialApplied++; + } + + // Draw the flash billboard effect. + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 200, (s8)effect->primColor.a); + SysMatrix_InsertTranslation(effect->position.x, effect->position.y, effect->position.z, MTXMODE_NEW); + SysMatrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_Scale(2.0f * effect->scale, 2.0f * effect->scale, 1.0f, MTXMODE_APPLY); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gClearTagFlashEffectDL); + } + } + + // Draw all light ray effects. + effect = firstEffect; + isMaterialApplied = false; + for (i = 0; i < ARRAY_COUNT(this->effect); i++, effect++) { + if (effect->type == CLEAR_TAG_EFFECT_LIGHT_RAYS) { + // Apply the light ray effect material if it has not already been applied. + if (!isMaterialApplied) { + gDPPipeSync(POLY_XLU_DISP++); + gDPSetEnvColor(POLY_XLU_DISP++, (u8)effect->envColor.r, (u8)effect->envColor.g, (u8)effect->envColor.b, + 0); + gSPDisplayList(POLY_XLU_DISP++, gClearTagLightRayEffectMaterialDL); + isMaterialApplied++; + } + + // Draw the light ray effect. + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, (u8)effect->primColor.r, (u8)effect->primColor.g, + (u8)effect->primColor.b, (u8)effect->primColor.a); + SysMatrix_InsertTranslation(effect->position.x, effect->position.y, effect->position.z, MTXMODE_NEW); + SysMatrix_InsertYRotation_f(effect->rotationY, MTXMODE_APPLY); + SysMatrix_RotateStateAroundXAxis(effect->rotationX); + SysMatrix_InsertZRotation_f(effect->rotationZ, MTXMODE_APPLY); + Matrix_Scale(effect->scale * 0.5f, effect->scale * 0.5f, effect->maxScale * effect->scale, MTXMODE_APPLY); + SysMatrix_RotateStateAroundXAxis(M_PI / 2); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gClearTagLightRayEffectDL); + } + } + + // Draw all splash effects. + effect = firstEffect; + for (i = 0; i < ARRAY_COUNT(this->effect); i++, effect++) { + if (effect->type == CLEAR_TAG_EFFECT_SPLASH) { + gDPPipeSync(POLY_XLU_DISP++); + gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 255, 200); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, 200); + gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(sSplashTex[effect->actionTimer])); + func_8012C9BC(gfxCtx); + gSPClearGeometryMode(POLY_XLU_DISP++, G_CULL_BACK); + isMaterialApplied++; + + // Apply material 16 times along a circle to give the appearance of a splash + for (j = 0; j < 16; j++) { + SysMatrix_InsertYRotation_f(2.0f * (j * M_PI) * (1.0f / 16.0f), MTXMODE_NEW); + SysMatrix_GetStateTranslationAndScaledZ(effect->maxScale, &vec); + /** + * Get the water surface at point (`x`, `ySurface`, `z`). `ySurface` doubles as position y input + * returns true if point is within the xz boundaries of an active water box, else false + * `ySurface` returns the water box's surface, while `outWaterBox` returns a pointer to the WaterBox + */ + ySurface = effect->position.y; + if (func_800CA1AC(globalCtx, &globalCtx->colCtx, effect->position.x + vec.x, effect->position.z + vec.z, + &ySurface, &waterBox)) { + if ((effect->position.y - ySurface) < 200.0f) { + // Draw the splash effect. + SysMatrix_InsertTranslation(effect->position.x + vec.x, ySurface, effect->position.z + vec.z, + MTXMODE_NEW); + SysMatrix_InsertYRotation_f(2.0f * (j * M_PI) * (1.0f / 16.0f), MTXMODE_APPLY); + SysMatrix_RotateStateAroundXAxis(effect->rotationX); + Matrix_Scale(effect->scale, effect->scale, effect->scale, MTXMODE_APPLY); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, D_0403A0F0); + } + } + } + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.h b/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.h index e8fad52079..ec8e3ef30e 100644 --- a/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.h +++ b/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.h @@ -5,9 +5,50 @@ struct EnClearTag; +typedef enum { + /* 0x00 */ CLEAR_TAG_EFFECT_AVAILABLE, + /* 0x01 */ CLEAR_TAG_EFFECT_DEBRIS, + /* 0x02 */ CLEAR_TAG_EFFECT_FIRE, // never set to, remnant of OoT + /* 0x03 */ CLEAR_TAG_EFFECT_SMOKE, + /* 0x04 */ CLEAR_TAG_EFFECT_FLASH, + /* 0x05 */ CLEAR_TAG_EFFECT_LIGHT_RAYS, + /* 0x06 */ CLEAR_TAG_EFFECT_SHOCKWAVE, + /* 0x07 */ CLEAR_TAG_EFFECT_SPLASH, + /* 0x08 */ CLEAR_TAG_EFFECT_ISOLATED_SMOKE, +} ClearTagEffectType; + +typedef struct EnClearTagEffect { + /* 0x00 */ u8 type; + /* 0x01 */ u8 actionTimer; + /* 0x04 */ Vec3f position; + /* 0x10 */ Vec3f velocity; + /* 0x1C */ Vec3f acceleration; + /* 0x28 */ Color_RGBAf primColor; + /* 0x38 */ Color_RGBAf envColor; + /* 0x48 */ s16 bounces; + /* 0x4A */ s16 effectsTimer; + /* 0x4C */ s16 lightRayAlpha; + /* 0x4E */ s16 lightRayAlphaDecrementSpeed; + /* 0x50 */ f32 scale; + /* 0x54 */ f32 maxScale; + /* 0x58 */ f32 rotationY; + /* 0x5C */ f32 rotationX; + /* 0x60 */ f32 rotationZ; + /* 0x64 */ f32 maxScaleTarget; + /* 0x68 */ f32 smokeScaleY; + /* 0x6C */ f32 smokeScaleX; +} EnClearTagEffect; // size = 0x70 + typedef struct EnClearTag { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_0144[0x2D40]; + /* 0x0144 */ EnClearTagEffect effect[103]; + /* 0x2E54 */ u8 cameraState; + /* 0x2E56 */ s16 activeTimer; // Actor Marked for Death when timer runs out + /* 0x2E58 */ UNK_TYPE1 unk2E58[0xC]; + /* 0x2E64 */ s16 camId; + /* 0x2E66 */ Color_RGBA8 flashEnvColor; + /* 0x2E6C */ Vec3f eye; // Camera eye + /* 0x2E78 */ Vec3f at; // Camera lookAt } EnClearTag; // size = 0x2E84 extern const ActorInit En_Clear_Tag_InitVars; 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 fd9892d5ae..3bbf965961 100644 --- a/src/overlays/actors/ovl_En_Encount2/z_en_encount2.c +++ b/src/overlays/actors/ovl_En_Encount2/z_en_encount2.c @@ -155,8 +155,8 @@ void EnEncount2_Popped(EnEncount2* this, GlobalContext* globalCtx) { Math_Vec3f_Copy(&curPos, &this->dyna.actor.world.pos); curPos.y += 60.0f; - Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, curPos.x, curPos.y, curPos.z, 0xFF, 0xFF, 0xC8, - 0x0001); + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, curPos.x, curPos.y, curPos.z, 255, 255, 200, + CLEAR_TAG_LARGE_EXPLOSION); for (i = 0; i != 100; ++i) { EnEncount2_InitParticles(this, &curPos, 10); diff --git a/src/overlays/actors/ovl_En_Firefly/z_en_firefly.c b/src/overlays/actors/ovl_En_Firefly/z_en_firefly.c index 3fa13f5b0f..dc4b15587e 100644 --- a/src/overlays/actors/ovl_En_Firefly/z_en_firefly.c +++ b/src/overlays/actors/ovl_En_Firefly/z_en_firefly.c @@ -351,7 +351,8 @@ void EnFirefly_SetupFall(EnFirefly* this, GlobalContext* globalCtx) { this->unk_2E8.x = 4.0f; this->unk_2E8.y = 0.55f; Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, this->collider.info.bumper.hitPos.x, - this->collider.info.bumper.hitPos.y, this->collider.info.bumper.hitPos.z, 0, 0, 0, 3); + this->collider.info.bumper.hitPos.y, this->collider.info.bumper.hitPos.z, 0, 0, 0, + CLEAR_TAG_SMALL_LIGHT_RAYS); } else if (this->actor.colChkInfo.damageEffect == 2) { this->unk_18F = 0; this->unk_2E8.x = 4.0f; diff --git a/src/overlays/actors/ovl_En_Fsn/z_en_fsn.c b/src/overlays/actors/ovl_En_Fsn/z_en_fsn.c index b64e5df9a3..34ad934ab2 100644 --- a/src/overlays/actors/ovl_En_Fsn/z_en_fsn.c +++ b/src/overlays/actors/ovl_En_Fsn/z_en_fsn.c @@ -557,7 +557,8 @@ void EnFsn_UpdateItemSelectedProperty(EnFsn* this) { s32 i; for (items = this->items, i = 0; i < this->totalSellingItems; items++, i++) { - if (this->actionFunc != EnFsn_SelectItem && this->actionFunc != EnFsn_PlayerCannotBuy && this->drawCursor == 0) { + if (this->actionFunc != EnFsn_SelectItem && this->actionFunc != EnFsn_PlayerCannotBuy && + this->drawCursor == 0) { (*items)->isSelected = false; } else { (*items)->isSelected = (i == this->cursorIdx) ? true : false; diff --git a/src/overlays/actors/ovl_En_Invadepoh/z_en_invadepoh.c b/src/overlays/actors/ovl_En_Invadepoh/z_en_invadepoh.c index 31c5bd3bfb..eeeee2a77d 100644 --- a/src/overlays/actors/ovl_En_Invadepoh/z_en_invadepoh.c +++ b/src/overlays/actors/ovl_En_Invadepoh/z_en_invadepoh.c @@ -1347,9 +1347,9 @@ void func_80B452EC(EnInvadepoh* this, GlobalContext* globalCtx) { s32 i; for (i = 0; i < this->unk379; i++) { - D_80B50320[i] = (EnInvadepoh*)Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_INVADEPOH, this->actor.world.pos.x, - this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, - (i & 7) | ((phi_s2 << 8) & 0x7F00) | 0x10); + D_80B50320[i] = (EnInvadepoh*)Actor_Spawn( + &globalCtx->actorCtx, globalCtx, ACTOR_EN_INVADEPOH, this->actor.world.pos.x, this->actor.world.pos.y, + this->actor.world.pos.z, 0, 0, 0, (i & 7) | ((phi_s2 << 8) & 0x7F00) | 0x10); if (phi_s2 != 0xFF) { Path* path = &globalCtx->setupPathList[phi_s2]; phi_s2 = path->unk1; @@ -1369,7 +1369,7 @@ void func_80B45460(EnInvadepoh* this, GlobalContext* globalCtx) { void func_80B454BC(EnInvadepoh* this, GlobalContext* globalCtx) { D_80B503F0 = (EnInvadepoh*)Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_INVADEPOH, this->actor.world.pos.x, - this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, 0x60); + this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, 0x60); } void EnInvadepoh_SetSysMatrix(Vec3f* vec) { @@ -1436,7 +1436,7 @@ void func_80B457A0(EnInvadepoh* this) { f32 phi_f20 = FLT_MAX; s32 i; s32 phi_s5 = -1; - + for (i = 0; i < this->unk379; i++) { if ((D_80B50320[i] != NULL) && D_80B50320[i]->drawAlien) { distanceSquared = Math3D_DistanceSquared(&D_80B50320[i]->actor.world.pos, &this->actor.world.pos); @@ -2307,7 +2307,7 @@ void func_80B479E8(EnInvadepoh* this, GlobalContext* globalCtx) { this->counter++; if (this->actionTimer == 8) { Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, this->actor.world.pos.x, - this->actor.world.pos.y - 10.0f, this->actor.world.pos.z, 0, 0, 3, 200); + this->actor.world.pos.y - 10.0f, this->actor.world.pos.z, 0, 0, 3, CLEAR_TAG_SMOKE); } if (this->actionTimer == 8) { @@ -2624,7 +2624,8 @@ void func_80B48848(EnInvadepoh* this, GlobalContext* globalCtx) { Math_StepToS(&this->behaviorInfo.unk4C, 0x7D0, 0x46); } func_80B43E6C(this, 6, this->behaviorInfo.unk4C, 0x46); - if (((this->actor.flags & 0x40) == 0x40) && (func_801378B8(&this->skelAnime, 0.0f) || func_801378B8(&this->skelAnime, 7.0f))) { + if (((this->actor.flags & 0x40) == 0x40) && + (func_801378B8(&this->skelAnime, 0.0f) || func_801378B8(&this->skelAnime, 7.0f))) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_ROMANI_WALK); } if (this->actionTimer > 0) { @@ -3077,7 +3078,8 @@ void func_80B49C38(EnInvadepoh* this, GlobalContext* globalCtx) { this->actor.flags |= (0x8 | 0x1); } - if (((this->actor.flags & 0x40) == 0x40) && (func_801378B8(&this->skelAnime, 0.0f) || func_801378B8(&this->skelAnime, 7.0f))) { + if (((this->actor.flags & 0x40) == 0x40) && + (func_801378B8(&this->skelAnime, 0.0f) || func_801378B8(&this->skelAnime, 7.0f))) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_ROMANI_WALK); } if (this->clockTime >= 0.9999f) { @@ -3302,7 +3304,8 @@ void func_80B4A67C(EnInvadepoh* this, GlobalContext* globalCtx) { this->unk378 = 0; this->actor.flags |= (0x8 | 0x1); } - if (((this->actor.flags & 0x40) == 0x40) && (func_801378B8(&this->skelAnime, 0.0f) || func_801378B8(&this->skelAnime, 7.0f))) { + if (((this->actor.flags & 0x40) == 0x40) && + (func_801378B8(&this->skelAnime, 0.0f) || func_801378B8(&this->skelAnime, 7.0f))) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_ROMANI_WALK); } if (this->pathIndex == this->endPoint) { @@ -3463,8 +3466,7 @@ void func_80B4ADCC(EnInvadepoh* this, GlobalContext* globalCtx) { } if (this->textId == 0x3333) { func_80B4AEC0(this); - } - else if (this->textId == 0x3334) { + } else if (this->textId == 0x3334) { func_801477B4(globalCtx); func_80B4B024(this); } @@ -3554,7 +3556,6 @@ void func_80B4B218(Actor* thisx, GlobalContext* globalCtx) { Player* player; AlienBehaviorInfo* substruct = &this->behaviorInfo; - this->actionFunc(this, globalCtx); if (sp38 && this->actor.update != NULL) { SkelAnime_FrameUpdateMatrix(&this->skelAnime); @@ -3658,7 +3659,8 @@ void func_80B4B768(EnInvadepoh* this, GlobalContext* globalCtx) { s32 pad; Math_StepToF(&this->actor.speedXZ, 0.0f, 1.0f); - Math_SmoothStepToS(&this->actor.world.rot.y, Actor_YawBetweenActors(&this->actor, &D_80B5040C->actor), 5, 0x1388, 0x64); + Math_SmoothStepToS(&this->actor.world.rot.y, Actor_YawBetweenActors(&this->actor, &D_80B5040C->actor), 5, 0x1388, + 0x64); func_80B44E90(this, globalCtx); if (func_801378B8(&this->skelAnime, 13.0f) || func_801378B8(&this->skelAnime, 19.0f)) { Audio_PlayActorSound2(&this->actor, NA_SE_EV_SMALL_DOG_ANG_BARK); @@ -3836,7 +3838,8 @@ void func_80B4BC4C(EnInvadepoh* this, GlobalContext* globalCtx) { } } - if (((this->actor.flags & 0x40) == 0x40) && (func_801378B8(&this->skelAnime, 0.0f) || func_801378B8(&this->skelAnime, 12.0f))) { + if (((this->actor.flags & 0x40) == 0x40) && + (func_801378B8(&this->skelAnime, 0.0f) || func_801378B8(&this->skelAnime, 12.0f))) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_ROMANI_WALK); } if (gSaveContext.time > CLOCK_TIME(20, 15)) { @@ -3971,14 +3974,14 @@ void func_80B4C5C0(Actor* thisx, GlobalContext* globalCtx) { } this->actionFunc(this, globalCtx); if (sp2C && (this->actor.update != NULL)) { - SkelAnime_FrameUpdateMatrix(&this->skelAnime); - func_80B45CE0(&this->behaviorInfo); - if ((this->actionFunc != func_80B4C058) && !isTalking && this->actor.isTargeted) { - func_800B8614(&this->actor, globalCtx, 350.0f); - } - Collider_UpdateCylinder(&this->actor, &this->collider); - CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + SkelAnime_FrameUpdateMatrix(&this->skelAnime); + func_80B45CE0(&this->behaviorInfo); + if ((this->actionFunc != func_80B4C058) && !isTalking && this->actor.isTargeted) { + func_800B8614(&this->actor, globalCtx, 350.0f); } + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } } void func_80B4C6C8(EnInvadepoh* this) { @@ -4006,7 +4009,7 @@ void func_80B4C730(EnInvadepoh* this, GlobalContext* globalCtx) { s8 temp_v1; s16 sp3A; s8 temp_v0; - + func_80B44700(this); func_80B44EFC(this, globalCtx); func_80B43E6C(this, 6, 2000, 100); @@ -4056,7 +4059,8 @@ void func_80B4C730(EnInvadepoh* this, GlobalContext* globalCtx) { substruct->unk26.y = CLAMP(temp_v1_4, -8000, 8000); } - if (((this->actor.flags & 0x40) == 0x40) && (func_801378B8(&this->skelAnime, 0.0f) || func_801378B8(&this->skelAnime, 7.0f))) { + if (((this->actor.flags & 0x40) == 0x40) && + (func_801378B8(&this->skelAnime, 0.0f) || func_801378B8(&this->skelAnime, 7.0f))) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_ROMANI_WALK); } diff --git a/src/overlays/actors/ovl_En_Pametfrog/z_en_pametfrog.c b/src/overlays/actors/ovl_En_Pametfrog/z_en_pametfrog.c index dc1337a76a..b450b92956 100644 --- a/src/overlays/actors/ovl_En_Pametfrog/z_en_pametfrog.c +++ b/src/overlays/actors/ovl_En_Pametfrog/z_en_pametfrog.c @@ -407,7 +407,7 @@ void func_8086A724(EnPametfrog* this, GlobalContext* globalCtx) { this->unk_2C4 = 3.0f; Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, this->collider.elements[0].info.bumper.hitPos.x, this->collider.elements[0].info.bumper.hitPos.y, - this->collider.elements[0].info.bumper.hitPos.z, 0, 0, 0, 4); + this->collider.elements[0].info.bumper.hitPos.z, 0, 0, 0, CLEAR_TAG_LARGE_LIGHT_RAYS); } else if (this->actor.colChkInfo.damageEffect == 3) { func_8086A024(this); } @@ -1305,7 +1305,8 @@ void EnPametfrog_ApplyDamage(EnPametfrog* this, GlobalContext* globalCtx) { Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, this->collider.elements[0].info.bumper.hitPos.x, this->collider.elements[0].info.bumper.hitPos.y, - this->collider.elements[0].info.bumper.hitPos.z, 0, 0, 0, 4); + this->collider.elements[0].info.bumper.hitPos.z, 0, 0, 0, + CLEAR_TAG_LARGE_LIGHT_RAYS); } func_8086CB4C(this); } diff --git a/src/overlays/actors/ovl_En_Po_Fusen/z_en_po_fusen.c b/src/overlays/actors/ovl_En_Po_Fusen/z_en_po_fusen.c index 43f1ddd7aa..b4d540fe73 100644 --- a/src/overlays/actors/ovl_En_Po_Fusen/z_en_po_fusen.c +++ b/src/overlays/actors/ovl_En_Po_Fusen/z_en_po_fusen.c @@ -242,7 +242,7 @@ void EnPoFusen_IncrementRomaniPop(EnPoFusen* this) { void EnPoFusen_Pop(EnPoFusen* this, GlobalContext* globalCtx) { Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, this->actor.world.pos.x, - this->actor.world.pos.y + 20.0f, this->actor.world.pos.z, 255, 255, 200, 2); + this->actor.world.pos.y + 20.0f, this->actor.world.pos.z, 255, 255, 200, CLEAR_TAG_POP); Audio_PlayActorSound2(&this->actor, NA_SE_IT_BOMB_EXPLOSION); Actor_MarkForDeath(&this->actor); } diff --git a/src/overlays/actors/ovl_Obj_Raillift/z_obj_raillift.c b/src/overlays/actors/ovl_Obj_Raillift/z_obj_raillift.c index 4e569ac155..6624db6ea1 100644 --- a/src/overlays/actors/ovl_Obj_Raillift/z_obj_raillift.c +++ b/src/overlays/actors/ovl_Obj_Raillift/z_obj_raillift.c @@ -53,7 +53,6 @@ static InitChainEntry sInitChain[] = { static CollisionHeader* sColHeaders[] = { &D_06004FF8, &D_060048D0 }; - void ObjRaillift_UpdatePosition(ObjRaillift* this, s32 idx) { Math_Vec3s_ToVec3f(&this->dyna.actor.world.pos, &this->points[idx]); } @@ -159,7 +158,8 @@ void ObjRaillift_Move(ObjRaillift* this, GlobalContext* globalCtx) { this->dyna.actor.speedXZ *= 0.4f; isTeleporting = OBJRAILLIFT_SHOULD_TELEPORT(&this->dyna.actor); isPosUpdated = true; - if (((this->curPoint >= this->endPoint) && (this->direction > 0)) || ((this->curPoint <= 0) && (this->direction < 0))) { + if (((this->curPoint >= this->endPoint) && (this->direction > 0)) || + ((this->curPoint <= 0) && (this->direction < 0))) { if (!isTeleporting) { this->direction = -this->direction; this->waitTimer = 10; @@ -168,7 +168,8 @@ void ObjRaillift_Move(ObjRaillift* this, GlobalContext* globalCtx) { endPoint = &this->points[this->endPoint]; this->curPoint = this->direction > 0 ? 0 : this->endPoint; initialPoint = &this->points[0]; - if ((initialPoint->x != endPoint->x) || (initialPoint->y != endPoint->y) || (initialPoint->z != endPoint->z)) { + if ((initialPoint->x != endPoint->x) || (initialPoint->y != endPoint->y) || + (initialPoint->z != endPoint->z)) { this->actionFunc = ObjRaillift_Teleport; func_800C62BC(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); isPosUpdated = false; @@ -245,11 +246,12 @@ void ObjRaillift_Update(Actor* thisx, GlobalContext* globalCtx) { } this->cycle += 0xCE4; Math_StepToF(&this->maxHeight, 0.0f, 0.12f); - step = this->isWeightOn ? Math_CosS(fabsf(this->cycleSpeed) * 2048.0f) + 0.02f : Math_SinS(fabsf(this->cycleSpeed) * 2048.0f) + 0.02f; + step = this->isWeightOn ? Math_CosS(fabsf(this->cycleSpeed) * 2048.0f) + 0.02f + : Math_SinS(fabsf(this->cycleSpeed) * 2048.0f) + 0.02f; target = this->isWeightOn ? -8.0f : 0.0f; Math_StepToF(&this->cycleSpeed, target, step); this->dyna.actor.shape.yOffset = ((Math_SinS(this->cycle) * this->maxHeight) + this->cycleSpeed) * 10.0f; - dummy:; + dummy:; } if (OBJRAILLIFT_GET_TYPE(thisx) == DEKU_FLOWER_PLATFORM && this->dyna.actor.child != NULL) { if (this->dyna.actor.child->update == NULL) { @@ -269,8 +271,8 @@ void ObjRaillift_Draw(Actor* thisx, GlobalContext* globalCtx) { OPEN_DISPS(globalCtx->state.gfxCtx); func_8012C28C(globalCtx->state.gfxCtx); gSPSegment(POLY_OPA_DISP++, 0x08, - Gfx_TwoTexScrollEnvColor(globalCtx->state.gfxCtx, 0, globalCtx->gameplayFrames, 0, 32, 32, 1, 0, 0, - 32, 32, 0, 0, 0, 160)); + Gfx_TwoTexScrollEnvColor(globalCtx->state.gfxCtx, 0, globalCtx->gameplayFrames, 0, 32, 32, 1, 0, 0, 32, + 32, 0, 0, 0, 160)); gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_OPA_DISP++, D_06004BF0); CLOSE_DISPS(globalCtx->state.gfxCtx); diff --git a/tables/functions.txt b/tables/functions.txt index ba61e27e63..15829960b9 100644 --- a/tables/functions.txt +++ b/tables/functions.txt @@ -7576,21 +7576,21 @@ 0x809469C0:("func_809469C0",), 0x8094702C:("func_8094702C",), 0x80947668:("func_80947668",), - 0x80947F60:("func_80947F60",), - 0x809480C8:("func_809480C8",), - 0x80948264:("func_80948264",), - 0x809484EC:("func_809484EC",), - 0x809485A8:("func_809485A8",), - 0x80948788:("func_80948788",), - 0x8094899C:("func_8094899C",), - 0x80948A54:("func_80948A54",), + 0x80947F60:("EnClearTag_CreateDebrisEffect",), + 0x809480C8:("EnClearTag_CreateSmokeEffect",), + 0x80948264:("EnClearTag_CreateIsolatedSmokeEffect",), + 0x809484EC:("EnClearTag_CreateFlashEffect",), + 0x809485A8:("EnClearTag_CreateLightRayEffect",), + 0x80948788:("EnClearTag_CreateIsolatedLightRayEffect",), + 0x8094899C:("EnClearTag_CreateShockwaveEffect",), + 0x80948A54:("EnClearTag_CreateSplashEffect",), 0x80948BB4:("EnClearTag_Destroy",), 0x80948BC4:("EnClearTag_Init",), - 0x80949288:("func_80949288",), + 0x80949288:("EnClearTag_UpdateCamera",), 0x80949570:("EnClearTag_Update",), 0x809495D8:("EnClearTag_Draw",), - 0x809495F8:("func_809495F8",), - 0x80949BD4:("func_80949BD4",), + 0x809495F8:("EnClearTag_UpdateEffects",), + 0x80949BD4:("EnClearTag_DrawEffects",), 0x8094DEE0:("func_8094DEE0",), 0x8094DF90:("func_8094DF90",), 0x8094DFF8:("func_8094DFF8",), diff --git a/tools/permuter_settings.toml b/tools/permuter_settings.toml index 11ef7d726e..cbfcfd31f5 100644 --- a/tools/permuter_settings.toml +++ b/tools/permuter_settings.toml @@ -1,5 +1,6 @@ [preserve_macros] "g[DS]P.*" = "void" +"gs[DS]P.*" = "void" "gDma.*" = "void" "G_IM_SIZ_.*" = "int" "G_[AC]C.*" = "int"