From f19571dfcd92f09c1d187372405b5304bda495e5 Mon Sep 17 00:00:00 2001 From: engineer124 <47598039+engineer124@users.noreply.github.com> Date: Mon, 27 Dec 2021 15:24:45 +1100 Subject: [PATCH] Bigslime OK and Documented (#361) * git subrepo pull tools/asm-differ --force subrepo: subdir: "tools/asm-differ" merged: "d218cdf0" upstream: origin: "https://github.com/simonlindholm/asm-differ.git" branch: "main" commit: "d218cdf0" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * git subrepo pull tools/graphovl --force subrepo: subdir: "tools/graphovl" merged: "f5fe93d7" upstream: origin: "https://github.com/AngheloAlf/graphovl.git" branch: "master" commit: "f5fe93d7" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * git subrepo pull tools/ZAPD --force subrepo: subdir: "tools/ZAPD" merged: "e7a8a48c" upstream: origin: "https://github.com/zeldaret/ZAPD.git" branch: "master" commit: "e7a8a48c" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * Bring Bigslime over from old branch * Format * Improve docs * format * More cleanup * Fix Zero Vectors Name * Improve docs * Spelling/Grammar * Small typo * Extra space * Fix zapd merge conflict * tab * Fix remaining names * format * Better documentation * format * fix * Add names to identity matrices * Minor Cleanup * easier to read comments * Another touch-up * Missed a spot * one more... * typo * Another typo * Fix merge master, fix EnBigslime_ApplyDamageEffectBigslime * PR Feedback * Fix variable * Add in gZeroVec3f in new prs * Fix gZeroVec3f * gZeroVec3f * PR Feedback, move lots of static data inside functions * Use z_actor decomp of `func_800BE680` for better macro name * Naming gone wrong, but fixed now * Fix dList * Add an extra line of docs about shadows for a function * dList -> shadowDList * Next round of PR feedback * Document object file, still need to double check some * Small cleanup * Improve and fix many docs, unname unknown material texture * format * Oops * Clean up blobs from object file * Aha! I finally get what's going on * Remove Bigslime undefined_syms * Remove more undefined symbols Co-authored-by: Angie --- assets/xml/objects/object_bigslime.xml | 236 +- assets/xml/overlays/ovl_En_Bigslime.xml | 22 + include/variables.h | 8 +- spec | 3 +- src/code/z_debug_display.c | 2 +- src/code/z_eff_blure.c | 4 +- src/code/z_eff_spark.c | 2 +- src/code/z_eff_tire_mark.c | 2 +- src/code/z_effect_soft_sprite_old_init.c | 4 +- src/code/z_room.c | 4 +- .../actors/ovl_Bg_Goron_Oyu/z_bg_goron_oyu.c | 4 +- .../ovl_Bg_Hakugin_Post/z_bg_hakugin_post.c | 2 +- .../ovl_Bg_Kin2_Fence/z_bg_kin2_fence.c | 2 +- src/overlays/actors/ovl_Boss_02/z_boss_02.c | 4 +- src/overlays/actors/ovl_En_Baguo/z_en_baguo.c | 4 +- src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.c | 8 +- .../actors/ovl_En_Bigslime/z_en_bigslime.c | 3424 +++++++++++++++-- .../actors/ovl_En_Bigslime/z_en_bigslime.h | 18 +- src/overlays/actors/ovl_En_Dai/z_en_dai.c | 2 +- .../actors/ovl_En_Dekunuts/z_en_dekunuts.c | 2 +- .../actors/ovl_En_Dinofos/z_en_dinofos.c | 2 +- src/overlays/actors/ovl_En_Dnb/z_en_dnb.c | 6 +- src/overlays/actors/ovl_En_Dnk/z_en_dnk.c | 4 +- src/overlays/actors/ovl_En_Dnp/z_en_dnp.c | 2 +- src/overlays/actors/ovl_En_Dns/z_en_dns.c | 14 +- .../actors/ovl_En_Dodongo/z_en_dodongo.c | 8 +- src/overlays/actors/ovl_En_Fish2/z_en_fish2.c | 4 +- .../actors/ovl_En_Floormas/z_en_floormas.c | 6 +- src/overlays/actors/ovl_En_Gm/z_en_gm.c | 6 +- .../actors/ovl_En_Invadepoh/z_en_invadepoh.c | 21 +- .../actors/ovl_En_Kakasi/z_en_kakasi.c | 3 +- .../actors/ovl_En_Minislime/z_en_minislime.c | 2 +- .../actors/ovl_En_Mushi2/z_en_mushi2.c | 4 +- .../actors/ovl_En_Pametfrog/z_en_pametfrog.c | 149 +- .../actors/ovl_En_Pametfrog/z_en_pametfrog.h | 2 +- src/overlays/actors/ovl_En_Pm/z_en_pm.c | 10 +- .../ovl_En_Po_Sisters/z_en_po_sisters.c | 2 +- src/overlays/actors/ovl_En_Poh/z_en_poh.c | 8 +- .../actors/ovl_En_Railgibud/z_en_railgibud.c | 2 +- src/overlays/actors/ovl_En_Rr/z_en_rr.c | 2 +- .../actors/ovl_En_Suttari/z_en_suttari.c | 8 +- src/overlays/actors/ovl_En_Sw/z_en_sw.c | 6 +- src/overlays/actors/ovl_En_Test5/z_en_test5.c | 2 +- .../actors/ovl_En_Thiefbird/z_en_thiefbird.c | 2 +- src/overlays/actors/ovl_En_Tite/z_en_tite.c | 6 +- src/overlays/actors/ovl_En_Tk/z_en_tk.c | 4 +- src/overlays/actors/ovl_En_Trt/z_en_trt.c | 4 +- src/overlays/actors/ovl_En_Tru/z_en_tru.c | 30 +- src/overlays/actors/ovl_En_Wf/z_en_wf.c | 2 +- src/overlays/actors/ovl_Obj_Aqua/z_obj_aqua.c | 2 +- .../actors/ovl_Obj_HsStump/z_obj_hsstump.c | 2 +- .../actors/ovl_Obj_Iceblock/z_obj_iceblock.c | 4 +- .../ovl_Obj_Lightswitch/z_obj_lightswitch.c | 2 +- .../ovl_Obj_Tokei_Step/z_obj_tokei_step.c | 2 +- tools/actorfixer.py | 5 + tools/disasm/functions.txt | 6 +- tools/disasm/variables.txt | 8 +- undefined_syms.txt | 74 - 58 files changed, 3472 insertions(+), 711 deletions(-) create mode 100644 assets/xml/overlays/ovl_En_Bigslime.xml diff --git a/assets/xml/objects/object_bigslime.xml b/assets/xml/objects/object_bigslime.xml index d0238adef4..18b7025061 100644 --- a/assets/xml/objects/object_bigslime.xml +++ b/assets/xml/objects/object_bigslime.xml @@ -1,114 +1,130 @@  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/overlays/ovl_En_Bigslime.xml b/assets/xml/overlays/ovl_En_Bigslime.xml new file mode 100644 index 0000000000..9526daea6f --- /dev/null +++ b/assets/xml/overlays/ovl_En_Bigslime.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/include/variables.h b/include/variables.h index 4c35d93172..81e55391ba 100644 --- a/include/variables.h +++ b/include/variables.h @@ -1628,10 +1628,10 @@ extern PadMgr* padmgrContext; // extern UNK_TYPE4 D_801D1538; extern UNK_PTR D_801D1540; // extern f32 sFactorialTbl[13]; -extern Vec3f D_801D15B0; -extern Vec3s D_801D15BC; -extern Mtx D_801D1DE0; -extern MtxF D_801D1E20; +extern Vec3f gZeroVec3f; +extern Vec3s gZeroVec3s; +extern Mtx gIdentityMtx; +extern MtxF gIdentityMtxF; // extern u64* initialgspUcodeText; // extern u64* initialgspUcodeData; // extern UNK_TYPE1 D_801D1E70; diff --git a/spec b/spec index 77a44b7f32..6fa30a0201 100644 --- a/spec +++ b/spec @@ -1276,8 +1276,7 @@ beginseg name "ovl_En_Bigslime" compress include "build/src/overlays/actors/ovl_En_Bigslime/z_en_bigslime.o" - include "build/data/ovl_En_Bigslime/ovl_En_Bigslime.data.o" - include "build/data/ovl_En_Bigslime/ovl_En_Bigslime.reloc.o" + include "build/src/overlays/actors/ovl_En_Bigslime/ovl_En_Bigslime_reloc.o" endseg beginseg diff --git a/src/code/z_debug_display.c b/src/code/z_debug_display.c index a62d4ddb9e..ab3478fa1c 100644 --- a/src/code/z_debug_display.c +++ b/src/code/z_debug_display.c @@ -116,7 +116,7 @@ void func_800E992C(GlobalContext* globalCtx, s32 arg1) { OPEN_DISPS(globalCtx->state.gfxCtx); func_8012C560(globalCtx->state.gfxCtx); - gSPMatrix(POLY_XLU_DISP++, &D_801D1DE0, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPMatrix(POLY_XLU_DISP++, &gIdentityMtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_XLU_DISP++, func_800E99B0(globalCtx->state.gfxCtx, arg1)); CLOSE_DISPS(globalCtx->state.gfxCtx); diff --git a/src/code/z_eff_blure.c b/src/code/z_eff_blure.c index 5c890dd8d4..8875343662 100644 --- a/src/code/z_eff_blure.c +++ b/src/code/z_eff_blure.c @@ -807,7 +807,7 @@ void EffectBlure_DrawSimpleVertices(GraphicsContext* gfxCtx, EffectBlure* this, gSPMatrix(POLY_XLU_DISP++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPVertex(POLY_XLU_DISP++, &vtx[j], 4, 0); gSP2Triangles(POLY_XLU_DISP++, 0, 1, 3, 0, 0, 3, 2, 0); - gSPMatrix(POLY_XLU_DISP++, &D_801D1DE0, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPMatrix(POLY_XLU_DISP++, &gIdentityMtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); } } @@ -934,7 +934,7 @@ void EffectBlure_Draw(void* thisx, GraphicsContext* gfxCtx) { OPEN_DISPS(gfxCtx); - gSPMatrix(POLY_XLU_DISP++, &D_801D1DE0, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPMatrix(POLY_XLU_DISP++, &gIdentityMtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); if (this->numElements != 0) { if (this->flags == 0) { diff --git a/src/code/z_eff_spark.c b/src/code/z_eff_spark.c index b05ee2eca7..27ed1443db 100644 --- a/src/code/z_eff_spark.c +++ b/src/code/z_eff_spark.c @@ -145,7 +145,7 @@ void EffectSpark_Draw(void* thisx, GraphicsContext* gfxCtx) { OPEN_DISPS(gfxCtx); if (this != NULL) { - gSPMatrix(POLY_XLU_DISP++, &D_801D1DE0, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPMatrix(POLY_XLU_DISP++, &gIdentityMtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 0x26); gDPSetCycleType(POLY_XLU_DISP++, G_CYC_2CYCLE); diff --git a/src/code/z_eff_tire_mark.c b/src/code/z_eff_tire_mark.c index f8e3f11a81..517ee52512 100644 --- a/src/code/z_eff_tire_mark.c +++ b/src/code/z_eff_tire_mark.c @@ -228,7 +228,7 @@ void EffectTireMark_Draw(void* thisx, GraphicsContext* gfxCtx) { vtx = GRAPH_ALLOC(gfxCtx, ALIGN16(this->numElements * sizeof(Vtx[2]))); if (vtx != NULL) { - gSPMatrix(POLY_OPA_DISP++, &D_801D1DE0, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPMatrix(POLY_OPA_DISP++, &gIdentityMtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); POLY_OPA_DISP = Gfx_CallSetupDL(POLY_OPA_DISP++, 0x2C); gDPSetRenderMode(POLY_OPA_DISP++, G_RM_PASS, G_RM_ZB_CLD_SURF2); diff --git a/src/code/z_effect_soft_sprite_old_init.c b/src/code/z_effect_soft_sprite_old_init.c index 6deeb79434..4303d3db2d 100644 --- a/src/code/z_effect_soft_sprite_old_init.c +++ b/src/code/z_effect_soft_sprite_old_init.c @@ -590,7 +590,7 @@ extern Vec3f D_801AE3E0; void func_800B2364(GlobalContext* globalCtx, Vec3f* pos, Gfx* dList) { Vec3f posVec = D_801AE3E0; - EffectSsHahen_Spawn(globalCtx, pos, &D_801D15B0, &posVec, 1, 5, 1, 10, dList); + EffectSsHahen_Spawn(globalCtx, pos, &gZeroVec3f, &posVec, 1, 5, 1, 10, dList); } // EffectSsStick Spawn Functions @@ -1032,7 +1032,7 @@ void EffectSsDeadDs_Spawn(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, } void func_800B31BC(GlobalContext* globalCtx, Vec3f* pos, s16 scale, s16 scaleStep, s16 alpha, s32 life) { - EffectSsDeadDs_Spawn(globalCtx, pos, &D_801D15B0, &D_801D15B0, scale, scaleStep, alpha, life); + EffectSsDeadDs_Spawn(globalCtx, pos, &gZeroVec3f, &gZeroVec3f, scale, scaleStep, alpha, life); } // EffectSsIceSmoke Spawn Functions diff --git a/src/code/z_room.c b/src/code/z_room.c index fe4b51d68c..1685acc80e 100644 --- a/src/code/z_room.c +++ b/src/code/z_room.c @@ -18,14 +18,14 @@ void Room_DrawType0Mesh(GlobalContext* globalCtx, Room* room, u32 flags) { func_800BCBF4(&D_801C1D10, globalCtx); gSPSegment(gfxCtx->polyOpa.p++, 0x03, room->segment); func_8012C268(globalCtx); - gSPMatrix(gfxCtx->polyOpa.p++, &D_801D1DE0, G_MTX_MODELVIEW | G_MTX_LOAD); + gSPMatrix(gfxCtx->polyOpa.p++, &gIdentityMtx, G_MTX_MODELVIEW | G_MTX_LOAD); } if (flags & 2) { func_800BCC68(&D_801C1D10, globalCtx); gSPSegment(gfxCtx->polyXlu.p++, 0x03, room->segment); func_8012C2DC(globalCtx->state.gfxCtx); - gSPMatrix(gfxCtx->polyXlu.p++, &D_801D1DE0, G_MTX_MODELVIEW | G_MTX_LOAD); + gSPMatrix(gfxCtx->polyXlu.p++, &gIdentityMtx, G_MTX_MODELVIEW | G_MTX_LOAD); } mesh = &room->mesh->type0; diff --git a/src/overlays/actors/ovl_Bg_Goron_Oyu/z_bg_goron_oyu.c b/src/overlays/actors/ovl_Bg_Goron_Oyu/z_bg_goron_oyu.c index e32492e9c0..3d0f5c204b 100644 --- a/src/overlays/actors/ovl_Bg_Goron_Oyu/z_bg_goron_oyu.c +++ b/src/overlays/actors/ovl_Bg_Goron_Oyu/z_bg_goron_oyu.c @@ -133,7 +133,7 @@ void BgGoronOyu_SpawnParticles(BgGoronOyu* this, GlobalContext* globalCtx) { if (BgCheck_EntityRaycastFloor2(globalCtx, &globalCtx->colCtx, &poly, &pos1) < this->waterBoxPos.y) { pos1.y = this->waterBoxPos.y + 10.0f; - EffectSsIceSmoke_Spawn(globalCtx, &pos1, &vel1, &D_801D15B0, scale); + EffectSsIceSmoke_Spawn(globalCtx, &pos1, &vel1, &gZeroVec3f, scale); } pos2.x = (Rand_ZeroOne() * this->waterBoxXLength) + this->waterBoxPos.x; pos2.y = this->waterBoxPos.y + 100.0f; @@ -145,7 +145,7 @@ void BgGoronOyu_SpawnParticles(BgGoronOyu* this, GlobalContext* globalCtx) { if (BgCheck_EntityRaycastFloor2(globalCtx, &globalCtx->colCtx, &poly, &pos2) < this->waterBoxPos.y) { pos2.y = this->waterBoxPos.y + 10.0f; - EffectSsIceSmoke_Spawn(globalCtx, &pos2, &vel2, &D_801D15B0, scale); + EffectSsIceSmoke_Spawn(globalCtx, &pos2, &vel2, &gZeroVec3f, scale); } } } diff --git a/src/overlays/actors/ovl_Bg_Hakugin_Post/z_bg_hakugin_post.c b/src/overlays/actors/ovl_Bg_Hakugin_Post/z_bg_hakugin_post.c index 77a0cb2eea..cf628cc952 100644 --- a/src/overlays/actors/ovl_Bg_Hakugin_Post/z_bg_hakugin_post.c +++ b/src/overlays/actors/ovl_Bg_Hakugin_Post/z_bg_hakugin_post.c @@ -362,7 +362,7 @@ void func_80A9B554(BgHakuginPost* this, GlobalContext* globalCtx, BgHakuginPostU spA0.x = Math_SinS(val) * temp_f20 + spB8.x; spA0.y = (Rand_ZeroOne() * 1.2f - 0.1f) * spE4 + spB8.y; spA0.z = Math_CosS(val) * temp_f20 + spB8.z; - func_800B0E48(globalCtx, &spA0, &D_801D15B0, &D_80A9D8EC, &D_80A9D8E4, &D_80A9D8E8, + func_800B0E48(globalCtx, &spA0, &gZeroVec3f, &D_80A9D8EC, &D_80A9D8E4, &D_80A9D8E8, (Rand_Next() >> 0x1A) + 0x82, (Rand_Next() >> 0x1A) + 0x6E); } diff --git a/src/overlays/actors/ovl_Bg_Kin2_Fence/z_bg_kin2_fence.c b/src/overlays/actors/ovl_Bg_Kin2_Fence/z_bg_kin2_fence.c index cc92791fcc..ac56722384 100644 --- a/src/overlays/actors/ovl_Bg_Kin2_Fence/z_bg_kin2_fence.c +++ b/src/overlays/actors/ovl_Bg_Kin2_Fence/z_bg_kin2_fence.c @@ -149,7 +149,7 @@ void BgKin2Fence_SpawnEyeSparkles(BgKin2Fence* this, GlobalContext* globalCtx, s for (i = 0; i < 2; i++) { Matrix_MultiplyVector3fByState(&eyeSparkleSpawnPositions[mask][i], &sp58); - EffectSsKiraKira_SpawnDispersed(globalCtx, &sp58, &D_801D15B0, &D_801D15B0, &primColor, &envColor, 6000, -10); + EffectSsKiraKira_SpawnDispersed(globalCtx, &sp58, &gZeroVec3f, &gZeroVec3f, &primColor, &envColor, 6000, -10); } } diff --git a/src/overlays/actors/ovl_Boss_02/z_boss_02.c b/src/overlays/actors/ovl_Boss_02/z_boss_02.c index 97dc4437a8..f0455bb05f 100644 --- a/src/overlays/actors/ovl_Boss_02/z_boss_02.c +++ b/src/overlays/actors/ovl_Boss_02/z_boss_02.c @@ -555,8 +555,8 @@ void func_809DA460(Boss02Effects* effects, Vec3f* vec) { if ((effects->unk_24 == 0) || (effects->unk_24 == 3)) { effects->unk_24 = 4; effects->unk_00 = *vec; - Math_Vec3f_Copy(&effects->unk_0C, &D_801D15B0); - Math_Vec3f_Copy(&effects->unk_18, &D_801D15B0); + Math_Vec3f_Copy(&effects->unk_0C, &gZeroVec3f); + Math_Vec3f_Copy(&effects->unk_18, &gZeroVec3f); effects->unk_2C = 0xFF; effects->unk_34 = 0.0f; break; diff --git a/src/overlays/actors/ovl_En_Baguo/z_en_baguo.c b/src/overlays/actors/ovl_En_Baguo/z_en_baguo.c index ea7b318b71..c776dc6963 100644 --- a/src/overlays/actors/ovl_En_Baguo/z_en_baguo.c +++ b/src/overlays/actors/ovl_En_Baguo/z_en_baguo.c @@ -200,8 +200,8 @@ void EnBaguo_Idle(EnBaguo* this, GlobalContext* globalCtx) { yaw = this->actor.yawTowardsPlayer - this->actor.world.rot.y; absoluteYaw = ABS_ALT(yaw); - Math_Vec3f_Copy(&this->targetRotation, &D_801D15B0); - Math_Vec3f_Copy(&this->currentRotation, &D_801D15B0); + Math_Vec3f_Copy(&this->targetRotation, &gZeroVec3f); + Math_Vec3f_Copy(&this->currentRotation, &gZeroVec3f); if (absoluteYaw < 0x2000) { this->targetRotation.x = 2000.0f; } else { diff --git a/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.c b/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.c index 7c72083052..7ea98689ec 100644 --- a/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.c +++ b/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.c @@ -707,13 +707,13 @@ void EnBigpo_BurnAwayDeath(EnBigpo* this, GlobalContext* globalCtx) { // not sure what we're turning this into, but its based on the timer modifiedTimer = ((f32)((this->idleTimer * 10) + 80) * 1.4000001f); - func_800B3030(globalCtx, &tempVec, &D_80B6506C, &D_801D15B0, modifiedTimer, 0, 2); + func_800B3030(globalCtx, &tempVec, &D_80B6506C, &gZeroVec3f, modifiedTimer, 0, 2); tempVec.x = (2.0f * this->actor.world.pos.x) - tempVec.x; tempVec.z = (2.0f * this->actor.world.pos.z) - tempVec.z; - func_800B3030(globalCtx, &tempVec, &D_80B6506C, &D_801D15B0, modifiedTimer, 0, 2); + func_800B3030(globalCtx, &tempVec, &D_80B6506C, &gZeroVec3f, modifiedTimer, 0, 2); tempVec.x = this->actor.world.pos.x; tempVec.z = this->actor.world.pos.z; - func_800B3030(globalCtx, &tempVec, &D_80B6506C, &D_801D15B0, modifiedTimer, 0, 2); + func_800B3030(globalCtx, &tempVec, &D_80B6506C, &gZeroVec3f, modifiedTimer, 0, 2); } else if (this->idleTimer >= 28) { EnBigpo_SetupLanternDrop(this, globalCtx); @@ -1378,7 +1378,7 @@ void EnBigpo_DrawLantern(Actor* thisx, GlobalContext* globalCtx) { magnitude2 = (magnitude > 1.0f) ? (20.0f / magnitude) : (20.0f); Math_Vec3f_Scale(&vec1, magnitude2); } else { - Math_Vec3f_Copy(&vec1, &D_801D15B0); + Math_Vec3f_Copy(&vec1, &gZeroVec3f); } { diff --git a/src/overlays/actors/ovl_En_Bigslime/z_en_bigslime.c b/src/overlays/actors/ovl_En_Bigslime/z_en_bigslime.c index f67e80980d..42395579eb 100644 --- a/src/overlays/actors/ovl_En_Bigslime/z_en_bigslime.c +++ b/src/overlays/actors/ovl_En_Bigslime/z_en_bigslime.c @@ -1,10 +1,12 @@ /* * File: z_en_bigslime.c * Overlay: ovl_En_Bigslime - * Description: Mad Jelly (miniboss) + * Description: Mad Jelly & Gekko Miniboss: Fused Jellies & Gekko */ #include "z_en_bigslime.h" +#include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h" +#include "objects/object_bigslime/object_bigslime.h" #define FLAGS 0x00000235 @@ -12,40 +14,200 @@ void EnBigslime_Init(Actor* thisx, GlobalContext* globalCtx); void EnBigslime_Destroy(Actor* thisx, GlobalContext* globalCtx); -void EnBigslime_Update(Actor* thisx, GlobalContext* globalCtx); -void EnBigslime_Draw(Actor* thisx, GlobalContext* globalCtx); +void EnBigslime_UpdateGekko(Actor* thisx, GlobalContext* globalCtx); +void EnBigslime_DrawGekko(Actor* thisx, GlobalContext* globalCtx); -void func_808E6E80(EnBigslime* this, GlobalContext* globalCtx); -void func_808E6F50(EnBigslime* this, GlobalContext* globalCtx); -void func_808E7048(EnBigslime* this, GlobalContext* globalCtx); -void func_808E71FC(EnBigslime* this, GlobalContext* globalCtx); -void func_808E7354(EnBigslime* this, GlobalContext* globalCtx); -void func_808E7B80(EnBigslime* this, GlobalContext* globalCtx); -void func_808E84DC(EnBigslime* this, GlobalContext* globalCtx); -void func_808E89CC(EnBigslime* this, GlobalContext* globalCtx); -void func_808E8CCC(EnBigslime* this, GlobalContext* globalCtx); -void func_808E91EC(EnBigslime* this, GlobalContext* globalCtx); -void func_808E97D0(EnBigslime* this, GlobalContext* globalCtx); -void func_808E9AE0(EnBigslime* this, GlobalContext* globalCtx); -void func_808E9DD0(EnBigslime* this, GlobalContext* globalCtx); -void func_808E9FC0(EnBigslime* this, GlobalContext* globalCtx); -void func_808EA1C8(EnBigslime* this, GlobalContext* globalCtx); -void func_808EA2D0(EnBigslime* this, GlobalContext* globalCtx); -void func_808EA5E8(EnBigslime* this, GlobalContext* globalCtx); -void func_808EA7A4(EnBigslime* this, GlobalContext* globalCtx); -void func_808EA860(EnBigslime* this, GlobalContext* globalCtx); -void func_808EA9B8(EnBigslime* this, GlobalContext* globalCtx); -void func_808EAA8C(EnBigslime* this, GlobalContext* globalCtx); -void func_808EAB74(EnBigslime* this, GlobalContext* globalCtx); -void func_808EACEC(EnBigslime* this, GlobalContext* globalCtx); -void func_808EB0A8(EnBigslime* this, GlobalContext* globalCtx); -void func_808EB24C(EnBigslime* this, GlobalContext* globalCtx); -void func_808EB574(EnBigslime* this, GlobalContext* globalCtx); -void func_808EB708(EnBigslime* this, GlobalContext* globalCtx); -void func_808EB804(EnBigslime* this, GlobalContext* globalCtx); -void func_808EB8B4(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_EndCutscene(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_CutsceneStartBattle(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetupCutsceneNoticePlayer(EnBigslime* this); +void EnBigslime_CutsceneNoticePlayer(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetupCallMinislime(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_CallMinislime(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_MoveOnCeiling(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetupDrop(EnBigslime* this); +void EnBigslime_Drop(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetTargetVtxToWideCone(EnBigslime* this); +void EnBigslime_SquishFlat(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetupSquishFlat(EnBigslime* this); +void EnBigslime_SetTargetVtxToThinCone(EnBigslime* this); +void EnBigslime_SetTargetVtxToInverseCone(EnBigslime* this); +void EnBigslime_SetTargetVtxToStaticVtx(EnBigslime* this); +void EnBigslime_SetupRise(EnBigslime* this); +void EnBigslime_Rise(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_CutsceneGrabPlayer(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetupAttackPlayerInBigslime(EnBigslime* this); +void EnBigslime_AttackPlayerInBigslime(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetupWindupThrowPlayer(EnBigslime* this); +void EnBigslime_WindupThrowPlayer(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetupSetDynamicVtxThrowPlayer(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetDynamicVtxThrowPlayer(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetupFrozenGround(EnBigslime* this); +void EnBigslime_FrozenGround(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_Freeze(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_Melt(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetupFrozenFall(EnBigslime* this); +void EnBigslime_FrozenFall(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetupJumpGekko(EnBigslime* this); +void EnBigslime_JumpGekko(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetupIdleLookAround(EnBigslime* this); +void EnBigslime_IdleLookAround(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetupIdleNoticePlayer(EnBigslime* this); +void EnBigslime_IdleNoticePlayer(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetupThrowMinislime(EnBigslime* this); +void EnBigslime_DamageGekko(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_StunGekko(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_CutsceneFormBigslime(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetupFormBigslime(EnBigslime* this); +void EnBigslime_FormBigslime(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_CutsceneDefeat(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetupGekkoDespawn(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_GekkoDespawn(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetupFrogSpawn(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_FrogSpawn(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetupDespawn(EnBigslime* this); +void EnBigslime_Despawn(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetupInitEntrance(EnBigslime* this); +void EnBigslime_InitEntrance(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_ThrowMinislime(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetupCutscene(EnBigslime* this); +void EnBigslime_PlayCutscene(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_AddIceShardEffect(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_UpdateBigslime(Actor* thisx, GlobalContext* globalCtx); +void EnBigslime_DrawBigslime(Actor* thisx, GlobalContext* globalCtx); +void EnBigslime_DrawShatteringEffects(EnBigslime* this, GlobalContext* globalCtx); + +/* + * Bigslime Spherical Vtx Data: + * - The vtx data for Bigslime is put directly into the overlay + * - This vtx is directly manipulated in a significant number of functions in this overlay + * - The initialized vtx data has the following properties: (some of this data may change as overlay functions are + * called) + * -- It is a sphere with radius 1000 + * -- There are 162 vertices numbered top to bottom along the y-axis, + * with vertex 0 being the top apex, and vertex 161 being the bottom apex + * -- There are 4 entire copies of the sphere + * --- The first 3 copies are identical + * --- All 4 copies have identical coordinates and number of vertices + * --- See below (variants) for the uses of these copies + * + * Vtx Rings: + * - The vtx mesh was designed to be seperated into distint "rings" of vertices and faces + * from top to bottom at discrete y-intervals + * - These different rings of vertices lie in the xzPlane along discrete y-direction steps of the sphere + * -- There are the single apex nodes at the top (vertex 0 y-coordiante 1000) and bottom (vertex 161 + * y-coordiante -1000) + * -- There are a cluster of vertices (vertex 1-5) which all have y-coordinate 962 + * and form a ring of vertices in the xz-plane + * -- There are a cluster of vertices (vertex 6-15) which all have y-coordinate around 870 + * and form a ring of vertices in the xz-plane + * -- So on and so forth (See sVtxRingStartIndex) + * -- BIGSLIME_NUM_RING_VTX: There are a total of 13 rings of vertices including the two single apex vertex + * -- BIGSLIME_NUM_RING_FACES: There are a total of 12 rings of faces between the rings of vertices + * - A collider is assigned to each of the 12 rings of faces for bigslime + * + * Three Variants of the Spherical Vtx: + * Static (1 copy): + * - Fixed mesh, no values are ever modified + * - Used as reference to store the original vertices + * - Never drawn, only used in calculations + * Dynamic (2 copies): + * - Coordinate are updated and deformed, mesh is drawn as the deforming Fused Jelly. + * - Initially Identical to Static. + * - Two copies are used that alternate every frame and copies over coordinates/normals immediately. + * One copy is the version that is drawn, and the other copy is updated in the background + * - Alpha values remain fixed + * Target (1 copy): + * - Used to define the target vertices/shape for the dynamic vertices to smoothly step to. + * - When frozen: + * -- The current target vertices are set to the current dynamic vertices + * -- These are the vertices that are used to draw the frozen Fused Jelly + * -- The alpha values are used for the frozen effects alpha + */ + +// Reference data: used to store the original vertices +static Vtx sBigslimeStaticVtx[BIGSLIME_NUM_VTX] = { +#include "overlays/ovl_En_Bigslime/sBigslimeStaticVtx.vtx.inc" +}; + +// Dynamic data: used to draw the real shape and has 2 states +static Vtx sBigslimeDynamicVtx[2][BIGSLIME_NUM_VTX] = { + { +#include "overlays/ovl_En_Bigslime/sBigslimeDynamicState0Vtx.vtx.inc" + }, + { +#include "overlays/ovl_En_Bigslime/sBigslimeDynamicState1Vtx.vtx.inc" + }, +}; + +// Target data: used to define the shape the dynamic vertices morph to +static Vtx sBigslimeTargetVtx[BIGSLIME_NUM_VTX] = { +#include "overlays/ovl_En_Bigslime/sBigslimeTargetVtx.vtx.inc" +}; + +/* + * Triangle face + * Connectivity matrix for mesh above. Covers every triangle in the sphere + * 320 triangles x 3 vertices per triangle + * Purpose: indices to calculate/update normal vector for lighting calculations + * "EnBigslimeTri" struct based on "Tri" struct from gbi.h, but without the flag + */ +static EnBigslimeTri sEnbigslimeTri[BIGSLIME_NUM_FACES] = { + { 0, 2, 1 }, { 1, 7, 6 }, { 1, 2, 7 }, { 2, 8, 7 }, { 6, 17, 16 }, { 6, 7, 17 }, + { 8, 19, 18 }, { 7, 8, 18 }, { 7, 18, 17 }, { 9, 21, 20 }, { 0, 3, 2 }, { 2, 9, 8 }, + { 2, 3, 9 }, { 3, 10, 9 }, { 8, 20, 19 }, { 8, 9, 20 }, { 10, 22, 21 }, { 9, 10, 21 }, + { 0, 4, 3 }, { 3, 11, 10 }, { 3, 4, 11 }, { 4, 12, 11 }, { 10, 23, 22 }, { 10, 11, 23 }, + { 12, 25, 24 }, { 11, 12, 24 }, { 11, 24, 23 }, { 13, 27, 26 }, { 0, 5, 4 }, { 4, 13, 12 }, + { 4, 5, 13 }, { 5, 14, 13 }, { 12, 26, 25 }, { 12, 13, 26 }, { 14, 28, 27 }, { 13, 14, 27 }, + { 0, 1, 5 }, { 5, 15, 14 }, { 5, 1, 15 }, { 1, 6, 15 }, { 14, 29, 28 }, { 14, 15, 29 }, + { 6, 16, 30 }, { 15, 6, 30 }, { 15, 30, 29 }, { 16, 32, 31 }, { 16, 17, 32 }, { 17, 33, 32 }, + { 17, 18, 33 }, { 18, 34, 33 }, { 18, 19, 34 }, { 19, 35, 34 }, { 19, 20, 36 }, { 20, 37, 36 }, + { 20, 21, 37 }, { 21, 38, 37 }, { 21, 22, 38 }, { 22, 39, 38 }, { 19, 36, 35 }, { 22, 40, 39 }, + { 22, 23, 40 }, { 23, 41, 40 }, { 23, 24, 41 }, { 24, 42, 41 }, { 24, 25, 42 }, { 25, 43, 42 }, + { 25, 26, 44 }, { 26, 45, 44 }, { 26, 27, 45 }, { 27, 46, 45 }, { 27, 28, 46 }, { 28, 47, 46 }, + { 25, 44, 43 }, { 28, 48, 47 }, { 28, 29, 48 }, { 29, 49, 48 }, { 29, 30, 49 }, { 30, 50, 49 }, + { 30, 16, 50 }, { 16, 31, 50 }, { 31, 32, 51 }, { 32, 52, 51 }, { 32, 33, 52 }, { 33, 53, 52 }, + { 33, 34, 53 }, { 34, 54, 53 }, { 34, 35, 54 }, { 35, 55, 54 }, { 35, 36, 55 }, { 36, 56, 55 }, + { 36, 37, 56 }, { 37, 57, 56 }, { 37, 38, 57 }, { 38, 58, 57 }, { 38, 39, 58 }, { 39, 59, 58 }, + { 39, 40, 59 }, { 40, 60, 59 }, { 40, 41, 60 }, { 41, 61, 60 }, { 41, 42, 61 }, { 42, 62, 61 }, + { 42, 43, 62 }, { 43, 63, 62 }, { 51, 72, 71 }, { 51, 52, 72 }, { 52, 73, 72 }, { 52, 53, 73 }, + { 53, 74, 73 }, { 53, 54, 74 }, { 54, 75, 74 }, { 54, 55, 75 }, { 55, 76, 75 }, { 55, 56, 76 }, + { 56, 77, 76 }, { 56, 57, 77 }, { 57, 78, 77 }, { 57, 58, 78 }, { 58, 79, 78 }, { 58, 59, 79 }, + { 59, 80, 79 }, { 59, 60, 80 }, { 60, 81, 80 }, { 60, 61, 81 }, { 61, 82, 81 }, { 61, 62, 82 }, + { 62, 83, 82 }, { 62, 63, 83 }, { 71, 72, 91 }, { 72, 92, 91 }, { 72, 73, 92 }, { 73, 93, 92 }, + { 73, 74, 93 }, { 74, 94, 93 }, { 74, 75, 94 }, { 75, 95, 94 }, { 75, 76, 95 }, { 76, 96, 95 }, + { 76, 77, 96 }, { 77, 97, 96 }, { 77, 78, 97 }, { 78, 98, 97 }, { 78, 79, 98 }, { 79, 99, 98 }, + { 79, 80, 99 }, { 80, 100, 99 }, { 80, 81, 100 }, { 81, 101, 100 }, { 81, 82, 101 }, { 82, 102, 101 }, + { 82, 83, 102 }, { 83, 103, 102 }, { 91, 112, 111 }, { 91, 92, 112 }, { 92, 113, 112 }, { 92, 93, 113 }, + { 93, 114, 113 }, { 93, 94, 114 }, { 94, 115, 114 }, { 94, 95, 115 }, { 95, 116, 115 }, { 95, 96, 116 }, + { 96, 117, 116 }, { 96, 97, 117 }, { 97, 118, 117 }, { 97, 98, 118 }, { 98, 119, 118 }, { 98, 99, 119 }, + { 99, 120, 119 }, { 99, 100, 120 }, { 100, 121, 120 }, { 100, 101, 121 }, { 101, 122, 121 }, { 101, 102, 122 }, + { 102, 123, 122 }, { 102, 103, 123 }, { 43, 44, 63 }, { 44, 64, 63 }, { 44, 45, 64 }, { 45, 65, 64 }, + { 45, 46, 65 }, { 46, 66, 65 }, { 46, 47, 66 }, { 47, 67, 66 }, { 47, 48, 67 }, { 48, 68, 67 }, + { 48, 49, 68 }, { 49, 69, 68 }, { 49, 50, 69 }, { 50, 70, 69 }, { 50, 31, 70 }, { 31, 51, 70 }, + { 63, 84, 83 }, { 63, 64, 84 }, { 64, 85, 84 }, { 64, 65, 85 }, { 65, 86, 85 }, { 65, 66, 86 }, + { 66, 87, 86 }, { 66, 67, 87 }, { 67, 88, 87 }, { 67, 68, 88 }, { 68, 89, 88 }, { 68, 69, 89 }, + { 69, 90, 89 }, { 69, 70, 90 }, { 70, 71, 90 }, { 70, 51, 71 }, { 83, 84, 103 }, { 84, 104, 103 }, + { 84, 85, 104 }, { 85, 105, 104 }, { 85, 86, 105 }, { 86, 106, 105 }, { 86, 87, 106 }, { 87, 107, 106 }, + { 87, 88, 107 }, { 88, 108, 107 }, { 88, 89, 108 }, { 89, 109, 108 }, { 89, 90, 109 }, { 90, 110, 109 }, + { 90, 71, 110 }, { 71, 91, 110 }, { 103, 124, 123 }, { 103, 104, 124 }, { 104, 125, 124 }, { 104, 105, 125 }, + { 105, 126, 125 }, { 105, 106, 126 }, { 106, 127, 126 }, { 106, 107, 127 }, { 107, 128, 127 }, { 107, 108, 128 }, + { 108, 129, 128 }, { 108, 109, 129 }, { 109, 130, 129 }, { 109, 110, 130 }, { 110, 111, 130 }, { 110, 91, 111 }, + { 161, 160, 156 }, { 155, 146, 160 }, { 146, 156, 160 }, { 146, 147, 156 }, { 144, 145, 155 }, { 145, 146, 155 }, + { 145, 131, 146 }, { 131, 147, 146 }, { 131, 132, 147 }, { 134, 135, 149 }, { 161, 156, 157 }, { 147, 148, 156 }, + { 148, 157, 156 }, { 148, 149, 157 }, { 132, 133, 147 }, { 133, 148, 147 }, { 133, 134, 148 }, { 134, 149, 148 }, + { 161, 157, 158 }, { 149, 150, 157 }, { 150, 158, 157 }, { 150, 151, 158 }, { 135, 136, 149 }, { 136, 150, 149 }, + { 136, 137, 150 }, { 137, 151, 150 }, { 137, 138, 151 }, { 140, 141, 153 }, { 161, 158, 159 }, { 151, 152, 158 }, + { 152, 159, 158 }, { 152, 153, 159 }, { 138, 139, 151 }, { 139, 152, 151 }, { 139, 140, 152 }, { 140, 153, 152 }, + { 161, 159, 160 }, { 153, 154, 159 }, { 154, 160, 159 }, { 154, 155, 160 }, { 141, 142, 153 }, { 142, 154, 153 }, + { 142, 143, 154 }, { 143, 155, 154 }, { 143, 144, 155 }, { 111, 131, 145 }, { 111, 112, 131 }, { 112, 132, 131 }, + { 112, 113, 132 }, { 113, 114, 132 }, { 114, 133, 132 }, { 114, 115, 133 }, { 115, 116, 134 }, { 116, 135, 134 }, + { 116, 117, 135 }, { 117, 118, 135 }, { 118, 136, 135 }, { 118, 119, 136 }, { 115, 134, 133 }, { 119, 137, 136 }, + { 119, 120, 137 }, { 120, 138, 137 }, { 120, 121, 138 }, { 121, 122, 138 }, { 122, 139, 138 }, { 122, 123, 139 }, + { 139, 123, 140 }, { 140, 123, 124 }, { 140, 124, 141 }, { 141, 124, 125 }, { 141, 125, 126 }, { 141, 126, 142 }, + { 142, 127, 143 }, { 143, 127, 128 }, { 143, 128, 144 }, { 144, 128, 129 }, { 144, 129, 130 }, { 144, 130, 145 }, + { 142, 126, 127 }, { 130, 111, 145 }, +}; -#if 0 const ActorInit En_Bigslime_InitVars = { ACTOR_EN_BIGSLIME, ACTORCAT_BOSS, @@ -54,289 +216,2941 @@ const ActorInit En_Bigslime_InitVars = { sizeof(EnBigslime), (ActorFunc)EnBigslime_Init, (ActorFunc)EnBigslime_Destroy, - (ActorFunc)EnBigslime_Update, - (ActorFunc)EnBigslime_Draw, + (ActorFunc)EnBigslime_UpdateGekko, + (ActorFunc)EnBigslime_DrawGekko, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_808F02A0 = { - { COLTYPE_NONE, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_NO_PUSH | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x20000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NONE, BUMP_ON | BUMP_HOOKABLE, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_NO_PUSH | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x20000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NONE, + BUMP_ON | BUMP_HOOKABLE, + OCELEM_ON, + }, { 30, 60, 0, { 0, 0, 0 } }, }; -// sColChkInfoInit -static CollisionCheckInfoInit D_808F02CC = { 10, 100, 100, 50 }; +static CollisionCheckInfoInit sColChkInfoInit = { 10, 100, 100, 50 }; -// static DamageTable sDamageTable = { -static DamageTable D_808F02D4 = { - /* Deku Nut */ DMG_ENTRY(0, 0x1), - /* Deku Stick */ DMG_ENTRY(1, 0x0), - /* Horse trample */ DMG_ENTRY(0, 0x0), - /* Explosives */ DMG_ENTRY(1, 0xF), - /* Zora boomerang */ DMG_ENTRY(1, 0x0), - /* Normal arrow */ DMG_ENTRY(1, 0x0), - /* UNK_DMG_0x06 */ DMG_ENTRY(0, 0x0), - /* Hookshot */ DMG_ENTRY(0, 0xE), - /* Goron punch */ DMG_ENTRY(1, 0xF), - /* Sword */ DMG_ENTRY(1, 0x0), - /* Goron pound */ DMG_ENTRY(1, 0xF), - /* Fire arrow */ DMG_ENTRY(1, 0x2), - /* Ice arrow */ DMG_ENTRY(1, 0x3), - /* Light arrow */ DMG_ENTRY(2, 0x4), - /* Goron spikes */ DMG_ENTRY(1, 0xF), - /* Deku spin */ DMG_ENTRY(0, 0xD), - /* Deku bubble */ DMG_ENTRY(1, 0x0), - /* Deku launch */ DMG_ENTRY(0, 0x0), - /* UNK_DMG_0x12 */ DMG_ENTRY(0, 0x1), - /* Zora barrier */ DMG_ENTRY(0, 0x5), - /* Normal shield */ DMG_ENTRY(0, 0x0), - /* Light ray */ DMG_ENTRY(0, 0x0), - /* Thrown object */ DMG_ENTRY(1, 0xF), - /* Zora punch */ DMG_ENTRY(1, 0x0), - /* Spin attack */ DMG_ENTRY(1, 0x0), - /* Sword beam */ DMG_ENTRY(1, 0x0), - /* Normal Roll */ DMG_ENTRY(0, 0x0), - /* UNK_DMG_0x1B */ DMG_ENTRY(0, 0x0), - /* UNK_DMG_0x1C */ DMG_ENTRY(0, 0x0), - /* Unblockable */ DMG_ENTRY(0, 0x0), - /* UNK_DMG_0x1E */ DMG_ENTRY(0, 0x0), - /* Powder Keg */ DMG_ENTRY(1, 0xF), +typedef enum { + /* 0x0 */ BIGSLIME_DMGEFF_NONE, + /* 0x0 */ BIGSLIME_DMGEFF_STUN, + /* 0x2 */ BIGSLIME_DMGEFF_FIRE, + /* 0x3 */ BIGSLIME_DMGEFF_ICE, + /* 0x4 */ BIGSLIME_DMGEFF_LIGHT, + /* 0x5 */ BIGSLIME_DMGEFF_ELECTRIC_STUN, + /* 0xD */ BIGSLIME_DMGEFF_DEKU_STUN = 0xD, + /* 0xE */ BIGSLIME_DMGEFF_HOOKSHOT, + /* 0xF */ BIGSLIME_DMGEFF_BREAK_ICE, +} BigslimeDamageEffect; + +static DamageTable sDamageTable = { + /* Deku Nut */ DMG_ENTRY(0, BIGSLIME_DMGEFF_STUN), + /* Deku Stick */ DMG_ENTRY(1, BIGSLIME_DMGEFF_NONE), + /* Horse trample */ DMG_ENTRY(0, BIGSLIME_DMGEFF_NONE), + /* Explosives */ DMG_ENTRY(1, BIGSLIME_DMGEFF_BREAK_ICE), + /* Zora boomerang */ DMG_ENTRY(1, BIGSLIME_DMGEFF_NONE), + /* Normal arrow */ DMG_ENTRY(1, BIGSLIME_DMGEFF_NONE), + /* UNK_DMG_0x06 */ DMG_ENTRY(0, BIGSLIME_DMGEFF_NONE), + /* Hookshot */ DMG_ENTRY(0, BIGSLIME_DMGEFF_HOOKSHOT), + /* Goron punch */ DMG_ENTRY(1, BIGSLIME_DMGEFF_BREAK_ICE), + /* Sword */ DMG_ENTRY(1, BIGSLIME_DMGEFF_NONE), + /* Goron pound */ DMG_ENTRY(1, BIGSLIME_DMGEFF_BREAK_ICE), + /* Fire arrow */ DMG_ENTRY(1, BIGSLIME_DMGEFF_FIRE), + /* Ice arrow */ DMG_ENTRY(1, BIGSLIME_DMGEFF_ICE), + /* Light arrow */ DMG_ENTRY(2, BIGSLIME_DMGEFF_LIGHT), + /* Goron spikes */ DMG_ENTRY(1, BIGSLIME_DMGEFF_BREAK_ICE), + /* Deku spin */ DMG_ENTRY(0, BIGSLIME_DMGEFF_DEKU_STUN), + /* Deku bubble */ DMG_ENTRY(1, BIGSLIME_DMGEFF_NONE), + /* Deku launch */ DMG_ENTRY(0, BIGSLIME_DMGEFF_NONE), + /* UNK_DMG_0x12 */ DMG_ENTRY(0, BIGSLIME_DMGEFF_STUN), + /* Zora barrier */ DMG_ENTRY(0, BIGSLIME_DMGEFF_ELECTRIC_STUN), + /* Normal shield */ DMG_ENTRY(0, BIGSLIME_DMGEFF_NONE), + /* Light ray */ DMG_ENTRY(0, BIGSLIME_DMGEFF_NONE), + /* Thrown object */ DMG_ENTRY(1, BIGSLIME_DMGEFF_BREAK_ICE), + /* Zora punch */ DMG_ENTRY(1, BIGSLIME_DMGEFF_NONE), + /* Spin attack */ DMG_ENTRY(1, BIGSLIME_DMGEFF_NONE), + /* Sword beam */ DMG_ENTRY(1, BIGSLIME_DMGEFF_NONE), + /* Normal Roll */ DMG_ENTRY(0, BIGSLIME_DMGEFF_NONE), + /* UNK_DMG_0x1B */ DMG_ENTRY(0, BIGSLIME_DMGEFF_NONE), + /* UNK_DMG_0x1C */ DMG_ENTRY(0, BIGSLIME_DMGEFF_NONE), + /* Unblockable */ DMG_ENTRY(0, BIGSLIME_DMGEFF_NONE), + /* UNK_DMG_0x1E */ DMG_ENTRY(0, BIGSLIME_DMGEFF_NONE), + /* Powder Keg */ DMG_ENTRY(1, BIGSLIME_DMGEFF_BREAK_ICE), }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_808F0338[] = { +// Start vtx numbers for each ring in the vtx sphere +static s32 sVtxRingStartIndex[] = { + 0, 1, 6, 16, 31, 51, 71, 91, 111, 131, 146, 156, 161, BIGSLIME_NUM_VTX, +}; + +static AnimationHeader* sGekkoAttackAnimations[] = { + &gGekkoJabPunchAnim, + &gGekkoHookPunchAnim, + &gGekkoKickAnim, +}; + +static InitChainEntry sInitChain[] = { ICHAIN_S8(hintId, 95, ICHAIN_CONTINUE), ICHAIN_F32_DIV1000(targetArrowOffset, -13221, ICHAIN_CONTINUE), ICHAIN_F32_DIV1000(gravity, -2000, ICHAIN_CONTINUE), ICHAIN_U8(targetMode, 5, ICHAIN_STOP), }; -#endif - -extern ColliderCylinderInit D_808F02A0; -extern CollisionCheckInfoInit D_808F02CC; -extern DamageTable D_808F02D4; -extern InitChainEntry D_808F0338[]; - -extern UNK_TYPE D_060010F4; -extern UNK_TYPE D_06001B08; -extern UNK_TYPE D_0600276C; -extern UNK_TYPE D_06002E0C; -extern UNK_TYPE D_0600347C; -extern UNK_TYPE D_060039C4; -extern UNK_TYPE D_060066B4; -extern UNK_TYPE D_060069FC; -extern UNK_TYPE D_06007790; -extern UNK_TYPE D_0600F048; -extern UNK_TYPE D_0600F990; -extern UNK_TYPE D_0600FB40; -extern UNK_TYPE D_06010530; -extern UNK_TYPE D_06011050; -extern UNK_TYPE D_060113B0; - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/EnBigslime_Init.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/EnBigslime_Destroy.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E5388.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E5430.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E5484.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E574C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E5988.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E5A00.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E5BB0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E5ED4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E601C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E616C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E62B8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E64D4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E6538.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E6570.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E670C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E6828.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E68AC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E69AC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E69F4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E6A70.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E6B08.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E6B68.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E6C18.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E6C44.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E6C70.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E6CC8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E6D58.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E6E80.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E6F08.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E6F50.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E6FE0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E7048.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E7154.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E71FC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E732C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E7354.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E75D8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E7770.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E7AF8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E7B80.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E7D68.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E8064.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E836C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E844C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E84DC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E88B8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E89CC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E8C38.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E8CCC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E90A4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E91EC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E9778.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E97D0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E994C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E9AE0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E9DA8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E9DD0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E9F38.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E9FC0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EA14C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EA1C8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EA264.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EA2D0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EA538.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EA5E8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EA748.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EA7A4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EA80C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EA860.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EA8FC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EA9B8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EAA40.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EAA8C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EAAF8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EAB74.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EABCC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EACEC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EAEBC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EB0A8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EB178.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EB24C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EB328.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EB574.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EB690.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EB708.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EB7F0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EB804.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EB83C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EB8B4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EB9E8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EBBE4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EBED0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EC158.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EC354.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/EnBigslime_Update.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EC708.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EC990.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808ECD14.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808ED07C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/EnBigslime_Draw.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808ED3F4.s") +void EnBigslime_Init(Actor* thisx, GlobalContext* globalCtx) { + // gSaveContext.weekEventReg[KEY] = VALUE + // KEY | VALUE + static s32 isFrogReturnedFlags[] = { + (32 << 8) | 0x40, // Woodfall Temple Frog Returned + (32 << 8) | 0x80, // Great Bay Temple Frog Returned + (33 << 8) | 0x01, // Southern Swamp Frog Returned + (33 << 8) | 0x02, // Laundry Pool Frog Returned + }; + EnBigslime* this = THIS; + GlobalContext* globalCtx2 = globalCtx; + s32 i; + + Actor_ProcessInitChain(&this->actor, sInitChain); + CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gGekkoSkel, &gGekkoLookAroundAnim, this->jointTable, + this->morphTable, GEKKO_LIMB_MAX); + + for (i = 0; i < BIGSLIME_NUM_RING_FACES; i++) { + Collider_InitAndSetCylinder(globalCtx, &this->bigslimeCollider[i], &this->actor, &sCylinderInit); + } + + this->bigslimeCollider[0].base.atFlags &= ~AT_ON; + Collider_InitAndSetCylinder(globalCtx, &this->gekkoCollider, &this->actor, &sCylinderInit); + this->gekkoCollider.base.colType = COLTYPE_HIT6; + this->gekkoCollider.info.elemType = ELEMTYPE_UNK1; + this->gekkoCollider.base.atFlags &= ~AT_ON; + this->gekkoCollider.base.ocFlags1 &= ~OC1_NO_PUSH; + this->actor.params = CLAMP(this->actor.params, 1, 4); + + if (Actor_GetRoomCleared(globalCtx, globalCtx->roomCtx.currRoom.num)) { + Actor_MarkForDeath(&this->actor); + if (!(gSaveContext.weekEventReg[isFrogReturnedFlags[this->actor.params - 1] >> 8] & + (u8)isFrogReturnedFlags[this->actor.params - 1])) { + Actor_Spawn(&globalCtx2->actorCtx, globalCtx, ACTOR_EN_MINIFROG, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, 0, this->actor.shape.rot.y, 0, + this->actor.params); + } + } else { + this->cutscene = this->actor.cutscene; + this->actor.scale.x = this->actor.scale.z = 0.15f; + this->actor.scale.y = 0.075f; + this->vtxScaleX = this->vtxScaleZ = 0.015000001f; + this->actor.home.pos.x = GBT_ROOM_5_CENTER_X; + this->actor.home.pos.y = GBT_ROOM_5_MAX_Y - 75.0f; + this->actor.home.pos.z = GBT_ROOM_5_CENTER_Z; + for (i = 0; i < MINISLIME_NUM_SPAWN; i++) { + this->minislime[i] = (EnMinislime*)Actor_SpawnAsChild(&globalCtx2->actorCtx, &this->actor, globalCtx, + ACTOR_EN_MINISLIME, 0.0f, 0.0f, 0.0f, 0, 0, 0, i); + if (this->minislime[i] == NULL) { + for (i = i - 1; i >= 0; i--) { + Actor_MarkForDeath(&this->minislime[i]->actor); + } + + Actor_MarkForDeath(&this->actor); + return; + } + } + + this->minislimeFrozenTexAnim = Lib_SegmentedToVirtual(&gMinislimeFrozenTexAnim); + this->bigslimeFrozenTexAnim = Lib_SegmentedToVirtual(&gBigslimeFrozenTexAnim); + this->iceShardTexAnim = Lib_SegmentedToVirtual(&gBigslimeIceShardTexAnim); + this->actor.world.pos.y = GBT_ROOM_5_MIN_Y; + this->actor.flags &= ~1; + this->actor.shape.shadowAlpha = 255; + this->gekkoScale = 0.007f; + this->actor.shape.rot.y = 0; + this->minislimeToThrow = this->minislime[0]; + EnBigslime_SetupInitEntrance(this); + } +} + +void EnBigslime_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnBigslime* this = THIS; + s32 i; + + for (i = 0; i < BIGSLIME_NUM_RING_FACES; i++) { + Collider_DestroyCylinder(globalCtx, &this->bigslimeCollider[i]); + } + + Collider_DestroyCylinder(globalCtx, &this->gekkoCollider); + func_801A72CC(&this->gekkoProjectedPos); +} + +void EnBigslime_DynamicVtxCopyState(EnBigslime* this) { + Vtx* dynamicVtxDest; + Vtx* dynamicVtxSrc; + s32 i; + s32 j; + + for (i = 0; i < BIGSLIME_NUM_VTX; i++) { + dynamicVtxDest = &sBigslimeDynamicVtx[this->dynamicVtxState][i]; + dynamicVtxSrc = &sBigslimeDynamicVtx[this->dynamicVtxState ^ 1][i]; + for (j = 0; j < 3; j++) { + dynamicVtxDest->n.ob[j] = dynamicVtxSrc->n.ob[j]; + dynamicVtxDest->n.n[j] = dynamicVtxSrc->n.n[j]; + } + } +} + +void EnBigslime_Vec3fNormalize(Vec3f* vec) { + f32 magnitude = Math3D_Vec3fMagnitude(vec); + + if (magnitude > 1.0f) { + Math_Vec3f_Scale(vec, 1.0f / magnitude); + } +} + +/** + * Updates the surface normal vector of each vertex in the fused jelly mesh + * each frame as the dynamic vtx is constantly changing shape + */ +void EnBigslime_UpdateSurfaceNorm(EnBigslime* this) { + Vec3f vtxNorm[BIGSLIME_NUM_VTX]; + Vec3f vecTriEdge1; + Vec3f vecTriEdge2; + Vec3f vecTriNorm; + Vec3f* vtxNormAddr; + Vtx* dynamicVtx; + Vtx* dynamicVtx12; + Vtx* dynamicVtx0; + s32 i; + + for (i = 0; i < BIGSLIME_NUM_VTX; i++) { + Math_Vec3f_Copy(&vtxNorm[i], &gZeroVec3f); + } + + for (i = 0; i < BIGSLIME_NUM_FACES; i++) { + dynamicVtx0 = &sBigslimeDynamicVtx[this->dynamicVtxState][sEnbigslimeTri[i].v[0]]; + dynamicVtx12 = &sBigslimeDynamicVtx[this->dynamicVtxState][sEnbigslimeTri[i].v[1]]; + vecTriEdge1.x = dynamicVtx12->n.ob[0] - dynamicVtx0->n.ob[0]; + vecTriEdge1.y = dynamicVtx12->n.ob[1] - dynamicVtx0->n.ob[1]; + vecTriEdge1.z = dynamicVtx12->n.ob[2] - dynamicVtx0->n.ob[2]; + + dynamicVtx12 = &sBigslimeDynamicVtx[this->dynamicVtxState][sEnbigslimeTri[i].v[2]]; + vecTriEdge2.x = dynamicVtx12->n.ob[0] - dynamicVtx0->n.ob[0]; + vecTriEdge2.y = dynamicVtx12->n.ob[1] - dynamicVtx0->n.ob[1]; + vecTriEdge2.z = dynamicVtx12->n.ob[2] - dynamicVtx0->n.ob[2]; + + Math3D_CrossProduct(&vecTriEdge1, &vecTriEdge2, &vecTriNorm); + EnBigslime_Vec3fNormalize(&vecTriNorm); + + Math_Vec3f_Sum(&vtxNorm[sEnbigslimeTri[i].v[0]], &vecTriNorm, &vtxNorm[sEnbigslimeTri[i].v[0]]); + Math_Vec3f_Sum(&vtxNorm[sEnbigslimeTri[i].v[1]], &vecTriNorm, &vtxNorm[sEnbigslimeTri[i].v[1]]); + Math_Vec3f_Sum(&vtxNorm[sEnbigslimeTri[i].v[2]], &vecTriNorm, &vtxNorm[sEnbigslimeTri[i].v[2]]); + } + + for (i = 0; i < BIGSLIME_NUM_VTX; i++) { + vtxNormAddr = &vtxNorm[i]; + EnBigslime_Vec3fNormalize(vtxNormAddr); + dynamicVtx = &sBigslimeDynamicVtx[this->dynamicVtxState][i]; + dynamicVtx->n.n[0] = vtxNormAddr->x * 120.0f; + dynamicVtx->n.n[1] = vtxNormAddr->y * 120.0f; + dynamicVtx->n.n[2] = vtxNormAddr->z * 120.0f; + } +} + +void EnBigslime_GetMaxMinVertices(EnBigslime* this, Vec3f* vtxMax, Vec3f* vtxMin) { + Vtx* dynamicVtx; + s16 vtxMaxX = 0; + s16 vtxMaxY = 0; + s16 vtxMaxZ = 0; + s16 vtxMinX = 0; + s16 vtxMinY = 0; + s16 vtxMinZ = 0; + s32 i; + + for (i = 0; i < BIGSLIME_NUM_VTX; i++) { + dynamicVtx = &sBigslimeDynamicVtx[this->dynamicVtxState][i]; + + if (vtxMaxX < dynamicVtx->n.ob[0]) { + vtxMaxX = dynamicVtx->n.ob[0]; + } else if (vtxMinX > dynamicVtx->n.ob[0]) { + vtxMinX = dynamicVtx->n.ob[0]; + } + + if (vtxMaxY < dynamicVtx->n.ob[1]) { + vtxMaxY = dynamicVtx->n.ob[1]; + } else if (vtxMinY > dynamicVtx->n.ob[1]) { + vtxMinY = dynamicVtx->n.ob[1]; + } + + if (vtxMaxZ < dynamicVtx->n.ob[2]) { + vtxMaxZ = dynamicVtx->n.ob[2]; + } else if (vtxMinZ > dynamicVtx->n.ob[2]) { + vtxMinZ = dynamicVtx->n.ob[2]; + } + } + + vtxMax->x = vtxMaxX * this->actor.scale.x; + vtxMax->y = vtxMaxY * this->actor.scale.y; + vtxMax->z = vtxMaxZ * this->actor.scale.z; + + vtxMin->x = vtxMinX * this->actor.scale.x; + vtxMin->y = vtxMinY * this->actor.scale.y; + vtxMin->z = vtxMinZ * this->actor.scale.z; +} + +void EnBigslime_UpdateScale(EnBigslime* this, Vec3f* vtxMax, Vec3f* vtxMin) { + if (vtxMin->x < vtxMax->x) { + this->vtxScaleX = vtxMax->x * (0.100000005f / BIGSLIME_RADIUS_F); + } else { + this->vtxScaleX = -vtxMin->x * (0.100000005f / BIGSLIME_RADIUS_F); + } + + if (vtxMin->z < vtxMax->z) { + this->vtxScaleZ = vtxMax->z * (0.100000005f / BIGSLIME_RADIUS_F); + } else { + this->vtxScaleZ = -vtxMin->z * (0.100000005f / BIGSLIME_RADIUS_F); + } +} + +/** + * Checks the world position against all walls, the floor, and the ceiling to ensure + * bigslime is not outside this range. Accounts only for the world position, and the + * maximum and minimum verticies. If any boundaries are crossed, the world position + * and bgCheckFlags are updated accordingly. + * + * Differs from EnBigslime_CheckVtxWallBoundaries by checking and updating + * a single world position instead of checking and updating individual vertices + */ +void EnBigslime_CheckRoomBoundaries(EnBigslime* this, Vec3f* vtxMax, Vec3f* vtxMin) { + f32 worldPosX; + f32 vtxMaxX; + f32 vtxMinX; + f32 worldPosZ; + f32 vtxMaxZ; + f32 vtxMinZ; + + this->actor.bgCheckFlags &= ~(0x2 | 0x8 | 0x10); + if ((this->actor.world.pos.y + vtxMax->y) > GBT_ROOM_5_MAX_Y) { + this->actor.world.pos.y = GBT_ROOM_5_MAX_Y - vtxMax->y; + this->actor.bgCheckFlags |= 0x10; + } + + if ((this->actor.world.pos.y + vtxMin->y) <= GBT_ROOM_5_MIN_Y) { + this->actor.world.pos.y = GBT_ROOM_5_MIN_Y - vtxMin->y; + if (!(this->actor.bgCheckFlags & 1)) { + this->actor.bgCheckFlags |= 2; + } + + this->actor.bgCheckFlags |= 1; + } else { + this->actor.bgCheckFlags &= ~1; + } + + if ((this->actionFunc != EnBigslime_Freeze) || !(this->actor.bgCheckFlags & 1)) { + worldPosX = this->actor.world.pos.x; + vtxMaxX = vtxMax->x; + if (GBT_ROOM_5_MAX_X < (worldPosX + vtxMaxX)) { + this->actor.bgCheckFlags |= 8; + this->actor.world.pos.x = GBT_ROOM_5_MAX_X - vtxMaxX; + } else { + vtxMinX = vtxMin->x; + if ((worldPosX + vtxMinX) < GBT_ROOM_5_MIN_X) { + this->actor.world.pos.x = GBT_ROOM_5_MIN_X - vtxMinX; + this->actor.bgCheckFlags |= 8; + } + } + + worldPosZ = this->actor.world.pos.z; + vtxMaxZ = vtxMax->z; + if (GBT_ROOM_5_MAX_Z < (worldPosZ + vtxMaxZ)) { + this->actor.bgCheckFlags |= 8; + this->actor.world.pos.z = GBT_ROOM_5_MAX_Z - vtxMaxZ; + } else { + vtxMinZ = vtxMin->z; + if ((worldPosZ + vtxMinZ) < GBT_ROOM_5_MIN_Z) { + this->actor.world.pos.z = GBT_ROOM_5_MIN_Z - vtxMinZ; + this->actor.bgCheckFlags |= 8; + } + } + } +} + +void EnBigslime_UpdateBigslimeCollider(EnBigslime* this, GlobalContext* globalCtx) { + Vtx* dynamicVtx; + f32 xzDist; + s16 vtxRingMaxY[BIGSLIME_NUM_RING_VTX]; + s16 vtxRingMinY[BIGSLIME_NUM_RING_VTX]; + f32 vtxRingMaxXZDist[BIGSLIME_NUM_RING_VTX]; + Cylinder16* dim; + f32 maxScaleXScaleZ = (this->actor.scale.z < this->actor.scale.x ? this->actor.scale.x : this->actor.scale.z); + s32 i; + s32 j; + + for (i = 0; i < BIGSLIME_NUM_RING_VTX; i++) { + vtxRingMaxY[i] = -30000; + vtxRingMinY[i] = 30000; + vtxRingMaxXZDist[i] = 0.0f; + + for (j = sVtxRingStartIndex[i]; j < sVtxRingStartIndex[i + 1]; j++) { + dynamicVtx = &sBigslimeDynamicVtx[this->dynamicVtxState][j]; + if (vtxRingMaxY[i] < dynamicVtx->n.ob[1]) { + vtxRingMaxY[i] = dynamicVtx->n.ob[1]; + } + + if (vtxRingMinY[i] > dynamicVtx->n.ob[1]) { + vtxRingMinY[i] = dynamicVtx->n.ob[1]; + } + + xzDist = sqrtf(SQ(dynamicVtx->n.ob[0]) + SQ(dynamicVtx->n.ob[2])); + if (vtxRingMaxXZDist[i] < xzDist) { + vtxRingMaxXZDist[i] = xzDist; + } + } + } + + for (i = 0; i < BIGSLIME_NUM_RING_FACES; i++) { + dim = &this->bigslimeCollider[i].dim; + dim->pos.y = (vtxRingMinY[i + 1] * this->actor.scale.y) + this->actor.world.pos.y; + dim->height = (vtxRingMaxY[i] - vtxRingMinY[i + 1]) * this->actor.scale.y; + dim->radius = maxScaleXScaleZ * + (vtxRingMaxXZDist[i] < vtxRingMaxXZDist[i + 1] ? vtxRingMaxXZDist[i + 1] : vtxRingMaxXZDist[i]); + dim->height = CLAMP_MIN(dim->height, 1); + dim->pos.x = this->actor.world.pos.x; + dim->pos.z = this->actor.world.pos.z; + } + + if (this->bigslimeCollider[0].base.atFlags & AT_ON) { + for (i = 0; i < BIGSLIME_NUM_RING_FACES; i++) { + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->bigslimeCollider[i].base); + } + } + + if (this->bigslimeCollider[0].base.acFlags & AC_ON) { + for (i = 0; i < BIGSLIME_NUM_RING_FACES; i++) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->bigslimeCollider[i].base); + } + } + + for (i = 0; i < BIGSLIME_NUM_RING_FACES; i++) { + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->bigslimeCollider[i].base); + } +} + +void EnBigslime_AddWavySurface(EnBigslime* this) { + s32 randInt; + f32 randFloat; + s32 i; + + this->wavySurfaceTimer = 24; + randInt = (s32)(Rand_ZeroOne() * 6.0f) >> 1; + randFloat = (Rand_ZeroOne() * 40.0f) + 50.0f; + + for (i = 0; i < BIGSLIME_NUM_VTX; i++) { + if ((i % 6) == 0) { + randFloat = (Rand_ZeroOne() * 40.0f) + 50.0f; + } + + this->vtxSurfacePerturbation[i] = sin_rad((randInt + i) * (M_PI / 3)) * randFloat * 0.001f; + } +} + +void EnBigslime_UpdateWavySurface(EnBigslime* this) { + f32 vtxSurfaceWave; + Vtx* staticVtx; + Vtx* dynamicVtx; + s32 i; + s32 j; + + if (this->wavySurfaceTimer == 0) { + EnBigslime_AddWavySurface(this); + } + + this->wavySurfaceTimer--; + vtxSurfaceWave = sin_rad(this->wavySurfaceTimer * (M_PI / 12)); + for (i = 0; i < BIGSLIME_NUM_VTX; i++) { + staticVtx = &sBigslimeStaticVtx[i]; + dynamicVtx = &sBigslimeDynamicVtx[this->dynamicVtxState][i]; + for (j = 0; j < 3; j++) { + // Formula: dynamicVtx = staticVtx * (1 + sin * perturbation) + dynamicVtx->n.ob[j] = + staticVtx->n.ob[j] + (s32)(vtxSurfaceWave * staticVtx->n.ob[j] * this->vtxSurfacePerturbation[i]); + } + } +} + +void EnBigslime_InitFallMinislime(EnBigslime* this) { + EnMinislime* minislime; + s32 i; + + for (i = 0; i < MINISLIME_NUM_SPAWN; i++) { + minislime = this->minislime[i]; + minislime->actor.params = MINISLIME_INIT_FALL; + minislime->actor.world.pos.x = randPlusMinusPoint5Scaled(80.0f) + (GBT_ROOM_5_MIN_X + ((i % 4) + 1) * 192.0f); + minislime->actor.world.pos.y = Rand_ZeroFloat(250.0f) + (GBT_ROOM_5_CENTER_Y + 50.0f); + minislime->actor.world.pos.z = randPlusMinusPoint5Scaled(80.0f) + (GBT_ROOM_5_MIN_Z + ((i / 4) + 1) * 192.0f); + } + + this->minislimeState = MINISLIME_ACTIVE_INIT_STATE; +} + +void EnBigslime_SetMinislimeBreakLocation(EnBigslime* this) { + // Minislime spawn at these vertices when Frozen Bigslime Shatters + static s32 minislimeSpawnVtx[] = { + 7, 9, 11, 13, 15, // 5 equally spaced vertices on vtx ring 2 from top + 52, 56, 60, 64, 68, // 5 equally spaced vertices on vtx ring 5 from top + 94, 98, 102, 106, 110, // 5 equally spaced vertices on vtx ring 7 from top + }; + Vtx* dynamicVtx; + EnMinislime* minislime; + s32 i; + + this->minislimeState = MINISLIME_ACTIVE_CONTINUE_STATE; + for (i = 0; i < MINISLIME_NUM_SPAWN; i++) { + dynamicVtx = &sBigslimeDynamicVtx[this->dynamicVtxState][minislimeSpawnVtx[i]]; + minislime = this->minislime[i]; + minislime->actor.params = MINISLIME_BREAK_BIGSLIME; + minislime->actor.world.pos.x = (dynamicVtx->n.ob[0] * this->actor.scale.x) + this->actor.world.pos.x; + minislime->actor.world.pos.y = (dynamicVtx->n.ob[1] * this->actor.scale.y) + this->actor.world.pos.y; + minislime->actor.world.pos.z = (dynamicVtx->n.ob[2] * this->actor.scale.z) + this->actor.world.pos.z; + minislime->actor.world.rot.x = 0x1000 + 0x333 * (MINISLIME_NUM_SPAWN - i); + } +} + +void EnBigslime_SetPlayerParams(EnBigslime* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (player->stateFlags2 & 0x80) { + player->actor.parent = NULL; + player->unk_AE8 = 100; + func_800B8D98(globalCtx, &this->actor, 10.0f, this->actor.world.rot.y, 10.0f); + } +} + +void EnBigslime_EndThrowMinislime(EnBigslime* this) { + if (this->actionFunc == EnBigslime_ThrowMinislime && + this->minislimeToThrow->actor.params == MINISLIME_SETUP_GEKKO_THROW) { + this->minislimeToThrow->actor.params = MINISLIME_IDLE; + } +} + +void EnBigslime_BreakIntoMinislime(EnBigslime* this, GlobalContext* globalCtx) { + s32 i; + s16 quake = Quake_Add(GET_ACTIVE_CAM(globalCtx), 3); + + Quake_SetSpeed(quake, 20000); + Quake_SetQuakeValues(quake, 15, 0, 0, 0); + Quake_SetCountdown(quake, 15); + func_8013ECE0(this->actor.xyzDistToPlayerSq, 180, 20, 100); + this->bigslimeCollider[0].base.atFlags &= ~AT_ON; + this->gekkoCollider.base.acFlags &= ~(AC_ON | AC_HIT); + + for (i = 0; i < BIGSLIME_NUM_RING_FACES; i++) { + this->bigslimeCollider[i].base.acFlags &= ~AC_HIT; + } + + EnBigslime_SetMinislimeBreakLocation(this); + this->actor.update = EnBigslime_UpdateGekko; + this->actor.draw = EnBigslime_DrawGekko; + this->actor.gravity = -2.0f; + EnBigslime_SetPlayerParams(this, globalCtx); + EnBigslime_EndCutscene(this, globalCtx); + this->actor.colChkInfo.mass = 50; + this->actor.flags &= ~(0x1 | 0x400); + this->actor.flags |= 0x200; + this->actor.hintId = 95; + this->gekkoRot.x = 0; + this->gekkoRot.y = 0; + this->actor.bgCheckFlags &= ~1; + this->formBigslimeTimer = 2; + EnBigslime_AddIceShardEffect(this, globalCtx); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_B_SLIME_BREAK); + EnBigslime_SetupJumpGekko(this); +} + +/** + * Smoothly moves the camera to a side view and keeps it there + * as bigslime grabs player and the Gekko melee-attacks player + */ +void EnBigslime_UpdateCameraGrabPlayer(EnBigslime* this, GlobalContext* globalCtx) { + Camera* subCam = Play_GetCamera(globalCtx, this->subCamId); + Vec3f subCamEye; + Vec3f subCamAt; + + Math_Vec3f_Copy(&subCamEye, &subCam->eye); + Math_Vec3f_Copy(&subCamAt, &subCam->at); + + Math_StepToF(&subCamEye.x, (Math_SinS(this->subCamYawGrabPlayer) * 250.0f) + this->actor.world.pos.x, 10.0f); + Math_StepToF(&subCamEye.y, GBT_ROOM_5_MIN_Y + 187.5f, 10.0f); + Math_StepToF(&subCamEye.z, (Math_CosS(this->subCamYawGrabPlayer) * 250.0f) + this->actor.world.pos.z, 10.0f); + + Math_StepToF(&subCamAt.x, this->actor.world.pos.x, 10.0f); + Math_StepToF(&subCamAt.y, GBT_ROOM_5_MIN_Y + 87.5f, 10.0f); + Math_StepToF(&subCamAt.z, this->actor.world.pos.z, 10.0f); + + Play_CameraSetAtEye(globalCtx, this->subCamId, &subCamAt, &subCamEye); +} + +/** + * Takes the camera eye and instantaneously moves it 10% closer to the focus point "at". + * This gives the camera a "jerk" feeling + * Used everytime player is hit inside of bigslime while being grabbed + */ +void EnBigslime_JerkCameraPlayerHit(EnBigslime* this, GlobalContext* globalCtx) { + Camera* subCam = Play_GetCamera(globalCtx, this->subCamId); + Vec3f subCamEye; + + Math_Vec3f_Diff(&subCam->eye, &subCam->at, &subCamEye); + Math_Vec3f_Scale(&subCamEye, 0.9f); + Math_Vec3f_Sum(&subCamEye, &subCam->at, &subCamEye); + Play_CameraSetAtEye(globalCtx, this->subCamId, &subCam->at, &subCamEye); +} + +/** + * Performs the camera motion for the intro cutscene as the player enters the room + * and the battle starts. Positions the camera slightly offset from player, + * then zooms into the Gekko until the Gekko calls the minislimes down from the ceiling + */ +void EnBigslime_UpdateCameraIntroCs(EnBigslime* this, GlobalContext* globalCtx, s32 noticeTimer) { + Camera* subCam = Play_GetCamera(globalCtx, this->subCamId); + Vec3f subCamEye; + f32 zoom = (noticeTimer * 19.0f) + 67.0f; + s16 yawOffset = this->actor.yawTowardsPlayer + (noticeTimer * 0x31); + + subCamEye.x = Math_SinS(yawOffset) * zoom + subCam->at.x; + subCamEye.z = Math_CosS(yawOffset) * zoom + subCam->at.z; + subCamEye.y = subCam->at.y + -4.0f + (noticeTimer * 2.0f); + + Play_CameraSetAtEye(globalCtx, this->subCamId, &subCam->at, &subCamEye); +} + +/** + * Takes the camera and makes the focus point (at) point at bigslime, who is on the + * center of the roof. This is used when the minislimes merges into bigslime. + */ +void EnBigslime_UpdateCameraFormingBigslime(EnBigslime* this, GlobalContext* globalCtx) { + Play_CameraSetAtEye(globalCtx, this->subCamId, &this->actor.focus.pos, + &Play_GetCamera(globalCtx, this->subCamId)->eye); +} + +void EnBigslime_EndCutscene(EnBigslime* this, GlobalContext* globalCtx) { + Camera* subCam; + + if (this->subCamId != MAIN_CAM) { + subCam = Play_GetCamera(globalCtx, this->subCamId); + Play_CameraSetAtEye(globalCtx, MAIN_CAM, &subCam->at, &subCam->eye); + this->subCamId = MAIN_CAM; + ActorCutscene_Stop(this->cutscene); + this->cutscene = ActorCutscene_GetAdditionalCutscene(this->actor.cutscene); + func_800B724C(globalCtx, &this->actor, 6); + } +} + +void EnBigslime_Scale(EnBigslime* this, s16 pitch, f32 xzScale, f32 yScale) { + this->actor.scale.x = ((Math_SinS(pitch) * xzScale) + 1.5f) * 0.1f; // = 0.15f + 0.1f * xzScale * sin(pitch) + this->actor.scale.y = ((Math_CosS(pitch) * yScale) + 0.75f) * 0.1f; // = 0.075f + 0.1f * yScale * cos(pitch) + this->actor.scale.z = 0.3f - this->actor.scale.x; // = 0.15f - 0.1f * xzScale * sin(pitch) +} + +/** + * Set the params used by the floor shockwave when bigslime shatters into minislime + */ +void EnBigslime_InitShockwave(EnBigslime* this, GlobalContext* globalCtx) { + globalCtx->envCtx.unk_C3 = 3; + Math_Vec3f_Copy(&this->frozenPos, &this->actor.world.pos); + this->frozenPos.y = GBT_ROOM_5_MIN_Y; + this->shockwaveAlpha = 235; + this->shockwaveScale = 0.025f; +} + +/** + * Restores bigslime behaviour to the state before it was frozen + */ +void EnBigslime_SetTargetVtxFromPreFrozen(EnBigslime* this) { + this->bigslimeCollider[0].base.acFlags |= AC_ON; + this->actionFunc = this->actionFuncStored; + this->skelAnime.playSpeed = 1.0f; + if (this->actionFunc == EnBigslime_SquishFlat) { + this->bigslimeCollider[0].base.atFlags |= AT_ON; + EnBigslime_SetTargetVtxToWideCone(this); + } else if (this->actionFunc == EnBigslime_Rise) { + if (this->riseCounter == 0) { + EnBigslime_SetTargetVtxToThinCone(this); + } else if (this->riseCounter == 1) { + EnBigslime_SetTargetVtxToInverseCone(this); + } else { + EnBigslime_SetTargetVtxToStaticVtx(this); + } + } +} + +/** + * Plays the standard Gekko sound effects without reverb + */ +void EnBigslime_GekkoSfxOutsideBigslime(EnBigslime* this, u16 sfxId) { + func_8019F1C0(&this->gekkoProjectedPos, sfxId); +} + +/** + * Adds reverb to Gekko sound effects when enclosed by bigslime + */ +void EnBigslime_GekkoSfxInsideBigslime(EnBigslime* this, u16 sfxId) { + func_8019F420(&this->gekkoProjectedPos, sfxId); +} + +void EnBigslime_GekkoFreeze(EnBigslime* this) { + this->gekkoDrawEffect = GEKKO_DRAW_EFFECT_FROZEN; + this->gekkoCollider.base.colType = COLTYPE_HIT3; + this->gekkoCollider.info.elemType = ELEMTYPE_UNK0; + this->stunTimer = 2; + this->unk_38C = 0.75f; + this->unk_390 = 1.125f; + this->unk_388 = 1.0f; + this->actor.flags &= ~0x200; +} + +void EnBigslime_GekkoThaw(EnBigslime* this, GlobalContext* globalCtx) { + if (this->gekkoDrawEffect == GEKKO_DRAW_EFFECT_FROZEN) { + this->gekkoDrawEffect = GEKKO_DRAW_EFFECT_THAW; + this->gekkoCollider.base.colType = COLTYPE_HIT6; + this->gekkoCollider.info.elemType = ELEMTYPE_UNK1; + this->unk_388 = 0.0f; + func_800BF7CC(globalCtx, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), 2, 0.3f, 0.2f); + this->actor.flags |= 0x200; + } +} + +void EnBigslime_SetupCutsceneStartBattle(EnBigslime* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + Camera* subCam = Play_GetCamera(globalCtx, this->subCamId); + + globalCtx->envCtx.unk_C3 = 4; + Animation_PlayLoop(&this->skelAnime, &gGekkoLookAroundAnim); + + this->bigslimeCollider[0].base.atFlags &= ~AT_ON; + this->bigslimeCollider[0].base.acFlags &= ~AC_ON; + + Math_Vec3f_Copy(&subCam->at, &this->actor.focus.pos); + func_800B7298(globalCtx, &this->actor, 4); + + player->actor.shape.rot.y = this->actor.yawTowardsPlayer + 0x8000; + player->actor.world.pos.x = Math_SinS(this->actor.yawTowardsPlayer) * 347.0f + this->actor.world.pos.x; + player->actor.world.pos.z = Math_CosS(this->actor.yawTowardsPlayer) * 347.0f + this->actor.world.pos.z; + + EnBigslime_UpdateCameraIntroCs(this, globalCtx, 25); + + this->gekkoRot.y = this->actor.yawTowardsPlayer + 0x8000; + this->isInitJump = false; + this->actionFunc = EnBigslime_CutsceneStartBattle; +} + +void EnBigslime_CutsceneStartBattle(EnBigslime* this, GlobalContext* globalCtx) { + if (this->isAnimUpdate) { + EnBigslime_SetupCutsceneNoticePlayer(this); + } else if (!this->isInitJump && Math_ScaledStepToS(&this->gekkoRot.y, this->actor.yawTowardsPlayer, 0x200)) { + Animation_PlayOnce(&this->skelAnime, &gGekkoSurpriseJumpAnim); + EnBigslime_GekkoSfxOutsideBigslime(this, NA_SE_EN_FROG_JUMP); + this->isInitJump = true; + } +} + +void EnBigslime_SetupCutsceneNoticePlayer(EnBigslime* this) { + Animation_PlayLoop(&this->skelAnime, &gGekkoNervousIdleAnim); + this->noticeTimer = 25; + this->actionFunc = EnBigslime_CutsceneNoticePlayer; +} + +void EnBigslime_CutsceneNoticePlayer(EnBigslime* this, GlobalContext* globalCtx) { + if (this->noticeTimer != 0) { + this->noticeTimer--; + } + + EnBigslime_UpdateCameraIntroCs(this, globalCtx, this->noticeTimer); + if (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 4.0f)) { + EnBigslime_GekkoSfxOutsideBigslime(this, NA_SE_EV_WALK_WATER); + } + + if (this->noticeTimer == 0) { + EnBigslime_SetupCallMinislime(this, globalCtx); + } +} + +void EnBigslime_SetupCallMinislime(EnBigslime* this, GlobalContext* globalCtx) { + Animation_MorphToPlayOnce(&this->skelAnime, &gGekkoCallAnim, 5.0f); + EnBigslime_GekkoSfxOutsideBigslime(this, NA_SE_EN_FROG_GREET); + this->callTimer = 0; + func_800B7298(globalCtx, &this->actor, 7); + this->actionFunc = EnBigslime_CallMinislime; +} + +void EnBigslime_CallMinislime(EnBigslime* this, GlobalContext* globalCtx) { + if (this->callTimer > 0) { + this->callTimer--; + if (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 4.0f)) { + EnBigslime_GekkoSfxOutsideBigslime(this, NA_SE_EV_WALK_WATER); + } + + if (this->callTimer == 0) { + EnBigslime_EndCutscene(this, globalCtx); + this->formBigslimeTimer = 2; + this->actor.flags |= 1; + EnBigslime_SetupIdleNoticePlayer(this); + } + } else if (this->isAnimUpdate) { + Animation_PlayLoop(&this->skelAnime, &gGekkoNervousIdleAnim); + EnBigslime_UpdateCameraIntroCs(this, globalCtx, 25); + func_801A2E54(0x38); + EnBigslime_InitFallMinislime(this); + globalCtx->envCtx.unk_C3 = 0xFF; + this->callTimer = 35; + func_800B7298(globalCtx, &this->actor, 4); + } +} + +void EnBigslime_SetupMoveOnCeiling(EnBigslime* this) { + Animation_PlayLoop(&this->skelAnime, &gGekkoSwimForwardAnim); + this->actor.gravity = 0.0f; + this->actor.velocity.y = 20.0f; + + if (this->subCamId != MAIN_CAM) { + this->actor.speedXZ = 0.0f; + this->ceilingMoveTimer = 20; + } else { + this->ceilingMoveTimer = 320; + this->actor.speedXZ = 5.0f; + } + + this->wavySurfaceTimer = 0; + this->bigslimeCollider[0].base.acFlags |= AC_ON; + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + this->actor.flags &= ~0x200; + this->actionFunc = EnBigslime_MoveOnCeiling; +} + +void EnBigslime_MoveOnCeiling(EnBigslime* this, GlobalContext* globalCtx) { + s16 pitch; // polar (zenith) angle + + Math_ScaledStepToS(&this->gekkoRot.x, 0, 0x400); + this->ceilingMoveTimer--; + pitch = this->ceilingMoveTimer * 0x800; + EnBigslime_Scale(this, pitch, 0.04f, 0.04f); + EnBigslime_UpdateWavySurface(this); + + if (this->subCamId != MAIN_CAM) { + if (this->ceilingMoveTimer == 0) { + EnBigslime_EndCutscene(this, globalCtx); + this->ceilingMoveTimer = 320; + } + } else if ((this->actor.xzDistToPlayer < 250.0f) || (this->ceilingMoveTimer == 0)) { + EnBigslime_SetupDrop(this); + } else { + this->actor.speedXZ = (fabsf(Math_SinS(pitch)) * 3.0f) + 5.0f; + Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 10, 0x800, 0x80); + this->gekkoRot.y = this->actor.world.rot.y; + } +} + +void EnBigslime_SetupDrop(EnBigslime* this) { + this->actor.velocity.y = 0.0f; + this->ceilingDropTimer = 30; + this->actor.speedXZ = 0.0f; + this->actionFunc = EnBigslime_Drop; +} + +void EnBigslime_Drop(EnBigslime* this, GlobalContext* globalCtx) { + Vtx* staticVtx; + Vtx* dynamicVtx; + s32 i; + + Math_ScaledStepToS(&this->gekkoRot.x, 0x4000, 0x400); + if (this->ceilingDropTimer != 0) { + s32 requiredScopeTemp; + + this->ceilingDropTimer--; + this->ceilingMoveTimer--; + EnBigslime_UpdateWavySurface(this); + EnBigslime_Scale(this, this->ceilingMoveTimer * 0x4000, 0.2f, 0.15); + this->actor.scale.z = this->actor.scale.x; + if (this->ceilingDropTimer == 0) { + this->actor.gravity = -2.0f; + EnBigslime_GekkoSfxOutsideBigslime(this, NA_SE_EN_FROG_DOWN); + this->rotation = 0; + } + } else if (this->actor.bgCheckFlags & 1) { + EnBigslime_SetupSquishFlat(this); + } else { + Math_StepToF(&this->actor.scale.x, 0.15f, 0.0025f); + Math_StepToF(&this->actor.scale.y, 0.080000006f, 0.0025f); + Math_StepToF(&this->actor.scale.z, 0.15f, 0.0025f); + for (i = 0; i < BIGSLIME_NUM_VTX; i++) { + staticVtx = &sBigslimeStaticVtx[i]; + dynamicVtx = &sBigslimeDynamicVtx[this->dynamicVtxState][i]; + if (i > 145) { + Math_StepToS(&dynamicVtx->n.ob[1], staticVtx->n.ob[1] * 0.9f, 5); + } else if (i < 16) { + Math_StepToS(&dynamicVtx->n.ob[1], staticVtx->n.ob[1] * 1.3f, 5); + } else { + Math_StepToS(&dynamicVtx->n.ob[1], staticVtx->n.ob[1], 5); + } + Math_StepToS(&dynamicVtx->n.ob[0], staticVtx->n.ob[0], 5); + Math_StepToS(&dynamicVtx->n.ob[2], staticVtx->n.ob[2], 5); + } + } +} + +/** + * Checks each individual vertex to see if it is outside the walls of the room. + * If it is, updates the vertex to be back inside the boundary of the room. + * Also raises the vertex in the y-direction 100 units in model-space for a single wall + * and 200 unites in the y-direction for two walls i.e a corner. + * + * Differs from EnBigslime_CheckRoomBoundaries by checking and updating + * individual vertices instead of checking and updating a single world position + */ +void EnBigslime_CheckVtxWallBoundaries(EnBigslime* this) { + Vtx* dynamicVtx; + f32 vtxX; + f32 vtxZ; + s32 collisionCounter; + s32 i; + s16 updateVtxY; + + for (i = 0; i < BIGSLIME_NUM_VTX; i++) { + dynamicVtx = &sBigslimeDynamicVtx[this->dynamicVtxState][i]; + vtxX = dynamicVtx->n.ob[0] * this->actor.scale.x; + vtxZ = dynamicVtx->n.ob[2] * this->actor.scale.z; + collisionCounter = 0; + if ((this->actor.world.pos.x + vtxX) > GBT_ROOM_5_MAX_X) { + dynamicVtx->n.ob[0] = (GBT_ROOM_5_MAX_X - this->actor.world.pos.x) / this->actor.scale.x; + collisionCounter++; + } else if ((this->actor.world.pos.x + vtxX) < GBT_ROOM_5_MIN_X) { + dynamicVtx->n.ob[0] = (GBT_ROOM_5_MIN_X - this->actor.world.pos.x) / this->actor.scale.x; + collisionCounter++; + } + + if ((this->actor.world.pos.z + vtxZ) > GBT_ROOM_5_MAX_Z) { + dynamicVtx->n.ob[2] = (GBT_ROOM_5_MAX_Z - this->actor.world.pos.z) / this->actor.scale.z; + collisionCounter++; + } else if ((this->actor.world.pos.z + vtxZ) < GBT_ROOM_5_MIN_Z) { + dynamicVtx->n.ob[2] = (GBT_ROOM_5_MIN_Z - this->actor.world.pos.z) / this->actor.scale.z; + collisionCounter++; + } + + if (dynamicVtx->n.ob[1] != -BIGSLIME_RADIUS_S) { + updateVtxY = collisionCounter * 100; + dynamicVtx->n.ob[1] += updateVtxY; + } + } +} + +/** + * This sets the target vertices into a wide cone shape + * + * Notes: + * - The flat surface of the cone is in the xz-plane at y = -1000 + * - The radius of the flat surface of the cone is 1000 units + * - The apex/point of the cone is at the point (0, 1000, 0) + * - It is wide because it is smooth and thicker near the apex than a standard cone + */ +void EnBigslime_SetTargetVtxToWideCone(EnBigslime* this) { + Vtx* staticVtx; + Vtx* targetVtx; + s16 vtxY; + f32 xzDist; + f32 xzScaleVtx; + s32 i; + s32 j; + + for (i = 0; i < BIGSLIME_NUM_RING_FACES / 2; i++) { + vtxY = (((cos_rad(i * (M_PI / 6)) + 1.0f) * 0.925f) + -0.85f) * BIGSLIME_RADIUS_F; + for (j = sVtxRingStartIndex[i]; j < sVtxRingStartIndex[i + 1]; j++) { + staticVtx = &sBigslimeStaticVtx[j]; + targetVtx = &sBigslimeTargetVtx[j]; + xzDist = sqrtf(SQ(staticVtx->n.ob[0]) + SQ(staticVtx->n.ob[2])); + + if (xzDist > 1.0f) { + xzScaleVtx = (BIGSLIME_RADIUS_F / (5.0f * xzDist)) * i; + } else { + xzScaleVtx = 200.0f * i; // only taken when i = 0, making 200.0f useless + } + + targetVtx->n.ob[0] = staticVtx->n.ob[0] * xzScaleVtx; + targetVtx->n.ob[2] = staticVtx->n.ob[2] * xzScaleVtx; + targetVtx->n.ob[1] = vtxY; + } + } + + for (; i < BIGSLIME_NUM_RING_VTX; i++) { + vtxY = ((cos_rad((i - BIGSLIME_NUM_RING_FACES / 2) * (M_PI / 16)) * 0.05f) + -1.0f) * BIGSLIME_RADIUS_F; + for (j = sVtxRingStartIndex[i]; j < sVtxRingStartIndex[i + 1]; j++) { + staticVtx = &sBigslimeStaticVtx[j]; + targetVtx = &sBigslimeTargetVtx[j]; + xzDist = sqrtf(SQ(staticVtx->n.ob[0]) + SQ(staticVtx->n.ob[2])); + if (xzDist > 1.0f) { + xzScaleVtx = (BIGSLIME_RADIUS_F / (8.0f * xzDist)) * (14 - i); + } else { + // only taken when j = 161, but gets immediately written over (bottom vtx of the sphere) + xzScaleVtx = 125.0f * (14 - i); + } + + targetVtx->n.ob[0] = staticVtx->n.ob[0] * xzScaleVtx; + targetVtx->n.ob[2] = staticVtx->n.ob[2] * xzScaleVtx; + targetVtx->n.ob[1] = vtxY; + } + } + + // Bottom vtx of the sphere + sBigslimeTargetVtx[BIGSLIME_NUM_VTX - 1].n.ob[0] = 0; + sBigslimeTargetVtx[BIGSLIME_NUM_VTX - 1].n.ob[2] = 0; + sBigslimeTargetVtx[BIGSLIME_NUM_VTX - 1].n.ob[1] = -BIGSLIME_RADIUS_S; +} + +void EnBigslime_SetupSquishFlat(EnBigslime* this) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_B_SLIME_JUMP2); + this->squishFlatTimer = 20; + this->actor.scale.x = 0.2f; + this->actor.scale.z = 0.2f; + this->actor.scale.y = 0.05f; + this->actor.world.pos.y = GBT_ROOM_5_MIN_Y + 50.0f; + EnBigslime_SetTargetVtxToWideCone(this); + EnBigslime_CheckVtxWallBoundaries(this); + this->bigslimeCollider[0].base.atFlags |= AT_ON; + this->actionFunc = EnBigslime_SquishFlat; +} + +/** + * Squishes flat like a pancake to try and grab player + * + * Notes: + * - The vtx shape of Fused Jelly starts from a wide cone shape + * - The squishing occurs throught the large changes in &this->actor.scale + */ +void EnBigslime_SquishFlat(EnBigslime* this, GlobalContext* globalCtx) { + Player* player; + Vtx* dynamicVtx; + Vtx* targetVtx; + s32 i; + + this->squishFlatTimer--; + Math_ScaledStepToS(&this->gekkoRot.x, 0, 0x400); + Math_SmoothStepToF(&this->actor.scale.x, 0.35f, 0.4f, 0.035f, 0.0034999999f); + Math_SmoothStepToF(&this->actor.scale.y, 0.030000001f, 0.4f, 0.0030000003f, 0.0003f); + this->actor.scale.z = this->actor.scale.x; + + for (i = 0; i < BIGSLIME_NUM_VTX; i++) { + dynamicVtx = &sBigslimeDynamicVtx[this->dynamicVtxState][i]; + targetVtx = &sBigslimeTargetVtx[i]; + Math_SmoothStepToS(&dynamicVtx->n.ob[0], targetVtx->n.ob[0], 5, 40, 5); + Math_SmoothStepToS(&dynamicVtx->n.ob[2], targetVtx->n.ob[2], 5, 40, 5); + Math_SmoothStepToS(&dynamicVtx->n.ob[1], targetVtx->n.ob[1], 2, 600, 3); + } + + EnBigslime_CheckVtxWallBoundaries(this); + + // Checks if any collider is interacting with player. If so, player is grabbed + for (i = 0; i < BIGSLIME_NUM_RING_FACES; i++) { + if (this->bigslimeCollider[i].base.atFlags & AT_HIT) { + break; + } + } + + if (i != BIGSLIME_NUM_RING_FACES) { + player = GET_PLAYER(globalCtx); + if (globalCtx->grabPlayer(globalCtx, player)) { + player->actor.parent = &this->actor; + EnBigslime_SetupCutscene(this); + return; + } + } + + if (this->squishFlatTimer == 0) { + EnBigslime_SetupRise(this); + } +} + +/** + * This sets the target vertices into a thin cone shape + * + * Notes: + * - The flat surface of the cone is in the xz-plane at y = -1000 + * - The radius of the flat surface of the cone is 1000 units + * - The apex/point of the cone is at the point (0, 1000, 0) + * - It is thin because it is smooth and thinner near the apex than a standard cone + */ +void EnBigslime_SetTargetVtxToThinCone(EnBigslime* this) { + Vtx* targetVtx; + Vtx* staticVtx; + f32 xzDistVtx; + f32 xzScaleVtx; + s32 i; + s32 j; + s16 upperSphereCos; + f32 lowerSphereCos; + s32 targetVtxY; + + // Top vtx of the sphere + sBigslimeTargetVtx[0].n.ob[1] = BIGSLIME_RADIUS_S; + sBigslimeTargetVtx[0].n.ob[0] = 0; + sBigslimeTargetVtx[0].n.ob[2] = 0; + + for (i = 1; i < BIGSLIME_NUM_RING_FACES / 2; i++) { + upperSphereCos = (((cos_rad((i - 1) * (M_PI / 5)) + 1.0f) * 0.925f) + -0.85f) * BIGSLIME_RADIUS_F; + for (j = sVtxRingStartIndex[i]; j < sVtxRingStartIndex[i + 1]; j++) { + staticVtx = &sBigslimeStaticVtx[j]; + targetVtx = &sBigslimeTargetVtx[j]; + xzDistVtx = sqrtf(SQ(staticVtx->n.ob[0]) + SQ(staticVtx->n.ob[2])); + xzDistVtx = (BIGSLIME_RADIUS_F / (5.0f * xzDistVtx)) * i; + // xzDistVtx is always less than 500.0f + xzScaleVtx = + xzDistVtx < 500.0f ? xzDistVtx * 0.75f : BIGSLIME_RADIUS_F - ((BIGSLIME_RADIUS_F - xzDistVtx) * 0.75f); + + targetVtx->n.ob[0] = staticVtx->n.ob[0] * xzScaleVtx; + targetVtx->n.ob[2] = staticVtx->n.ob[2] * xzScaleVtx; + targetVtx->n.ob[1] = upperSphereCos; + } + } + + for (; i < BIGSLIME_NUM_RING_FACES; i++) { + lowerSphereCos = cos_rad((i - BIGSLIME_NUM_RING_FACES / 2) * (M_PI / BIGSLIME_NUM_RING_FACES)); + for (j = sVtxRingStartIndex[i]; j < sVtxRingStartIndex[i + 1]; j++) { + staticVtx = &sBigslimeStaticVtx[j]; + targetVtx = &sBigslimeTargetVtx[j]; + targetVtx->n.ob[0] = staticVtx->n.ob[0]; + targetVtx->n.ob[2] = staticVtx->n.ob[2]; + targetVtxY = (s16)(((lowerSphereCos * 0.05f) + -1.0f) * BIGSLIME_RADIUS_F); + targetVtx->n.ob[1] = targetVtxY; + } + } + + // Bottom vtx of the sphere + sBigslimeTargetVtx[BIGSLIME_NUM_VTX - 1].n.ob[1] = -BIGSLIME_RADIUS_S; + sBigslimeTargetVtx[BIGSLIME_NUM_VTX - 1].n.ob[0] = 0; + sBigslimeTargetVtx[BIGSLIME_NUM_VTX - 1].n.ob[2] = 0; +} + +/** + * This sets the target vertices into a thin inverse cone shape + * + * Notes: + * - The flat surface of the cone is in the xz-plane at y = +1000 + * - The radius of the flat surface of the cone is 1000 units + * - The apex/point of the cone is at the point (0, -1000, 0) + * - It is thin because it is smooth and thinner near the apex than a standard cone + */ +void EnBigslime_SetTargetVtxToInverseCone(EnBigslime* this) { + Vtx* targetVtx; + Vtx* staticVtx; + f32 xzDistVtx; + f32 upperSphereCos; + s16 lowerSphereCos; + f32 xzScaleVtx; + s32 i; + s32 j; + s32 vtxY; + + // Top vtx of the sphere + sBigslimeTargetVtx[0].n.ob[1] = BIGSLIME_RADIUS_S; + sBigslimeTargetVtx[0].n.ob[0] = 0; + sBigslimeTargetVtx[0].n.ob[2] = 0; + + for (i = 1; i < BIGSLIME_NUM_RING_FACES / 2; i++) { + upperSphereCos = cos_rad((i - 1) * (M_PI / 10)); + for (j = sVtxRingStartIndex[i]; j < sVtxRingStartIndex[i + 1]; j++) { + staticVtx = &sBigslimeStaticVtx[j]; + targetVtx = &sBigslimeTargetVtx[j]; + targetVtx->n.ob[0] = staticVtx->n.ob[0]; + targetVtx->n.ob[2] = staticVtx->n.ob[2]; + vtxY = (s16)(((upperSphereCos * 0.1f) + 0.9f) * BIGSLIME_RADIUS_F); + targetVtx->n.ob[1] = vtxY; + } + } + + for (; i < BIGSLIME_NUM_RING_FACES; i++) { + lowerSphereCos = + (((cos_rad((i - BIGSLIME_NUM_RING_FACES / 2) * (M_PI / 5)) + 1) * 0.925f) + -1.0f) * BIGSLIME_RADIUS_F; + for (j = sVtxRingStartIndex[i]; j < sVtxRingStartIndex[i + 1]; j++) { + staticVtx = &sBigslimeStaticVtx[j]; + targetVtx = &sBigslimeTargetVtx[j]; + xzDistVtx = sqrtf(SQ(staticVtx->n.ob[0]) + SQ(staticVtx->n.ob[2])); + xzDistVtx = (BIGSLIME_RADIUS_F / (6.0f * xzDistVtx)) * (BIGSLIME_NUM_RING_FACES - i); + // xzDistVtx is always less than 500.0f + xzScaleVtx = + xzDistVtx < 500.0f ? xzDistVtx * 0.75f : BIGSLIME_RADIUS_F - ((BIGSLIME_RADIUS_F - xzDistVtx) * 0.75f); + + targetVtx->n.ob[0] = staticVtx->n.ob[0] * xzScaleVtx; + targetVtx->n.ob[2] = staticVtx->n.ob[2] * xzScaleVtx; + targetVtx->n.ob[1] = lowerSphereCos; + } + } + + // Bottom vtx of the sphere + sBigslimeTargetVtx[BIGSLIME_NUM_VTX - 1].n.ob[1] = -BIGSLIME_RADIUS_S; + sBigslimeTargetVtx[BIGSLIME_NUM_VTX - 1].n.ob[0] = 0; + sBigslimeTargetVtx[BIGSLIME_NUM_VTX - 1].n.ob[2] = 0; +} + +void EnBigslime_SetTargetVtxToStaticVtx(EnBigslime* this) { + s32 i; + Vtx* staticVtx; + + for (i = 0; i < BIGSLIME_NUM_VTX; i++) { + staticVtx = &sBigslimeStaticVtx[i]; + sBigslimeTargetVtx[i].n.ob[0] = staticVtx->n.ob[0]; + sBigslimeTargetVtx[i].n.ob[2] = staticVtx->n.ob[2]; + sBigslimeTargetVtx[i].n.ob[1] = staticVtx->n.ob[1]; + } +} + +void EnBigslime_SetupRise(EnBigslime* this) { + Animation_PlayLoop(&this->skelAnime, &gGekkoSwimForwardAnim); + EnBigslime_GekkoSfxOutsideBigslime(this, NA_SE_EN_FROG_JUMP_ABOVE); + EnBigslime_GekkoSfxOutsideBigslime(this, NA_SE_EN_UTSUBO_APPEAR_TRG); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_B_SLIME_JUMP1); + this->riseCounter = 0; + this->bigslimeCollider[0].base.atFlags &= ~AT_ON; + this->actor.gravity = 0.0f; + this->actor.velocity.y = 0.0f; + EnBigslime_SetTargetVtxToThinCone(this); + this->actor.world.rot.y = this->gekkoRot.y; + this->actionFunc = EnBigslime_Rise; +} + +/** + * Moves Fused Jelly from a squish pancake on the floor to the ceiling + * + * Notes: + * - When riseCounter == 0, Fused Jelly is un-squishing into a thin cone shape + * - When riseCounter == 1, Fused Jelly is deforming into an inverse thin cone shape + * - When riseCounter == 2 to 9, Fused Jelly is returning to its default spherical shape + * - When riseCounter == 10, Fused Jelly starts moving on the ceiling + */ +void EnBigslime_Rise(EnBigslime* this, GlobalContext* globalCtx) { + Vtx* dynamicVtx; + Vtx* targetVtx; + s32 i; + + if (this->riseCounter < 2) { + Math_SmoothStepToF(&this->actor.scale.x, 0.13f, 0.2f, 0.039f, 0.0038999997f); + Math_ScaledStepToS(&this->gekkoRot.x, -0x4000, 0x400); + } else { + Math_SmoothStepToF(&this->actor.scale.x, 0.15f, 0.4f, 0.015000001f, 0.0015f); + Math_ScaledStepToS(&this->gekkoRot.x, 0, 0x400); + } + + this->actor.scale.z = this->actor.scale.x; + EnBigslime_CheckVtxWallBoundaries(this); + if (this->riseCounter == 0) { + if (Math_SmoothStepToF(&this->actor.scale.y, 0.3f, 0.5f, 0.015000001f, 0.00075f) < 0.01f) { + this->riseCounter = 1; + EnBigslime_SetTargetVtxToInverseCone(this); + } + + for (i = 0; i < BIGSLIME_NUM_VTX; i++) { + dynamicVtx = &sBigslimeDynamicVtx[this->dynamicVtxState][i]; + targetVtx = &sBigslimeTargetVtx[i]; + Math_SmoothStepToS(&dynamicVtx->n.ob[1], targetVtx->n.ob[1], 5, 550, 3); + Math_SmoothStepToS(&dynamicVtx->n.ob[0], targetVtx->n.ob[0], 5, 40, 5); + Math_SmoothStepToS(&dynamicVtx->n.ob[2], targetVtx->n.ob[2], 5, 40, 5); + } + + } else if (this->riseCounter == 1) { + if (Math_SmoothStepToF(&this->actor.scale.y, 0.075f, 0.4f, 0.0075000003f, 0.00075f) < 0.01f) { + EnBigslime_SetTargetVtxToStaticVtx(this); + this->riseCounter++; + } + + for (i = 0; i < BIGSLIME_NUM_VTX; i++) { + dynamicVtx = &sBigslimeDynamicVtx[this->dynamicVtxState][i]; + targetVtx = &sBigslimeTargetVtx[i]; + Math_SmoothStepToS(&dynamicVtx->n.ob[1], targetVtx->n.ob[1], 5, 50, 3); + Math_SmoothStepToS(&dynamicVtx->n.ob[0], targetVtx->n.ob[0], 5, 40, 5); + Math_SmoothStepToS(&dynamicVtx->n.ob[2], targetVtx->n.ob[2], 5, 40, 5); + } + + this->actor.world.pos.y = GBT_ROOM_5_MAX_Y - (this->actor.scale.y * BIGSLIME_RADIUS_F); + } else if (this->riseCounter == 10) { + EnBigslime_SetupMoveOnCeiling(this); + } else { + this->riseCounter++; + for (i = 0; i < BIGSLIME_NUM_VTX; i++) { + dynamicVtx = &sBigslimeDynamicVtx[this->dynamicVtxState][i]; + targetVtx = &sBigslimeTargetVtx[i]; + Math_SmoothStepToS(&dynamicVtx->n.ob[1], targetVtx->n.ob[1], 5, 550, 3); + Math_SmoothStepToS(&dynamicVtx->n.ob[0], targetVtx->n.ob[0], 5, 40, 5); + Math_SmoothStepToS(&dynamicVtx->n.ob[2], targetVtx->n.ob[2], 5, 40, 5); + } + } + + EnBigslime_CheckVtxWallBoundaries(this); + Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 10, 0x800, 0x80); +} + +void EnBigslime_SetupCutsceneGrabPlayer(EnBigslime* this, GlobalContext* globalCtx) { + Camera* mainCam = Play_GetCamera(globalCtx, MAIN_CAM); + s16 yaw; + + Play_CameraSetAtEye(globalCtx, this->subCamId, &mainCam->at, &mainCam->eye); + this->grabPlayerTimer = 15; + this->wavySurfaceTimer = 0; + this->bigslimeCollider[0].base.atFlags &= ~AT_ON; + this->actor.world.rot.y = Actor_YawToPoint(&this->actor, &this->actor.home.pos); + yaw = func_800DFCDC(GET_ACTIVE_CAM(globalCtx)) - this->actor.world.rot.y; + + if (yaw > 0x4000) { + this->subCamYawGrabPlayer = -0x2000; + } else if (yaw > 0) { + this->subCamYawGrabPlayer = -0x6000; + } else if (yaw < -0x4000) { + this->subCamYawGrabPlayer = 0x2000; + } else { + this->subCamYawGrabPlayer = 0x6000; + } + + this->subCamYawGrabPlayer += this->actor.world.rot.y; + Animation_PlayLoop(&this->skelAnime, &gGekkoBoxingStanceAnim); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_B_SLIME_EAT); + this->actionFunc = EnBigslime_CutsceneGrabPlayer; +} + +void EnBigslime_CutsceneGrabPlayer(EnBigslime* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + f32 invgrabPlayerTimer; + f32 magPosXZOffset; + Vtx* dynamicVtx; + s32 i; + s32 j; + + player->unk_AE8 = 0; + Math_ScaledStepToS(&this->gekkoRot.x, 0, 0x400); + EnBigslime_UpdateCameraGrabPlayer(this, globalCtx); + if (this->grabPlayerTimer > 0) { + invgrabPlayerTimer = 1.0f / this->grabPlayerTimer; + + this->actor.scale.x = F32_LERPIMP(this->actor.scale.x, 0.15f, invgrabPlayerTimer); + this->actor.scale.y = F32_LERPIMP(this->actor.scale.y, 0.075f, invgrabPlayerTimer); + this->actor.scale.z = this->actor.scale.x; + + player->actor.world.pos.x = F32_LERPIMP(player->actor.world.pos.x, this->actor.world.pos.x, invgrabPlayerTimer); + player->actor.world.pos.z = F32_LERPIMP(player->actor.world.pos.z, this->actor.world.pos.z, invgrabPlayerTimer); + player->actor.world.pos.y = F32_LERPIMP( + player->actor.world.pos.y, this->actor.world.pos.y + this->actor.scale.y * -500.0f, invgrabPlayerTimer); + + for (i = 0; i < BIGSLIME_NUM_VTX; i++) { + dynamicVtx = &sBigslimeDynamicVtx[this->dynamicVtxState][i]; + + // loop over x, y, z + for (j = 0; j < 3; j++) { + // Linearly interpolate dynamicVtx --> staticVtx + dynamicVtx->n.ob[j] += + (s16)((sBigslimeStaticVtx[i].n.ob[j] - dynamicVtx->n.ob[j]) * invgrabPlayerTimer); + } + } + + invgrabPlayerTimer = (15 - this->grabPlayerTimer) / 15.0f; + magPosXZOffset = invgrabPlayerTimer * -50.0f; + this->gekkoPosOffset.x = Math_SinS(this->gekkoRot.y) * magPosXZOffset; + this->gekkoPosOffset.y = invgrabPlayerTimer * -40.0f; + this->gekkoPosOffset.z = Math_CosS(this->gekkoRot.y) * magPosXZOffset; + this->grabPlayerTimer--; + if (this->grabPlayerTimer == 0) { + EnBigslime_SetupAttackPlayerInBigslime(this); + } + } +} + +void EnBigslime_SetupAttackPlayerInBigslime(EnBigslime* this) { + Animation_PlayOnce(&this->skelAnime, sGekkoAttackAnimations[(s32)Rand_ZeroFloat(3.0f) % 3]); + this->numGekkoMeleeAttacks = (s32)Rand_ZeroFloat(3.0f) + 1; + this->numGekkoPosGrabPlayer = 6; + this->actionFunc = EnBigslime_AttackPlayerInBigslime; +} + +void EnBigslime_AttackPlayerInBigslime(EnBigslime* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s16 pitch = this->scaleFactor * 0x3333; // polar (zenith) angle + + player->unk_AE8 = 0; + Math_ScaledStepToS(&this->gekkoRot.x, 0, 0x400); + EnBigslime_UpdateCameraGrabPlayer(this, globalCtx); + EnBigslime_UpdateWavySurface(this); + + if (this->scaleFactor != 0) { + this->scaleFactor--; + } + + // Checks to see if it's the frame of impact + if (((this->skelAnime.animation == &gGekkoJabPunchAnim) && + Animation_OnFrame(&this->skelAnime, 2.0f)) || // Jab punch makes impact on frame 2 of animation + ((this->skelAnime.animation == &gGekkoHookPunchAnim) && + Animation_OnFrame(&this->skelAnime, 9.0f)) || // Hook Punch makes impact on frames 9 of animation + ((this->skelAnime.animation == &gGekkoKickAnim) && + Animation_OnFrame(&this->skelAnime, 2.0f))) { // Kick makes impact on frame 2 of animation + this->scaleFactor = 10; + player->actor.world.pos.x += 20.0f * Math_SinS(this->gekkoRot.y); + player->actor.world.pos.z += 20.0f * Math_CosS(this->gekkoRot.y); + EnBigslime_JerkCameraPlayerHit(this, globalCtx); + if (this->skelAnime.animation == &gGekkoKickAnim) { + EnBigslime_GekkoSfxInsideBigslime(this, NA_SE_EN_FROG_KICK); + } else { + EnBigslime_GekkoSfxInsideBigslime(this, NA_SE_EN_FROG_PUNCH1); + } + } else { + Math_StepToF(&player->actor.world.pos.x, this->actor.world.pos.x, 4.0f); + Math_StepToF(&player->actor.world.pos.z, this->actor.world.pos.z, 4.0f); + } + + EnBigslime_Scale(this, pitch, ((this->scaleFactor * 0.08f) + 0.2f) * 0.15f, + ((this->scaleFactor * 0.08f) + 0.2f) * 0.05f); + player->actor.world.pos.y = this->actor.world.pos.y + (this->actor.scale.y * -500.0f); + if (this->isAnimUpdate) { + this->numGekkoMeleeAttacks--; + if (this->numGekkoMeleeAttacks == 0) { + this->numGekkoPosGrabPlayer--; + + if ((gSaveContext.health < 5) || (this->numGekkoPosGrabPlayer == 0)) { + this->numGekkoPosGrabPlayer = 0; + this->gekkoRot.y = this->actor.world.rot.y; + this->gekkoPosOffset.x = Math_SinS(this->gekkoRot.y) * -50.0f; + this->gekkoPosOffset.z = Math_CosS(this->gekkoRot.y) * -50.0f; + EnBigslime_SetupWindupThrowPlayer(this); + return; + } + + globalCtx->damagePlayer(globalCtx, -4); + func_800B8E58(&player->actor, player->ageProperties->unk_92 + 0x6805); + this->gekkoRot.y += (s16)(Rand_S16Offset(0x4000, 0x4000) * (Rand_ZeroOne() < 0.5f ? -1 : 1)); + this->gekkoPosOffset.x = Math_SinS(this->gekkoRot.y) * -50.0f; + this->gekkoPosOffset.z = Math_CosS(this->gekkoRot.y) * -50.0f; + this->numGekkoMeleeAttacks = (s32)Rand_ZeroFloat(3.0f) + 1; + } + Animation_PlayOnce(&this->skelAnime, sGekkoAttackAnimations[((s32)Rand_ZeroFloat(3.0f) % 3)]); + } + + func_800B9010(&this->actor, NA_SE_EN_B_SLIME_PUNCH_MOVE - SFX_FLAG); +} + +/** + * Calculates the surface perturbation (multiplicative offset from the static vertices) + * used to update dynamic vertices when bigslime is about to throw/eject player from inside + * at the end of the grab-player cutscene + * + * A unit normal vector (unitVec) is used to represent the direction player will be thrown. + * This unit vector has the following spherical coordinates: + * - radius = 1 + * - yaw (azimuthal angle) = this->actor.world.rot.y + * - pitch (polar/zenith angle) = M_PI / 4 + * + * This unit normal vector is converted into x-y-z coordinates and dot-producted with + * the model coordinates of each individual vertex. The surface perturbation is then + * set to be linearly proportional to this dot product + * + * This leads to the bending shape observed during windup as player is about being thrown out of bigslime + */ +void EnBigslime_SetupWindupThrowPlayer(EnBigslime* this) { + Vtx* dynamicVtx; + f32 dotXYZ; + f32 unitVecX = Math_SinS(this->actor.world.rot.y) * M_SQRT1_2; + f32 unitVecZ = Math_CosS(this->actor.world.rot.y) * M_SQRT1_2; + s32 i; + + for (i = 0; i < BIGSLIME_NUM_VTX; i++) { + dynamicVtx = &sBigslimeDynamicVtx[this->dynamicVtxState][i]; + + // vector dot product between each dynamicVtx and the unit normal vector describing player's thrown direction + dotXYZ = (dynamicVtx->n.ob[0] * unitVecX + dynamicVtx->n.ob[1] * M_SQRT1_2 + dynamicVtx->n.ob[2] * unitVecZ) * + 0.001f; + if (dotXYZ < 0.01f) { + this->vtxSurfacePerturbation[i] = 0.0f; + } else { + this->vtxSurfacePerturbation[i] = dotXYZ * 0.5f; + } + } + + this->windupPunchTimer = 27; + Animation_PlayOnce(&this->skelAnime, &gGekkoWindupPunchAnim); + EnBigslime_GekkoSfxInsideBigslime(this, NA_SE_EN_FROG_PUNCH2); + this->actionFunc = EnBigslime_WindupThrowPlayer; +} + +void EnBigslime_WindupThrowPlayer(EnBigslime* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + f32 scale; + f32 invWindupPunchTimer; + Vtx* dynamicVtx; + Vtx* staticVtx; + s32 i; + s32 j; + + this->windupPunchTimer--; + EnBigslime_UpdateCameraGrabPlayer(this, globalCtx); + if (this->windupPunchTimer > 0) { + invWindupPunchTimer = 1.0f / this->windupPunchTimer; + scale = cos_rad(this->windupPunchTimer * (M_PI / 27)) + 1.0f; + player->actor.world.pos.y = this->actor.world.pos.y + (this->actor.scale.y * -500.0f); + + // Linearly interpolate gekkoRot.y --> this->actor.world.rot.y + this->gekkoRot.y += (s16)((s16)(this->actor.world.rot.y - this->gekkoRot.y) * invWindupPunchTimer); + this->gekkoPosOffset.x = Math_SinS(this->gekkoRot.y) * -50.0f; + this->gekkoPosOffset.z = Math_CosS(this->gekkoRot.y) * -50.0f; + } else { + if (this->windupPunchTimer == 0) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_B_SLIME_REVERSE); + EnBigslime_GekkoSfxInsideBigslime(this, NA_SE_EN_FROG_PUNCH1); + } + + scale = 0.5f - cos_rad(-this->windupPunchTimer * (M_PI / 5)) * 0.5f; + if (this->windupPunchTimer == -5) { + if (player->stateFlags2 & 0x80) { + player->actor.parent = NULL; + player->unk_AE8 = 100; + } + + player->actor.velocity.y = 0.0f; + func_800B8D50(globalCtx, &this->actor, 10.0f, this->actor.world.rot.y, 10.0f, 4); + EnBigslime_SetupSetDynamicVtxThrowPlayer(this, globalCtx); + } + + player->actor.world.pos.x = + (Math_SinS(this->actor.world.rot.y) * (1060.5f * this->actor.scale.x) * scale) + this->actor.world.pos.x; + player->actor.world.pos.z = + (Math_CosS(this->actor.world.rot.y) * (1060.5f * this->actor.scale.z) * scale) + this->actor.world.pos.z; + player->actor.world.pos.y = + this->actor.world.pos.y + (this->actor.scale.y * -500.0f) + (1060.5f * this->actor.scale.y * scale); + invWindupPunchTimer = 1.0f / (this->windupPunchTimer + 6); + // this->gekkoPosOffset *= (1 - invWindupPunchTimer) + this->gekkoPosOffset.x -= this->gekkoPosOffset.x * invWindupPunchTimer; + this->gekkoPosOffset.y -= this->gekkoPosOffset.y * invWindupPunchTimer; + this->gekkoPosOffset.z -= this->gekkoPosOffset.z * invWindupPunchTimer; + scale = 2.0f - (3.0f * scale); + } + + // Deforming Bigslime during the final windup punch while grabbing player using vtxSurfacePerturbation + for (i = 0; i < BIGSLIME_NUM_VTX; i++) { + dynamicVtx = &sBigslimeDynamicVtx[this->dynamicVtxState][i]; + staticVtx = &sBigslimeStaticVtx[i]; + if (this->vtxSurfacePerturbation[i] != 0.0f) { + if (this->windupPunchTimer > 0) { + // loop over x, y, z + for (j = 0; j < 3; j++) { + // Linearly interpolate dynamicVtx --> staticVtx * (1 - scale * vtxSurfacePerturbation) + dynamicVtx->n.ob[j] += (s16)( + ((staticVtx->n.ob[j] - (s32)(scale * staticVtx->n.ob[j] * this->vtxSurfacePerturbation[i])) - + dynamicVtx->n.ob[j]) * + invWindupPunchTimer); + } + } else { + // loop over x, y, z + for (j = 0; j < 3; j++) { + // Directly set dynamicVtx --> staticVtx * (1 - scale * vtxSurfacePerturbation) + dynamicVtx->n.ob[j] = + staticVtx->n.ob[j] - (s32)((scale * staticVtx->n.ob[j]) * this->vtxSurfacePerturbation[i]); + } + } + } else { + if (this->windupPunchTimer > 0) { + // loop over x, y, z + for (j = 0; j < 3; j++) { + // Linearly interpolate dynamicVtx --> staticVtx + dynamicVtx->n.ob[j] += (s16)((staticVtx->n.ob[j] - dynamicVtx->n.ob[j]) * invWindupPunchTimer); + } + } + } + } +} + +void EnBigslime_SetupSetDynamicVtxThrowPlayer(EnBigslime* this, GlobalContext* globalCtx) { + this->grabPlayerTimer = 10; + EnBigslime_SetTargetVtxToWideCone(this); + EnBigslime_CheckVtxWallBoundaries(this); + EnBigslime_EndCutscene(this, globalCtx); + this->actionFunc = EnBigslime_SetDynamicVtxThrowPlayer; +} + +/** + * Restores bigslime to wide cone after player is thrown + */ +void EnBigslime_SetDynamicVtxThrowPlayer(EnBigslime* this, GlobalContext* globalCtx) { + f32 invThrowPlayerTimer; + Vtx* targetVtx; + Vtx* dynamicVtx; + s32 i; + s32 j; + + this->throwPlayerTimer--; + if (this->throwPlayerTimer > 0) { + invThrowPlayerTimer = 1.0f / this->throwPlayerTimer; + for (i = 0; i < BIGSLIME_NUM_VTX; i++) { + targetVtx = &sBigslimeTargetVtx[i]; + dynamicVtx = &sBigslimeDynamicVtx[this->dynamicVtxState][i]; + + // loop over x, y, z + for (j = 0; j < 3; j++) { + // Linearly interpolate dynamicVtx --> targetVtx + dynamicVtx->n.ob[j] += (s16)((targetVtx->n.ob[j] - dynamicVtx->n.ob[j]) * invThrowPlayerTimer); + } + } + + this->actor.scale.x = F32_LERPIMP(this->actor.scale.x, 0.2f, invThrowPlayerTimer); + this->actor.scale.y = F32_LERPIMP(this->actor.scale.y, 0.05f, invThrowPlayerTimer); + this->actor.scale.z = this->actor.scale.x; + EnBigslime_CheckVtxWallBoundaries(this); + } + + if (this->throwPlayerTimer == 0) { + EnBigslime_SetupRise(this); + } +} + +/** + * Sets the frozen effect as a seed on the bottom 4 nodes of a sphere + * The frozen effect is initially set to be dimmer the farther from the initial seed you are + */ +void EnBigslime_SetupFreeze(EnBigslime* this) { + Vtx* targetVtx; + Vtx* dynamicVtx; + s32 i; + s32 j; + + this->actor.speedXZ = 0.0f; + this->freezeTimer = 40; + if (this->actor.bgCheckFlags & 1) { + this->actor.velocity.y = 0.0f; + this->actor.gravity = 0.0f; + } else if ((this->actionFunc == EnBigslime_Rise) && (this->riseCounter < 2)) { + this->actor.gravity = -2.0f; + } + + this->bigslimeCollider[0].base.atFlags &= ~AT_ON; + this->bigslimeCollider[0].base.acFlags &= ~AC_ON; + + // Resets frozen effect alpha to 0 + for (i = 0; i < BIGSLIME_NUM_VTX; i++) { + dynamicVtx = &sBigslimeDynamicVtx[this->dynamicVtxState][i]; + targetVtx = &sBigslimeTargetVtx[i]; + for (j = 0; j < 3; j++) { + targetVtx->n.ob[j] = dynamicVtx->n.ob[j]; + } + targetVtx->n.a = 0; + } + + // Initalizes frozen effect alpha near bottom of sphere by increasing levels of alpha + for (i = 0; i < 20; i++) { + sBigslimeTargetVtx[i + 138].n.a = 10 * i; + } + + // Initalizes/seeds frozen effect alpha in bottom 4 nodes in vtx sphere to highest level of alpha + for (i = 0; i < 4; i++) { + sBigslimeTargetVtx[i + 158].n.a = 200; + } + + for (i = 0; i < BIGSLIME_NUM_RING_FACES; i++) { + this->bigslimeCollider[i].base.ocFlags1 &= ~OC1_NO_PUSH; + } + + this->actionFuncStored = this->actionFunc; + this->actionFunc = EnBigslime_Freeze; +} + +/** + * Propogates the frozen effect from the seed at the bottom out through all vertices + */ +void EnBigslime_Freeze(EnBigslime* this, GlobalContext* globalCtx) { + f32 randFloat; + Vtx* targetVtx; + Vtx* dynamicVtx; + s32 vtxIceUpdate; + s32 vtxIceSeed; + s32 j; + + if (this->freezeTimer) { + this->freezeTimer--; + } + + this->skelAnime.playSpeed = this->freezeTimer / 40.0f; + vtxIceSeed = this->freezeTimer * 4; + for (vtxIceUpdate = 0; vtxIceUpdate < 4; vtxIceUpdate++, vtxIceSeed++) { + if (vtxIceSeed < BIGSLIME_NUM_VTX) { + dynamicVtx = &sBigslimeDynamicVtx[this->dynamicVtxState][vtxIceSeed]; + targetVtx = &sBigslimeTargetVtx[vtxIceSeed]; + randFloat = randPlusMinusPoint5Scaled(40.0f); + dynamicVtx->n.ob[0] += (s16)(randFloat / this->actor.scale.x); + dynamicVtx->n.ob[1] += (s16)(randFloat / this->actor.scale.y); + dynamicVtx->n.ob[2] += (s16)(randFloat / this->actor.scale.z); + if (((dynamicVtx->n.ob[1] * this->actor.scale.y) + this->actor.world.pos.y) < GBT_ROOM_5_MIN_Y) { + dynamicVtx->n.ob[1] = ((GBT_ROOM_5_MIN_Y - this->actor.world.pos.y) / this->actor.scale.y) - 1.0f; + } + + for (j = 0; j < 3; j++) { + targetVtx->n.ob[j] = dynamicVtx->n.ob[j]; + } + } + } + + for (vtxIceUpdate = 4; vtxIceUpdate < BIGSLIME_NUM_VTX; vtxIceUpdate++) { + sBigslimeTargetVtx[vtxIceUpdate - 4].n.a = sBigslimeTargetVtx[vtxIceUpdate].n.a; + } + + func_800B9010(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG); + if (this->actor.bgCheckFlags & 2) { + if (this->freezeTimer == 0) { + EnBigslime_BreakIntoMinislime(this, globalCtx); + } else { + this->bigslimeCollider[0].base.acFlags |= AC_ON; + EnBigslime_AddIceShardEffect(this, globalCtx); + EnBigslime_SetupSquishFlat(this); + } + } else if (this->freezeTimer == 0) { + if (!(this->actor.bgCheckFlags & 1)) { + EnBigslime_SetupFrozenFall(this); + } else { + EnBigslime_SetupFrozenGround(this); + } + } +} + +void EnBigslime_SetupFrozenGround(EnBigslime* this) { + this->freezeTimer = 80; + this->bigslimeCollider[0].base.acFlags |= AC_ON; + this->actionFunc = EnBigslime_FrozenGround; +} + +void EnBigslime_FrozenGround(EnBigslime* this, GlobalContext* globalCtx) { + f32 invFreezerTimer; + s32 randSign; + f32 randFloat; + + this->freezeTimer--; + if (this->freezeTimer == 0) { + EnBigslime_AddIceShardEffect(this, globalCtx); + EnBigslime_SetTargetVtxFromPreFrozen(this); + } else if (this->freezeTimer == 40) { + Math_Vec3f_Copy(&this->frozenPos, &this->actor.world.pos); + } else if ((this->freezeTimer < 20) || ((this->freezeTimer < 40) && ((this->freezeTimer % 2) != 0))) { + invFreezerTimer = 1.0f / this->freezeTimer; + + // clang-format off + randFloat = Rand_ZeroFloat(4.0f * invFreezerTimer); + randSign = Rand_ZeroOne() < 0.5f ? -1 : 1; \ + this->actor.world.pos.x = randSign * (1.0f + invFreezerTimer + randFloat) + this->frozenPos.x; + // clang-format on + + randFloat = Rand_ZeroFloat(4.0f * invFreezerTimer); + randSign = Rand_ZeroOne() < 0.5f ? -1 : 1; + this->actor.world.pos.z = randSign * (1.0f + invFreezerTimer + randFloat) + this->frozenPos.z; + } +} + +void EnBigslime_SetupMelt(EnBigslime* this) { + s32 i; + + this->bigslimeCollider[0].base.acFlags &= ~AC_ON; + for (i = 0; i < 2; i++) { + sBigslimeTargetVtx[i].n.a = 0; + } + + for (i = 0; i < 20; i++) { + sBigslimeTargetVtx[i + 2].n.a = 10 * i; + } + + this->meltCounter = 0; + this->actionFunc = EnBigslime_Melt; +} + +void EnBigslime_Melt(EnBigslime* this, GlobalContext* globalCtx) { + static Vec3f iceSmokeVelocity = { 0.0f, 2.0f, 0.0f }; + Vec3f iceSmokePos; + Vtx* targetVtx; + Vtx* dynamicVtx; + s32 i; + + this->meltCounter++; + if ((this->meltCounter < 70) && ((this->meltCounter % 2) != 0)) { + dynamicVtx = + &sBigslimeDynamicVtx[this->dynamicVtxState][(s32)Rand_ZeroFloat(BIGSLIME_NUM_VTX) % BIGSLIME_NUM_VTX]; + iceSmokePos.x = (dynamicVtx->n.ob[0] * this->actor.scale.x) + this->actor.world.pos.x; + iceSmokePos.y = (dynamicVtx->n.ob[1] * this->actor.scale.y) + this->actor.world.pos.y; + iceSmokePos.z = (dynamicVtx->n.ob[2] * this->actor.scale.z) + this->actor.world.pos.z; + EffectSsIceSmoke_Spawn(globalCtx, &iceSmokePos, &iceSmokeVelocity, &gZeroVec3f, 600); + } + + func_800B9010(&this->actor, NA_SE_EV_ICE_MELT_LEVEL - SFX_FLAG); + for (i = 159; i >= 0; i--) { + sBigslimeTargetVtx[i + 2].n.a = sBigslimeTargetVtx[i].n.a; + } + + if (this->meltCounter == 100) { + EnBigslime_SetTargetVtxFromPreFrozen(this); + } else if (this->meltCounter == 50) { + globalCtx->envCtx.unk_C3 = 0xFF; + } +} + +void EnBigslime_SetupFrozenFall(EnBigslime* this) { + s32 i; + + this->bigslimeCollider[0].base.atFlags |= AT_ON; + this->actor.gravity = -2.0f; + this->actor.velocity.y = 0.0f; + + for (i = 0; i < BIGSLIME_NUM_RING_FACES; i++) { + this->bigslimeCollider[i].base.ocFlags1 |= OC1_NO_PUSH; + } + + this->actionFunc = EnBigslime_FrozenFall; +} + +void EnBigslime_FrozenFall(EnBigslime* this, GlobalContext* globalCtx) { + s32 i; + + for (i = 0; i < BIGSLIME_NUM_RING_FACES; i++) { + if (this->bigslimeCollider[i].base.atFlags & AT_HIT) { + break; + } + } + + if (i != BIGSLIME_NUM_RING_FACES) { + func_800B8D50(globalCtx, &this->actor, 7.0f, this->actor.yawTowardsPlayer, 5.0f, 0x10); + } + + if (this->actor.bgCheckFlags & 1) { + EnBigslime_BreakIntoMinislime(this, globalCtx); + } +} + +void EnBigslime_SetupJumpGekko(EnBigslime* this) { + Animation_PlayLoop(&this->skelAnime, &gGekkoJumpForwardAnim); + this->actor.speedXZ = 8.0f; + this->jumpTimer = 100; + this->actor.world.rot.y = this->gekkoRot.y; + this->gekkoYaw = this->actor.yawTowardsPlayer + 0x8000; + this->actionFunc = EnBigslime_JumpGekko; +} + +void EnBigslime_JumpGekko(EnBigslime* this, GlobalContext* globalCtx) { + s16 yaw; + s16 yawDiff; + + if (this->actor.bgCheckFlags & 1) { + this->gekkoCollider.base.acFlags |= AC_ON; + this->actor.flags |= 1; + } + + this->jumpTimer--; + if (Animation_OnFrame(&this->skelAnime, 1.0f)) { + EnBigslime_GekkoSfxOutsideBigslime(this, NA_SE_EN_FROG_JUMP); + } else if (Animation_OnFrame(&this->skelAnime, 11.0f)) { + EnBigslime_GekkoSfxOutsideBigslime(this, NA_SE_EV_WALK_WATER); + } + + if (!(this->actor.bgCheckFlags & 1) || ((this->skelAnime.curFrame > 1.0f) && (this->skelAnime.curFrame < 12.0f))) { + this->actor.speedXZ = 8.0f; + } else { + this->actor.speedXZ = 0.0f; + } + + if (Math_SmoothStepToS(&this->actor.world.rot.y, this->gekkoYaw, 5, 0x1000, 0x80) == 0) { + if (Actor_XZDistanceToPoint(&this->actor, &this->actor.home.pos) > 240.0f) { + yaw = Actor_YawToPoint(&this->actor, &this->actor.home.pos); + yawDiff = yaw - (s16)(this->actor.yawTowardsPlayer + 0x8000); + this->gekkoYaw = + ABS_ALT(yawDiff) < 0x3000 ? yaw : (yawDiff / 2) + (s16)(this->actor.yawTowardsPlayer + 0x8000); + } else { + this->gekkoYaw = this->actor.yawTowardsPlayer + 0x8000; + } + } + + this->gekkoRot.y = this->actor.world.rot.y; + if (this->jumpTimer == 0) { + if (this->formBigslimeTimer == 0) { + EnBigslime_SetupCutscene(this); + } else { + this->formBigslimeTimer--; + EnBigslime_SetupIdleLookAround(this); + } + } else if ((this->actor.xzDistToPlayer > 300.0f) && (this->gekkoCollider.base.ocFlags1 & OC1_HIT)) { + if ((this->gekkoCollider.base.oc->params == MINISLIME_IDLE) && + (this->gekkoCollider.base.oc->id == ACTOR_EN_MINISLIME)) { + this->gekkoCollider.base.oc->params = MINISLIME_SETUP_GEKKO_THROW; + this->minislimeToThrow = (EnMinislime*)this->gekkoCollider.base.oc; + EnBigslime_SetupThrowMinislime(this); + } + } +} + +void EnBigslime_SetupIdleLookAround(EnBigslime* this) { + Animation_PlayOnce(&this->skelAnime, &gGekkoNervousIdleAnim); + this->idleTimer = 60; + this->actor.speedXZ = 0.0f; + if (BINANG_SUB(Actor_YawToPoint(&this->actor, &this->actor.home.pos), this->gekkoRot.y) > 0) { + this->gekkoYaw = this->gekkoRot.y + ((u32)Rand_Next() >> 20) + 0x2000; + } else { + this->gekkoYaw = this->gekkoRot.y - ((u32)Rand_Next() >> 20) - 0x2000; + } + this->actionFunc = EnBigslime_IdleLookAround; +} + +void EnBigslime_IdleLookAround(EnBigslime* this, GlobalContext* globalCtx) { + s16 yawDiff; + + this->idleTimer--; + if (this->isAnimUpdate) { + if (Rand_ZeroOne() < 0.25f) { + Animation_PlayOnce(&this->skelAnime, &gGekkoLookAroundAnim); + } else { + Animation_PlayOnce(&this->skelAnime, &gGekkoNervousIdleAnim); + } + } + + if ((this->skelAnime.animation == &gGekkoNervousIdleAnim) && + Math_ScaledStepToS(&this->gekkoRot.y, this->gekkoYaw, 0x400)) { + if (BINANG_SUB(Actor_YawToPoint(&this->actor, &this->actor.home.pos), this->gekkoRot.y) > 0) { + this->gekkoYaw = this->gekkoRot.y + ((u32)Rand_Next() >> 20) + 0x2000; + } else { + this->gekkoYaw = this->gekkoRot.y - ((u32)Rand_Next() >> 20) - 0x2000; + } + } + + yawDiff = this->actor.yawTowardsPlayer - this->gekkoRot.y; + if ((this->idleTimer == 0) || ((ABS_ALT(yawDiff) < 0x2800) && (this->actor.xzDistToPlayer < 240.0f))) { + EnBigslime_SetupIdleNoticePlayer(this); + } +} + +void EnBigslime_SetupIdleNoticePlayer(EnBigslime* this) { + Animation_PlayOnce(&this->skelAnime, &gGekkoSurpriseJumpAnim); + this->gekkoYaw = this->gekkoRot.y + 0x8000; + EnBigslime_GekkoSfxOutsideBigslime(this, NA_SE_EN_FROG_JUMP_MID); + this->actionFunc = EnBigslime_IdleNoticePlayer; +} + +void EnBigslime_IdleNoticePlayer(EnBigslime* this, GlobalContext* globalCtx) { + s16* yaw = &this->gekkoRot.y; + + if (this->skelAnime.curFrame > 10.0f) { + Math_ScaledStepToS(yaw, this->gekkoYaw, 0x800); + } + if (this->isAnimUpdate) { + EnBigslime_SetupJumpGekko(this); + } +} + +void EnBigslime_SetupThrowMinislime(EnBigslime* this) { + Animation_PlayOnce(&this->skelAnime, &gGekkoWindupPunchAnim); + EnBigslime_GekkoSfxOutsideBigslime(this, NA_SE_EN_FROG_HOLD_SLIME); + this->actor.speedXZ = 0.0f; + this->actionFunc = EnBigslime_ThrowMinislime; +} + +void EnBigslime_ThrowMinislime(EnBigslime* this, GlobalContext* globalCtx) { + s16 jumpTimerStored; + + Math_ScaledStepToS(&this->gekkoRot.y, this->actor.yawTowardsPlayer, 0x300); + if (Animation_OnFrame(&this->skelAnime, 27.0f) && + (this->minislimeToThrow->actor.params == MINISLIME_SETUP_GEKKO_THROW)) { + EnBigslime_GekkoSfxOutsideBigslime(this, NA_SE_EN_FROG_THROW_SLIME); + this->minislimeToThrow->actor.params = MINISLIME_GEKKO_THROW; + } + if (this->isAnimUpdate) { + jumpTimerStored = this->jumpTimer; // Stores jumpTimer so it doesn't get overwritten back to 100 + EnBigslime_SetupJumpGekko(this); + this->jumpTimer = jumpTimerStored; + } +} + +void EnBigslime_SetupDamageGekko(EnBigslime* this, s32 isNotFrozen) { + Animation_MorphToPlayOnce(&this->skelAnime, &gGekkoDamagedAnim, -3.0f); + this->gekkoCollider.base.acFlags &= ~AC_ON; + this->damageSpinTimer = 20; + this->actor.speedXZ = 10.0f; + this->actor.gravity = -2.0f; + this->actor.velocity.y = 0.0f; + if (isNotFrozen) { + func_800BE504(&this->actor, &this->gekkoCollider); + } + + EnBigslime_GekkoSfxOutsideBigslime(this, NA_SE_EN_FROG_DAMAGE); + if ((this->actor.flags & 0x2000) == 0x2000) { + this->actor.flags &= ~0x2000; + } + + this->actionFunc = EnBigslime_DamageGekko; +} + +/** + * Spins Gekko around as it takes damage + */ +void EnBigslime_DamageGekko(EnBigslime* this, GlobalContext* globalCtx) { + s32 damageSpinTimer; + + this->damageSpinTimer--; + damageSpinTimer = CLAMP_MAX(this->damageSpinTimer, 10); + this->gekkoRot.y += 0x300 * damageSpinTimer; + Math_StepToF(&this->actor.speedXZ, 0.0f, 0.5f); + if (this->damageSpinTimer == 0) { + EnBigslime_SetupCutscene(this); + } +} + +void EnBigslime_SetupStunGekko(EnBigslime* this) { + if ((this->skelAnime.animation == &gGekkoJumpForwardAnim) || + (this->skelAnime.animation == &gGekkoSurpriseJumpAnim)) { + this->skelAnime.curFrame = 1.0f; + } + this->actionFunc = EnBigslime_StunGekko; + this->skelAnime.playSpeed = 0.0f; + this->actor.speedXZ = 0.0f; +} + +void EnBigslime_StunGekko(EnBigslime* this, GlobalContext* globalCtx) { + this->stunTimer--; + if (this->stunTimer == 0) { + if (this->gekkoDrawEffect == GEKKO_DRAW_EFFECT_FROZEN) { + EnBigslime_GekkoThaw(this, globalCtx); + EnBigslime_SetupDamageGekko(this, false); + } else { + this->gekkoCollider.base.acFlags &= ~AC_ON; + EnBigslime_SetupCutscene(this); + } + } +} + +void EnBigslime_SetupCutsceneFormBigslime(EnBigslime* this) { + Animation_PlayOnce(&this->skelAnime, &gGekkoJumpUpAnim); + this->gekkoCollider.base.acFlags &= ~AC_ON; + this->actor.world.rot.x = -Actor_PitchToPoint(&this->actor, &this->actor.home.pos); + this->actor.world.rot.y = Actor_YawToPoint(&this->actor, &this->actor.home.pos); + this->actionFunc = EnBigslime_CutsceneFormBigslime; + this->actor.speedXZ = 0.0f; +} + +void EnBigslime_CutsceneFormBigslime(EnBigslime* this, GlobalContext* globalCtx) { + EnBigslime_UpdateCameraFormingBigslime(this, globalCtx); + Math_ScaledStepToS(&this->gekkoRot.y, this->actor.world.rot.y, 0x800); + if (Animation_OnFrame(&this->skelAnime, 18.0f)) { + EnBigslime_SetupFormBigslime(this); + } +} + +void EnBigslime_SetupFormBigslime(EnBigslime* this) { + s32 i; + + this->actor.gravity = 0.0f; + this->gekkoRot.x = 0x4000 - this->actor.world.rot.x; + this->formBigslimeTimer = 0; + this->wavySurfaceTimer = 0; + this->actor.speedXZ = 25.0f; + this->gekkoRot.y = this->actor.world.rot.y; + this->formBigslimeCutsceneTimer = 2; + + for (i = 0; i < MINISLIME_NUM_SPAWN; i++) { + this->minislime[i]->actor.params = MINISLIME_FORM_BIGSLIME; + } + + for (i = 0; i < BIGSLIME_NUM_RING_FACES; i++) { + this->bigslimeCollider[i].base.ocFlags1 |= OC1_NO_PUSH; + } + + this->actor.update = EnBigslime_UpdateBigslime; + this->actor.draw = EnBigslime_DrawBigslime; + Actor_SetScale(&this->actor, 0.0f); + this->vtxScaleX = 0.0f; + this->vtxScaleZ = 0.0f; + EnBigslime_GekkoSfxOutsideBigslime(this, NA_SE_EN_FROG_JUMP_ABOVE); + EnBigslime_GekkoSfxOutsideBigslime(this, NA_SE_EN_UTSUBO_APPEAR_TRG); + this->actionFunc = EnBigslime_FormBigslime; +} + +void EnBigslime_FormBigslime(EnBigslime* this, GlobalContext* globalCtx) { + f32 xzScale; + f32 yScaleFactor; + s32 i; + + EnBigslime_UpdateWavySurface(this); + EnBigslime_UpdateCameraFormingBigslime(this, globalCtx); + if (this->formBigslimeCutsceneTimer < 0) { + Math_ScaledStepToS(&this->gekkoRot.x, 0, 0x400); + } else if (this->actor.world.pos.y > (GBT_ROOM_5_MAX_Y - 100.0f)) { + this->gekkoRot.x -= 0x4000; + Math_Vec3f_Copy(&this->actor.world.pos, &this->actor.home.pos); + this->actor.gravity = 0.0f; + this->actor.velocity.y = 0.0f; + this->actor.speedXZ = 0.0f; + Animation_PlayLoop(&this->skelAnime, &gGekkoSwimForwardAnim); + this->formBigslimeCutsceneTimer--; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_B_SLIME_COMBINE); + } else if (this->isAnimUpdate) { + this->formBigslimeCutsceneTimer--; + if (this->formBigslimeCutsceneTimer == 0) { + Animation_PlayLoop(&this->skelAnime, &gGekkoSwimUpAnim); + } + } + + for (i = 0; i < MINISLIME_NUM_SPAWN; i++) { + if (this->minislime[i]->actor.params == MINISLIME_SETUP_DISAPPEAR) { + this->minislime[i]->actor.params = MINISLIME_DISAPPEAR; + this->minislimeCounter++; + } + } + + if (this->minislimeCounter > 0) { + yScaleFactor = sqrtf(this->minislimeCounter * (2.0f / 30.0f)) * 0.6f + 0.4f; + xzScale = 0.15f * yScaleFactor; + this->actor.scale.x = xzScale; + this->actor.scale.y = 0.079f * yScaleFactor; + this->actor.scale.z = xzScale; + } + + if (this->minislimeCounter == MINISLIME_NUM_SPAWN) { + this->minislimeState = MINISLIME_INACTIVE_STATE; + this->actor.hintId = 3; + EnBigslime_SetupMoveOnCeiling(this); + } +} + +void EnBigslime_SetupCutsceneDefeat(EnBigslime* this, GlobalContext* globalCtx) { + Vec3f subCamEye; + Vec3f subCamAt; + s32 i; + s16 yawOffset; + + Animation_Change(&this->skelAnime, &gGekkoDamagedAnim, 0.5f, 0.0f, + Animation_GetLastFrame(&gGekkoDamagedAnim.common), 3, 0.0f); + this->gekkoCollider.base.acFlags &= ~AC_ON; + this->defeatTimer = 60; + this->actor.speedXZ = 10.0f; + this->actor.gravity = -2.0f; + this->actor.velocity.y = 0.0f; + EnBigslime_GekkoSfxOutsideBigslime(this, NA_SE_EN_FROG_DEAD); + + // Points the camera at the defeated Gekko + subCamAt.x = this->actor.world.pos.x; + subCamAt.y = this->actor.world.pos.y + 40.0f; + subCamAt.z = this->actor.world.pos.z; + + if (BINANG_SUB(Actor_YawToPoint(&this->actor, &this->actor.home.pos), this->actor.world.rot.y) > 0) { + yawOffset = this->actor.world.rot.y + 0x4000; + } else { + yawOffset = this->actor.world.rot.y - 0x4000; + } + + // Moves the camera to the side of player and Gekko + subCamEye.x = (Math_SinS(yawOffset) * 250.0f) + subCamAt.x; + subCamEye.y = subCamAt.y + 60.0f; + subCamEye.z = (Math_CosS(yawOffset) * 250.0f) + subCamAt.z; + Play_CameraSetAtEye(globalCtx, this->subCamId, &subCamAt, &subCamEye); + + for (i = 0; i < MINISLIME_NUM_SPAWN; i++) { + this->minislime[i]->actor.params = MINISLIME_DEFEAT_IDLE; + } + + this->actor.flags &= ~1; + EnBigslime_GekkoThaw(this, globalCtx); + this->actionFunc = EnBigslime_CutsceneDefeat; +} + +void EnBigslime_CutsceneDefeat(EnBigslime* this, GlobalContext* globalCtx) { + s32 defeatTimer; + Camera* subCam; + Vec3f subCamAt; + + this->defeatTimer--; + defeatTimer = CLAMP_MAX(this->defeatTimer, 10); + this->gekkoRot.y += 0x300 * defeatTimer; + if (Math_StepToF(&this->actor.speedXZ, 0.0f, 0.5f)) { + EnBigslime_SetupGekkoDespawn(this, globalCtx); + } else { + // Continue for the camera to follow Gekko as it spins in defeat + subCam = Play_GetCamera(globalCtx, this->subCamId); + subCamAt.x = this->actor.world.pos.x; + subCamAt.y = this->actor.world.pos.y + 40.0f; + subCamAt.z = this->actor.world.pos.z; + Play_CameraSetAtEye(globalCtx, this->subCamId, &subCamAt, &subCam->eye); + } +} + +void EnBigslime_SetupGekkoDespawn(EnBigslime* this, GlobalContext* globalCtx) { + Camera* subCam = Play_GetCamera(globalCtx, this->subCamId); + f32 magnitude; + f32 invMagnitude; + + Math_Vec3f_Diff(&subCam->eye, &subCam->at, &this->subCamDistToFrog); + magnitude = Math3D_Vec3fMagnitude(&this->subCamDistToFrog); + if (magnitude > 78.0f) { + invMagnitude = 1.0f / magnitude; + magnitude -= 77.0f; + magnitude /= 20.0f; + Math_Vec3f_Scale(&this->subCamDistToFrog, magnitude * invMagnitude); + } else { + Math_Vec3f_Copy(&this->subCamDistToFrog, &gZeroVec3f); + } + + this->shockwaveAlpha = 0; + this->despawnTimer = 20; + this->actionFunc = EnBigslime_GekkoDespawn; +} + +void EnBigslime_GekkoDespawn(EnBigslime* this, GlobalContext* globalCtx) { + Vec3f subCamEye; + Vec3f subCamAt; + Camera* subCam; + + this->despawnTimer--; + this->gekkoScale = this->despawnTimer * 0.00035000002f; + if (this->despawnTimer == 0) { + EnBigslime_SetupFrogSpawn(this, globalCtx); + } else { + subCam = Play_GetCamera(globalCtx, this->subCamId); + Math_Vec3f_Copy(&subCamAt, &subCam->at); + Math_Vec3f_Diff(&subCam->eye, &this->subCamDistToFrog, &subCamEye); + subCamEye.y -= 1.8f; + subCamAt.y -= 1.7f; + Play_CameraSetAtEye(globalCtx, this->subCamId, &subCamAt, &subCamEye); + } +} + +void EnBigslime_SetupFrogSpawn(EnBigslime* this, GlobalContext* globalCtx) { + static Color_RGBA8 dustPrimColor = { 250, 250, 250, 255 }; + static Color_RGBA8 dustEnvColor = { 180, 180, 180, 255 }; + static Vec3f hahenAccel = { 0.0f, -0.5f, 0.0f }; + Camera* subCam = Play_GetCamera(globalCtx, this->subCamId); + Vec3f* worldPos; + Vec3f dustPos; + Vec3f hahenVel; + s16 yaw = func_800DFCDC(GET_ACTIVE_CAM(globalCtx)); + s16 yawReverse = yaw + 0x8000; + s32 i; + + this->gekkoCollider.base.ocFlags1 &= ~OC1_ON; + + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_MINIFROG, this->actor.world.pos.x, this->actor.world.pos.y, + this->actor.world.pos.z, 0, yawReverse, 0, this->actor.params); + + dustPos.x = (Math_SinS(yawReverse) * 20.0f) + this->actor.world.pos.x; + dustPos.y = this->actor.world.pos.y + 20.0f; + worldPos = &this->actor.world.pos; + dustPos.z = (Math_CosS(yawReverse) * 20.0f) + this->actor.world.pos.z; + + Audio_PlaySoundAtPosition(globalCtx, worldPos, 40, NA_SE_EN_NPC_APPEAR); + + // dust cloud where the red frog appears + func_800B0DE0(globalCtx, &dustPos, &gZeroVec3f, &gZeroVec3f, &dustPrimColor, &dustEnvColor, 500, 50); + + for (i = 0; i < 25; i++) { + hahenVel.x = randPlusMinusPoint5Scaled(5.0f); + hahenVel.y = Rand_ZeroFloat(3.0f) + 4.0f; + hahenVel.z = randPlusMinusPoint5Scaled(5.0f); + EffectSsHahen_Spawn(globalCtx, worldPos, &hahenVel, &hahenAccel, 0, Rand_S16Offset(12, 3), HAHEN_OBJECT_DEFAULT, + 10, 0); + } + + this->spawnFrogTimer = 40; + Math_Vec3f_Diff(&subCam->eye, &subCam->at, &this->subCamDistToFrog); + this->actionFunc = EnBigslime_FrogSpawn; +} + +void EnBigslime_FrogSpawn(EnBigslime* this, GlobalContext* globalCtx) { + Camera* subCam = Play_GetCamera(globalCtx, this->subCamId); + Vec3f subCamEye; + f32 subCamZoom; + + this->spawnFrogTimer--; + + // Zoom the camera in and out at the newly spawned red frog + subCamZoom = sin_rad(this->spawnFrogTimer * (M_PI / 5)) * ((0.04f * (this->spawnFrogTimer * 0.1f)) + 0.02f) + 1.0f; + subCamEye.x = subCam->at.x + (this->subCamDistToFrog.x * subCamZoom); + subCamEye.z = subCam->at.z + (this->subCamDistToFrog.z * subCamZoom); + subCamEye.y = subCam->at.y + (this->subCamDistToFrog.y * subCamZoom); + Play_CameraSetAtEye(globalCtx, this->subCamId, &subCam->at, &subCamEye); + + if (this->spawnFrogTimer == 0) { + EnBigslime_EndCutscene(this, globalCtx); + EnBigslime_SetupDespawn(this); + } +} + +void EnBigslime_SetupDespawn(EnBigslime* this) { + s32 i; + + for (i = 0; i < MINISLIME_NUM_SPAWN; i++) { + this->minislime[i]->actor.params = MINISLIME_DEFEAT_MELT; + } + + this->isDespawned = false; + this->gekkoCollider.base.ocFlags1 &= ~OC1_ON; + this->actionFunc = EnBigslime_Despawn; +} + +void EnBigslime_Despawn(EnBigslime* this, GlobalContext* globalCtx) { + s32 i; + s32 counter = 0; + + for (i = 0; i < MINISLIME_NUM_SPAWN; i++) { + if (this->minislime[i]->actor.shape.shadowAlpha == 0) { + counter++; + } + } + + if (!this->isDespawned) { + Actor_SetRoomClearedTemp(globalCtx, globalCtx->roomCtx.currRoom.num); + this->isDespawned = true; + } + + if (counter == MINISLIME_NUM_SPAWN) { + for (i = 0; i < MINISLIME_NUM_SPAWN; i++) { + this->minislime[i]->actor.params = MINISLIME_DESPAWN; + } + + Actor_MarkForDeath(&this->actor); + } +} + +void EnBigslime_SetupInitEntrance(EnBigslime* this) { + this->actionFunc = EnBigslime_InitEntrance; +} + +void EnBigslime_InitEntrance(EnBigslime* this, GlobalContext* globalCtx) { + if (globalCtx->roomCtx.prevRoom.num == -1) { + EnBigslime_SetupCutscene(this); + } +} + +void EnBigslime_SetupCutscene(EnBigslime* this) { + if (ActorCutscene_GetCurrentIndex() == 0x7D) { + ActorCutscene_Stop(0x7D); + } + + if (this->actor.colChkInfo.health == 0) { + this->cutscene = this->actor.cutscene; + } + + ActorCutscene_SetIntentToPlay(this->cutscene); + this->actionFuncStored = this->actionFunc; + this->actionFunc = EnBigslime_PlayCutscene; + this->actor.speedXZ = 0.0f; +} + +void EnBigslime_PlayCutscene(EnBigslime* this, GlobalContext* globalCtx) { + if (ActorCutscene_GetCurrentIndex() == 0x7D) { + ActorCutscene_Stop(0x7D); + ActorCutscene_SetIntentToPlay(this->cutscene); + } else if (ActorCutscene_GetCanPlayNext(this->cutscene)) { + ActorCutscene_Start(this->cutscene, &this->actor); + if (this->actionFuncStored != EnBigslime_SquishFlat) { + func_800B724C(globalCtx, &this->actor, 7); + } + + this->subCamId = ActorCutscene_GetCurrentCamera(this->cutscene); + if (this->actor.colChkInfo.health == 0) { + EnBigslime_SetupCutsceneDefeat(this, globalCtx); + } else if ((this->actionFuncStored == EnBigslime_DamageGekko) || + (this->actionFuncStored == EnBigslime_JumpGekko) || + (this->actionFuncStored == EnBigslime_StunGekko)) { + EnBigslime_SetupCutsceneFormBigslime(this); + } else if (this->actionFuncStored == EnBigslime_SquishFlat) { + EnBigslime_SetupCutsceneGrabPlayer(this, globalCtx); + } else { + EnBigslime_SetupCutsceneStartBattle(this, globalCtx); + } + } else { + ActorCutscene_SetIntentToPlay(this->cutscene); + } +} + +void EnBigslime_ApplyDamageEffectBigslime(EnBigslime* this, GlobalContext* globalCtx) { + s32 i; + + for (i = 0; i < BIGSLIME_NUM_RING_FACES; i++) { + if (this->bigslimeCollider[i].base.acFlags & AC_HIT) { + this->bigslimeCollider[i].base.acFlags &= ~AC_HIT; + if (this->actionFunc == EnBigslime_FrozenGround) { + if (this->actor.colChkInfo.damageEffect == BIGSLIME_DMGEFF_BREAK_ICE) { + EnBigslime_BreakIntoMinislime(this, globalCtx); + break; + } else if (this->actor.colChkInfo.damageEffect == BIGSLIME_DMGEFF_FIRE) { + EnBigslime_SetPlayerParams(this, globalCtx); + EnBigslime_SetupMelt(this); + break; + } + } else { + if (this->actor.colChkInfo.damageEffect == BIGSLIME_DMGEFF_ICE) { + EnMinislime* minislime; + + globalCtx->envCtx.unk_C3 = 2; + EnBigslime_SetPlayerParams(this, globalCtx); + this->rotation = 0; + EnBigslime_SetupFreeze(this); + minislime = (EnMinislime*)func_ActorCategoryIterateById(globalCtx, NULL, ACTORCAT_ITEMACTION, + ACTOR_ARROW_ICE); + if (minislime != NULL) { + minislime->shakeRefPos.z = -100.0f; + } + break; + } + + if ((this->actor.colChkInfo.damageEffect != BIGSLIME_DMGEFF_STUN) && (this->itemDropTimer == 0)) { + f32 randFloat = Rand_ZeroOne(); + + if (randFloat < 0.15f) { + Item_DropCollectible(globalCtx, &this->actor.world.pos, ITEM00_ARROWS_10); + } else if (randFloat < 0.3f) { + Item_DropCollectible(globalCtx, &this->actor.world.pos, ITEM00_MAGIC_SMALL); + } + this->itemDropTimer = 40; + } + } + } + } + + for (; i < BIGSLIME_NUM_RING_FACES; i++) { + this->bigslimeCollider[i].base.acFlags &= ~AC_HIT; + } +} + +void EnBigslime_ApplyDamageEffectGekko(EnBigslime* this, GlobalContext* globalCtx) { + if (this->gekkoCollider.base.acFlags & AC_HIT) { + this->gekkoCollider.base.acFlags &= ~AC_HIT; + if ((this->gekkoDrawEffect != GEKKO_DRAW_EFFECT_FROZEN) || + !(this->gekkoCollider.info.acHitInfo->toucher.dmgFlags & 0xDB0B3)) { + EnBigslime_EndThrowMinislime(this); + if (this->actor.colChkInfo.damageEffect != BIGSLIME_DMGEFF_HOOKSHOT) { + if (Actor_ApplyDamage(&this->actor) == 0) { + func_800BE504(&this->actor, &this->gekkoCollider); + func_801A2ED8(); + Enemy_StartFinishingBlow(globalCtx, &this->actor); + this->gekkoCollider.base.acFlags &= ~AC_ON; + EnBigslime_GekkoThaw(this, globalCtx); + if ((this->actor.colChkInfo.damageEffect == BIGSLIME_DMGEFF_FIRE) || + (this->actor.colChkInfo.damageEffect == BIGSLIME_DMGEFF_LIGHT)) { + this->unk_388 = 4.0f; + this->unk_38C = 0.75f; + if (this->actor.colChkInfo.damageEffect == BIGSLIME_DMGEFF_FIRE) { + this->gekkoDrawEffect = GEKKO_DRAW_EFFECT_THAW; + } else { + this->gekkoDrawEffect = GEKKO_DRAW_EFFECT_LIGHT_ORBS; + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, + this->gekkoCollider.info.bumper.hitPos.x, + this->gekkoCollider.info.bumper.hitPos.y, + this->gekkoCollider.info.bumper.hitPos.z, 0, 0, 0, CLEAR_TAG_LARGE_LIGHT_RAYS); + } + } else if (this->actor.colChkInfo.damageEffect == BIGSLIME_DMGEFF_ICE) { + EnBigslime_GekkoFreeze(this); + } + EnBigslime_SetupCutscene(this); + } else if (this->actor.colChkInfo.damageEffect == BIGSLIME_DMGEFF_ELECTRIC_STUN) { + this->stunTimer = 40; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_COMMON_FREEZE); + this->gekkoDrawEffect = GEKKO_DRAW_EFFECT_ELECTRIC_STUN; + this->unk_38C = 0.75f; + this->unk_388 = 2.0f; + EnBigslime_SetupStunGekko(this); + } else if (this->actor.colChkInfo.damageEffect == BIGSLIME_DMGEFF_STUN || + this->actor.colChkInfo.damageEffect == BIGSLIME_DMGEFF_DEKU_STUN) { + this->stunTimer = 40; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_COMMON_FREEZE); + EnBigslime_SetupStunGekko(this); + } else if (this->actor.colChkInfo.damageEffect == BIGSLIME_DMGEFF_ICE) { + EnBigslime_GekkoFreeze(this); + func_800BE504(&this->actor, &this->gekkoCollider); + EnBigslime_SetupStunGekko(this); + } else { + EnBigslime_GekkoThaw(this, globalCtx); + if ((this->actor.colChkInfo.damageEffect == BIGSLIME_DMGEFF_FIRE) || + (this->actor.colChkInfo.damageEffect == BIGSLIME_DMGEFF_LIGHT)) { + this->unk_388 = 3.0f; + this->unk_38C = 0.75f; + if (this->actor.colChkInfo.damageEffect == BIGSLIME_DMGEFF_FIRE) { + this->gekkoDrawEffect = GEKKO_DRAW_EFFECT_THAW; + } else { + this->gekkoDrawEffect = GEKKO_DRAW_EFFECT_LIGHT_ORBS; + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, + this->gekkoCollider.info.bumper.hitPos.x, + this->gekkoCollider.info.bumper.hitPos.y, + this->gekkoCollider.info.bumper.hitPos.z, 0, 0, 0, CLEAR_TAG_LARGE_LIGHT_RAYS); + } + } + EnBigslime_SetupDamageGekko(this, true); + } + } + } + } +} + +/** + * Adds ice shard effects and calls EnBigslime_InitShockwave + */ +void EnBigslime_AddIceShardEffect(EnBigslime* this, GlobalContext* globalCtx) { + Vtx* targetVtx = &sBigslimeTargetVtx[0]; + EnBigslimeIceShardEffect* iceShardEffect; + s32 i; + f32 randFloat; + s16 randPitch; // Elevation Angle + s16 vtxX; + s16 vtxZ; + f32 xzDist; + + for (i = 0; i < BIGSLIME_NUM_VTX; i++, targetVtx++) { + if (targetVtx->n.a > 0) { + iceShardEffect = &this->iceShardEffect[i]; + iceShardEffect->pos.x = (targetVtx->n.ob[0] * this->actor.scale.x) + this->actor.world.pos.x; + iceShardEffect->pos.y = (targetVtx->n.ob[1] * this->actor.scale.y) + this->actor.world.pos.y; + iceShardEffect->pos.z = (targetVtx->n.ob[2] * this->actor.scale.z) + this->actor.world.pos.z; + iceShardEffect->rotation.x = Rand_Next() >> 0x10; + iceShardEffect->rotation.y = Rand_Next() >> 0x10; + iceShardEffect->rotation.z = Rand_Next() >> 0x10; + iceShardEffect->isActive = true; + randPitch = Rand_S16Offset(0x1000, 0x3000); + vtxZ = targetVtx->n.ob[2]; + vtxX = targetVtx->n.ob[0]; + xzDist = sqrtf(SQ(vtxZ) + SQ(vtxX)); + randFloat = Rand_ZeroFloat(5.0f) + 14.0f; + if (xzDist > 1.0f) { + xzDist = Math_CosS(randPitch) * randFloat / xzDist; + } else { + xzDist = Math_CosS(randPitch) * randFloat; + } + + iceShardEffect->vel.x = targetVtx->n.ob[0] * xzDist; + iceShardEffect->vel.y = Math_SinS(randPitch) * randFloat; + iceShardEffect->vel.z = targetVtx->n.ob[2] * xzDist; + iceShardEffect->scale = 0.001f * (Rand_ZeroFloat(6.0f) + 2.0f); + } + } + + Audio_PlayActorSound2(&this->actor, NA_SE_EV_ICE_BROKEN); + EnBigslime_InitShockwave(this, globalCtx); +} + +/** + * Updates ice shard effects, shockwave effects, and actor damage draw effects + */ +void EnBigslime_UpdateEffects(EnBigslime* this) { + EnBigslimeIceShardEffect* iceShardEffect; + s32 i; + + // Update ice shards + for (i = 0; i < BIGSLIME_NUM_ICE_SHARD; i++) { + iceShardEffect = &this->iceShardEffect[i]; + if (iceShardEffect->isActive > false) { + iceShardEffect->vel.y += -1.0f; + Math_Vec3f_Sum(&iceShardEffect->pos, &iceShardEffect->vel, &iceShardEffect->pos); + if (iceShardEffect->pos.y < (GBT_ROOM_5_MIN_Y - 20.0f)) { + iceShardEffect->isActive = false; + } + iceShardEffect->rotation.x += (s16)(((u32)Rand_Next() >> 0x17) + 0x700); + iceShardEffect->rotation.y += (s16)(((u32)Rand_Next() >> 0x17) + 0x900); + iceShardEffect->rotation.z += (s16)(((u32)Rand_Next() >> 0x17) + 0xB00); + } + } + + // update shockwave + if (this->shockwaveAlpha > 0) { + this->shockwaveAlpha = (this->shockwaveAlpha - 10 < 0) ? 0 : (this->shockwaveAlpha - 10); + this->shockwaveScale += 0.0013f; + } + + // update actor damage draw effects + if (this->unk_388 > 0.0f) { + if ((this->gekkoDrawEffect != GEKKO_DRAW_EFFECT_FROZEN) && (this->actionFunc != EnBigslime_PlayCutscene)) { + Math_StepToF(&this->unk_388, 0.0f, 0.05f); + this->unk_38C = 0.375f * (this->unk_388 + 1.0f); + this->unk_38C = CLAMP_MAX(this->unk_38C, 0.75f); + } else if (!Math_StepToF(&this->unk_390, 0.75f, 0.01875f)) { + func_800B9010(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG); + } + } +} + +void EnBigslime_UpdateBigslime(Actor* thisx, GlobalContext* globalCtx) { + EnBigslime* this = THIS; + s32 i; + Vec3f vtxMax; + Vec3f vtxMin; + + if (globalCtx->envCtx.unk_C3 == 3) { + globalCtx->envCtx.unk_C3 = 0xFF; + } + + func_8019F540(1); + this->dynamicVtxState ^= 1; + EnBigslime_DynamicVtxCopyState(this); + this->isAnimUpdate = SkelAnime_Update(&this->skelAnime); + if (this->actionFunc != EnBigslime_PlayCutscene) { + EnBigslime_ApplyDamageEffectBigslime(this, globalCtx); + } else { + for (i = 0; i < BIGSLIME_NUM_RING_FACES; i++) { + this->bigslimeCollider[i].base.acFlags &= ~AC_HIT; + } + } + + this->actionFunc(this, globalCtx); + + if (this->actionFunc != EnBigslime_FormBigslime) { + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + } else { + Actor_SetVelocityAndMoveXYRotation(&this->actor); + } + + if (this->actionFunc != EnBigslime_JumpGekko) { + EnBigslime_GetMaxMinVertices(this, &vtxMax, &vtxMin); + EnBigslime_UpdateScale(this, &vtxMax, &vtxMin); + EnBigslime_CheckRoomBoundaries(this, &vtxMax, &vtxMin); + EnBigslime_UpdateSurfaceNorm(this); + EnBigslime_UpdateBigslimeCollider(this, globalCtx); + } + + EnBigslime_UpdateEffects(this); + + if (this->itemDropTimer > 0) { + this->itemDropTimer--; + } +} + +void EnBigslime_UpdateGekko(Actor* thisx, GlobalContext* globalCtx) { + static s32 isGekkoOnGround = false; + EnBigslime* this = THIS; + Player* player; + s32 pad; + + if (globalCtx->envCtx.unk_C3 == 3) { + globalCtx->envCtx.unk_C3 = 0xFF; + } + + func_8019F540(0); + this->isAnimUpdate = SkelAnime_Update(&this->skelAnime); + if (this->actionFunc != EnBigslime_PlayCutscene) { + EnBigslime_ApplyDamageEffectGekko(this, globalCtx); + } else { + this->gekkoCollider.base.acFlags &= ~AC_HIT; + } + + this->actionFunc(this, globalCtx); + if (this->actionFunc != EnBigslime_FormBigslime) { + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + } else { + Actor_SetVelocityAndMoveXYRotation(&this->actor); + } + + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 40.0f, 80.0f, 0x1F); + this->gekkoCollider.dim.pos.x = (s16)this->actor.world.pos.x; + this->gekkoCollider.dim.pos.z = (s16)this->actor.world.pos.z; + if (this->gekkoCollider.base.acFlags & AC_ON) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->gekkoCollider.base); + } + + if ((this->actor.update == EnBigslime_UpdateGekko) && (this->gekkoCollider.base.ocFlags1 & OC1_ON)) { + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->gekkoCollider.base); + } + + EnBigslime_UpdateEffects(this); + + if ((this->actionFunc != EnBigslime_StunGekko) && + (this->gekkoCollider.dim.pos.y < (s16)(3.0f + GBT_ROOM_5_MIN_Y))) { + Vec3f vtxNorm; + + if (((globalCtx->gameplayFrames % 4) == 0) || !isGekkoOnGround) { + player = GET_PLAYER(globalCtx); + vtxNorm.x = this->actor.world.pos.x; + vtxNorm.z = this->actor.world.pos.z; + vtxNorm.y = player->actor.world.pos.y + player->actor.depthInWater; + EffectSsGRipple_Spawn(globalCtx, &vtxNorm, 150, 550, 0); + isGekkoOnGround = true; + } + } else { + isGekkoOnGround = false; + } +} + +/** + * Related to transforming and drawing shadows + */ +void EnBigslime_SetSysMatrix(Vec3f* pos, GlobalContext* globalCtx, Gfx* shadowDList, f32 scaleX, f32 scalez, f32 scaleY, + s16 rotation, f32 alpha) { + f32 yDistMinY; + f32 xz; + MtxF* sysMatrix = Matrix_GetCurrentState(); + + yDistMinY = pos->y - scaleY - GBT_ROOM_5_MIN_Y; + yDistMinY = CLAMP((yDistMinY), 0.0f, (GBT_ROOM_5_CENTER_Y - GBT_ROOM_5_MIN_Y) / 2); + xz = 1.0f - (yDistMinY * (1.0f / 1550.0f)); + + OPEN_DISPS(globalCtx->state.gfxCtx); + POLY_OPA_DISP = Gfx_CallSetupDL(POLY_OPA_DISP, 0x2C); + sysMatrix->xx = xz; + sysMatrix->yy = 1.0f; + sysMatrix->zz = xz; + sysMatrix->xz = sysMatrix->xy = 0.0f; + sysMatrix->yz = sysMatrix->yx = 0.0f; + sysMatrix->zy = sysMatrix->zx = 0.0f; + sysMatrix->wx = pos->x; + sysMatrix->wy = GBT_ROOM_5_MIN_Y; + sysMatrix->wz = pos->z; + sysMatrix->xw = sysMatrix->yw = sysMatrix->zw = 0.0f; + sysMatrix->ww = 1.0f; + + Matrix_RotateY(rotation, MTXMODE_APPLY); + Matrix_Scale(scaleX, 1.0f, scalez, MTXMODE_APPLY); + if (shadowDList != gBigslimeShadowDL) { + gDPSetCombineLERP(POLY_OPA_DISP++, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, COMBINED, 0, 0, 0, + COMBINED); + } + + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 0, 0, 0, (u8)(alpha * xz)); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, shadowDList); + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void EnBigslime_DrawMinislime(EnBigslime* this, GlobalContext* globalCtx) { + EnMinislime* minislime; + GlobalContext* globalCtx2 = globalCtx; + s32 pad; + s32 currIndex; + s32 i; + Lights* lights; + s32 indices[MINISLIME_NUM_SPAWN]; + + for (i = 0; i < MINISLIME_NUM_SPAWN; i++) { + indices[i] = i; + } + + // Insertion sorting algorithm based on z projected Pos + for (i = 0; i < MINISLIME_NUM_SPAWN - 1; i++) { + if (this->minislime[indices[i]]->actor.projectedPos.z < this->minislime[indices[i + 1]]->actor.projectedPos.z) { + currIndex = indices[i]; + indices[i] = indices[i + 1]; + indices[i + 1] = currIndex; + if (i != 0) { + i -= 2; + } + } + } + + OPEN_DISPS(globalCtx->state.gfxCtx); + for (i = 0; i < MINISLIME_NUM_SPAWN; i++) { + minislime = this->minislime[indices[i]]; + lights = LightContext_NewLights(&globalCtx2->lightCtx, globalCtx->state.gfxCtx); + Lights_BindAll(lights, globalCtx2->lightCtx.listHead, &minislime->actor.world.pos, globalCtx); + Lights_Draw(lights, globalCtx->state.gfxCtx); + func_8012C2DC(globalCtx->state.gfxCtx); + func_800B8118(&minislime->actor, globalCtx, 0); + Matrix_SetStateRotationAndTranslation(minislime->actor.world.pos.x, minislime->actor.world.pos.y, + minislime->actor.world.pos.z, &minislime->actor.shape.rot); + Matrix_Scale(minislime->actor.scale.x, minislime->actor.scale.y, minislime->actor.scale.z, MTXMODE_APPLY); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 255, 255, 255, minislime->actor.shape.shadowAlpha); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, &gMinislimeNormalDL); + if (minislime->frozenAlpha > 0) { + Matrix_InsertTranslation(0.0f, (0.1f - minislime->frozenScale) * -4000.0f, 0.0f, 1); + Matrix_Scale(0.1f, minislime->frozenScale, 0.1f, MTXMODE_APPLY); + AnimatedMat_Draw(globalCtx, this->minislimeFrozenTexAnim); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 255, 255, 255, minislime->frozenAlpha); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, &gMinislimeFrozenDL); + } + + EnBigslime_SetSysMatrix(&minislime->actor.world.pos, globalCtx, gBigslimeShadowDL, + (minislime->actor.scale.x * 0.4f) * 0.1f, (minislime->actor.scale.z * 0.4f) * 0.1f, + minislime->actor.scale.y * 400.0f, minislime->actor.shape.rot.y, + minislime->actor.shape.shadowAlpha * (175.0f / 255.0f)); + } + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void EnBigslime_DrawBigslime(Actor* thisx, GlobalContext* globalCtx) { + // 28 equidistance-spaced vtx Points (uniformally over the sphere) + static EnBigslimeBubbles bubblesInfo[] = { + { 0, 0.3f }, { 6, 0.1f }, { 12, 0.45f }, { 18, 0.5f }, { 24, 0.6f }, { 30, 0.2f }, { 36, 0.4f }, + { 42, 0.25f }, { 48, 0.35f }, { 54, 0.65f }, { 60, 0.25f }, { 66, 0.55f }, { 72, 0.3f }, { 78, 0.1f }, + { 84, 0.45f }, { 90, 0.5f }, { 96, 0.6f }, { 102, 0.2f }, { 108, 0.4f }, { 114, 0.15f }, { 120, 0.35f }, + { 126, 0.65f }, { 132, 0.25f }, { 138, 0.3f }, { 144, 0.15f }, { 150, 0.45f }, { 156, 0.3f }, { 161, 0.25f }, + }; + EnBigslime* this = THIS; + EnBigslimeBubbles* bubblesInfoPtr; + Vtx* dynamicVtx; + MtxF* billboardMtxF; + s32 i; + + func_8012C2DC(globalCtx->state.gfxCtx); + func_800B8118(&this->actor, globalCtx, 0); + OPEN_DISPS(globalCtx->state.gfxCtx); + + // Draw Bigslime + gSPSegment(POLY_XLU_DISP++, 0x09, sBigslimeDynamicVtx[this->dynamicVtxState]); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, &gBigslimeNormalDL); + gSPDisplayList(POLY_XLU_DISP++, &gBigslimeVtxDL); + + // Draw frozen Bigslime + if ((this->actionFunc == EnBigslime_Freeze) || (this->actionFunc == EnBigslime_FrozenGround) || + (this->actionFunc == EnBigslime_FrozenFall) || (this->actionFunc == EnBigslime_Melt)) { + AnimatedMat_Draw(globalCtx, this->bigslimeFrozenTexAnim); + gSPSegment(POLY_XLU_DISP++, 0x09, sBigslimeTargetVtx); + gSPDisplayList(POLY_XLU_DISP++, &gBigslimeFrozenVtxDL); + gSPDisplayList(POLY_XLU_DISP++, &gBigslimeVtxDL); + } + + // Draw bubbles inside Bigslime + if (this->actor.scale.x > 0.0f) { + Matrix_SetCurrentState(&globalCtx->billboardMtxF); + Matrix_Scale(0.0050000003f, 0.0050000003f, 0.0050000003f, MTXMODE_APPLY); + billboardMtxF = Matrix_GetCurrentState(); + + for (i = 0; i < 28; i++) { + bubblesInfoPtr = &bubblesInfo[i]; + dynamicVtx = &sBigslimeDynamicVtx[this->dynamicVtxState][bubblesInfoPtr->v]; + billboardMtxF->wx = + dynamicVtx->n.ob[0] * this->actor.scale.x * bubblesInfoPtr->scaleVtx + this->actor.world.pos.x; + billboardMtxF->wy = + dynamicVtx->n.ob[1] * this->actor.scale.y * bubblesInfoPtr->scaleVtx + this->actor.world.pos.y; + billboardMtxF->wz = + dynamicVtx->n.ob[2] * this->actor.scale.z * bubblesInfoPtr->scaleVtx + this->actor.world.pos.z; + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, &gBigslimeBubbleDL); + } + } + CLOSE_DISPS(globalCtx->state.gfxCtx); + + EnBigslime_SetSysMatrix(&this->actor.world.pos, globalCtx, gBigslimeShadowDL, this->vtxScaleX, this->vtxScaleZ, + this->actor.scale.y * BIGSLIME_RADIUS_F, this->rotation, 175.0f); + EnBigslime_DrawGekko(&this->actor, globalCtx); +} + +void EnBigslime_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + /* value -1: Limb Not used + * value 0: GEKKO_LIMB_WAIST + * value 1: GEKKO_LIMB_L_SHIN + * value 2: GEKKO_LIMB_L_FOOT + * value 3: GEKKO_LIMB_R_SHIN + * value 4: GEKKO_LIMB_R_FOOT + * value 5: GEKKO_LIMB_L_UPPER_ARM + * value 6: GEKKO_LIMB_L_FOREARM + * value 7: GEKKO_LIMB_L_HAND + * value 8: GEKKO_LIMB_R_UPPER_ARM + * value 9: GEKKO_LIMB_R_FOREARM + * value 10: GEKKO_LIMB_R_HAND + * value 11: GEKKO_LIMB_JAW + */ + static s8 limbPosIndex[] = { + -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1, 5, 6, -1, 7, 8, 9, -1, 10, -1, 11, -1, -1, + }; + // Some kind of offset for the position of the Gekkos right foot + static Vec3f rightFootOffsetRef = { 1500.0f, 2200.0f, 0.0f }; + EnBigslime* this = THIS; + Vec3f rightFootOffset; + + if (limbIndex == GEKKO_LIMB_HEAD) { + Matrix_GetStateTranslation(&this->actor.focus.pos); + this->actor.focus.rot.y = this->gekkoRot.y; + } + + if (limbPosIndex[limbIndex] != -1) { + Matrix_GetStateTranslation(&this->limbPos[limbPosIndex[limbIndex]]); + } + + if (limbIndex == GEKKO_LIMB_R_ANKLE) { + Matrix_MultiplyVector3fByState(&rightFootOffsetRef, &rightFootOffset); + this->gekkoCollider.dim.pos.y = rightFootOffset.y; + } +} + +void EnBigslime_DrawGekko(Actor* thisx, GlobalContext* globalCtx) { + static Color_RGBA8 gekkoDamageColor = { 255, 0, 0, 0 }; + static Color_RGBA8 gekkoStunColor = { 0, 0, 255, 0 }; + Vec3f gekkoPos; + EnBigslime* this = THIS; + s32 pad; + + func_8012C28C(globalCtx->state.gfxCtx); + if (this->actionFunc == EnBigslime_DamageGekko) { + func_800AE434(globalCtx, &gekkoDamageColor, this->damageSpinTimer, 20); + } else if ((this->actionFunc == EnBigslime_CutsceneDefeat) || (this->actionFunc == EnBigslime_GekkoDespawn)) { + func_800AE434(globalCtx, &gekkoDamageColor, 20, 20); + } else if (this->actionFunc == EnBigslime_StunGekko) { + if (this->gekkoDrawEffect == GEKKO_DRAW_EFFECT_FROZEN) { + func_800AE434(globalCtx, &gekkoDamageColor, this->stunTimer, 80); + } else if (this->gekkoDrawEffect == GEKKO_DRAW_EFFECT_ELECTRIC_STUN) { + func_800AE434(globalCtx, &gekkoStunColor, this->stunTimer, 40); + } else { + func_800AE434(globalCtx, &gekkoStunColor, this->stunTimer, 40); + } + } + + OPEN_DISPS(globalCtx->state.gfxCtx); + + Math_Vec3f_Sum(&this->actor.world.pos, &this->gekkoPosOffset, &gekkoPos); + Matrix_SetStateRotationAndTranslation(gekkoPos.x, gekkoPos.y, gekkoPos.z, &this->gekkoRot); + Matrix_Scale(this->gekkoScale, this->gekkoScale, this->gekkoScale, MTXMODE_APPLY); + SkinMatrix_Vec3fMtxFMultXYZ(&globalCtx->viewProjectionMtxF, &gekkoPos, &this->gekkoProjectedPos); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + NULL, EnBigslime_PostLimbDraw, &this->actor); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + + if ((this->actionFunc == EnBigslime_DamageGekko) || (this->actionFunc == EnBigslime_CutsceneDefeat) || + (this->actionFunc == EnBigslime_GekkoDespawn) || (this->actionFunc == EnBigslime_StunGekko)) { + func_800AE5A0(globalCtx); + } + + EnBigslime_SetSysMatrix(&gekkoPos, globalCtx, D_04076BC0, this->gekkoScale * (550.0f / 7.0f), + this->gekkoScale * (550.0f / 7.0f), 0.0f, 0, 255.0f); + + if (this->minislimeState != MINISLIME_INACTIVE_STATE) { + EnBigslime_DrawMinislime(this, globalCtx); + } + + EnBigslime_DrawShatteringEffects(this, globalCtx); + + // Draw actor damage effects + func_800BE680(globalCtx, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), + this->gekkoScale * (999.99991f / 7.0f) * this->unk_38C, this->unk_390, this->unk_388, + this->gekkoDrawEffect); +} + +void EnBigslime_DrawShatteringEffects(EnBigslime* this, GlobalContext* globalCtx) { + EnBigslimeIceShardEffect* iceShardEffect; + s32 i; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C2DC(globalCtx->state.gfxCtx); + + // Draw Shockwave + if (this->shockwaveAlpha > 0) { + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 195, 225, 235, this->shockwaveAlpha); + gSPSegment(POLY_XLU_DISP++, 0x0D, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, globalCtx->gameplayFrames % 128, + (u8)(globalCtx->gameplayFrames * 8), 32, 64, 1, + (-globalCtx->gameplayFrames * 2) % 64, 0, 16, 16)); + Matrix_InsertTranslation(this->frozenPos.x, this->frozenPos.y, this->frozenPos.z, MTXMODE_NEW); + Matrix_Scale(this->shockwaveScale, this->shockwaveScale, this->shockwaveScale, MTXMODE_APPLY); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, &gBigslimeShockwaveDL); + } + + // Draw Ice Shards + AnimatedMat_Draw(globalCtx, this->iceShardTexAnim); + gSPDisplayList(POLY_XLU_DISP++, &gBigslimeIceShardDL); + + for (i = 0; i < BIGSLIME_NUM_ICE_SHARD; i++) { + iceShardEffect = &this->iceShardEffect[i]; + if (iceShardEffect->isActive > false) { + Matrix_SetStateRotationAndTranslation(iceShardEffect->pos.x, iceShardEffect->pos.y, iceShardEffect->pos.z, + &iceShardEffect->rotation); + Matrix_Scale(iceShardEffect->scale, iceShardEffect->scale, iceShardEffect->scale, MTXMODE_APPLY); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, &gBigslimeIceShardVtxDL); + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Bigslime/z_en_bigslime.h b/src/overlays/actors/ovl_En_Bigslime/z_en_bigslime.h index 419b6c1f61..3f57f1666e 100644 --- a/src/overlays/actors/ovl_En_Bigslime/z_en_bigslime.h +++ b/src/overlays/actors/ovl_En_Bigslime/z_en_bigslime.h @@ -63,7 +63,7 @@ typedef struct EnBigslime { u8 minislimeCounter; u8 numGekkoMeleeAttacks; // The Gekko will melee-attack link at 1-3 times at each position while engulfed in bigslime }; - /* 0x02B4 */ u8 iceShardAlpha; + /* 0x02B4 */ u8 shockwaveAlpha; /* 0x02B5 */ u8 gekkoDrawEffect; /* 0x02B6 */ s16 gekkoYaw; /* 0x02B8 */ s16 cutscene; @@ -95,16 +95,16 @@ typedef struct EnBigslime { }; /* 0x02C2 */ s16 ceilingDropTimer; // Bigslime is still during this timer and shakes before dropping /* 0x02C4 */ s16 numGekkoPosGrabPlayer; // The Gekko will melee-attack link at 6 positions while engulfed in bigslime - /* 0x02C6 */ s16 camId; - /* 0x02C8 */ s16 cameraYawGrabPlayer; + /* 0x02C6 */ s16 subCamId; + /* 0x02C8 */ s16 subCamYawGrabPlayer; /* 0x02CA */ s16 rotation; // is always 0, used in Matrix_RotateY /* 0x02CC */ s16 itemDropTimer; // items only drop when zero, Set to 40 then decrements, prevents itemDrop spam /* 0x02CE */ Vec3s gekkoRot; /* 0x02D4 */ Vec3f gekkoPosOffset; // Used when Bigslime grabs link /* 0x02E0 */ Vec3f gekkoProjectedPos; /* 0x02EC */ union { - Vec3f iceShardRefPos; - Vec3f eyeDistToFrog; // Used to zoom into frogs as Gekko despawns/Frog spawns + Vec3f frozenPos; + Vec3f subCamDistToFrog; // Used to zoom into frogs as Gekko despawns/Frog spawns }; /* 0x02F8 */ Vec3f limbPos[12]; /* 0x0388 */ f32 unk_388; // used as arg to func_800BE680 @@ -114,14 +114,14 @@ typedef struct EnBigslime { /* 0x0398 */ f32 vtxSurfacePerturbation[BIGSLIME_NUM_VTX]; /* 0x0620 */ f32 vtxScaleX; /* 0x0624 */ f32 vtxScaleZ; - /* 0x0628 */ f32 iceShardScale; + /* 0x0628 */ f32 shockwaveScale; /* 0x062C */ ColliderCylinder gekkoCollider; /* 0x0678 */ ColliderCylinder bigslimeCollider[BIGSLIME_NUM_RING_FACES]; /* 0x0A14 */ EnMinislime* minislime[MINISLIME_NUM_SPAWN]; /* 0x0A44 */ EnMinislime* minislimeToThrow; - /* 0x0A48 */ AnimatedMaterial* bigslimeFrozenTex; - /* 0x0A4C */ AnimatedMaterial* minislimeFrozenTex; - /* 0x0A50 */ AnimatedMaterial* iceShardTex; + /* 0x0A48 */ AnimatedMaterial* bigslimeFrozenTexAnim; + /* 0x0A4C */ AnimatedMaterial* minislimeFrozenTexAnim; + /* 0x0A50 */ AnimatedMaterial* iceShardTexAnim; /* 0x0A54 */ EnBigslimeIceShardEffect iceShardEffect[BIGSLIME_NUM_ICE_SHARD]; // 312 = 162 (bigslime) + 10 * 15 (minislime) } EnBigslime; // size = 0x3634 diff --git a/src/overlays/actors/ovl_En_Dai/z_en_dai.c b/src/overlays/actors/ovl_En_Dai/z_en_dai.c index 8f14b6c678..b84feb51a2 100644 --- a/src/overlays/actors/ovl_En_Dai/z_en_dai.c +++ b/src/overlays/actors/ovl_En_Dai/z_en_dai.c @@ -591,7 +591,7 @@ s32 func_80B3F598(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* p } if (limbIndex == 11) { - Matrix_MultiplyVector3fByState(&D_801D15B0, &this->unk_1E4); + Matrix_MultiplyVector3fByState(&gZeroVec3f, &this->unk_1E4); } if (limbIndex == 10) { diff --git a/src/overlays/actors/ovl_En_Dekunuts/z_en_dekunuts.c b/src/overlays/actors/ovl_En_Dekunuts/z_en_dekunuts.c index 1ab2c9654b..69d2fc9d63 100644 --- a/src/overlays/actors/ovl_En_Dekunuts/z_en_dekunuts.c +++ b/src/overlays/actors/ovl_En_Dekunuts/z_en_dekunuts.c @@ -547,7 +547,7 @@ void func_808BE4D4(EnDekunuts* this, GlobalContext* globalCtx) { sp40.x = this->actor.world.pos.x; sp40.y = this->actor.world.pos.y + 18.0f; sp40.z = this->actor.world.pos.z; - EffectSsDeadDb_Spawn(globalCtx, &sp40, &D_801D15B0, &D_801D15B0, &D_808BEF90, &D_808BEF94, 200, 0, 13); + EffectSsDeadDb_Spawn(globalCtx, &sp40, &gZeroVec3f, &gZeroVec3f, &D_808BEF90, &D_808BEF94, 200, 0, 13); Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 11, NA_SE_EN_EXTINCT); sp40.y = this->actor.world.pos.y + 10.0f; EffectSsHahen_SpawnBurst(globalCtx, &sp40, 3.0f, 0, 12, 3, 15, HAHEN_OBJECT_DEFAULT, 10, NULL); diff --git a/src/overlays/actors/ovl_En_Dinofos/z_en_dinofos.c b/src/overlays/actors/ovl_En_Dinofos/z_en_dinofos.c index bc4fbf7209..f82295874b 100644 --- a/src/overlays/actors/ovl_En_Dinofos/z_en_dinofos.c +++ b/src/overlays/actors/ovl_En_Dinofos/z_en_dinofos.c @@ -1475,7 +1475,7 @@ void func_8089DC84(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* sp4C.x -= sp48->mf[3][0]; sp4C.y -= sp48->mf[3][1]; sp4C.z -= sp48->mf[3][2]; - EffectSsDFire_Spawn(globalCtx, &this->unk_34C, &sp4C, &D_801D15B0, 30, 22, 255 - (sp58 * 20), 20, 3, 8); + EffectSsDFire_Spawn(globalCtx, &this->unk_34C, &sp4C, &gZeroVec3f, 30, 22, 255 - (sp58 * 20), 20, 3, 8); this->unk_292 = this->unk_290; } } diff --git a/src/overlays/actors/ovl_En_Dnb/z_en_dnb.c b/src/overlays/actors/ovl_En_Dnb/z_en_dnb.c index be0f95eb93..7e4b67b7c3 100644 --- a/src/overlays/actors/ovl_En_Dnb/z_en_dnb.c +++ b/src/overlays/actors/ovl_En_Dnb/z_en_dnb.c @@ -47,7 +47,7 @@ void func_80A4FDD0(EnDnbParticle* particle, EnDnb* this, s16* alloc, s32 idx) { particle->unk_00 = sp1C; particle->unk_0C = sp1C; particle->unk_24 = Math_Vec3f_Yaw(&this->dyna.actor.world.pos, &sp1C); - particle->unk_18 = D_801D15BC; + particle->unk_18 = gZeroVec3s; } s32 func_80A4FEBC(EnDnbParticle* particle, f32 arg1) { @@ -76,7 +76,7 @@ void func_80A4FFE8(EnDnbParticle* particle, s16 arg1) { particle->unk_1E.x = (Rand_ZeroOne() - 0.5f) * 400.0f; particle->unk_1E.y = (Rand_ZeroOne() - 0.5f) * 400.0f; particle->unk_1E.z = (Rand_ZeroOne() - 0.5f) * 400.0f; - particle->unk_18 = D_801D15BC; + particle->unk_18 = gZeroVec3s; particle->unk_30 = 40.0f; particle->unk_2C = 0.0f; particle->unk_26 = arg1; @@ -86,7 +86,7 @@ void func_80A4FFE8(EnDnbParticle* particle, s16 arg1) { s32 func_80A500F8(EnDnb* this) { static Vec3f D_80A50CB0 = { 0.0f, 0.0f, 1000.0f }; Actor* actor = &this->dyna.actor; - Vec3f spA8 = D_801D15B0; + Vec3f spA8 = gZeroVec3f; Vec3f sp9C; s32 i; f32 temp_f20; diff --git a/src/overlays/actors/ovl_En_Dnk/z_en_dnk.c b/src/overlays/actors/ovl_En_Dnk/z_en_dnk.c index 7fd5c84b8f..8a6c3a5833 100644 --- a/src/overlays/actors/ovl_En_Dnk/z_en_dnk.c +++ b/src/overlays/actors/ovl_En_Dnk/z_en_dnk.c @@ -283,7 +283,7 @@ s32 func_80A51A78(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* p void func_80A51AA4(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { EnDnk* this = THIS; MtxF sp5C; - Vec3f sp50 = D_801D15B0; + Vec3f sp50 = gZeroVec3f; Vec3f sp44; Vec3s sp3C; @@ -359,7 +359,7 @@ s32 func_80A51D78(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* p void func_80A51DA4(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { EnDnk* this = THIS; MtxF sp5C; - Vec3f sp50 = D_801D15B0; + Vec3f sp50 = gZeroVec3f; Vec3f sp44; Vec3s sp3C; diff --git a/src/overlays/actors/ovl_En_Dnp/z_en_dnp.c b/src/overlays/actors/ovl_En_Dnp/z_en_dnp.c index 8e0bbbaab2..f3753c978a 100644 --- a/src/overlays/actors/ovl_En_Dnp/z_en_dnp.c +++ b/src/overlays/actors/ovl_En_Dnp/z_en_dnp.c @@ -435,7 +435,7 @@ s32 func_80B3D974(s16 arg0, s16 arg1, Vec3f* arg2, Vec3s* arg3, s32 arg4, s32 ar Vec3s sp6C; MtxF sp2C; - Matrix_MultiplyVector3fByState(&D_801D15B0, &sp74); + Matrix_MultiplyVector3fByState(&gZeroVec3f, &sp74); Matrix_CopyCurrentState(&sp2C); func_8018219C(&sp2C, &sp6C, 0); *arg2 = sp74; diff --git a/src/overlays/actors/ovl_En_Dns/z_en_dns.c b/src/overlays/actors/ovl_En_Dns/z_en_dns.c index e75f1aa461..97db5bcb68 100644 --- a/src/overlays/actors/ovl_En_Dns/z_en_dns.c +++ b/src/overlays/actors/ovl_En_Dns/z_en_dns.c @@ -284,11 +284,11 @@ s32 func_8092CCEC(EnDns* this, GlobalContext* globalCtx) { Math_Vec3f_Copy(&sp30, &this->actor.world.pos); Math_Vec3f_Copy(&sp3C, &player->actor.world.pos); - this->unk_2D6 = Math_Vec3f_Yaw(&D_801D15B0, &sp3C); - this->unk_2D4 = Math_Vec3f_Yaw(&D_801D15B0, &sp30); - this->unk_2EC = Math_Vec3f_DistXZ(&sp30, &D_801D15B0); - sp2E = Math_Vec3f_Yaw(&D_801D15B0, &sp3C); - sp2E -= Math_Vec3f_Yaw(&D_801D15B0, &sp30); + this->unk_2D6 = Math_Vec3f_Yaw(&gZeroVec3f, &sp3C); + this->unk_2D4 = Math_Vec3f_Yaw(&gZeroVec3f, &sp30); + this->unk_2EC = Math_Vec3f_DistXZ(&sp30, &gZeroVec3f); + sp2E = Math_Vec3f_Yaw(&gZeroVec3f, &sp3C); + sp2E -= Math_Vec3f_Yaw(&gZeroVec3f, &sp30); this->unk_2D8 = (Rand_ZeroOne() * 182.0f) + 182.0f; this->unk_2D8 = (sp2E > 0) ? this->unk_2D8 : -this->unk_2D8; this->unk_2D0 = 0x28; @@ -413,7 +413,7 @@ void EnDns_DoNothing(EnDns* this, GlobalContext* globalCtx) { void func_8092D330(EnDns* this, GlobalContext* globalCtx) { s32 pad; - Vec3f sp30 = D_801D15B0; + Vec3f sp30 = gZeroVec3f; s16 temp = this->unk_2D6 - this->unk_2D4; if (ABS_ALT(temp) < 0xC16) { @@ -549,7 +549,7 @@ s32 func_8092D954(s16 arg0, s16 arg1, Vec3f* arg2, Vec3s* arg3, s32 arg4, s32 ar Vec3s sp6C; MtxF sp2C; - Matrix_MultiplyVector3fByState(&D_801D15B0, &sp74); + Matrix_MultiplyVector3fByState(&gZeroVec3f, &sp74); Matrix_CopyCurrentState(&sp2C); func_8018219C(&sp2C, &sp6C, 0); *arg2 = sp74; diff --git a/src/overlays/actors/ovl_En_Dodongo/z_en_dodongo.c b/src/overlays/actors/ovl_En_Dodongo/z_en_dodongo.c index c7a512552d..fe92a5b1f9 100644 --- a/src/overlays/actors/ovl_En_Dodongo/z_en_dodongo.c +++ b/src/overlays/actors/ovl_En_Dodongo/z_en_dodongo.c @@ -384,7 +384,7 @@ void func_80876930(EnDodongo* this, GlobalContext* globalCtx, Vec3f* arg2) { sp88.z = randPlusMinusPoint5Scaled(temp3) + arg2->z; D_8087933C.x = randPlusMinusPoint5Scaled(2.0f); D_8087933C.z = randPlusMinusPoint5Scaled(2.0f); - func_800B0DE0(globalCtx, &sp88, &D_801D15B0, &D_8087933C, sp80, sp7C, temp1, temp2); + func_800B0DE0(globalCtx, &sp88, &gZeroVec3f, &D_8087933C, sp80, sp7C, temp1, temp2); } } @@ -780,13 +780,13 @@ void func_80877E60(EnDodongo* this, GlobalContext* globalCtx) { sp5E = this->unk_334 * 50.0f; sp5C = this->unk_334 * 5.0f; Math_Vec3f_Copy(&sp64, &this->unk_348[0]); - func_800B0DE0(globalCtx, &sp64, &D_801D15B0, &D_80879360, &D_8087936C, &D_8087936C, sp5E, sp5C); + func_800B0DE0(globalCtx, &sp64, &gZeroVec3f, &D_80879360, &D_8087936C, &D_8087936C, sp5E, sp5C); sp64.x -= Math_CosS(this->actor.shape.rot.y) * 6.0f * this->unk_334; sp64.z += Math_SinS(this->actor.shape.rot.y) * 6.0f * this->unk_334; - func_800B0DE0(globalCtx, &sp64, &D_801D15B0, &D_80879360, &D_8087936C, &D_8087936C, sp5E, sp5C); + func_800B0DE0(globalCtx, &sp64, &gZeroVec3f, &D_80879360, &D_8087936C, &D_8087936C, sp5E, sp5C); sp64.x = (2.0f * this->unk_348[0].x) - sp64.x; sp64.z = (2.0f * this->unk_348[0].z) - sp64.z; - func_800B0DE0(globalCtx, &sp64, &D_801D15B0, &D_80879360, &D_8087936C, &D_8087936C, sp5E, sp5C); + func_800B0DE0(globalCtx, &sp64, &gZeroVec3f, &D_80879360, &D_8087936C, &D_8087936C, sp5E, sp5C); } } diff --git a/src/overlays/actors/ovl_En_Fish2/z_en_fish2.c b/src/overlays/actors/ovl_En_Fish2/z_en_fish2.c index f9dfa048d6..cd553b537f 100644 --- a/src/overlays/actors/ovl_En_Fish2/z_en_fish2.c +++ b/src/overlays/actors/ovl_En_Fish2/z_en_fish2.c @@ -1069,11 +1069,11 @@ void EnFish2_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, } if (limbIndex == 14) { - Matrix_MultiplyVector3fByState(&D_801D15B0, &this->unk_318); + Matrix_MultiplyVector3fByState(&gZeroVec3f, &this->unk_318); } if (limbIndex == 17) { - Matrix_MultiplyVector3fByState(&D_801D15B0, &this->unk_300); + Matrix_MultiplyVector3fByState(&gZeroVec3f, &this->unk_300); } Collider_UpdateSpheres(limbIndex, &this->collider); diff --git a/src/overlays/actors/ovl_En_Floormas/z_en_floormas.c b/src/overlays/actors/ovl_En_Floormas/z_en_floormas.c index a1818b0950..f8b88f50a7 100644 --- a/src/overlays/actors/ovl_En_Floormas/z_en_floormas.c +++ b/src/overlays/actors/ovl_En_Floormas/z_en_floormas.c @@ -461,10 +461,10 @@ void func_808D14DC(EnFloormas* this, GlobalContext* globalCtx) { sp28.x = Math_SinS(this->actor.shape.rot.y + 0x6000) * 7.0f; sp28.z = Math_CosS(this->actor.shape.rot.y + 0x6000) * 7.0f; - func_800B1210(globalCtx, &sp34, &sp28, &D_801D15B0, 0x1C2, 0x64); + func_800B1210(globalCtx, &sp34, &sp28, &gZeroVec3f, 0x1C2, 0x64); sp28.x = Math_SinS(this->actor.shape.rot.y - 0x6000) * 7.0f; sp28.z = Math_CosS(this->actor.shape.rot.y - 0x6000) * 7.0f; - func_800B1210(globalCtx, &sp34, &sp28, &D_801D15B0, 0x1C2, 0x64); + func_800B1210(globalCtx, &sp34, &sp28, &gZeroVec3f, 0x1C2, 0x64); func_800B9010(&this->actor, NA_SE_EN_FLOORMASTER_SLIDING - SFX_FLAG); } @@ -682,7 +682,7 @@ void func_808D1ED4(EnFloormas* this, GlobalContext* globalCtx) { sp34.x = this->actor.world.pos.x; sp34.y = this->actor.world.pos.y + 15.0f; sp34.z = this->actor.world.pos.z; - func_800B3030(globalCtx, &sp34, &D_801D15B0, &D_801D15B0, 150, -10, 2); + func_800B3030(globalCtx, &sp34, &gZeroVec3f, &gZeroVec3f, 150, -10, 2); Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 11, NA_SE_EN_EXTINCT); this->actionFunc = func_808D1F7C; } diff --git a/src/overlays/actors/ovl_En_Gm/z_en_gm.c b/src/overlays/actors/ovl_En_Gm/z_en_gm.c index 412bf7381a..5f3854a138 100644 --- a/src/overlays/actors/ovl_En_Gm/z_en_gm.c +++ b/src/overlays/actors/ovl_En_Gm/z_en_gm.c @@ -1408,7 +1408,7 @@ s32 func_8095097C(EnGm* this, GlobalContext* globalCtx) { func_8013AF00(sp7C, 3, this->unk_234->count + 3); if (!(this->unk_3A4 & 8)) { - sp58 = D_801D15B0; + sp58 = gZeroVec3f; func_8013B6B0(this->unk_234, &this->unk_244, &this->unk_254, this->unk_24C, this->unk_248, &this->unk_250, sp7C, &sp58, this->unk_3C4); func_8013B878(globalCtx, this->unk_234, this->unk_250, &sp58); @@ -1427,7 +1427,7 @@ s32 func_8095097C(EnGm* this, GlobalContext* globalCtx) { sp58 = this->actor.world.pos; } - this->unk_238 = D_801D15B0; + this->unk_238 = gZeroVec3f; if (func_8013B6B0(this->unk_234, &this->unk_244, &this->unk_254, this->unk_24C, this->unk_248, &this->unk_250, sp7C, &this->unk_238, this->unk_3C4)) { @@ -1705,7 +1705,7 @@ void func_809514BC(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* CLOSE_DISPS(globalCtx->state.gfxCtx); if (limbIndex == 9) { - Matrix_MultiplyVector3fByState(&D_801D15B0, &sp30); + Matrix_MultiplyVector3fByState(&gZeroVec3f, &sp30); Math_Vec3f_ToVec3s(&this->colliderSphere.dim.worldSphere.center, &sp30); } } 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 b71a44a342..94a360df8c 100644 --- a/src/overlays/actors/ovl_En_Invadepoh/z_en_invadepoh.c +++ b/src/overlays/actors/ovl_En_Invadepoh/z_en_invadepoh.c @@ -221,7 +221,6 @@ extern Gfx D_06000720[]; extern Gfx D_06000080[]; extern s32 D_801BDA9C; -extern Vec3s D_801D15BC; const ActorInit En_Invadepoh_InitVars = { ACTOR_EN_INVADEPOH, @@ -2568,7 +2567,7 @@ void func_80B48620(Actor* thisx, GlobalContext* globalCtx) { this->actor.update = func_80B4873C; SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06013928, &D_06009E58, this->jointTable, this->morphTable, 23); - func_80B45C04(&this->behaviorInfo, D_80B4EA90, 6, D_80B4EB00, 2, &D_801D15BC, 5000, 0.05f, 0.3f, 0.12f); + func_80B45C04(&this->behaviorInfo, D_80B4EA90, 6, D_80B4EB00, 2, &gZeroVec3s, 5000, 0.05f, 0.3f, 0.12f); Animation_PlayLoop(&this->skelAnime, &D_06009E58); func_80B482D4(this); } @@ -2636,7 +2635,7 @@ void func_80B48948(EnInvadepoh* this) { this->actionTimer = Rand_S16Offset(150, 150); if (rand < 0.5f) { this->rand = 0; - Math_Vec3s_Copy(&substruct->unk26, &D_801D15BC); + Math_Vec3s_Copy(&substruct->unk26, &gZeroVec3s); substruct->unk30 = 0.1f; substruct->unk2C = 1000; } else if (rand < 0.75f) { @@ -2702,7 +2701,7 @@ void func_80B48AD4(EnInvadepoh* this, GlobalContext* globalCtx) { if (temp_v1_3 != this->rand) { this->rand = temp_v1_3; if (this->rand == 0) { - Math_Vec3s_Copy(&substruct->unk26, &D_801D15BC); + Math_Vec3s_Copy(&substruct->unk26, &gZeroVec3s); substruct->unk30 = 0.07f; } else if (this->rand == 1) { substruct->unk26.x = Rand_S16Offset(1000, 1000); @@ -2772,7 +2771,7 @@ void func_80B48FB0(Actor* thisx, GlobalContext* globalCtx) { this->actor.textId = 0x3330; SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06013928, &D_06009E58, this->jointTable, this->morphTable, 23); - func_80B45C04(&this->behaviorInfo, D_80B4EA90, 6, D_80B4EB00, 2, &D_801D15BC, 100, 0.03, 0.3, 0.03); + func_80B45C04(&this->behaviorInfo, D_80B4EA90, 6, D_80B4EB00, 2, &gZeroVec3s, 100, 0.03, 0.3, 0.03); func_80B444F4(this, globalCtx); EnInvadepoh_SetPathPointToWorldPos(this, 0); func_800B4AEC(globalCtx, &this->actor, 50.0f); @@ -3124,7 +3123,7 @@ void func_80B49F88(Actor* thisx, GlobalContext* globalCtx) { func_80B44F58(); SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06013928, &D_06014088, this->jointTable, this->morphTable, 23); - func_80B45C04(&this->behaviorInfo, D_80B4EA90, 1, D_80B4EB00, 1, &D_801D15BC, 100, 0.03, 0.3, 0.03); + func_80B45C04(&this->behaviorInfo, D_80B4EA90, 1, D_80B4EB00, 1, &gZeroVec3s, 100, 0.03, 0.3, 0.03); func_80B44540(this, globalCtx); func_80B44570(this); func_80B44C24(this, globalCtx); @@ -3355,7 +3354,7 @@ void func_80B4A9C8(Actor* thisx, GlobalContext* globalCtx) { func_80B44F58(); SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06013928, &D_06014088, this->jointTable, this->morphTable, 23); - func_80B45C04(&this->behaviorInfo, D_80B4EA90, 1, D_80B4EB00, 1, &D_801D15BC, 100, 0.03f, 0.3f, 0.03f); + func_80B45C04(&this->behaviorInfo, D_80B4EA90, 1, D_80B4EB00, 1, &gZeroVec3s, 100, 0.03f, 0.3f, 0.03f); func_80B44620(this, globalCtx); if ((sp38 < CLOCK_TIME(2, 15)) || (sp38 >= CLOCK_TIME(6, 0))) { this->pathIndex = 0; @@ -3532,7 +3531,7 @@ void func_80B4B0C4(Actor* thisx, GlobalContext* globalCtx) { 23); Animation_MorphToLoop(&this->skelAnime, &D_06009E58, 0.0f); substruct = &this->behaviorInfo; - func_80B45C04(&this->behaviorInfo, D_80B4EA90, 1, D_80B4EB00, 3, &D_801D15BC, 2000, 0.08f, 0.3f, 0.03f); + func_80B45C04(&this->behaviorInfo, D_80B4EA90, 1, D_80B4EB00, 3, &gZeroVec3s, 2000, 0.08f, 0.3f, 0.03f); substruct->unk30 = 0.08f; substruct->unk2C = 0x7D0; func_800B4AEC(globalCtx, &this->actor, 50.0f); @@ -3685,7 +3684,7 @@ void func_80B4B8BC(Actor* thisx, GlobalContext* globalCtx) { Actor_SetObjectSegment(globalCtx, &this->actor); SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_060080F0, &D_060021C8, this->jointTable, this->morphTable, 13); - func_80B45C04(&this->behaviorInfo, 0, 0, 0, 0, &D_801D15BC, 3000, 0.1f, 0.0f, 0.0f); + func_80B45C04(&this->behaviorInfo, 0, 0, 0, 0, &gZeroVec3s, 3000, 0.1f, 0.0f, 0.0f); func_80B44664(this, globalCtx); EnInvadepoh_SetPathPointToWorldPos(this, 0); func_800B4AEC(globalCtx, &this->actor, 50.0f); @@ -3919,7 +3918,7 @@ void func_80B4C3A0(Actor* thisx, GlobalContext* globalCtx) { func_80B44FEC(); SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06015C28, &D_06016720, this->jointTable, this->morphTable, 22); - func_80B45C04(&this->behaviorInfo, D_80B4EBDC, 1, D_80B4EC08, 0, &D_801D15BC, 100, 0.03f, 0.3f, 0.03f); + func_80B45C04(&this->behaviorInfo, D_80B4EBDC, 1, D_80B4EC08, 0, &gZeroVec3s, 100, 0.03f, 0.3f, 0.03f); this->actor.textId = 0x33CD; if (currentTime < 0xD5A0) { this->unk304 = -0x8000; @@ -4140,7 +4139,7 @@ void func_80B4CE54(Actor* thisx, GlobalContext* globalCtx) { func_80B44F58(); SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06013928, &D_06014088, this->jointTable, this->morphTable, 23); - func_80B45C04(&this->behaviorInfo, D_80B4EA90, 1, D_80B4EB00, 3, &D_801D15BC, 100, 0.03f, 0.3f, 0.03f); + func_80B45C04(&this->behaviorInfo, D_80B4EA90, 1, D_80B4EB00, 3, &gZeroVec3s, 100, 0.03f, 0.3f, 0.03f); func_80B446D0(this, globalCtx); this->actor.world.rot.y = this->actor.shape.rot.y; func_80B44700(this); diff --git a/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.c b/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.c index 631fc26e59..be3fe843d2 100644 --- a/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.c +++ b/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.c @@ -1157,8 +1157,7 @@ void EnKakasi_LimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec EnKakasi* this = (EnKakasi*)actor; if (limbIndex == 4) { - // what is D_801D15B0 ? we didn't have to define it, we store the output though - Matrix_MultiplyVector3fByState(&D_801D15B0, &this->unk1BC); + Matrix_MultiplyVector3fByState(&gZeroVec3f, &this->unk1BC); } } diff --git a/src/overlays/actors/ovl_En_Minislime/z_en_minislime.c b/src/overlays/actors/ovl_En_Minislime/z_en_minislime.c index 831e6a4b91..bb7fd235e1 100644 --- a/src/overlays/actors/ovl_En_Minislime/z_en_minislime.c +++ b/src/overlays/actors/ovl_En_Minislime/z_en_minislime.c @@ -215,7 +215,7 @@ void EnMinislime_AddIceSmokeEffect(EnMinislime* this, GlobalContext* globalCtx) vel.x = randPlusMinusPoint5Scaled(1.5f); vel.z = randPlusMinusPoint5Scaled(1.5f); vel.y = 2.0f; - EffectSsIceSmoke_Spawn(globalCtx, &pos, &vel, &D_801D15B0, 500); + EffectSsIceSmoke_Spawn(globalCtx, &pos, &vel, &gZeroVec3f, 500); } void EnMinislime_SetupDisappear(EnMinislime* this) { diff --git a/src/overlays/actors/ovl_En_Mushi2/z_en_mushi2.c b/src/overlays/actors/ovl_En_Mushi2/z_en_mushi2.c index b2792ec129..70945999f3 100644 --- a/src/overlays/actors/ovl_En_Mushi2/z_en_mushi2.c +++ b/src/overlays/actors/ovl_En_Mushi2/z_en_mushi2.c @@ -219,7 +219,7 @@ s32 func_80A68C5C(Vec3f* arg0, Vec3f* arg1) { f32 temp_f0 = Math3D_Vec3fMagnitude(arg0); if (temp_f0 < 0.005f) { - Math_Vec3f_Copy(arg0, &D_801D15B0); + Math_Vec3f_Copy(arg0, &gZeroVec3f); return false; } else { arg1->x = arg0->x * (1.0f / temp_f0); @@ -1095,7 +1095,7 @@ void func_80A6B0D8(EnMushi2* this, GlobalContext* globalCtx) { sp48.x = (this->unk_328.x * -0.6f) + (this->unk_31C.x * 0.1f); sp48.y = (this->unk_328.y * -0.6f) + (this->unk_31C.y * 0.1f); sp48.z = (this->unk_328.z * -0.6f) + (this->unk_31C.z * 0.1f); - func_800B0E48(globalCtx, &this->actor.world.pos, &sp48, &D_801D15B0, &D_80A6B984[sp44], &D_80A6B98C[sp44], + func_800B0E48(globalCtx, &this->actor.world.pos, &sp48, &gZeroVec3f, &D_80A6B984[sp44], &D_80A6B98C[sp44], (Rand_ZeroOne() * 5.0f) + 8.0f, (Rand_ZeroOne() * 5.0f) + 8.0f); } 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 9d15d2df31..cb796119a0 100644 --- a/src/overlays/actors/ovl_En_Pametfrog/z_en_pametfrog.c +++ b/src/overlays/actors/ovl_En_Pametfrog/z_en_pametfrog.c @@ -7,6 +7,7 @@ #include "z_en_pametfrog.h" #include "overlays/actors/ovl_En_Bigpamet/z_en_bigpamet.h" #include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h" +#include "objects/object_bigslime/object_bigslime.h" #define FLAGS 0x00000035 @@ -65,28 +66,6 @@ void EnPametfrog_SnapperSpawn(EnPametfrog* this, GlobalContext* globalCtx); void EnPametfrog_SetupTransitionGekkoSnapper(EnPametfrog* this, GlobalContext* globalCtx); void EnPametfrog_TransitionGekkoSnapper(EnPametfrog* this, GlobalContext* globalCtx); -extern AnimationHeader D_06000994; // Begin Rear on Snapper -extern AnimationHeader D_06001B08; // Call Snapper -extern AnimationHeader D_06001E14; // Crawl on Wall -extern AnimationHeader D_06001F20; // Falling -extern AnimationHeader D_060030E4; // Get up from Back -extern AnimationHeader D_0600347C; // Jab Punch -extern AnimationHeader D_060039C4; // Jump on Ground -extern AnimationHeader D_06003F28; // Kick -extern AnimationHeader D_06004298; // Fall on Back -extern AnimationHeader D_06004680; // Idle -extern AnimationHeader D_06004894; // Jump on Snapper -extern AnimationHeader D_06004D50; // Continue Rear on Snapper -extern AnimationHeader D_060050B8; // Squeeze Body -extern AnimationHeader D_060052EC; // Land on Snapper -extern AnimationHeader D_06005694; // Wiggle -extern AnimationHeader D_06005D54; // Head Knockback -extern AnimationHeader D_060066B4; // Look Around -extern AnimationHeader D_060070C4; // Hook Punch -extern FlexSkeletonHeader D_0600DF98; -extern AnimationHeader D_0600F048; // Windup Punch -extern AnimationHeader D_0600F990; // Melee Ready Stance - const ActorInit En_Pametfrog_InitVars = { ACTOR_EN_PAMETFROG, ACTORCAT_BOSS, @@ -207,7 +186,8 @@ void EnPametfrog_Init(Actor* thisx, GlobalContext* globalCtx) { Actor_ProcessInitChain(&this->actor, sInitChain); ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 55.0f); CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, &sColChkInit); - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_0600DF98, &D_0600F990, this->jointTable, this->morphTable, 24); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gGekkoSkel, &gGekkoBoxingStanceAnim, this->jointTable, + this->morphTable, GEKKO_LIMB_MAX); Collider_InitAndSetJntSph(globalCtx, &this->collider, &this->actor, &sJntSphInit, this->colElement); this->params = CLAMP(this->actor.params, 1, 4); if (Actor_GetRoomCleared(globalCtx, globalCtx->roomCtx.currRoom.num)) { @@ -250,7 +230,7 @@ u8 EnPametfrog_Vec3fNormalize(Vec3f* vec) { } } -void EnPametfrog_ChangeColliderFreeze(EnPametfrog* this) { +void EnPametfrog_Freeze(EnPametfrog* this) { this->drawEffect = GEKKO_DRAW_EFFECT_FROZEN; this->collider.base.colType = COLTYPE_HIT3; this->collider.elements->info.elemType = ELEMTYPE_UNK0; @@ -259,14 +239,14 @@ void EnPametfrog_ChangeColliderFreeze(EnPametfrog* this) { this->unk_2C4 = 1.0f; } -void EnPametfrog_ChangeColliderThaw(EnPametfrog* this, GlobalContext* globalCtx) { +void EnPametfrog_Thaw(EnPametfrog* this, GlobalContext* globalCtx) { this->freezeTimer = 0; if (this->drawEffect == GEKKO_DRAW_EFFECT_FROZEN) { - this->drawEffect = GEKKO_DRAW_EFFECT_NONE; + this->drawEffect = GEKKO_DRAW_EFFECT_THAW; this->collider.base.colType = COLTYPE_HIT6; this->collider.elements->info.elemType = ELEMTYPE_UNK1; this->unk_2C4 = 0.0f; - func_800BF7CC(globalCtx, &this->actor, this->limbPos, 12, 2, 0.3f, 0.2f); + func_800BF7CC(globalCtx, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), 2, 0.3f, 0.2f); } } @@ -407,7 +387,7 @@ void EnPametfrog_JumpOnGround(EnPametfrog* this, GlobalContext* globalCtx) { void EnPametfrog_ApplyMagicArrowEffects(EnPametfrog* this, GlobalContext* globalCtx) { if (this->actor.colChkInfo.damageEffect == GEKKO_DMGEFF_FIRE) { - this->drawEffect = GEKKO_DRAW_EFFECT_NONE; + this->drawEffect = GEKKO_DRAW_EFFECT_THAW; this->unk_2C4 = 3.0f; this->unk_2C8 = 0.75f; } else if (this->actor.colChkInfo.damageEffect == GEKKO_DMGEFF_LIGHT) { @@ -418,7 +398,7 @@ void EnPametfrog_ApplyMagicArrowEffects(EnPametfrog* this, GlobalContext* global 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, CLEAR_TAG_LARGE_LIGHT_RAYS); } else if (this->actor.colChkInfo.damageEffect == GEKKO_DMGEFF_ICE) { - EnPametfrog_ChangeColliderFreeze(this); + EnPametfrog_Freeze(this); } } @@ -439,11 +419,11 @@ void EnPametfrog_ApplyStun(EnPametfrog* this) { void EnPametfrog_SetupRearOnSnapper(EnPametfrog* this) { if (this->actionFunc == EnPametfrog_RearOnSnapperRise) { - Animation_PlayOnce(&this->skelAnime, &D_06005694); + Animation_PlayOnce(&this->skelAnime, &gGekkoWiggleAnim); } else if (this->actionFunc == EnPametfrog_RearOnSnapperWave) { - Animation_PlayOnce(&this->skelAnime, &D_060052EC); + Animation_PlayOnce(&this->skelAnime, &gGekkoLandOnSnapperAnim); } else { - Animation_PlayOnce(&this->skelAnime, &D_06004680); + Animation_PlayOnce(&this->skelAnime, &gGekkoStandingIdleAnim); } this->actor.flags &= ~1; @@ -458,9 +438,9 @@ void EnPametfrog_RearOnSnapper(EnPametfrog* this, GlobalContext* globalCtx) { if (SkelAnime_Update(&this->skelAnime)) { if (Rand_ZeroOne() < 0.5f) { - Animation_PlayOnce(&this->skelAnime, &D_06004D50); + Animation_PlayOnce(&this->skelAnime, &gGekkoQuickFistPumpAnim); } else { - Animation_PlayOnce(&this->skelAnime, &D_06004680); + Animation_PlayOnce(&this->skelAnime, &gGekkoStandingIdleAnim); } } @@ -478,7 +458,7 @@ void EnPametfrog_RearOnSnapper(EnPametfrog* this, GlobalContext* globalCtx) { } void EnPametfrog_SetupRearOnSnapperWave(EnPametfrog* this) { - Animation_PlayOnce(&this->skelAnime, &D_06004894); + Animation_PlayOnce(&this->skelAnime, &gGekkoJumpOnSnapperAnim); this->timer = 15; this->actionFunc = EnPametfrog_RearOnSnapperWave; } @@ -493,7 +473,7 @@ void EnPametfrog_RearOnSnapperWave(EnPametfrog* this, GlobalContext* globalCtx) } void EnPametfrog_SetupRearOnSnapperRise(EnPametfrog* this) { - Animation_PlayOnce(&this->skelAnime, &D_060050B8); + Animation_PlayOnce(&this->skelAnime, &gGekkoSqueezeAnim); this->timer = 10; this->actor.params = GEKKO_REAR_ON_SNAPPER; this->actor.shape.rot.x = 0; @@ -517,7 +497,7 @@ void EnPametfrog_SetupFallOffSnapper(EnPametfrog* this, GlobalContext* globalCtx Vec3f eye; s16 yaw; - Animation_PlayOnce(&this->skelAnime, &D_06001F20); + Animation_PlayOnce(&this->skelAnime, &gGekkoFallInAirAnim); this->actor.params = GEKKO_FALL_OFF_SNAPPER; this->actor.speedXZ = 7.0f; this->actor.velocity.y = 15.0f; @@ -554,7 +534,7 @@ void EnPametfrog_FallOffSnapper(EnPametfrog* this, GlobalContext* globalCtx) { } void EnPametfrog_SetupJumpToWall(EnPametfrog* this) { - Animation_Change(&this->skelAnime, &D_060039C4, 2.0f, 0.0f, 0.0f, 0, -2.0f); + Animation_Change(&this->skelAnime, &gGekkoJumpForwardAnim, 2.0f, 0.0f, 0.0f, 0, -2.0f); this->actor.shape.rot.x = 0; this->actor.shape.rot.z = 0; this->actor.bgCheckFlags &= ~8; @@ -578,14 +558,14 @@ void EnPametfrog_JumpToWall(EnPametfrog* this, GlobalContext* globalCtx) { void EnPametfrog_SetupWallCrawl(EnPametfrog* this) { if (this->actionFunc == EnPametfrog_JumpToWall) { - Animation_PlayLoop(&this->skelAnime, &D_06001E14); + Animation_PlayLoop(&this->skelAnime, &gGekkoCrawlAnim); this->collider.base.acFlags |= AC_ON; this->unk_2D0.x = 0.0f; this->unk_2D0.z = 0.0f; this->actor.gravity = 0.0f; this->actor.world.pos.y = this->actor.focus.pos.y; this->unk_2D0.y = 1.0f; - Math_Vec3f_Copy(&this->actor.colChkInfo.displacement, &D_801D15B0); + Math_Vec3f_Copy(&this->actor.colChkInfo.displacement, &gZeroVec3f); this->actor.colChkInfo.mass = MASS_IMMOVABLE; this->unk_2DC.x = COLPOLY_GET_NORMAL(this->actor.wallPoly->normal.x); this->unk_2DC.y = COLPOLY_GET_NORMAL(this->actor.wallPoly->normal.y); @@ -721,7 +701,8 @@ void EnPametfrog_WallPause(EnPametfrog* this, GlobalContext* globalCtx) { void EnPametfrog_SetupClimbDownWall(EnPametfrog* this) { s16 yaw; - Animation_Change(&this->skelAnime, &D_060039C4, 0.0f, 0.0f, Animation_GetLastFrame(&D_060039C4), 2, 0.0f); + Animation_Change(&this->skelAnime, &gGekkoJumpForwardAnim, 0.0f, 0.0f, + Animation_GetLastFrame(&gGekkoJumpForwardAnim), 2, 0.0f); this->actor.shape.rot.y = Actor_YawBetweenActors(&this->actor, this->actor.child); this->actor.world.rot.y = this->actor.shape.rot.y; this->actor.shape.rot.x = 0; @@ -755,7 +736,7 @@ void EnPametfrog_ClimbDownWall(EnPametfrog* this, GlobalContext* globalCtx) { } void EnPametfrog_SetupRunToSnapper(EnPametfrog* this) { - Animation_Change(&this->skelAnime, &D_060039C4, 2.0f, 0.0f, 0.0f, 0, -2.0f); + Animation_Change(&this->skelAnime, &gGekkoJumpForwardAnim, 2.0f, 0.0f, 0.0f, 0, -2.0f); this->actor.params = GEKKO_RETURN_TO_SNAPPER; this->actionFunc = EnPametfrog_RunToSnapper; } @@ -778,7 +759,7 @@ void EnPametfrog_RunToSnapper(EnPametfrog* this, GlobalContext* globalCtx) { } void EnPametfrog_SetupJumpOnSnapper(EnPametfrog* this) { - Animation_MorphToPlayOnce(&this->skelAnime, &D_06004680, 6.0f); + Animation_MorphToPlayOnce(&this->skelAnime, &gGekkoStandingIdleAnim, 6.0f); this->timer = 6; this->collider.base.ocFlags1 &= ~OC1_ON; this->collider.base.acFlags &= ~AC_ON; @@ -810,7 +791,7 @@ void EnPametfrog_JumpOnSnapper(EnPametfrog* this, GlobalContext* globalCtx) { } void EnPametfrog_SetupLandOnSnapper(EnPametfrog* this) { - Animation_PlayOnce(&this->skelAnime, &D_06000994); + Animation_PlayOnce(&this->skelAnime, &gGekkoFullFistPumpAnim); this->actor.shape.rot.y = this->actor.child->shape.rot.y; this->actor.params = GEKKO_ON_SNAPPER; this->actionFunc = EnPametfrog_LandOnSnapper; @@ -828,7 +809,7 @@ void EnPametfrog_SetupFallInAir(EnPametfrog* this, GlobalContext* globalCtx) { Vec3f eye; f32 xzDist; - Animation_PlayOnce(&this->skelAnime, &D_06001F20); + Animation_PlayOnce(&this->skelAnime, &gGekkoFallInAirAnim); if (this->actor.colChkInfo.health > 0) { this->actor.params = GEKKO_RETURN_TO_SNAPPER; } @@ -889,13 +870,13 @@ void EnPametfrog_FallInAir(EnPametfrog* this, GlobalContext* globalCtx) { } void EnPametfrog_SetupFallOnGround(EnPametfrog* this, GlobalContext* globalCtx) { - Animation_PlayOnce(&this->skelAnime, &D_06004298); + Animation_PlayOnce(&this->skelAnime, &gGekkoFallOnGroundAnim); this->actor.shape.rot.x = 0; this->actor.shape.rot.y += this->spinYaw; this->actor.shape.rot.z = 0; this->spinYaw = 0; this->timer = 5; - EnPametfrog_ChangeColliderThaw(this, globalCtx); + EnPametfrog_Thaw(this, globalCtx); EnPametfrog_JumpWaterEffects(this, globalCtx); Audio_PlayActorSound2(&this->actor, NA_SE_EV_WALK_WATER); this->actionFunc = EnPametfrog_FallOnGround; @@ -903,14 +884,14 @@ void EnPametfrog_SetupFallOnGround(EnPametfrog* this, GlobalContext* globalCtx) void EnPametfrog_FallOnGround(EnPametfrog* this, GlobalContext* globalCtx) { if (SkelAnime_Update(&this->skelAnime)) { - if (this->skelAnime.animation == &D_06004298) { + if (this->skelAnime.animation == &gGekkoFallOnGroundAnim) { if (this->actor.colChkInfo.health == 0) { this->timer--; if (this->timer == 0) { EnPametfrog_SetupDefeatGekko(this, globalCtx); } } else { - Animation_PlayOnce(&this->skelAnime, &D_060030E4); + Animation_PlayOnce(&this->skelAnime, &gGekkoRecoverAnim); } } else { EnPametfrog_SetupRunToSnapper(this); @@ -982,7 +963,7 @@ void EnPametfrog_SetupSpawnFrog(EnPametfrog* this, GlobalContext* globalCtx) { vec1.y = this->actor.world.pos.y + 25.0f; vec1.z = (Math_CosS(yaw) * 20.0f) + this->actor.world.pos.z; this->collider.base.ocFlags1 &= ~OC1_ON; - func_800B0DE0(globalCtx, &vec1, &D_801D15B0, &D_801D15B0, &primColor, &envColor, 800, 50); + func_800B0DE0(globalCtx, &vec1, &gZeroVec3f, &gZeroVec3f, &primColor, &envColor, 800, 50); Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EN_NPC_APPEAR); Actor_SetRoomClearedTemp(globalCtx, globalCtx->roomCtx.currRoom.num); @@ -1043,7 +1024,7 @@ void EnPametfrog_PlayCutscene(EnPametfrog* this, GlobalContext* globalCtx) { } void EnPametfrog_SetupLookAround(EnPametfrog* this) { - Animation_PlayOnce(&this->skelAnime, &D_060066B4); + Animation_PlayOnce(&this->skelAnime, &gGekkoLookAroundAnim); this->collider.base.atFlags &= ~AT_ON; this->actor.speedXZ = 0.0f; this->actor.world.rot.y = this->actor.shape.rot.y; @@ -1064,7 +1045,7 @@ void EnPametfrog_LookAround(EnPametfrog* this, GlobalContext* globalCtx) { } void EnPametfrog_SetupJumpToLink(EnPametfrog* this) { - Animation_PlayLoop(&this->skelAnime, &D_060039C4); + Animation_PlayLoop(&this->skelAnime, &gGekkoJumpForwardAnim); this->collider.base.acFlags |= AC_ON; this->actor.world.rot.y = this->actor.shape.rot.y; this->actionFunc = EnPametfrog_JumpToLink; @@ -1089,17 +1070,17 @@ void EnPametfrog_JumpToLink(EnPametfrog* this, GlobalContext* globalCtx) { } void EnPametfrog_SetupMeleeAttack(EnPametfrog* this) { - Animation_PlayOnce(&this->skelAnime, &D_0600F990); + Animation_PlayOnce(&this->skelAnime, &gGekkoBoxingStanceAnim); this->timer = 7; this->actor.speedXZ = 0.0f; this->actionFunc = EnPametfrog_MeleeAttack; } static AnimationHeader* sAttackAnimations[] = { - &D_0600347C, // Jab Punch - &D_060070C4, // Hook Punch - &D_06003F28, // Kick - &D_0600F048, // Windup Punch + &gGekkoJabPunchAnim, + &gGekkoHookPunchAnim, + &gGekkoKickAnim, + &gGekkoWindupPunchAnim, }; void EnPametfrog_MeleeAttack(EnPametfrog* this, GlobalContext* globalCtx) { @@ -1109,18 +1090,18 @@ void EnPametfrog_MeleeAttack(EnPametfrog* this, GlobalContext* globalCtx) { if (this->timer == 0) { EnPametfrog_SetupLookAround(this); } else if (this->timer == 6) { - Animation_PlayOnce(&this->skelAnime, &D_0600F990); + Animation_PlayOnce(&this->skelAnime, &gGekkoBoxingStanceAnim); } else { Animation_PlayOnce(&this->skelAnime, sAttackAnimations[(s32)Rand_ZeroFloat(4.0f) % 4]); } } - if ((this->skelAnime.animation == &D_0600347C && Animation_OnFrame(&this->skelAnime, 2.0f)) || - (this->skelAnime.animation == &D_060070C4 && Animation_OnFrame(&this->skelAnime, 9.0f)) || - (this->skelAnime.animation == &D_06003F28 && Animation_OnFrame(&this->skelAnime, 2.0f)) || - ((this->skelAnime.animation == &D_0600F048) && Animation_OnFrame(&this->skelAnime, 27.0f))) { + if ((this->skelAnime.animation == &gGekkoJabPunchAnim && Animation_OnFrame(&this->skelAnime, 2.0f)) || + (this->skelAnime.animation == &gGekkoHookPunchAnim && Animation_OnFrame(&this->skelAnime, 9.0f)) || + (this->skelAnime.animation == &gGekkoKickAnim && Animation_OnFrame(&this->skelAnime, 2.0f)) || + ((this->skelAnime.animation == &gGekkoWindupPunchAnim) && Animation_OnFrame(&this->skelAnime, 27.0f))) { this->collider.base.atFlags |= AT_ON; - if (this->skelAnime.animation == &D_06003F28) { + if (this->skelAnime.animation == &gGekkoKickAnim) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_FROG_KICK); } else { Audio_PlayActorSound2(&this->actor, NA_SE_EN_FROG_PUNCH1); @@ -1131,7 +1112,7 @@ void EnPametfrog_MeleeAttack(EnPametfrog* this, GlobalContext* globalCtx) { } void EnPametfrog_SetupDamage(EnPametfrog* this) { - Animation_MorphToPlayOnce(&this->skelAnime, &D_06005D54, -3.0f); + Animation_MorphToPlayOnce(&this->skelAnime, &gGekkoKnockbackAnim, -3.0f); this->timer = 20; this->collider.base.atFlags &= ~AT_ON; this->collider.base.acFlags &= ~AC_ON; @@ -1157,7 +1138,7 @@ void EnPametfrog_Damage(EnPametfrog* this, GlobalContext* globalCtx) { } void EnPametfrog_SetupStun(EnPametfrog* this) { - if (this->skelAnime.animation == &D_060039C4) { + if (this->skelAnime.animation == &gGekkoJumpForwardAnim) { this->skelAnime.curFrame = 0.0f; SkelAnime_Update(&this->skelAnime); } @@ -1175,10 +1156,10 @@ void EnPametfrog_SetupStun(EnPametfrog* this) { void EnPametfrog_Stun(EnPametfrog* this, GlobalContext* globalCtx) { this->freezeTimer--; if (this->freezeTimer == 0) { - EnPametfrog_ChangeColliderThaw(this, globalCtx); + EnPametfrog_Thaw(this, globalCtx); EnPametfrog_SetupJumpToLink(this); } else if (this->freezeTimer == 78) { - EnPametfrog_ChangeColliderThaw(this, globalCtx); + EnPametfrog_Thaw(this, globalCtx); this->actor.colorFilterTimer = 0; EnPametfrog_SetupCutscene(this); } @@ -1189,7 +1170,7 @@ void EnPametfrog_SetupCallSnapper(EnPametfrog* this, GlobalContext* globalCtx) { Vec3f at; s16 yawDiff; - Animation_MorphToPlayOnce(&this->skelAnime, &D_06001B08, 3.0f); + Animation_MorphToPlayOnce(&this->skelAnime, &gGekkoCallAnim, 3.0f); Audio_PlayActorSound2(&this->actor, NA_SE_EN_FROG_GREET); this->actor.flags &= ~1; this->actor.colChkInfo.health = 6; @@ -1298,14 +1279,14 @@ void EnPametfrog_ApplyDamageEffect(EnPametfrog* this, GlobalContext* globalCtx) EnPametfrog_ApplyStun(this); EnPametfrog_SetupStun(this); } else if (this->actor.colChkInfo.damageEffect == GEKKO_DMGEFF_ICE) { - EnPametfrog_ChangeColliderFreeze(this); + EnPametfrog_Freeze(this); this->freezeTimer = 80; func_800BCB70(&this->actor, 0x4000, 0xFF, 0, 0x50); EnPametfrog_SetupStun(this); } else { - EnPametfrog_ChangeColliderThaw(this, globalCtx); + EnPametfrog_Thaw(this, globalCtx); if (this->actor.colChkInfo.damageEffect == GEKKO_DMGEFF_FIRE) { - this->drawEffect = GEKKO_DRAW_EFFECT_NONE; + this->drawEffect = GEKKO_DRAW_EFFECT_THAW; this->unk_2C8 = 0.75f; this->unk_2C4 = 4.0f; } else if (this->actor.colChkInfo.damageEffect == GEKKO_DMGEFF_LIGHT) { @@ -1388,19 +1369,19 @@ void EnPametfrog_Update(Actor* thisx, GlobalContext* globalCtx) { } } -/* index -1: Limb Not used - * index 0: GEKKO_LIMB_WAIST - * index 1: GEKKO_LIMB_L_SHIN - * index 2: GEKKO_LIMB_L_FOOT - * index 3: GEKKO_LIMB_R_SHIN - * index 4: GEKKO_LIMB_R_FOOT - * index 5: GEKKO_LIMB_L_UPPER_ARM - * index 6: GEKKO_LIMB_L_FOREARM - * index 7: GEKKO_LIMB_L_HAND - * index 8: GEKKO_LIMB_R_UPPER_ARM - * index 9: GEKKO_LIMB_R_FOREARM - * index 10: GEKKO_LIMB_R_HAND - * index 11: GEKKO_LIMB_JAW +/* value -1: Limb Not used + * value 0: GEKKO_LIMB_WAIST + * value 1: GEKKO_LIMB_L_SHIN + * value 2: GEKKO_LIMB_L_FOOT + * value 3: GEKKO_LIMB_R_SHIN + * value 4: GEKKO_LIMB_R_FOOT + * value 5: GEKKO_LIMB_L_UPPER_ARM + * value 6: GEKKO_LIMB_L_FOREARM + * value 7: GEKKO_LIMB_L_HAND + * value 8: GEKKO_LIMB_R_UPPER_ARM + * value 9: GEKKO_LIMB_R_FOREARM + * value 10: GEKKO_LIMB_R_HAND + * value 11: GEKKO_LIMB_JAW */ static s8 limbPosIndex[] = { -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1, 5, 6, -1, 7, 8, 9, -1, 10, -1, 11, -1, -1, diff --git a/src/overlays/actors/ovl_En_Pametfrog/z_en_pametfrog.h b/src/overlays/actors/ovl_En_Pametfrog/z_en_pametfrog.h index f00acecb5e..957a46cfc4 100644 --- a/src/overlays/actors/ovl_En_Pametfrog/z_en_pametfrog.h +++ b/src/overlays/actors/ovl_En_Pametfrog/z_en_pametfrog.h @@ -21,7 +21,7 @@ typedef enum { } EnPametfrogState; typedef enum { - /* 00 */ GEKKO_DRAW_EFFECT_NONE, // May be GEKKO_DRAW_EFFECT_THAW + /* 00 */ GEKKO_DRAW_EFFECT_THAW, /* 10 */ GEKKO_DRAW_EFFECT_FROZEN = 10, /* 20 */ GEKKO_DRAW_EFFECT_LIGHT_ORBS = 20, /* 30 */ GEKKO_DRAW_EFFECT_ELECTRIC_STUN = 30, diff --git a/src/overlays/actors/ovl_En_Pm/z_en_pm.c b/src/overlays/actors/ovl_En_Pm/z_en_pm.c index 5cb68e3df7..5993ab3664 100644 --- a/src/overlays/actors/ovl_En_Pm/z_en_pm.c +++ b/src/overlays/actors/ovl_En_Pm/z_en_pm.c @@ -1449,7 +1449,7 @@ s32 func_80AF9E7C(EnPm* this, GlobalContext* globalCtx) { func_8013AF00(sp7C, 3, this->unk_234->count + 3); if (!(this->unk_356 & 8)) { - sp58 = D_801D15B0; + sp58 = gZeroVec3f; func_8013B6B0(this->unk_234, &this->unk_244, &this->unk_254, this->unk_24C, this->unk_248, &this->unk_250, sp7C, &sp58, this->unk_374); func_8013B878(globalCtx, this->unk_234, this->unk_250, &sp58); @@ -1468,7 +1468,7 @@ s32 func_80AF9E7C(EnPm* this, GlobalContext* globalCtx) { sp58 = this->actor.world.pos; } - this->unk_238 = D_801D15B0; + this->unk_238 = gZeroVec3f; if (func_8013B6B0(this->unk_234, &this->unk_244, &this->unk_254, this->unk_24C, this->unk_248, &this->unk_250, sp7C, &this->unk_238, this->unk_374)) { @@ -1827,7 +1827,7 @@ void func_80AFAA44(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* switch (limbIndex) { case 15: if (ActorCutscene_GetCurrentIndex() == -1) { - Matrix_MultiplyVector3fByState(&D_801D15B0, &this->actor.focus.pos); + Matrix_MultiplyVector3fByState(&gZeroVec3f, &this->actor.focus.pos); Math_Vec3s_Copy(&this->actor.focus.rot, &this->actor.world.rot); } if ((this->unk_356 & 0x8000) && !(gSaveContext.weekEventReg[90] & 4)) { @@ -1843,10 +1843,10 @@ void func_80AFAA44(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* case 8: if ((this->unk_258 == 9) || (this->unk_258 == 20) || (this->unk_258 == 21) || (this->unk_258 == 22)) { - Matrix_MultiplyVector3fByState(&D_801D15B0, &sp2C); + Matrix_MultiplyVector3fByState(&gZeroVec3f, &sp2C); Math_Vec3f_ToVec3s(&this->colliderSphere.dim.worldSphere.center, &sp2C); } else if (this->unk_258 == 24) { - Matrix_MultiplyVector3fByState(&D_801D15B0, &sp2C); + Matrix_MultiplyVector3fByState(&gZeroVec3f, &sp2C); Math_Vec3f_ToVec3s(&this->colliderSphere.dim.worldSphere.center, &sp2C); } func_80AF8890(this, gfx, 2); diff --git a/src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.c b/src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.c index 834830a687..6f267771b3 100644 --- a/src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.c +++ b/src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.c @@ -726,7 +726,7 @@ void func_80B1BE4C(EnPoSisters* this, s32 arg1) { sp34.x = this->actor.world.pos.x; sp34.y = this->actor.world.pos.y + 45.0f; sp34.z = this->actor.world.pos.z; - func_800B3030(arg1, &sp34, &D_801D15B0, &D_801D15B0, 150, 0, 3); + func_800B3030(arg1, &sp34, &gZeroVec3f, &gZeroVec3f, 150, 0, 3); } Lights_PointSetColorAndRadius(&this->lightInfo, 0, 0, 0, 0); this->actionFunc = func_80B1BF2C; diff --git a/src/overlays/actors/ovl_En_Poh/z_en_poh.c b/src/overlays/actors/ovl_En_Poh/z_en_poh.c index 4042aecac7..f9dc6ddf44 100644 --- a/src/overlays/actors/ovl_En_Poh/z_en_poh.c +++ b/src/overlays/actors/ovl_En_Poh/z_en_poh.c @@ -203,7 +203,7 @@ void func_80B2C910(Vec3f* vec, GlobalContext* globalCtx) { } Math_Vec3f_ScaleAndStore(&sp20, temp_f0, vec); } else { - Math_Vec3f_Copy(vec, &D_801D15B0); + Math_Vec3f_Copy(vec, &gZeroVec3f); } } @@ -426,13 +426,13 @@ void func_80B2D300(EnPoh* this, GlobalContext* globalCtx) { sp44.z = (Math_CosS(sp38) * 23.0f) + this->actor.world.pos.z; } sp36 = (this->unk_18E * 10) + 80; - func_800B3030(globalCtx, &sp44, &D_80B2F710, &D_801D15B0, sp36, 0, 2); + func_800B3030(globalCtx, &sp44, &D_80B2F710, &gZeroVec3f, sp36, 0, 2); sp44.x = (2.0f * this->actor.world.pos.x) - sp44.x; sp44.z = (2.0f * this->actor.world.pos.z) - sp44.z; - func_800B3030(globalCtx, &sp44, &D_80B2F710, &D_801D15B0, sp36, 0, 2); + func_800B3030(globalCtx, &sp44, &D_80B2F710, &gZeroVec3f, sp36, 0, 2); sp44.x = this->actor.world.pos.x; sp44.z = this->actor.world.pos.z; - func_800B3030(globalCtx, &sp44, &D_80B2F710, &D_801D15B0, sp36, 0, 2); + func_800B3030(globalCtx, &sp44, &D_80B2F710, &gZeroVec3f, sp36, 0, 2); } else if (this->unk_18E == 28) { func_80B2DC50(this, globalCtx); } else if (this->unk_18E > 18) { diff --git a/src/overlays/actors/ovl_En_Railgibud/z_en_railgibud.c b/src/overlays/actors/ovl_En_Railgibud/z_en_railgibud.c index 6b1d57ea80..de64df7dfd 100644 --- a/src/overlays/actors/ovl_En_Railgibud/z_en_railgibud.c +++ b/src/overlays/actors/ovl_En_Railgibud/z_en_railgibud.c @@ -611,7 +611,7 @@ void func_80BA6800(EnRailgibud* this, GlobalContext* globalCtx, s32 arg2) { void func_80BA6974(GlobalContext* globalCtx, Vec3f* vec, f32 arg2, s32 arg3, s16 arg4, s16 arg5) { Vec3f sp8C; Vec3f sp80 = { 0.0f, 0.3f, 0.0f }; - Vec3f sp74 = D_801D15B0; + Vec3f sp74 = gZeroVec3f; s32 i; s32 pad; diff --git a/src/overlays/actors/ovl_En_Rr/z_en_rr.c b/src/overlays/actors/ovl_En_Rr/z_en_rr.c index 96e688bb4c..f012353277 100644 --- a/src/overlays/actors/ovl_En_Rr/z_en_rr.c +++ b/src/overlays/actors/ovl_En_Rr/z_en_rr.c @@ -720,7 +720,7 @@ void func_808FB42C(EnRr* this, GlobalContext* globalCtx) { sp74.x = this->actor.world.pos.x; sp74.y = this->actor.world.pos.y + 20.0f; sp74.z = this->actor.world.pos.z; - func_800B3030(globalCtx, &sp74, &D_801D15B0, &D_801D15B0, 100, 0, 0); + func_800B3030(globalCtx, &sp74, &gZeroVec3f, &gZeroVec3f, 100, 0, 0); Audio_PlaySoundAtPosition(globalCtx, &sp74, 11, NA_SE_EN_EXTINCT); } else { temp_f20 = this->actor.scale.y * 66.66667f; 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 c767f953b6..9cc8897a2e 100644 --- a/src/overlays/actors/ovl_En_Suttari/z_en_suttari.c +++ b/src/overlays/actors/ovl_En_Suttari/z_en_suttari.c @@ -411,7 +411,7 @@ void func_80BAAFDC(EnSuttari* this, GlobalContext* globalCtx) { Matrix_MultiplyVector3fByState(&effectVelOffset, &effectVel); Matrix_StatePop(); if (this->unk3F0 == 0) { - EffectSsSolderSrchBall_Spawn(globalCtx, &effectPos, &effectVel, &D_801D15B0, 50, &this->unk3F0, 1); + EffectSsSolderSrchBall_Spawn(globalCtx, &effectPos, &effectVel, &gZeroVec3f, 50, &this->unk3F0, 1); } if (this->unk3F0 == 1) { play_sound(NA_SE_SY_FOUND); @@ -443,7 +443,7 @@ void func_80BAB1A0(EnSuttari* this, GlobalContext* globalCtx) { Matrix_MultiplyVector3fByState(&effectVelOffset, &effectVel); Matrix_StatePop(); if (this->unk3F0 == 0) { - EffectSsSolderSrchBall_Spawn(globalCtx, &effectPos, &effectVel, &D_801D15B0, 50, &this->unk3F0, 1); + EffectSsSolderSrchBall_Spawn(globalCtx, &effectPos, &effectVel, &gZeroVec3f, 50, &this->unk3F0, 1); } if (this->unk3F0 == 1) { play_sound(NA_SE_SY_FOUND); @@ -755,7 +755,7 @@ s32 func_80BABFD4(EnSuttari* this, GlobalContext* globalCtx) { func_8013AF00(sp7C, 3, this->unk404->count + 3); if (this->unk42C == 0) { - sp58 = D_801D15B0; + sp58 = gZeroVec3f; func_8013B6B0(this->unk404, &this->unk414, &this->unk424, this->unk41C, this->unk418, &this->unk420, sp7C, &sp58, this->unk42A); func_8013B878(globalCtx, this->unk404, this->unk420, &sp58); @@ -771,7 +771,7 @@ s32 func_80BABFD4(EnSuttari* this, GlobalContext* globalCtx) { sp50 = this->unk420; sp58 = this->actor.world.pos; } - this->unk408 = D_801D15B0; + this->unk408 = gZeroVec3f; if (func_8013B6B0(this->unk404, &this->unk414, &this->unk424, this->unk41C, this->unk418, &this->unk420, sp7C, &this->unk408, this->unk42A)) { this->unk430 = 1; diff --git a/src/overlays/actors/ovl_En_Sw/z_en_sw.c b/src/overlays/actors/ovl_En_Sw/z_en_sw.c index 221de85014..204d251d19 100644 --- a/src/overlays/actors/ovl_En_Sw/z_en_sw.c +++ b/src/overlays/actors/ovl_En_Sw/z_en_sw.c @@ -174,11 +174,11 @@ void func_808D8940(EnSw* this, GlobalContext* globalCtx) { sp94.x = 0.0f; sp94.y = (Rand_ZeroOne() * 0.2f) + 0.1f; sp94.z = Rand_ZeroOne() + 1.0f; - Lib_Vec3f_TranslateAndRotateY(&D_801D15B0, temp_s0, &sp94, &spAC); + Lib_Vec3f_TranslateAndRotateY(&gZeroVec3f, temp_s0, &sp94, &spAC); sp94.x = 0.0f; sp94.y = 0.7f; sp94.z = 2.0f; - Lib_Vec3f_TranslateAndRotateY(&D_801D15B0, temp_s0, &sp94, &spB8); + Lib_Vec3f_TranslateAndRotateY(&gZeroVec3f, temp_s0, &sp94, &spB8); spA0.x = this->actor.world.pos.x + (2.0f * spB8.x); spA0.z = this->actor.world.pos.z + (2.0f * spB8.z); func_800B0EB0(globalCtx, &spA0, &spB8, &spAC, &D_808DBAA4, &D_808DBAA8, 60, 30, temp_f4); @@ -1148,7 +1148,7 @@ void func_808DB2E0(EnSw* this, GlobalContext* globalCtx) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALTURA_BOUND); } else { func_800BC154(globalCtx, &globalCtx->actorCtx, &this->actor, 5); - Math_Vec3f_Copy(&this->actor.velocity, &D_801D15B0); + Math_Vec3f_Copy(&this->actor.velocity, &gZeroVec3f); this->unk_410 &= ~(0x10 | 0x1); this->actionFunc = func_808DB100; } diff --git a/src/overlays/actors/ovl_En_Test5/z_en_test5.c b/src/overlays/actors/ovl_En_Test5/z_en_test5.c index 4da30599cb..f1ec4e817e 100644 --- a/src/overlays/actors/ovl_En_Test5/z_en_test5.c +++ b/src/overlays/actors/ovl_En_Test5/z_en_test5.c @@ -102,7 +102,7 @@ void EnTest5_Update(Actor* thisx, GlobalContext* globalCtx2) { steamVel.x = 0.0f; steamVel.z = 0.0f; - EffectSsIceSmoke_Spawn(globalCtx, &steamPos, &steamVel, &D_801D15B0, + EffectSsIceSmoke_Spawn(globalCtx, &steamPos, &steamVel, &gZeroVec3f, (s16)((-200) - (s32)(Rand_ZeroOne() * 50.0f))); } } diff --git a/src/overlays/actors/ovl_En_Thiefbird/z_en_thiefbird.c b/src/overlays/actors/ovl_En_Thiefbird/z_en_thiefbird.c index 89973ff694..cb33c2621a 100644 --- a/src/overlays/actors/ovl_En_Thiefbird/z_en_thiefbird.c +++ b/src/overlays/actors/ovl_En_Thiefbird/z_en_thiefbird.c @@ -658,7 +658,7 @@ void func_80C11DF0(EnThiefbird* this, GlobalContext* globalCtx) { if ((this->actor.bgCheckFlags & 1) || (this->actor.floorHeight == BGCHECK_Y_MIN)) { for (i = 0; i < ARRAY_COUNT(this->unk_350); i++) { - func_800B3030(globalCtx, &this->unk_350[i], &D_801D15B0, &D_801D15B0, 0x8C, 0, 0); + func_800B3030(globalCtx, &this->unk_350[i], &gZeroVec3f, &gZeroVec3f, 0x8C, 0, 0); } Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 11, NA_SE_EN_EXTINCT); diff --git a/src/overlays/actors/ovl_En_Tite/z_en_tite.c b/src/overlays/actors/ovl_En_Tite/z_en_tite.c index 61a12cfb0a..bcf8547eff 100644 --- a/src/overlays/actors/ovl_En_Tite/z_en_tite.c +++ b/src/overlays/actors/ovl_En_Tite/z_en_tite.c @@ -266,7 +266,7 @@ void func_80893BCC(EnTite* this, GlobalContext* globalCtx) { sp7C.x = ptr->x + randPlusMinusPoint5Scaled(1.0f); sp7C.y = ptr->y + randPlusMinusPoint5Scaled(1.0f); sp7C.z = ptr->z + randPlusMinusPoint5Scaled(1.0f); - func_800B0DE0(globalCtx, &sp7C, &D_801D15B0, &D_80896B64, &D_80896B3C, &D_80896B40, + func_800B0DE0(globalCtx, &sp7C, &gZeroVec3f, &D_80896B64, &D_80896B3C, &D_80896B40, (s32)Rand_ZeroFloat(16.0f) + 80, 15); } } @@ -677,7 +677,7 @@ void func_808951B8(EnTite* this, GlobalContext* globalCtx) { if (this->unk_2BC == 0) { for (i = 0; i < ARRAY_COUNT(this->unk_2D0); i++) { - func_800B3030(globalCtx, &this->unk_2D0[i], &D_801D15B0, &D_801D15B0, 40, 7, 1); + func_800B3030(globalCtx, &this->unk_2D0[i], &gZeroVec3f, &gZeroVec3f, 40, 7, 1); Audio_PlaySoundAtPosition(globalCtx, &this->unk_2D0[i], 11, NA_SE_EN_EXTINCT); } Actor_MarkForDeath(&this->actor); @@ -816,7 +816,7 @@ void func_8089595C(EnTite* this, GlobalContext* globalCtx) { sp2C.x = randPlusMinusPoint5Scaled(20.0f) + this->actor.world.pos.x; sp2C.y = this->actor.world.pos.y + 15.0f; sp2C.z = randPlusMinusPoint5Scaled(20.0f) + this->actor.world.pos.z; - func_800B0DE0(globalCtx, &sp2C, &D_801D15B0, &D_80896B44, &D_80896B3C, &D_80896B40, 500, 50); + func_800B0DE0(globalCtx, &sp2C, &gZeroVec3f, &D_80896B44, &D_80896B3C, &D_80896B40, 500, 50); } void func_80895A10(EnTite* this) { diff --git a/src/overlays/actors/ovl_En_Tk/z_en_tk.c b/src/overlays/actors/ovl_En_Tk/z_en_tk.c index 07bf625d21..74577c188b 100644 --- a/src/overlays/actors/ovl_En_Tk/z_en_tk.c +++ b/src/overlays/actors/ovl_En_Tk/z_en_tk.c @@ -405,7 +405,7 @@ s32 func_80AECE60(EnTk* this, GlobalContext* globalCtx) { func_8013AF00(spA0, 3, this->unk_3C8->count + 3); if (!(this->unk_3CE & 4)) { - sp7C = D_801D15B0; + sp7C = gZeroVec3f; func_8013B6B0(this->unk_3C8, &this->unk_3E0, &this->unk_3F0, this->unk_3E8, this->unk_3E4, &this->unk_3EC, spA0, &sp7C, this->unk_3D0); func_8013B878(globalCtx, this->unk_3C8, this->unk_3EC, &sp7C); @@ -428,7 +428,7 @@ s32 func_80AECE60(EnTk* this, GlobalContext* globalCtx) { sp7C = this->actor.world.pos; } - this->unk_3D4 = D_801D15B0; + this->unk_3D4 = gZeroVec3f; if (func_8013B6B0(this->unk_3C8, &this->unk_3E0, &this->unk_3F0, this->unk_3E8, this->unk_3E4, &this->unk_3EC, spA0, &this->unk_3D4, this->unk_3D0)) { diff --git a/src/overlays/actors/ovl_En_Trt/z_en_trt.c b/src/overlays/actors/ovl_En_Trt/z_en_trt.c index a03072c529..e6cd134b5e 100644 --- a/src/overlays/actors/ovl_En_Trt/z_en_trt.c +++ b/src/overlays/actors/ovl_En_Trt/z_en_trt.c @@ -1712,11 +1712,11 @@ void EnTrt_UpdateHeadYawAndPitch(EnTrt* this, GlobalContext* globalCtx) { void EnTrt_UpdateHeadPosAndRot(s16 pitch, s16 yaw, Vec3f* pos, Vec3s* rot, s32 isFullyAwake) { Vec3f newPos; - Vec3f D_801D15B0tmp = D_801D15B0; + Vec3f zeroVec = gZeroVec3f; Vec3s newRot; MtxF currentState; - Matrix_MultiplyVector3fByState(&D_801D15B0tmp, &newPos); + Matrix_MultiplyVector3fByState(&zeroVec, &newPos); Matrix_CopyCurrentState(¤tState); func_8018219C(¤tState, &newRot, MTXMODE_NEW); *pos = newPos; diff --git a/src/overlays/actors/ovl_En_Tru/z_en_tru.c b/src/overlays/actors/ovl_En_Tru/z_en_tru.c index 4874ac2496..cbb31ebc35 100644 --- a/src/overlays/actors/ovl_En_Tru/z_en_tru.c +++ b/src/overlays/actors/ovl_En_Tru/z_en_tru.c @@ -130,7 +130,7 @@ void func_80A85620(EnTruUnkStruct* arg0, Vec3f* arg1, f32 arg2, f32 arg3, f32 ar arg0->unk_01 = arg0->unk_02; arg0->unk_00 = 1; arg0->unk_04 = *arg1; - arg0->unk_1C = D_801D15B0; + arg0->unk_1C = gZeroVec3f; arg0->unk_10 = D_80A8B250; arg0->unk_28 = arg2; arg0->unk_2C = arg3; @@ -190,8 +190,8 @@ void func_80A85AA4(EnTruUnkStruct* arg0, Vec3f* arg1, f32 arg2, f32 arg3, f32 ar arg0->unk_01 = arg0->unk_02; arg0->unk_00 = 2; arg0->unk_04 = *arg1; - arg0->unk_1C = D_801D15B0; - arg0->unk_10 = D_801D15B0; + arg0->unk_1C = gZeroVec3f; + arg0->unk_10 = gZeroVec3f; arg0->unk_28 = arg2; arg0->unk_2C = arg3; break; @@ -350,23 +350,23 @@ s32 func_80A86460(EnTru* this) { f32 temp_f6; s16 phi_s1; - Math_Vec3f_Copy(&spB0, &D_801D15B0); - Math_Vec3f_Copy(&sp8C, &D_801D15B0); - Math_Vec3f_Copy(&spA4, &D_801D15B0); - Math_Vec3f_Copy(&sp98, &D_801D15B0); + Math_Vec3f_Copy(&spB0, &gZeroVec3f); + Math_Vec3f_Copy(&sp8C, &gZeroVec3f); + Math_Vec3f_Copy(&spA4, &gZeroVec3f); + Math_Vec3f_Copy(&sp98, &gZeroVec3f); phi_s1 = (Rand_ZeroOne() * 360.0f) * 182.0f; spB0.z = 20.0f; Lib_Vec3f_TranslateAndRotateY(&this->actor.world.pos, this->actor.world.rot.y, &spB0, &sp8C); for (i = 0; i < 8; i++, phi_s1 += 0x1FFE) { - Math_Vec3f_Copy(&spB0, &D_801D15B0); + Math_Vec3f_Copy(&spB0, &gZeroVec3f); spB0.y = 1.0f; spB0.z = Rand_ZeroOne() + 3.0f; - Lib_Vec3f_TranslateAndRotateY(&D_801D15B0, phi_s1, &spB0, &sp98); - Math_Vec3f_Copy(&spB0, &D_801D15B0); + Lib_Vec3f_TranslateAndRotateY(&gZeroVec3f, phi_s1, &spB0, &sp98); + Math_Vec3f_Copy(&spB0, &gZeroVec3f); spB0.z = (Rand_ZeroOne() * 4.0f) + 12.0f; Lib_Vec3f_TranslateAndRotateY(&sp8C, phi_s1, &spB0, &spA4); - func_80A85E2C(this->unk_394, &spA4, &D_801D15B0, &sp98, 0.4f, 0.06f, 12.0f, 4); + func_80A85E2C(this->unk_394, &spA4, &gZeroVec3f, &sp98, 0.4f, 0.06f, 12.0f, 4); } return false; @@ -378,7 +378,7 @@ s32 func_80A86674(EnTru* this) { Vec3f sp34; Lib_Vec3f_TranslateAndRotateY(&this->actor.world.pos, this->actor.world.rot.y, &D_80A8B3D8, &sp40); - Lib_Vec3f_TranslateAndRotateY(&D_801D15B0, this->actor.world.rot.y, &D_80A8B3E4, &sp34); + Lib_Vec3f_TranslateAndRotateY(&gZeroVec3f, this->actor.world.rot.y, &D_80A8B3E4, &sp34); if (this->unk_390 == 1) { func_80A85E2C(this->unk_394, &sp40, &D_80A8B3F0, &sp34, 0.2f, 0.1f, 12.0f, 3); } else if (this->unk_390 == 2) { @@ -396,12 +396,12 @@ s32 func_80A86770(EnTru* this) { s16 phi_s0 = Rand_ZeroOne() * 360.0f * 182.0f; for (i = 0; i < 4; i++, phi_s0 += 0x3FFC) { - Lib_Vec3f_TranslateAndRotateY(&this->actor.world.pos, phi_s0, &D_801D15B0, &sp98); + Lib_Vec3f_TranslateAndRotateY(&this->actor.world.pos, phi_s0, &gZeroVec3f, &sp98); sp98.y = this->actor.floorHeight + 1.0f; sp8C.x = Rand_ZeroOne() - 0.5f; sp8C.z = Rand_ZeroOne() - 0.5f; sp8C.y = Rand_ZeroOne() * 0.2f; - func_80A85E2C(this->unk_394, &sp98, &sp8C, &D_801D15B0, 1.0f, 0.04f, 28.0f, 4); + func_80A85E2C(this->unk_394, &sp98, &sp8C, &gZeroVec3f, 1.0f, 0.04f, 28.0f, 4); } return false; @@ -931,7 +931,7 @@ s32 func_80A87B48(Actor* thisx, GlobalContext* globalCtx) { case 1: if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { sp3E = BINANG_ROT180(func_800DFCDC(GET_ACTIVE_CAM(globalCtx))); - Math_Vec3f_Copy(&sp4C, &D_801D15B0); + Math_Vec3f_Copy(&sp4C, &gZeroVec3f); sp4C.z = 40.0f; Lib_Vec3f_TranslateAndRotateY(&this->actor.world.pos, sp3E, &sp4C, &sp40); func_80A85620(this->unk_394, &sp40, 2.0f, 0.08f, 60.0f); diff --git a/src/overlays/actors/ovl_En_Wf/z_en_wf.c b/src/overlays/actors/ovl_En_Wf/z_en_wf.c index fac66b679a..931d283e47 100644 --- a/src/overlays/actors/ovl_En_Wf/z_en_wf.c +++ b/src/overlays/actors/ovl_En_Wf/z_en_wf.c @@ -508,7 +508,7 @@ void func_80990C6C(EnWf* this, GlobalContext* globalCtx, s32 arg2) { sp88.x = randPlusMinusPoint5Scaled(50.0f) + this->actor.world.pos.x; sp88.y = Rand_ZeroFloat(5.0f) + this->actor.world.pos.y; sp88.z = randPlusMinusPoint5Scaled(50.0f) + this->actor.world.pos.z; - func_800B0F18(globalCtx, &sp88, &D_801D15B0, &D_809942DC, phi_s1, phi_s1, phi_s6, 5, + func_800B0F18(globalCtx, &sp88, &gZeroVec3f, &D_809942DC, phi_s1, phi_s1, phi_s6, 5, Rand_ZeroFloat(5.0f) + 14.0f); } } diff --git a/src/overlays/actors/ovl_Obj_Aqua/z_obj_aqua.c b/src/overlays/actors/ovl_Obj_Aqua/z_obj_aqua.c index 098d0503ea..acef9d1ab6 100644 --- a/src/overlays/actors/ovl_Obj_Aqua/z_obj_aqua.c +++ b/src/overlays/actors/ovl_Obj_Aqua/z_obj_aqua.c @@ -114,7 +114,7 @@ void func_80ACB940(ObjAqua* this, GlobalContext* globalCtx) { effectPos.x = this->actor.world.pos.x + (effectVel.x * 40.0f); effectPos.y = this->actor.world.pos.y; effectPos.z = this->actor.world.pos.z + (effectVel.z * 40.0f); - EffectSsIceSmoke_Spawn(globalCtx, &effectPos, &effectVel, &D_801D15B0, (s32)(Rand_ZeroOne() * 24.0f) + 70); + EffectSsIceSmoke_Spawn(globalCtx, &effectPos, &effectVel, &gZeroVec3f, (s32)(Rand_ZeroOne() * 24.0f) + 70); } void func_80ACBA10(ObjAqua* this) { diff --git a/src/overlays/actors/ovl_Obj_HsStump/z_obj_hsstump.c b/src/overlays/actors/ovl_Obj_HsStump/z_obj_hsstump.c index cca1b99224..d7001bed0f 100644 --- a/src/overlays/actors/ovl_Obj_HsStump/z_obj_hsstump.c +++ b/src/overlays/actors/ovl_Obj_HsStump/z_obj_hsstump.c @@ -116,7 +116,7 @@ void ObjHsStump_Appear(ObjHsStump* this, GlobalContext* globalCtx) { offsetAngle = i * angleBinary; Lib_Vec3f_TranslateAndRotateY(&this->dyna.actor.world.pos, offsetAngle, &iceSmokePosOffset, &iceSmokePos); - Lib_Vec3f_TranslateAndRotateY(&D_801D15B0, offsetAngle, &iceSmokeVelOffset, &iceSmokeVel); + Lib_Vec3f_TranslateAndRotateY(&gZeroVec3f, offsetAngle, &iceSmokeVelOffset, &iceSmokeVel); EffectSsIceSmoke_Spawn(globalCtx, &iceSmokePos, &iceSmokeVel, &iceSmokeAccel, 100); } } diff --git a/src/overlays/actors/ovl_Obj_Iceblock/z_obj_iceblock.c b/src/overlays/actors/ovl_Obj_Iceblock/z_obj_iceblock.c index 5589d1d265..f623ca4f88 100644 --- a/src/overlays/actors/ovl_Obj_Iceblock/z_obj_iceblock.c +++ b/src/overlays/actors/ovl_Obj_Iceblock/z_obj_iceblock.c @@ -751,7 +751,7 @@ void func_80A24DD0(ObjIceblock* this, GlobalContext* globalCtx) { spA8.z += this->dyna.actor.world.pos.z; temp_f20 = ((Rand_ZeroOne() * 800.0f) + (1600.0f * this->dyna.actor.scale.x)) * phi_f22; - func_800B0E48(globalCtx, &spA8, &D_801D15B0, &D_80A26F90, &D_80A26F9C, &D_80A26FA0, temp_f20, + func_800B0E48(globalCtx, &spA8, &gZeroVec3f, &D_80A26F90, &D_80A26F9C, &D_80A26FA0, temp_f20, (Rand_ZeroOne() * 20.0f) + 30.0f); } } @@ -786,7 +786,7 @@ void func_80A2508C(ObjIceblock* this, GlobalContext* globalCtx) { sp34.z = (this->dyna.actor.scale.z * sp34.z) + this->dyna.actor.world.pos.z; if ((this->unk_244 - 3.0f) < sp34.y) { - EffectSsIceSmoke_Spawn(globalCtx, &sp34, &sp40, &D_801D15B0, + EffectSsIceSmoke_Spawn(globalCtx, &sp34, &sp40, &gZeroVec3f, (s32)(this->dyna.actor.scale.y * 1300.0f) + 60); } } diff --git a/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.c b/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.c index 35c81daa91..eab5d8f1cf 100644 --- a/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.c +++ b/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.c @@ -145,7 +145,7 @@ void ObjLightswitch_SpawnEffects(ObjLightswitch* this, GlobalContext* globalCtx) effectPos.y = this->actor.world.pos.y + tempResultDiff + 10.0f; effectPos.z = this->actor.world.pos.z + ((rand * cosResult) - (tempResult * sinResult)); - EffectSsDeadDb_Spawn(globalCtx, &effectPos, &D_801D15B0, &D_801D15B0, &sLightswitchEffectPrimColor, + EffectSsDeadDb_Spawn(globalCtx, &effectPos, &gZeroVec3f, &gZeroVec3f, &sLightswitchEffectPrimColor, &sLightswitchEffectEnvColor, 100, 0, 9); } } diff --git a/src/overlays/actors/ovl_Obj_Tokei_Step/z_obj_tokei_step.c b/src/overlays/actors/ovl_Obj_Tokei_Step/z_obj_tokei_step.c index 6f81b7d809..f7710909f6 100644 --- a/src/overlays/actors/ovl_Obj_Tokei_Step/z_obj_tokei_step.c +++ b/src/overlays/actors/ovl_Obj_Tokei_Step/z_obj_tokei_step.c @@ -85,7 +85,7 @@ void ObjTokeiStep_SpawnDust(ObjTokeiStep* this, ObjTokeiStepPanel* panel, Global dustSpawnPos.x += panel->pos.x; dustSpawnPos.y += panel->pos.y; dustSpawnPos.z += panel->pos.z; - func_800B1210(globalCtx, &dustSpawnPos, &D_801D15B0, &sDustEffectAccel, (s32)((Rand_ZeroOne() * 40.0f) + 80.0f), + func_800B1210(globalCtx, &dustSpawnPos, &gZeroVec3f, &sDustEffectAccel, (s32)((Rand_ZeroOne() * 40.0f) + 80.0f), (s32)((Rand_ZeroOne() * 20.0f) + 50.0f)); } } diff --git a/tools/actorfixer.py b/tools/actorfixer.py index eb78c31462..89d7364eae 100755 --- a/tools/actorfixer.py +++ b/tools/actorfixer.py @@ -345,6 +345,11 @@ animdict = { "globalCtx->mf_187FC" : "globalCtx->billboardMtxF", "globalCtx->projectionMatrix" : "globalCtx->viewProjectionMtxF", + + "D_801D15B0" : "gZeroVec3f", + "D_801D15BC" : "gZeroVec3s", + "D_801D1DE0" : "gIdentityMtx", + "D_801D1E20" : "gIdentityMtxF", } def replace_anim(file): diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index d83f43e4ce..2ac78bf859 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -4991,8 +4991,8 @@ 0x80869D90:("EnPametfrog_Init",), 0x80869F90:("EnPametfrog_Destroy",), 0x80869FBC:("EnPametfrog_Vec3fNormalize",), - 0x8086A024:("EnPametfrog_ChangeColliderFreeze",), - 0x8086A068:("EnPametfrog_ChangeColliderThaw",), + 0x8086A024:("EnPametfrog_Freeze",), + 0x8086A068:("EnPametfrog_Thaw",), 0x8086A0F4:("EnPametfrog_JumpWaterEffects",), 0x8086A1A0:("EnPametfrog_IdleWaterEffects",), 0x8086A238:("func_8086A238",), @@ -6671,7 +6671,7 @@ 0x808EC990:("func_808EC990",), 0x808ECD14:("func_808ECD14",), 0x808ED07C:("func_808ED07C",), - 0x808ED138:("EnBigslime_Draw",), + 0x808ED138:("EnBigslime_DrawGekko",), 0x808ED3F4:("func_808ED3F4",), 0x808F1200:("EnKarebaba_Init",), 0x808F1334:("EnKarebaba_Destroy",), diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index 4a870b7907..44d1683d4f 100644 --- a/tools/disasm/variables.txt +++ b/tools/disasm/variables.txt @@ -2245,11 +2245,11 @@ 0x801D1538:("D_801D1538","UNK_TYPE4","",0x4), 0x801D1540:("D_801D1540","UNK_PTR","",0x4), 0x801D1570:("D_801D1570","f32","[13]",0x34), - 0x801D15B0:("D_801D15B0","Vec3f","",0xC), - 0x801D15BC:("D_801D15BC","UNK_TYPE4","",0x4), + 0x801D15B0:("gZeroVec3f","Vec3f","",0xC), + 0x801D15BC:("gZeroVec3s","Vec3s","",0x6), 0x801D15D0:("sATan2Tbl","s16","[1025]",0x802), - 0x801D1DE0:("D_801D1DE0","Mtx","",0x40), - 0x801D1E20:("D_801D1E20","MtxF","",0x40), + 0x801D1DE0:("gIdentityMtx","Mtx","",0x40), + 0x801D1E20:("gIdentityMtxF","MtxF","",0x40), 0x801D1E60:("initialgspUcodeText","UNK_PTR","",0x4), 0x801D1E64:("initialgspUcodeData","UNK_PTR","",0x4), 0x801D1E70:("D_801D1E70","UNK_TYPE1","",0x1), diff --git a/undefined_syms.txt b/undefined_syms.txt index c4d3e52a63..cb1d8903a2 100644 --- a/undefined_syms.txt +++ b/undefined_syms.txt @@ -1660,37 +1660,6 @@ D_06004210 = 0x06004210; D_06007C70 = 0x06007C70; D_0600823C = 0x0600823C; -// ovl_En_Bigslime - -D_060010F4 = 0x060010F4; -D_06001B08 = 0x06001B08; -D_0600276C = 0x0600276C; -D_06002E0C = 0x06002E0C; -D_0600347C = 0x0600347C; -D_060039C4 = 0x060039C4; -D_06003F28 = 0x06003F28; -D_060066B4 = 0x060066B4; -D_060069FC = 0x060069FC; -D_060070C4 = 0x060070C4; -D_06007790 = 0x06007790; -D_0600DF98 = 0x0600DF98; -D_0600F048 = 0x0600F048; -D_0600F3F0 = 0x0600F3F0; -D_0600F990 = 0x0600F990; -D_0600F9D0 = 0x0600F9D0; -D_0600FB40 = 0x0600FB40; -D_06010530 = 0x06010530; -D_060105E8 = 0x060105E8; -D_06010B80 = 0x06010B80; -D_06010C48 = 0x06010C48; -D_06010DB0 = 0x06010DB0; -D_06010EC8 = 0x06010EC8; -D_06010F20 = 0x06010F20; -D_06010FE0 = 0x06010FE0; -D_06011008 = 0x06011008; -D_06011050 = 0x06011050; -D_060113B0 = 0x060113B0; - // ovl_En_Bji_01 D_0600066C = 0x0600066C; @@ -3228,30 +3197,6 @@ D_06006EE8 = 0x06006EE8; D_060072E8 = 0x060072E8; D_060073E8 = 0x060073E8; -// ovl_En_Pametfrog - -D_06000994 = 0x06000994; -D_06001B08 = 0x06001B08; -D_06001E14 = 0x06001E14; -D_06001F20 = 0x06001F20; -D_060030E4 = 0x060030E4; -D_0600347C = 0x0600347C; -D_060039C4 = 0x060039C4; -D_06003F28 = 0x06003F28; -D_06004298 = 0x06004298; -D_06004680 = 0x06004680; -D_06004894 = 0x06004894; -D_06004D50 = 0x06004D50; -D_060050B8 = 0x060050B8; -D_060052EC = 0x060052EC; -D_06005694 = 0x06005694; -D_06005D54 = 0x06005D54; -D_060066B4 = 0x060066B4; -D_060070C4 = 0x060070C4; -D_0600DF98 = 0x0600DF98; -D_0600F048 = 0x0600F048; -D_0600F990 = 0x0600F990; - // ovl_En_Paper D_0600D5A0 = 0x0600D5A0; @@ -3832,27 +3777,8 @@ D_0600FEF0 = 0x0600FEF0; // ovl_En_Tru -D_06001F90 = 0x06001F90; -D_060020C8 = 0x060020C8; -D_06002BD8 = 0x06002BD8; -D_06003698 = 0x06003698; -D_0600446C = 0x0600446C; -D_06007FA0 = 0x06007FA0; -D_06009348 = 0x06009348; -D_0600EEDC = 0x0600EEDC; -D_0600F9A0 = 0x0600F9A0; -D_060108AC = 0x060108AC; -D_06011F88 = 0x06011F88; -D_06014728 = 0x06014728; -D_06015CA0 = 0x06015CA0; -D_06016B4C = 0x06016B4C; -D_06018FA0 = 0x06018FA0; -D_060197A0 = 0x060197A0; -D_06019FA0 = 0x06019FA0; D_0601A820 = 0x0601A820; D_0601A830 = 0x0601A830; -D_0601AA60 = 0x0601AA60; -D_0601B5C4 = 0x0601B5C4; // ovl_En_Tru_Mt