diff --git a/include/functions.h b/include/functions.h index 26de0794d0..3f22bd67b7 100644 --- a/include/functions.h +++ b/include/functions.h @@ -975,7 +975,7 @@ s32 DynaPolyActor_IsInRidingMovingState(DynaPolyActor* dynaActor); s32 DynaPolyActor_IsInRidingRotatingState(DynaPolyActor* dynaActor); s32 DynaPolyActor_IsInSwitchPressedState(DynaPolyActor* dynaActor); s32 DynaPolyActor_IsInHeavySwitchPressedState(DynaPolyActor* dynaActor); -s32 DynaPolyActor_ValidateMove(GlobalContext* globalCtx, DynaPolyActor* dynaActor, s16 arg2, s16 arg3, s16 arg4); +s32 DynaPolyActor_ValidateMove(GlobalContext* globalCtx, DynaPolyActor* dynaActor, s16 startRadius, s16 endRadius, s16 startHeight); f32 Camera_fabsf(f32 f); f32 Camera_LengthVec3f(Vec3f* v); // void func_800CB270(void); diff --git a/spec b/spec index 64b949c120..7a8a21569b 100644 --- a/spec +++ b/spec @@ -2236,8 +2236,7 @@ beginseg name "ovl_Obj_Pzlblock" compress include "build/src/overlays/actors/ovl_Obj_Pzlblock/z_obj_pzlblock.o" - include "build/data/ovl_Obj_Pzlblock/ovl_Obj_Pzlblock.data.o" - include "build/data/ovl_Obj_Pzlblock/ovl_Obj_Pzlblock.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Pzlblock/ovl_Obj_Pzlblock_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_Obj_Pzlblock/z_obj_pzlblock.c b/src/overlays/actors/ovl_Obj_Pzlblock/z_obj_pzlblock.c index d6f35c491e..95b9a3a13d 100644 --- a/src/overlays/actors/ovl_Obj_Pzlblock/z_obj_pzlblock.c +++ b/src/overlays/actors/ovl_Obj_Pzlblock/z_obj_pzlblock.c @@ -5,6 +5,8 @@ */ #include "z_obj_pzlblock.h" +#include "objects/gameplay_dangeon_keep/gameplay_dangeon_keep.h" +#include "objects/object_secom_obj/object_secom_obj.h" #define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_4000000) @@ -14,7 +16,15 @@ void ObjPzlblock_Init(Actor* thisx, GlobalContext* globalCtx); void ObjPzlblock_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjPzlblock_Update(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_809A3A48(ObjPzlblock* this); +void func_809A3A74(ObjPzlblock* this, GlobalContext* globalCtx); +void func_809A3BA4(ObjPzlblock* this); +void func_809A3BC0(ObjPzlblock* this, GlobalContext* globalCtx); +void func_809A3D1C(ObjPzlblock* this); +void func_809A3D38(ObjPzlblock* this, GlobalContext* globalCtx); +void func_809A3E58(Actor* thisx, GlobalContext* globalCtx); +void func_809A3F0C(Actor* thisx, GlobalContext* globalCtx); + const ActorInit Obj_Pzlblock_InitVars = { ACTOR_OBJ_PZLBLOCK, ACTORCAT_PROP, @@ -27,46 +37,337 @@ const ActorInit Obj_Pzlblock_InitVars = { (ActorFunc)NULL, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_809A4078[] = { +s16 D_809A4050[] = { 1, -1, 0, 0 }; +s16 D_809A4058[] = { 0, 0, 1, -1 }; + +typedef struct { + /* 0x0 */ s16 unk_00; + /* 0x4 */ CollisionHeader* unk_04; + /* 0x8 */ Gfx* unk_08; +} ObjPzlblockStruct; + +ObjPzlblockStruct D_809A4060[] = { + { GAMEPLAY_DANGEON_KEEP, &gameplay_dangeon_keep_Colheader_01D488, gameplay_dangeon_keep_DL_01C228 }, + { OBJECT_SECOM_OBJ, &object_secom_obj_Colheader_002CB8, object_secom_obj_DL_001A58 }, +}; + +static InitChainEntry sInitChain[] = { ICHAIN_VEC3S(world.rot, 0, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 100, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 200, ICHAIN_STOP), }; -#endif +Color_RGB8 D_809A4088[] = { + { 180, 150, 250 }, { 100, 180, 150 }, { 0, 0, 255 }, { 255, 255, 0 }, + { 0, 255, 255 }, { 255, 0, 255 }, { 0, 0, 0 }, { 255, 255, 255 }, +}; -extern InitChainEntry D_809A4078[]; +s32 func_809A33E0(ObjPzlblock* this, GlobalContext* globalCtx, s16 arg2) { + return !DynaPolyActor_ValidateMove(globalCtx, &this->dyna, 30, arg2, 1) || + !DynaPolyActor_ValidateMove(globalCtx, &this->dyna, 30, arg2, 28); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Pzlblock/func_809A33E0.s") +s32 func_809A3448(ObjPzlblock* this) { + s16 temp_v0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Pzlblock/func_809A3448.s") + if (fabsf(this->dyna.pushForce) > 0.1f) { + temp_v0 = BINANG_ADD(this->dyna.yRotation, 0x2000); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Pzlblock/func_809A34E0.s") + if (this->dyna.pushForce < 0.0f) { + temp_v0 = BINANG_ROT180(temp_v0); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Pzlblock/func_809A35EC.s") + if (temp_v0 < -0x4000) { + return 3; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Pzlblock/func_809A376C.s") + if (temp_v0 < 0) { + return 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Pzlblock/ObjPzlblock_Init.s") + if (temp_v0 < 0x4000) { + return 2; + } + return 0; + } + return -1; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Pzlblock/ObjPzlblock_Destroy.s") +s32 func_809A34E0(ObjPzlblock* this, s32 arg1) { + s32 temp_v0 = OBJPZLBLOCK_GET_ROTZ(&this->dyna.actor); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Pzlblock/func_809A3A48.s") + if (temp_v0 == 0) { + return arg1 == 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Pzlblock/func_809A3A74.s") + if (temp_v0 == 1) { + return arg1 == 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Pzlblock/func_809A3BA4.s") + if (temp_v0 == 2) { + return arg1 == 2; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Pzlblock/func_809A3BC0.s") + if (temp_v0 == 3) { + return arg1 == 3; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Pzlblock/func_809A3D1C.s") + if (temp_v0 == 4) { + return arg1 == 0 || arg1 == 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Pzlblock/func_809A3D38.s") + if (temp_v0 == 5) { + return arg1 == 2 || arg1 == 3; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Pzlblock/ObjPzlblock_Update.s") + if (temp_v0 == 6) { + if (this->unk_176 != 0) { + return arg1 == 0 || arg1 == 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Pzlblock/func_809A3E58.s") + if (this->unk_178 != 0) { + return arg1 == 2 || arg1 == 3; + } + return true; + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Pzlblock/func_809A3F0C.s") +s32 func_809A35EC(ObjPzlblock* this, s32 arg1) { + s32 temp_v0 = OBJPZLBLOCK_GET_ROTZ(&this->dyna.actor); + s32 temp_v1 = this->dyna.actor.home.rot.x & 0xF; + s32 temp; + + if (temp_v0 == 0) { + return this->unk_176 < temp_v1; + } + + if (temp_v0 == 1) { + return -temp_v1 < this->unk_176; + } + + if (temp_v0 == 2) { + return this->unk_178 < temp_v1; + } + + if (temp_v0 == 3) { + return -temp_v1 < this->unk_178; + } + + if (temp_v0 == 4) { + temp = D_809A4050[arg1] + this->unk_176; + return (temp_v1 >= temp) && (-temp_v1 <= temp); + } + + if (temp_v0 == 5) { + temp = D_809A4058[arg1] + this->unk_178; + return (temp_v1 >= temp) && (-temp_v1 <= temp); + } + + if (temp_v0 == 6) { + if ((arg1 == 0) || (arg1 == 1)) { + temp = D_809A4050[arg1] + this->unk_176; + return (temp_v1 >= temp) && (-temp_v1 <= temp); + } + + temp = D_809A4058[arg1] + this->unk_178; + return (temp_v1 >= temp) && (-temp_v1 <= temp); + } + + return false; +} + +void func_809A376C(ObjPzlblock* this, s32 arg1) { + this->unk_176 += D_809A4050[arg1]; + this->unk_178 += D_809A4058[arg1]; + if ((arg1 == 0) || (arg1 == 1)) { + this->unk_164 = &this->dyna.actor.world.pos.x; + this->unk_168 = this->dyna.actor.home.pos.x + (this->unk_176 * 60); + } else { + this->unk_164 = &this->dyna.actor.world.pos.z; + this->unk_168 = this->dyna.actor.home.pos.z + (this->unk_178 * 60); + } + this->unk_16C = arg1; +} + +void ObjPzlblock_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ObjPzlblock* this = THIS; + s32 sp2C = OBJPZLBLOCK_GET_ROTZ(&this->dyna.actor); + s32 sp28 = this->dyna.actor.home.rot.x & 0xF; + ObjPzlblockStruct* sp24 = &D_809A4060[OBJPZLBLOCK_GET_1000(&this->dyna.actor)]; + + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); + Actor_SetScale(&this->dyna.actor, 0.1f); + + this->dyna.actor.home.rot.y = 0; + this->dyna.actor.shape.rot.x = 0; + this->dyna.actor.shape.rot.z = 0; + + DynaPolyActor_Init(&this->dyna, 0); + + this->unk_17A = Object_GetIndex(&globalCtx->objectCtx, sp24->unk_00); + + if (sp28 == 0) { + func_809A3D1C(this); + } else if (Flags_GetSwitch(globalCtx, OBJPZLBLOCK_GET_7F(&this->dyna.actor))) { + if (sp2C == 0) { + this->dyna.actor.world.pos.x = this->dyna.actor.home.pos.x + (sp28 * 60); + func_809A3D1C(this); + } else if (sp2C == 1) { + this->dyna.actor.world.pos.x = this->dyna.actor.home.pos.x - (sp28 * 60); + func_809A3D1C(this); + } else if (sp2C == 2) { + this->dyna.actor.world.pos.z = this->dyna.actor.home.pos.z + (sp28 * 60); + func_809A3D1C(this); + } else if (sp2C == 3) { + this->dyna.actor.world.pos.z = this->dyna.actor.home.pos.z - (sp28 * 60); + func_809A3D1C(this); + } else { + func_809A3A48(this); + } + } else { + func_809A3A48(this); + } +} + +void ObjPzlblock_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ObjPzlblock* this = THIS; + + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); +} + +void func_809A3A48(ObjPzlblock* this) { + this->actionFunc = func_809A3A74; + this->unk_16E[1] = 0; + this->unk_16E[2] = 0; + this->unk_16E[3] = 0; + this->unk_16E[0] = 0; + this->unk_160 = 4; +} + +void func_809A3A74(ObjPzlblock* this, GlobalContext* globalCtx) { + s32 i; + s32 sp20 = func_809A3448(this); + + for (i = 0; i < ARRAY_COUNT(this->unk_16E); i++) { + if (sp20 == i) { + this->unk_16E[i]++; + } else if (this->unk_16E[i] > 0) { + this->unk_16E[i]--; + } + } + + if (sp20 != -1) { + if ((this->unk_16E[sp20] >= 11) && func_809A34E0(this, sp20) && func_809A35EC(this, sp20)) { + if (!func_809A33E0(this, globalCtx, (this->dyna.pushForce > 0.0f) ? 90 : 120)) { + func_809A376C(this, sp20); + func_809A3BA4(this); + return; + } + } + + GET_PLAYER(globalCtx)->stateFlags2 &= ~0x10; + this->dyna.pushForce = 0.0f; + } +} + +void func_809A3BA4(ObjPzlblock* this) { + this->actionFunc = func_809A3BC0; + this->unk_160 = 5; +} + +void func_809A3BC0(ObjPzlblock* this, GlobalContext* globalCtx) { + if (Math_StepToF(this->unk_164, this->unk_168, 2.3f)) { + Player* player = GET_PLAYER(globalCtx); + s32 params = OBJPZLBLOCK_GET_ROTZ(&this->dyna.actor); + s32 pad; + s32 sp20 = 0; + + if ((params == 4) || (params == 5) || (params == 6)) { + if (!func_809A35EC(this, this->unk_16C) || func_809A33E0(this, globalCtx, 0x5A)) { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_BLOCK_BOUND); + } + } else if (func_809A35EC(this, this->unk_16C)) { + if (func_809A33E0(this, globalCtx, 0x5A)) { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_BLOCK_BOUND); + } + } else { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_BLOCK_BOUND); + Flags_SetSwitch(globalCtx, OBJPZLBLOCK_GET_7F(&this->dyna.actor)); + sp20 = 1; + } + + player->stateFlags2 &= ~0x10; + this->dyna.pushForce = 0.0f; + if (sp20 == 0) { + func_809A3A48(this); + } else { + func_809A3D1C(this); + } + } else { + func_800B9010(&this->dyna.actor, NA_SE_EV_ROCK_SLIDE - SFX_FLAG); + } +} + +void func_809A3D1C(ObjPzlblock* this) { + this->actionFunc = func_809A3D38; + this->unk_160 = 4; +} + +void func_809A3D38(ObjPzlblock* this, GlobalContext* globalCtx) { + if (fabsf(this->dyna.pushForce) > 0.1f) { + GET_PLAYER(globalCtx)->stateFlags2 &= ~0x10; + this->dyna.pushForce = 0.0f; + } +} + +void ObjPzlblock_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ObjPzlblock* this = THIS; + + this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y; + Actor_UpdateBgCheckInfo(globalCtx, &this->dyna.actor, 15.0f, 30.0f, 0.0f, 4); + + if (Object_IsLoaded(&globalCtx->objectCtx, this->unk_17A)) { + ObjPzlblockStruct* sp2C = &D_809A4060[OBJPZLBLOCK_GET_1000(&this->dyna.actor)]; + + this->dyna.actor.objBankIndex = this->unk_17A; + Actor_SetObjectDependency(globalCtx, &this->dyna.actor); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, sp2C->unk_04); + this->dyna.actor.update = func_809A3E58; + this->dyna.actor.draw = func_809A3F0C; + } +} + +void func_809A3E58(Actor* thisx, GlobalContext* globalCtx) { + ObjPzlblock* this = THIS; + + this->actionFunc(this, globalCtx); + + this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y; + + if (this->unk_160 != 0) { + Actor_UpdateBgCheckInfo(globalCtx, &this->dyna.actor, 15.0f, 30.0f, 0.0f, this->unk_160); + if (((this->actionFunc == func_809A3A74) || (this->actionFunc == func_809A3D38)) && + (this->dyna.actor.bgCheckFlags & 1) && !DynaPoly_GetActor(&globalCtx->colCtx, this->dyna.actor.floorBgId)) { + this->unk_160 = 0; + } + } +} + +void func_809A3F0C(Actor* thisx, GlobalContext* globalCtx) { + ObjPzlblockStruct* sp2C = &D_809A4060[OBJPZLBLOCK_GET_1000(thisx)]; + Color_RGB8* sp28 = &D_809A4088[OBJPZLBLOCK_GET_700(thisx)]; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, sp28->r, sp28->g, sp28->b, 255); + gSPDisplayList(POLY_OPA_DISP++, sp2C->unk_08); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Obj_Pzlblock/z_obj_pzlblock.h b/src/overlays/actors/ovl_Obj_Pzlblock/z_obj_pzlblock.h index 437583f621..fa1ca1f59f 100644 --- a/src/overlays/actors/ovl_Obj_Pzlblock/z_obj_pzlblock.h +++ b/src/overlays/actors/ovl_Obj_Pzlblock/z_obj_pzlblock.h @@ -5,9 +5,24 @@ struct ObjPzlblock; +typedef void (*ObjPzlblockActionFunc)(struct ObjPzlblock*, GlobalContext*); + +#define OBJPZLBLOCK_GET_7F(thisx) ((thisx)->params & 0x7F) +#define OBJPZLBLOCK_GET_700(thisx) (((thisx)->params >> 8) & 7) +#define OBJPZLBLOCK_GET_1000(thisx) (((thisx)->params >> 0xC) & 1) +#define OBJPZLBLOCK_GET_ROTZ(thisx) ((thisx)->home.rot.z & 7) + typedef struct ObjPzlblock { - /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x38]; + /* 0x000 */ DynaPolyActor dyna; + /* 0x15C */ ObjPzlblockActionFunc actionFunc; + /* 0x160 */ s32 unk_160; + /* 0x164 */ f32* unk_164; + /* 0x168 */ f32 unk_168; + /* 0x16C */ s16 unk_16C; + /* 0x16E */ s16 unk_16E[4]; + /* 0x176 */ s16 unk_176; + /* 0x178 */ s16 unk_178; + /* 0x17A */ s8 unk_17A; } ObjPzlblock; // size = 0x17C extern const ActorInit Obj_Pzlblock_InitVars;