diff --git a/include/functions.h b/include/functions.h index 605a41ed35..4af08dd4f6 100644 --- a/include/functions.h +++ b/include/functions.h @@ -2817,7 +2817,7 @@ void func_801434E4(GameState* gamestate, SkyboxContext* skyboxCtx, s16 skyType); // void func_80143624(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE1 param_5, UNK_TYPE1 param_6, UNK_TYPE1 param_7); // void func_80143668(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6, UNK_TYPE4 param_7); // void func_80143A04(void); -// void func_80143A10(void); +void func_80143A10(u8 owlId); // void func_80143A54(void); // void func_80143AC4(void); void func_80143B0C(GlobalContext* globalCtx); diff --git a/include/z64.h b/include/z64.h index a3715a2748..6f80cfdb8c 100644 --- a/include/z64.h +++ b/include/z64.h @@ -956,7 +956,10 @@ typedef struct { /* 0x1207C */ s32 bankRupees; /* 0x12080 */ UNK_TYPE1 pad12080[0x31]; /* 0x120B1 */ u8 unk120B1; - /* 0x120B2 */ UNK_TYPE1 pad120B2[0x2E]; + /* 0x120B2 */ UNK_TYPE1 pad120B2[0x22]; + /* 0x120D4 */ UNK_TYPE2 unk120D4; + /* 0x120D6 */ UNK_TYPE2 unk120D6; + /* 0x120D8 */ UNK_TYPE1 pad120D8[0x8]; } MessageContext; // size = 0x120E0 typedef struct ActorBgMbarChair ActorBgMbarChair; diff --git a/include/z64save.h b/include/z64save.h index c25bd8b0e2..b59381d329 100644 --- a/include/z64save.h +++ b/include/z64save.h @@ -73,7 +73,7 @@ typedef struct { /* 0x0042 */ u8 doubleDefense; // "life_ability" /* 0x0043 */ u8 unk_43; // "ocarina_round" /* 0x0044 */ u8 unk_44; // "first_memory" - /* 0x0046 */ u16 unk_46; // "memory_warp_point" + /* 0x0046 */ u16 owlsHit; // "memory_warp_point" /* 0x0048 */ u8 unk_48; // "last_warp_pt" /* 0x004A */ s16 savedSceneNum; // "scene_data_ID" /* 0x004C */ ItemEquips equips; diff --git a/spec b/spec index cffbfa67e3..97af0e7f5a 100644 --- a/spec +++ b/spec @@ -4490,7 +4490,6 @@ beginseg name "ovl_Obj_Warpstone" compress include "build/src/overlays/actors/ovl_Obj_Warpstone/z_obj_warpstone.o" - include "build/data/ovl_Obj_Warpstone/ovl_Obj_Warpstone.data.o" include "build/data/ovl_Obj_Warpstone/ovl_Obj_Warpstone.reloc.o" endseg diff --git a/src/overlays/actors/ovl_Obj_Warpstone/z_obj_warpstone.c b/src/overlays/actors/ovl_Obj_Warpstone/z_obj_warpstone.c index cc0c25b632..712addcaf3 100644 --- a/src/overlays/actors/ovl_Obj_Warpstone/z_obj_warpstone.c +++ b/src/overlays/actors/ovl_Obj_Warpstone/z_obj_warpstone.c @@ -8,14 +8,16 @@ void ObjWarpstone_Init(Actor* thisx, GlobalContext* globalCtx); void ObjWarpstone_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjWarpstone_Update(Actor* thisx, GlobalContext* globalCtx); void ObjWarpstone_Draw(Actor* thisx, GlobalContext* globalCtx); - -void func_80B92C00(ObjWarpstone* this, GlobalContext* globalCtx); -void func_80B92CD0(ObjWarpstone* this, GlobalContext* globalCtx); -void func_80B92DC4(ObjWarpstone* this, GlobalContext* globalCtx); - void ObjWarpstone_SetupAction(ObjWarpstone* this, ObjWarpstoneActionFunc actionFunc); +s32 ObjWarpstone_ClosedIdle(ObjWarpstone* this, GlobalContext* globalCtx); +s32 ObjWarpstone_BeginOpeningCutscene(ObjWarpstone* this, GlobalContext* globalCtx); +s32 ObjWarpstone_PlayOpeningCutscene(ObjWarpstone* this, GlobalContext* globalCtx); +s32 ObjWarpstone_OpenedIdle(ObjWarpstone* this, GlobalContext* globalCtx); + +extern Gfx D_04023210[]; // gOwlStatueWhiteFlashDL +extern Gfx D_060001D0[]; // gOwlStatueClosedDL +extern Gfx D_06003770[]; // gOwlStatueOpenedDL -#if 0 const ActorInit Obj_Warpstone_InitVars = { ACTOR_OBJ_WARPSTONE, ACTORCAT_ITEMACTION, @@ -28,37 +30,157 @@ const ActorInit Obj_Warpstone_InitVars = { (ActorFunc)ObjWarpstone_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80B93220 = { - { COLTYPE_METAL, AT_NONE, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_2, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK2, { 0x00100000, 0x00, 0x00 }, { 0x01000202, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_HOOKABLE, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_METAL, + AT_NONE, + AC_ON | AC_HARD | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK2, + { 0x00100000, 0x00, 0x00 }, + { 0x01000202, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_HOOKABLE, + OCELEM_ON, + }, { 20, 60, 0, { 0, 0, 0 } }, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80B9324C[] = { +static InitChainEntry sInitChain[] = { ICHAIN_U8(targetMode, 1, ICHAIN_STOP), }; -#endif +static Gfx* sOwlStatueDLs[] = { D_060001D0, D_06003770 }; -extern ColliderCylinderInit D_80B93220; -extern InitChainEntry D_80B9324C[]; +void ObjWarpstone_SetupAction(ObjWarpstone* this, ObjWarpstoneActionFunc actionFunc) { + this->actionFunc = actionFunc; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Warpstone/ObjWarpstone_SetupAction.s") +void ObjWarpstone_Init(Actor* thisx, GlobalContext* globalCtx) { + ObjWarpstone* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Warpstone/ObjWarpstone_Init.s") + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->dyna.actor, &sCylinderInit); + Actor_SetHeight(&this->dyna.actor, 40.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Warpstone/ObjWarpstone_Destroy.s") + if (!IS_OWL_HIT(GET_OWL_ID(this))) { + ObjWarpstone_SetupAction(this, ObjWarpstone_ClosedIdle); + } else { + ObjWarpstone_SetupAction(this, ObjWarpstone_OpenedIdle); + this->modelIndex = SEK_MODEL_OPENED; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Warpstone/func_80B92C00.s") +void ObjWarpstone_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ObjWarpstone* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Warpstone/func_80B92C48.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Warpstone/func_80B92CD0.s") +s32 ObjWarpstone_ClosedIdle(ObjWarpstone* this, GlobalContext* globalCtx) { + if (this->collider.base.acFlags & AC_HIT) { + ObjWarpstone_SetupAction(this, ObjWarpstone_BeginOpeningCutscene); + return true; + } else { + /*Ye who hold the sacred sword, leave proof of our encounter.*/ + this->dyna.actor.textId = 0xC00; + return false; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Warpstone/func_80B92DC4.s") +s32 ObjWarpstone_BeginOpeningCutscene(ObjWarpstone* this, GlobalContext* globalCtx) { + if (this->dyna.actor.cutscene < 0 || ActorCutscene_GetCanPlayNext(this->dyna.actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->dyna.actor.cutscene, &this->dyna.actor); + ObjWarpstone_SetupAction(this, ObjWarpstone_PlayOpeningCutscene); + Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_OWL_WARP_SWITCH_ON); + } else { + ActorCutscene_SetIntentToPlay(this->dyna.actor.cutscene); + } + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Warpstone/ObjWarpstone_Update.s") +s32 ObjWarpstone_PlayOpeningCutscene(ObjWarpstone* this, GlobalContext* globalCtx) { + if (this->openingCSTimer++ >= OBJ_WARPSTONE_TIMER_ACTIVATE_THRESHOLD) { + ActorCutscene_Stop(this->dyna.actor.cutscene); + func_80143A10(GET_OWL_ID(this)); + ObjWarpstone_SetupAction(this, ObjWarpstone_OpenedIdle); + } else if (this->openingCSTimer < OBJ_WARPSTONE_TIMER_OPEN_THRESHOLD) { + Math_StepToF(&this->dyna.actor.velocity.x, 0.01f, 0.001f); + Math_StepToS(&this->dyna.actor.home.rot.x, 0xFF, 0x12); + } else { + Math_StepToF(&this->dyna.actor.velocity.x, 20.0f, 0.01f); + if (this->dyna.actor.velocity.x > 0.2f) { + this->modelIndex = SEK_MODEL_OPENED; + Math_StepToS(&this->dyna.actor.home.rot.x, 0, 0x14); + } + } + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Warpstone/ObjWarpstone_Draw.s") +s32 ObjWarpstone_OpenedIdle(ObjWarpstone* this, GlobalContext* globalCtx) { + /*You can save your progress and quit here.*/ + this->dyna.actor.textId = 0xC01; + return false; +} + +void ObjWarpstone_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjWarpstone* this = THIS; + s32 pad; + + if (this->isTalking) { + if (func_800B867C(&this->dyna.actor, globalCtx) != 0) { + this->isTalking = false; + } else if ((func_80152498(&globalCtx->msgCtx) == 4) && (func_80147624(globalCtx))) { + if (globalCtx->msgCtx.choiceIndex != 0) { + func_8019F208(); + globalCtx->msgCtx.unk11F22 = 0x4D; + globalCtx->msgCtx.unk120D6 = 0; + globalCtx->msgCtx.unk120D4 = 0; + gSaveContext.owlSaveLocation = GET_OWL_ID(this); + } else { + func_801477B4(globalCtx); + } + } + } else if (func_800B84D0(&this->dyna.actor, globalCtx)) { + this->isTalking = true; + } else if (!this->actionFunc(this, globalCtx)) { + func_800B863C(&this->dyna.actor, globalCtx); + } + Collider_ResetCylinderAC(globalCtx, &this->collider.base); + Collider_UpdateCylinder(&this->dyna.actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); +} + +void ObjWarpstone_Draw(Actor* thisx, GlobalContext* globalCtx2) { + ObjWarpstone* this = THIS; + GlobalContext* globalCtx = globalCtx2; + + func_800BDFC0(globalCtx, sOwlStatueDLs[this->modelIndex]); + if (this->dyna.actor.home.rot.x != 0) { + OPEN_DISPS(globalCtx->state.gfxCtx); + func_8012C2DC(globalCtx->state.gfxCtx); + SysMatrix_InsertTranslation(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y + 34.0f, + this->dyna.actor.world.pos.z, MTXMODE_NEW); + SysMatrix_InsertMatrix(&globalCtx->mf_187FC, MTXMODE_APPLY); + SysMatrix_InsertTranslation(0.0f, 0.0f, 30.0f, MTXMODE_APPLY); + Matrix_Scale(this->dyna.actor.velocity.x, this->dyna.actor.velocity.x, this->dyna.actor.velocity.x, + MTXMODE_APPLY); + SysMatrix_StatePush(); + gDPPipeSync(POLY_XLU_DISP++); + gDPSetPrimColor(POLY_XLU_DISP++, 128, 128, 255, 255, 200, this->dyna.actor.home.rot.x); + gDPSetEnvColor(POLY_XLU_DISP++, 100, 200, 0, 255); + SysMatrix_InsertZRotation_f((((globalCtx->gameplayFrames * 1500) & 0xFFFF) * M_PI) / 0x8000, MTXMODE_APPLY); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, D_04023210); + SysMatrix_StatePop(); + SysMatrix_InsertZRotation_f((~((globalCtx->gameplayFrames * 1200) & 0xFFFF) * M_PI) / 0x8000, MTXMODE_APPLY); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, D_04023210); + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} diff --git a/src/overlays/actors/ovl_Obj_Warpstone/z_obj_warpstone.h b/src/overlays/actors/ovl_Obj_Warpstone/z_obj_warpstone.h index 5562534741..e2c3937b20 100644 --- a/src/overlays/actors/ovl_Obj_Warpstone/z_obj_warpstone.h +++ b/src/overlays/actors/ovl_Obj_Warpstone/z_obj_warpstone.h @@ -5,14 +5,30 @@ struct ObjWarpstone; -typedef void (*ObjWarpstoneActionFunc)(struct ObjWarpstone* this, GlobalContext* globalCtx); +typedef s32 (*ObjWarpstoneActionFunc)(struct ObjWarpstone* this, GlobalContext* globalCtx); + +typedef enum { + /* 0 */ SEK_MODEL_CLOSED, + /* 1 */ SEK_MODEL_OPENED +} ObjectSekModels; + +typedef enum { + /* 25 */ OBJ_WARPSTONE_TIMER_OPEN_THRESHOLD = 25, + /* 66 */ OBJ_WARPSTONE_TIMER_ACTIVATE_THRESHOLD = 66 +} ObjWarpstoneTimerCutoffs; typedef struct ObjWarpstone { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x68]; - /* 0x01AC */ ObjWarpstoneActionFunc actionFunc; + /* 0x000 */ DynaPolyActor dyna; + /* 0x15C */ ColliderCylinder collider; + /* 0x1A8 */ u8 isTalking; + /* 0x1A9 */ u8 openingCSTimer; + /* 0x1AA */ u8 modelIndex; + /* 0x1AC */ ObjWarpstoneActionFunc actionFunc; } ObjWarpstone; // size = 0x1B0 extern const ActorInit Obj_Warpstone_InitVars; +#define GET_OWL_ID(this) ((u16)(this->dyna.actor.params & 0xF)) +#define IS_OWL_HIT(owlId) (((void)0,gSaveContext.owlsHit) & (u16)gBitFlags[owlId]) + #endif // Z_OBJ_WARPSTONE_H diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index 1e10b20bc4..3971bbeac4 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -14840,10 +14840,10 @@ 0x80B92B10:("ObjWarpstone_SetupAction",), 0x80B92B1C:("ObjWarpstone_Init",), 0x80B92BD4:("ObjWarpstone_Destroy",), - 0x80B92C00:("func_80B92C00",), - 0x80B92C48:("func_80B92C48",), - 0x80B92CD0:("func_80B92CD0",), - 0x80B92DC4:("func_80B92DC4",), + 0x80B92C00:("ObjWarpstone_ClosedIdle",), + 0x80B92C48:("ObjWarpstone_BeginOpeningCutscene",), + 0x80B92CD0:("ObjWarpstone_PlayOpeningCutscene",), + 0x80B92DC4:("ObjWarpstone_OpenedIdle",), 0x80B92DDC:("ObjWarpstone_Update",), 0x80B92F40:("ObjWarpstone_Draw",), 0x80B93310:("func_80B93310",),