diff --git a/spec b/spec index 8328eaa435..958bb80f96 100644 --- a/spec +++ b/spec @@ -4187,8 +4187,7 @@ beginseg name "ovl_Bg_Ikana_Block" compress include "build/src/overlays/actors/ovl_Bg_Ikana_Block/z_bg_ikana_block.o" - include "build/data/ovl_Bg_Ikana_Block/ovl_Bg_Ikana_Block.data.o" - include "build/data/ovl_Bg_Ikana_Block/ovl_Bg_Ikana_Block.reloc.o" + include "build/src/overlays/actors/ovl_Bg_Ikana_Block/ovl_Bg_Ikana_Block_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_Bg_Ikana_Block/z_bg_ikana_block.c b/src/overlays/actors/ovl_Bg_Ikana_Block/z_bg_ikana_block.c index 9d2fd67d90..f693022785 100644 --- a/src/overlays/actors/ovl_Bg_Ikana_Block/z_bg_ikana_block.c +++ b/src/overlays/actors/ovl_Bg_Ikana_Block/z_bg_ikana_block.c @@ -5,6 +5,7 @@ */ #include "z_bg_ikana_block.h" +#include "objects/gameplay_dangeon_keep/gameplay_dangeon_keep.h" #define FLAGS (ACTOR_FLAG_10) @@ -14,12 +15,16 @@ void BgIkanaBlock_Init(Actor* thisx, GlobalContext* globalCtx); void BgIkanaBlock_Destroy(Actor* thisx, GlobalContext* globalCtx); void BgIkanaBlock_Update(Actor* thisx, GlobalContext* globalCtx); +void func_80B7F00C(BgIkanaBlock* this); void func_80B7F034(BgIkanaBlock* this, GlobalContext* globalCtx); +void func_80B7F0A4(BgIkanaBlock* this); void func_80B7F0D0(BgIkanaBlock* this, GlobalContext* globalCtx); +void func_80B7F1A8(BgIkanaBlock* this); void func_80B7F290(BgIkanaBlock* this, GlobalContext* globalCtx); +void func_80B7F360(BgIkanaBlock* this); void func_80B7F398(BgIkanaBlock* this, GlobalContext* globalCtx); +void func_80B7F564(Actor* thisx, GlobalContext* globalCtx); -#if 0 const ActorInit Bg_Ikana_Block_InitVars = { ACTOR_BG_IKANA_BLOCK, ACTORCAT_BG, @@ -32,58 +37,350 @@ const ActorInit Bg_Ikana_Block_InitVars = { (ActorFunc)NULL, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80B7F640[] = { +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 250, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 250, ICHAIN_CONTINUE), ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP), }; -#endif +void func_80B7EA60(BgIkanaBlock* this) { + s32 phi_v0; -extern InitChainEntry D_80B7F640[]; + this->unk_17A &= ~(0x8 | 0x4 | 0x2 | 0x1); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/func_80B7EA60.s") + if (fabsf(this->dyna.pushForce) > 0.1f) { + if (this->dyna.pushForce > 0.0f) { + phi_v0 = this->dyna.yRotation; + } else { + phi_v0 = BINANG_ROT180(this->dyna.yRotation); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/func_80B7EB30.s") + if ((phi_v0 < -0x6000) || (phi_v0 >= 0x6000)) { + this->unk_17A |= 8; + } else if (phi_v0 < -0x2000) { + this->unk_17A |= 2; + } else if (phi_v0 < 0x2000) { + this->unk_17A |= 4; + } else { + this->unk_17A |= 1; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/func_80B7EB64.s") +void func_80B7EB30(BgIkanaBlock* this) { + if (this->unk_17A & (0x8 | 0x4 | 0x2 | 0x1)) { + if (this->unk_17B < 127) { + this->unk_17B++; + } + } else { + this->unk_17B = 0; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/func_80B7EB7C.s") +s32 func_80B7EB64(BgIkanaBlock* this, GlobalContext* globalCtx) { + return !(this->unk_17C & 8); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/func_80B7EB94.s") +s32 func_80B7EB7C(BgIkanaBlock* this, GlobalContext* globalCtx) { + return this->unk_17B > 10; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/func_80B7ECFC.s") +s32 func_80B7EB94(BgIkanaBlock* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f sp70; + Vec3f sp64; + Vec3f sp58; + CollisionPoly* sp54; + s32 sp50; + s32 sp4C = false; + s16 phi_a0; + f32 phi_f12; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/func_80B7ED54.s") + if (this->dyna.pushForce > 0.0f) { + sp4C = true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/func_80B7EDC4.s") + if (sp4C) { + phi_a0 = this->dyna.yRotation; + } else { + phi_a0 = BINANG_ROT180(this->dyna.yRotation); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/func_80B7EE70.s") + sp70.x = this->dyna.actor.world.pos.x; + sp70.y = this->dyna.actor.world.pos.y + this->unk_170 + 2.0f; + sp70.z = this->dyna.actor.world.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/func_80B7EEB4.s") + Matrix_RotateY(phi_a0, MTXMODE_NEW); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/BgIkanaBlock_Init.s") + if (sp4C) { + phi_f12 = 89.0f; + } else { + phi_f12 = 119.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/BgIkanaBlock_Destroy.s") + Matrix_GetStateTranslationAndScaledZ(phi_f12, &sp64); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/func_80B7F00C.s") + sp64.x += this->dyna.actor.world.pos.x; + sp64.y += this->dyna.actor.world.pos.y + this->unk_170 + 2.0f; + sp64.z += this->dyna.actor.world.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/func_80B7F034.s") + return !BgCheck_EntityLineTest3(&globalCtx->colCtx, &sp70, &sp64, &sp58, &sp54, true, false, false, true, &sp50, + &this->dyna.actor, 0.0f); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/func_80B7F0A4.s") +s32 func_80B7ECFC(BgIkanaBlock* this, GlobalContext* globalCtx) { + return func_80B7EB64(this, globalCtx) && func_80B7EB7C(this, globalCtx) && func_80B7EB94(this, globalCtx); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/func_80B7F0D0.s") +void func_80B7ED54(BgIkanaBlock* this) { + s32 pad; + Vec3f sp18; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/func_80B7F1A8.s") + Matrix_RotateY(this->dyna.actor.shape.rot.y, MTXMODE_NEW); + Matrix_InsertXRotation_s(this->dyna.actor.shape.rot.x, MTXMODE_APPLY); + Matrix_InsertZRotation_s(this->dyna.actor.shape.rot.z, MTXMODE_APPLY); + Matrix_GetStateTranslationAndScaledY(30.0f, &sp18); + this->unk_170 = sp18.y - 30.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/func_80B7F290.s") +s32 func_80B7EDC4(BgIkanaBlock* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f sp30; + s32 sp2C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/func_80B7F360.s") + sp30.x = this->dyna.actor.world.pos.x; + sp30.y = this->dyna.actor.world.pos.y + this->unk_170 + 40.0f; + sp30.z = this->dyna.actor.world.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/func_80B7F398.s") + this->dyna.actor.floorHeight = BgCheck_EntityRaycastFloor5_2( + globalCtx, &globalCtx->colCtx, &this->dyna.actor.floorPoly, &sp2C, &this->dyna.actor, &sp30); + this->dyna.actor.floorBgId = sp2C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/BgIkanaBlock_Update.s") + return ((this->dyna.actor.world.pos.y + this->unk_170) - this->dyna.actor.floorHeight) < 2.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/func_80B7F564.s") +s32 func_80B7EE70(BgIkanaBlock* this, GlobalContext* globalCtx) { + if (func_80B7EDC4(this, globalCtx)) { + this->dyna.actor.world.pos.y = this->dyna.actor.floorHeight - this->unk_170; + return true; + } + return false; +} + +s32 func_80B7EEB4(BgIkanaBlock* this, GlobalContext* globalCtx) { + func_80B7EDC4(this, globalCtx); + + if (this->dyna.actor.floorHeight > (BGCHECK_Y_MIN + 1.0f)) { + if (DynaPoly_GetActor(&globalCtx->colCtx, this->dyna.actor.floorBgId)) { + this->dyna.actor.world.pos.y = this->dyna.actor.floorHeight - this->unk_170; + return true; + } + } + return false; +} + +void BgIkanaBlock_Init(Actor* thisx, GlobalContext* globalCtx) { + BgIkanaBlock* this = THIS; + + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); + DynaPolyActor_Init(&this->dyna, 1); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &gameplay_dangeon_keep_Colheader_007498); + func_800C62BC(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + this->unk_15C = Lib_SegmentedToVirtual(gameplay_dangeon_keep_Matanimheader_01B370); + this->unk_174 = this->dyna.actor.shape.rot; + func_80B7ED54(this); + func_80B7F00C(this); +} + +void BgIkanaBlock_Destroy(Actor* thisx, GlobalContext* globalCtx) { + BgIkanaBlock* this = THIS; + + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); +} + +void func_80B7F00C(BgIkanaBlock* this) { + this->unk_17C &= ~7; + this->unk_17D = 40; + this->actionFunc = func_80B7F034; +} + +void func_80B7F034(BgIkanaBlock* this, GlobalContext* globalCtx) { + if (this->unk_17D > 0) { + this->unk_17D--; + } + + if (func_80B7EEB4(this, globalCtx)) { + func_800C6314(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + this->dyna.actor.draw = func_80B7F564; + func_80B7F0A4(this); + } +} + +void func_80B7F0A4(BgIkanaBlock* this) { + this->unk_17B = 0; + this->unk_17C &= ~7; + this->unk_17C |= 1; + this->actionFunc = func_80B7F0D0; +} + +void func_80B7F0D0(BgIkanaBlock* this, GlobalContext* globalCtx) { + s32 sp24 = 0; + s32 phi_v1; + + func_80B7EA60(this); + func_80B7EB30(this); + + if (this->unk_17C & 4) { + sp24 = 1; + } else if (func_80B7ECFC(this, globalCtx)) { + sp24 = 2; + } + + if ((sp24 != 2) && (this->unk_17A & (0x8 | 0x4 | 0x2 | 0x1))) { + Player* player = GET_PLAYER(globalCtx); + + player->stateFlags2 &= ~0x10; + this->dyna.pushForce = 0.0f; + } + + if (sp24 == 1) { + func_80B7F360(this); + } else if (sp24 == 2) { + func_80B7F1A8(this); + } +} + +void func_80B7F1A8(BgIkanaBlock* this) { + f32 temp_f0; + f32* phi_v0; + s32 phi_v0_2; + + if (this->unk_17A & (0x2 | 0x1)) { + this->unk_164 = &this->dyna.actor.world.pos.x; + phi_v0 = &this->dyna.actor.home.pos.x; + } else { + this->unk_164 = &this->dyna.actor.world.pos.z; + phi_v0 = &this->dyna.actor.home.pos.z; + } + + temp_f0 = (*this->unk_164 - *phi_v0) * 0.016666668f; + + if (temp_f0 >= 0.0f) { + temp_f0 += 0.5f; + } else { + temp_f0 -= 0.5f; + } + + if (this->unk_17A & (0x4 | 0x1)) { + phi_v0_2 = 1; + } else { + phi_v0_2 = -1; + } + + this->unk_168 = *phi_v0 + (((s32)temp_f0 + phi_v0_2) * 60.0f); + this->unk_16C = 0.0f; + this->unk_17C &= ~7; + this->unk_17C |= 2; + this->actionFunc = func_80B7F290; +} + +void func_80B7F290(BgIkanaBlock* this, GlobalContext* globalCtx) { + s32 pad; + + Math_StepToF(&this->unk_16C, 2.0f, 0.4f); + + if (Math_StepToF(this->unk_164, this->unk_168, this->unk_16C)) { + Player* player = GET_PLAYER(globalCtx); + + if (!func_80B7EB94(this, globalCtx)) { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_BLOCK_BOUND); + } + + player->stateFlags2 &= ~0x10; + this->dyna.pushForce = 0.0f; + + if (func_80B7EDC4(this, globalCtx)) { + func_80B7F0A4(this); + } else { + func_80B7F360(this); + } + } else { + func_800B9010(&this->dyna.actor, NA_SE_EV_ROCK_SLIDE - SFX_FLAG); + } +} + +void func_80B7F360(BgIkanaBlock* this) { + this->unk_17C &= ~7; + this->unk_17C |= 4; + this->unk_17D = 1; + this->dyna.actor.velocity.y = 0.0f; + this->actionFunc = func_80B7F398; +} + +void func_80B7F398(BgIkanaBlock* this, GlobalContext* globalCtx) { + if (this->unk_17D > 0) { + this->unk_17D--; + return; + } + + this->dyna.actor.velocity.y -= 2.0f; + this->dyna.actor.velocity.y *= 0.95f; + + if (this->dyna.actor.velocity.y < -30.0f) { + this->dyna.actor.velocity.y = -30.0f; + } + + this->dyna.actor.world.pos.y += this->dyna.actor.velocity.y; + + if (func_80B7EE70(this, globalCtx)) { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_BLOCK_BOUND); + Actor_PlaySfxAtPos( + &this->dyna.actor, + SurfaceType_GetSfx(&globalCtx->colCtx, this->dyna.actor.floorPoly, this->dyna.actor.floorBgId) + SFX_FLAG); + func_80B7F0A4(this); + } +} + +void BgIkanaBlock_Update(Actor* thisx, GlobalContext* globalCtx) { + BgIkanaBlock* this = THIS; + + if ((this->dyna.actor.shape.rot.x != this->unk_174.x) || (this->dyna.actor.shape.rot.y != this->unk_174.y) || + (this->dyna.actor.shape.rot.z != this->unk_174.z)) { + this->unk_174 = this->dyna.actor.shape.rot; + func_80B7ED54(this); + } + + this->actionFunc(this, globalCtx); + + Actor_SetFocus(&this->dyna.actor, 30.0f); + + if (this->unk_17E != 0) { + if (this->unk_17F > 0) { + this->unk_17F--; + ActorCutscene_Stop(this->dyna.actor.cutscene); + this->unk_17E = 0; + } else if (ActorCutscene_GetCanPlayNext(this->dyna.actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->dyna.actor.cutscene, &this->dyna.actor); + this->unk_17F = 30; + } else { + ActorCutscene_SetIntentToPlay(this->dyna.actor.cutscene); + } + } +} + +void func_80B7F564(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + BgIkanaBlock* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + AnimatedMat_DrawStep(globalCtx, this->unk_15C, 0); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(POLY_OPA_DISP++, 0xFF, 0xFF, 255, 255, 255, 255); + gSPDisplayList(POLY_OPA_DISP++, gameplay_dangeon_keep_DL_0182A8); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Bg_Ikana_Block/z_bg_ikana_block.h b/src/overlays/actors/ovl_Bg_Ikana_Block/z_bg_ikana_block.h index 112e4ad008..3ad797cbab 100644 --- a/src/overlays/actors/ovl_Bg_Ikana_Block/z_bg_ikana_block.h +++ b/src/overlays/actors/ovl_Bg_Ikana_Block/z_bg_ikana_block.h @@ -8,15 +8,20 @@ struct BgIkanaBlock; typedef void (*BgIkanaBlockActionFunc)(struct BgIkanaBlock*, GlobalContext*); typedef struct BgIkanaBlock { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x1C]; + /* 0x0000 */ DynaPolyActor dyna; + /* 0x015C */ AnimatedMaterial* unk_15C; /* 0x0160 */ BgIkanaBlockActionFunc actionFunc; - /* 0x0164 */ char unk_164[0xC]; + /* 0x0164 */ f32* unk_164; + /* 0x0168 */ f32 unk_168; + /* 0x016C */ f32 unk_16C; /* 0x0170 */ f32 unk_170; - /* 0x0174 */ char unk_174[0x8]; + /* 0x0174 */ Vec3s unk_174; + /* 0x017A */ u8 unk_17A; + /* 0x017B */ s8 unk_17B; /* 0x017C */ u8 unk_17C; - /* 0x017D */ char unk_17D[0x1]; - /* 0x017E */ u8 unk_17E; + /* 0x017D */ s8 unk_17D; + /* 0x017E */ s8 unk_17E; + /* 0x017F */ s8 unk_17F; } BgIkanaBlock; // size = 0x180 extern const ActorInit Bg_Ikana_Block_InitVars; diff --git a/src/overlays/actors/ovl_Bg_Ikana_Rotaryroom/z_bg_ikana_rotaryroom.c b/src/overlays/actors/ovl_Bg_Ikana_Rotaryroom/z_bg_ikana_rotaryroom.c index a3b234392b..944ab5828d 100644 --- a/src/overlays/actors/ovl_Bg_Ikana_Rotaryroom/z_bg_ikana_rotaryroom.c +++ b/src/overlays/actors/ovl_Bg_Ikana_Rotaryroom/z_bg_ikana_rotaryroom.c @@ -400,10 +400,10 @@ void func_80B80C88(BgIkanaRotaryroom* this, GlobalContext* globalCtx) { Matrix_StatePush(); Matrix_InsertMatrix(&this->unk_204.unk_04, MTXMODE_APPLY); - Matrix_GetStateTranslation(&ikanaBlock->actor.world.pos); - func_80B80358(&ikanaBlock->actor.world.pos); + Matrix_GetStateTranslation(&ikanaBlock->dyna.actor.world.pos); + func_80B80358(&ikanaBlock->dyna.actor.world.pos); Matrix_CopyCurrentState(&sp3C); - func_8018219C(&sp3C, &ikanaBlock->actor.shape.rot, 0); + func_8018219C(&sp3C, &ikanaBlock->dyna.actor.shape.rot, 0); Matrix_StatePop(); } @@ -473,20 +473,21 @@ void func_80B80C88(BgIkanaRotaryroom* this, GlobalContext* globalCtx) { s32 func_80B80F08(BgIkanaRotaryroom* this, GlobalContext* globalCtx) { s32 pad; - BgIkanaBlock* sp40 = (BgIkanaBlock*)this->unk_204.unk_00; + BgIkanaBlock* ikanaBlock = (BgIkanaBlock*)this->unk_204.unk_00; Vec3f sp34; Vec3f sp28; s32 sp24 = false; - if (sp40 != NULL) { + if (ikanaBlock != NULL) { Matrix_StatePush(); Matrix_SetStateRotationAndTranslation(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, this->dyna.actor.world.pos.z, &this->dyna.actor.shape.rot); Matrix_InsertTranslation(D_80B82178.x, D_80B82178.y, D_80B82178.z, MTXMODE_APPLY); Matrix_GetStateTranslation(&sp34); - Matrix_SetStateRotationAndTranslation(sp40->actor.world.pos.x, sp40->actor.world.pos.y + sp40->unk_170, - sp40->actor.world.pos.z, &sp40->actor.shape.rot); + Matrix_SetStateRotationAndTranslation(ikanaBlock->dyna.actor.world.pos.x, + ikanaBlock->dyna.actor.world.pos.y + ikanaBlock->unk_170, + ikanaBlock->dyna.actor.world.pos.z, &ikanaBlock->dyna.actor.shape.rot); Matrix_GetStateTranslation(&sp28); Matrix_StatePop();