From 6e4d156ad788f4add678481d38f6cfa5f35e33e2 Mon Sep 17 00:00:00 2001 From: Rozelette Date: Sat, 27 Mar 2021 11:17:42 -0500 Subject: [PATCH] Door_Spiral OK (from zel) (#87) * Door_Spiral OK * Cleanup --- include/functions.h | 4 +- include/segment.h | 3 + include/z64.h | 22 +- include/z64actor.h | 8 +- linker_scripts/code_script.txt | 4 +- linker_scripts/object_script.txt | 18 + src/code/z_scene.c | 2 +- .../actors/ovl_Door_Spiral/z_door_spiral.c | 325 +++++++++++++++++- .../actors/ovl_Door_Spiral/z_door_spiral.h | 11 +- .../actors/ovl_En_Po_Fusen/z_en_po_fusen.c | 21 +- .../actors/ovl_En_Po_Fusen/z_en_po_fusen.h | 3 - 11 files changed, 374 insertions(+), 47 deletions(-) diff --git a/include/functions.h b/include/functions.h index ee99370452..eec09c7f77 100644 --- a/include/functions.h +++ b/include/functions.h @@ -1946,7 +1946,7 @@ void func_80104CF4(GlobalContext* ctxt); // void func_8010534C(void); void func_8010549C(GlobalContext* ctxt, void* segmentAddress); void func_8010565C(GlobalContext* ctxt, u8 num, void* segmentAddress); -void func_80105818(GlobalContext* ctxt, u32 uParm2, TransitionActorInit* puParm3); +void func_80105818(GlobalContext* ctxt, u32 uParm2, TransitionActorEntry* puParm3); // void func_80105A40(void); // void func_80105B34(void); // void func_80105C40(void); @@ -2203,7 +2203,7 @@ void func_801229A0(GlobalContext* globalCtx, ActorPlayer* player); // void func_80122D44(void); // void func_80122ED8(void); // void func_80122EEC(void); -// void func_80122F28(void); +void func_80122F28(ActorPlayer* player, GlobalContext* globalCtx, Actor* actor); // void func_80122F9C(void); // void func_80122FCC(void); // void func_8012300C(void); diff --git a/include/segment.h b/include/segment.h index 81738e9c59..b8b987f4a3 100644 --- a/include/segment.h +++ b/include/segment.h @@ -27,4 +27,7 @@ extern UNK_PTR D_04062060[]; extern UNK_PTR D_04062000[]; extern Gfx D_040622C0[]; +extern Gfx D_0501D980[]; +extern Gfx D_050219E0[]; + #endif diff --git a/include/z64.h b/include/z64.h index 2a7fef08c1..ccbd0c5248 100644 --- a/include/z64.h +++ b/include/z64.h @@ -404,17 +404,15 @@ typedef struct { } TitleCardContext; // size = 0x10 typedef struct { - /* 0x0 */ s8 unk0; - /* 0x1 */ UNK_TYPE1 pad1[0x1]; - /* 0x2 */ s8 unk2; - /* 0x3 */ UNK_TYPE1 pad3[0x1]; - /* 0x4 */ s16 actorIndex; // negative means already loaded? - /* 0x6 */ s16 x; - /* 0x8 */ s16 y; - /* 0xA */ s16 z; - /* 0xC */ s16 yRot; // lower 7 bits contain cutscene number - /* 0xE */ u16 variable; -} TransitionActorInit; // size = 0x10 + struct { + s8 room; // Room to switch to + s8 effects; // How the camera reacts during the transition + } /* 0x00 */ sides[2]; // 0 = front, 1 = back + /* 0x04 */ s16 id; + /* 0x06 */ Vec3s pos; + /* 0x0C */ s16 rotY; + /* 0x0E */ s16 params; +} TransitionActorEntry; // size = 0x10 typedef struct { /* 0x0 */ s32 topY; @@ -1630,7 +1628,7 @@ struct GlobalContext { /* 0x186E0 */ RoomContext roomContext; /* 0x18760 */ u8 transitionActorCount; /* 0x18761 */ UNK_TYPE1 pad18761[0x3]; - /* 0x18764 */ TransitionActorInit* transitionActorList; + /* 0x18764 */ TransitionActorEntry* transitionActorList; /* 0x18768 */ UNK_TYPE1 pad18768[0x48]; /* 0x187B0 */ z_Matrix unk187B0; /* 0x187F0 */ UNK_TYPE1 pad187F0[0xC]; diff --git a/include/z64actor.h b/include/z64actor.h index 1f97ac8b81..34520966a7 100644 --- a/include/z64actor.h +++ b/include/z64actor.h @@ -226,7 +226,13 @@ typedef struct { /* 0x34C */ Actor* heldActor; /* 0x350 */ UNK_TYPE1 pad350[0x18]; /* 0x368 */ Vec3f unk368; - /* 0x374 */ UNK_TYPE1 pad374[0x20]; + /* 0x374 */ UNK_TYPE1 pad374[0x8]; + /* 0x37C */ s8 doorType; + /* 0x37D */ s8 doorDirection; + /* 0x37E */ s8 doorTimer; + /* 0x37F */ s8 unk37F; + /* 0x380 */ Actor* doorActor; + /* 0x384 */ UNK_TYPE1 unk384[0x10]; /* 0x394 */ u8 unk394; /* 0x395 */ UNK_TYPE1 pad395[0x37]; /* 0x3CC */ s16 unk3CC; diff --git a/linker_scripts/code_script.txt b/linker_scripts/code_script.txt index d9c4e61c3e..71fa3a5229 100644 --- a/linker_scripts/code_script.txt +++ b/linker_scripts/code_script.txt @@ -3472,9 +3472,9 @@ SECTIONS ovl_Door_Spiral : AT(RomLocation) { build/src/overlays/actors/ovl_Door_Spiral/z_door_spiral.o(.text) - build/asm/overlays/ovl_Door_Spiral_data.o(.data) + build/src/overlays/actors/ovl_Door_Spiral/z_door_spiral.o(.data) build/src/overlays/actors/ovl_Door_Spiral/z_door_spiral.o(.rodata) - build/asm/overlays/ovl_Door_Spiral_rodata.o(.rodata) + build/src/overlays/actors/ovl_Door_Spiral/z_door_spiral_overlay.o(.ovl) } SegmentEnd = .; SegmentSize = SegmentEnd - SegmentStart; diff --git a/linker_scripts/object_script.txt b/linker_scripts/object_script.txt index 8569e1c93d..2a33b657f9 100644 --- a/linker_scripts/object_script.txt +++ b/linker_scripts/object_script.txt @@ -11,6 +11,9 @@ D_04062060 = 0x04062060; D_04062000 = 0x04062000; D_040622C0 = 0x040622C0; +D_0501D980 = 0x0501D980; +D_050219E0 = 0x050219E0; + object_ikana_obj_001100 = 0x06001100; object_ikana_obj_001228 = 0x06001228; @@ -101,3 +104,18 @@ D_060024F0 = 0x060024F0; /* bg_ikana_shutter */ D_06000F28 = 0x06000F28; D_06000CE8 = 0x06000CE8; + +/* door_spiral */ +/* these are symbols from other objects based on the type of door */ +D_06000590 = 0x06000590; +D_060007A8 = 0x060007A8; +D_06000EA0 = 0x06000EA0; +D_060012C0 = 0x060012C0; +D_060014C8 = 0x060014C8; +D_06002110 = 0x06002110; +D_06004448 = 0x06004448; +D_060051B8 = 0x060051B8; +D_06006128 = 0x06006128; +D_06009278 = 0x06009278; +D_06012B70 = 0x06012B70; +D_06013EA8 = 0x06013EA8; diff --git a/src/code/z_scene.c b/src/code/z_scene.c index 86de5dd848..5dc227d25b 100644 --- a/src/code/z_scene.c +++ b/src/code/z_scene.c @@ -323,7 +323,7 @@ void Scene_HeaderCommand0D(GlobalContext* ctxt, SceneCmd* entry) { // Scene Command 0x0E: Transition Actor List void Scene_HeaderCommand0E(GlobalContext* ctxt, SceneCmd* entry) { ctxt->transitionActorCount = entry->transiActorList.num; - ctxt->transitionActorList = (TransitionActorInit*)Lib_PtrSegToVirt((void*)entry->transiActorList.segment); + ctxt->transitionActorList = (TransitionActorEntry*)Lib_PtrSegToVirt((void*)entry->transiActorList.segment); func_80105818(ctxt, ctxt->transitionActorCount, ctxt->transitionActorList); } diff --git a/src/overlays/actors/ovl_Door_Spiral/z_door_spiral.c b/src/overlays/actors/ovl_Door_Spiral/z_door_spiral.c index 6955aadddd..7cce06c1fe 100644 --- a/src/overlays/actors/ovl_Door_Spiral/z_door_spiral.c +++ b/src/overlays/actors/ovl_Door_Spiral/z_door_spiral.c @@ -2,14 +2,61 @@ #define FLAGS 0x00000010 -#define THIS ((DoorSpiral*)thisx) +#define GET_ORIENTATION_PARAM(this) ((((Actor*)(this))->params >> 7) & 0x1) +#define GET_UNK145_PARAM(this) ((((Actor*)(this))->params >> 8) & 0x3) +#define GET_TRANSITION_ID_PARAM(this) ((u16)((Actor*)(this))->params >> 10) + +typedef enum { + /* 0 */ SPIRAL_OVERWORLD, // does not display anything as there is not a DL in GAMEPLAY_KEEP for it + /* 1 */ SPIRAL_DUNGEON, + /* 2 */ SPIRAL_WOODFALL_TEMPLE, + /* 3 */ SPIRAL_WOODFALL_TEMPLE_ALT, // SPIRAL_WOODFALL_TEMPLE but with positional lights enabled? + /* 4 */ SPIRAL_SNOWHEAD_TEMPLE, + /* 5 */ SPIRAL_STONE_TOWER, + /* 6 */ SPIRAL_IKANA_CASTLE, + /* 7 */ SPIRAL_DAMPES_HOUSE +} SpiralType; + +typedef enum { + /* 0 */ SPIRAL_OBJECT_OVERWORLD, + /* 1 */ SPIRAL_OBJECT_DUNGEON, + /* 2 */ SPIRAL_OBJECT_WOODFALL, + /* 3 */ SPIRAL_OBJECT_SNOWHEAD, + /* 4 */ SPIRAL_OBJECT_STONE_TOWER, + /* 5 */ SPIRAL_OBJECT_DAMPES_HOUSE, + /* 6 */ SPIRAL_OBJECT_IKANA_CASTLE +} SpiralObjectType; + +typedef struct { + /* 0x00 */ Gfx* spiralDL[2]; // one displaylist for downward spiral, and one for upward + /* 0x08 */ s32 unk8; // unused + /* 0x0C */ u8 unkC; // unused + /* 0x0D */ u8 unkD; // unused + /* 0x0E */ u8 spiralWidth; + /* 0x0F */ u8 spiralHeight; +} SpiralInfo; + +// Maps SpiralObjectType to SpiralType +typedef struct { + /* 0x00 */ s16 objectBankId; + /* 0x02 */ u8 spiralType; +} SpiralObjectInfo; + +// Maps scenes to SpiralObjectType +typedef struct { + /* 0x00 */ s16 sceneNum; + /* 0x02 */ u8 objectType; +} SpiralSceneInfo; void DoorSpiral_Init(Actor* thisx, GlobalContext* globalCtx); void DoorSpiral_Destroy(Actor* thisx, GlobalContext* globalCtx); void DoorSpiral_Update(Actor* thisx, GlobalContext* globalCtx); void DoorSpiral_Draw(Actor* thisx, GlobalContext* globalCtx); -/* +void DoorSpiral_WaitForObject(DoorSpiral* this, GlobalContext* globalCtx); +void DoorSpiral_Wait(DoorSpiral* this, GlobalContext* globalCtx); +void DoorSpiral_PlayerClimb(DoorSpiral* this, GlobalContext* globalCtx); + const ActorInit Door_Spiral_InitVars = { ACTOR_DOOR_SPIRAL, ACTORCAT_DOOR, @@ -19,30 +66,276 @@ const ActorInit Door_Spiral_InitVars = { (ActorFunc)DoorSpiral_Init, (ActorFunc)DoorSpiral_Destroy, (ActorFunc)DoorSpiral_Update, - (ActorFunc)DoorSpiral_Draw + (ActorFunc)DoorSpiral_Draw, }; -*/ -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Door_Spiral_0x809A2B60/func_809A2B60.asm") +extern Gfx D_06000590[]; +extern Gfx D_060007A8[]; +extern Gfx D_06000EA0[]; +extern Gfx D_060012C0[]; +extern Gfx D_060014C8[]; +extern Gfx D_06002110[]; +extern Gfx D_06004448[]; +extern Gfx D_060051B8[]; +extern Gfx D_06006128[]; +extern Gfx D_06009278[]; +extern Gfx D_06012B70[]; +extern Gfx D_06013EA8[]; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Door_Spiral_0x809A2B60/func_809A2B70.asm") +// Parameters for each staircase, indexed with SpiralType +static SpiralInfo sSpiralInfo[] = { + { { NULL, NULL }, 0, 130, 12, 50, 15 }, // SPIRAL_OVERWORLD + { { D_050219E0, D_0501D980 }, 0, 130, 12, 50, 15 }, // SPIRAL_DUNGEON + { { D_06004448, D_060007A8 }, 0, 130, 12, 50, 15 }, // SPIRAL_WOODFALL_TEMPLE + { { D_060051B8, D_060014C8 }, 0, 130, 12, 50, 15 }, // SPIRAL_WOODFALL_TEMPLE_ALT + { { D_06009278, D_06006128 }, 0, 130, 12, 50, 15 }, // SPIRAL_SNOWHEAD_TEMPLE + { { D_06013EA8, D_06012B70 }, 0, 130, 12, 50, 15 }, // SPIRAL_STONE_TOWER + { { D_06000EA0, D_06000590 }, 0, 130, 12, 50, 15 }, // SPIRAL_IKANA_CASTLE + { { D_06002110, D_060012C0 }, 0, 130, 12, 50, 15 }, // SPIRAL_DAMPES_HOUSE +}; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Door_Spiral_0x809A2B60/func_809A2BF8.asm") +// Defines which object bank a staircase should use, and its index to `sSpiralInfo` +static SpiralObjectInfo sSpiralObjectInfo[] = { + { GAMEPLAY_KEEP, SPIRAL_OVERWORLD }, + { GAMEPLAY_DANGEON_KEEP, SPIRAL_DUNGEON }, + { OBJECT_NUMA_OBJ, SPIRAL_WOODFALL_TEMPLE }, + { OBJECT_HAKUGIN_OBJ, SPIRAL_SNOWHEAD_TEMPLE }, + { OBJECT_IKANA_OBJ, SPIRAL_STONE_TOWER }, + { OBJECT_DANPEI_OBJECT, SPIRAL_DAMPES_HOUSE }, + { OBJECT_IKNINSIDE_OBJ, SPIRAL_IKANA_CASTLE }, +}; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Door_Spiral_0x809A2B60/DoorSpiral_Init.asm") +/** + * Sets the actor's action function + */ +void DoorSpiral_SetupAction(DoorSpiral* this, DoorSpiralActionFunc actionFunc) { + this->actionFunc = actionFunc; + this->unk14A = 0; // set but never used +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Door_Spiral_0x809A2B60/DoorSpiral_Destroy.asm") +/** + * Sets this->spiralType, which is derived from `sSpiralObjectInfo`, and is used as an index to `sSpiralInfo`. + */ +s32 DoorSpiral_SetSpiralType(DoorSpiral* this, GlobalContext* globalCtx) { + SpiralObjectInfo* doorObjectInfo = &sSpiralObjectInfo[this->objectType]; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Door_Spiral_0x809A2B60/func_809A2DB0.asm") + this->spiralType = doorObjectInfo->spiralType; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Door_Spiral_0x809A2B60/func_809A2E08.asm") + if ((this->spiralType == SPIRAL_DAMPES_HOUSE) || + ((this->spiralType == SPIRAL_WOODFALL_TEMPLE) && globalCtx->roomContext.currRoom.enablePosLights)) { + if (this->spiralType == SPIRAL_WOODFALL_TEMPLE) { + this->spiralType = SPIRAL_WOODFALL_TEMPLE_ALT; + } -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Door_Spiral_0x809A2B60/func_809A2EA0.asm") + this->actor.flags |= 0x10000000; + } -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Door_Spiral_0x809A2B60/func_809A2FF8.asm") + DoorSpiral_SetupAction(this, DoorSpiral_Wait); -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Door_Spiral_0x809A2B60/func_809A3098.asm") + return 0; +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Door_Spiral_0x809A2B60/DoorSpiral_Update.asm") +/** + * Gets the object type to be used as an index to `sSpiralObjectInfo`. + * It first checks `sSpiralSceneInfo`, but if the current scene is not found it will fall back to the default spiral (overworld or dungeon). + */ +s32 DoorSpiral_GetObjectType(GlobalContext* globalCtx) { + // Defines which object type should be used for specific scenes + static SpiralSceneInfo spiralSceneInfo[] = { + { SCENE_MITURIN, SPIRAL_OBJECT_WOODFALL }, + { SCENE_HAKUGIN, SPIRAL_OBJECT_SNOWHEAD }, + { SCENE_INISIE_N, SPIRAL_OBJECT_STONE_TOWER }, + { SCENE_INISIE_R, SPIRAL_OBJECT_STONE_TOWER }, + { SCENE_DANPEI2TEST, SPIRAL_OBJECT_DAMPES_HOUSE }, + { SCENE_IKNINSIDE, SPIRAL_OBJECT_IKANA_CASTLE }, + { SCENE_CASTLE, SPIRAL_OBJECT_IKANA_CASTLE }, + }; + SpiralSceneInfo* sceneInfo = spiralSceneInfo; + s32 i; + s32 type; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Door_Spiral_0x809A2B60/DoorSpiral_Draw.asm") + for (i = 0; i < ARRAY_COUNT(spiralSceneInfo); sceneInfo++, i++) { + if (globalCtx->sceneNum == sceneInfo->sceneNum) { + break; + } + } + + type = i; + + if (type < ARRAY_COUNT(spiralSceneInfo)) { + type = sceneInfo->objectType; + } else { + // Set the type based on if link is in a dungeon scene, or the overworld + type = (Scene_FindSceneObjectIndex(&globalCtx->sceneContext, GAMEPLAY_DANGEON_KEEP) >= 0) ? SPIRAL_OBJECT_DUNGEON : SPIRAL_OBJECT_OVERWORLD; + } + + return type; +} + +static InitChainEntry sInitChain[] = { + ICHAIN_VEC3F(scale, 1, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneScale, 400, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneDownward, 400, ICHAIN_STOP), +}; + +void DoorSpiral_Init(Actor* thisx, GlobalContext* globalCtx) { + DoorSpiral* this = (DoorSpiral*)thisx; + s32 pad; + s32 transition = GET_TRANSITION_ID_PARAM(thisx); + s8 objBankId; + + if (this->actor.room != globalCtx->transitionActorList[transition].sides[0].room) { + Actor_MarkForDeath(&this->actor); + return; + } + + Actor_ProcessInitChain(&this->actor, sInitChain); + this->unk145 = GET_UNK145_PARAM(thisx); // set but never used + this->orientation = GET_ORIENTATION_PARAM(thisx); + this->objectType = DoorSpiral_GetObjectType(globalCtx); + objBankId = Scene_FindSceneObjectIndex(&globalCtx->sceneContext, sSpiralObjectInfo[this->objectType].objectBankId); + this->bankIndex = objBankId; + + if (objBankId < 0) { + Actor_MarkForDeath(&this->actor); + return; + } + + DoorSpiral_SetupAction(this, DoorSpiral_WaitForObject); + Actor_SetHeight(&this->actor, 60.0f); +} + +void DoorSpiral_Destroy(Actor* thisx, GlobalContext* globalCtx) { + s32 transition = GET_TRANSITION_ID_PARAM(thisx); + + globalCtx->transitionActorList[transition].id *= -1; +} + +/** + * Waits for the required object to be loaded. + */ +void DoorSpiral_WaitForObject(DoorSpiral* this, GlobalContext* globalCtx) { + if (Scene_IsObjectLoaded(&globalCtx->sceneContext, this->bankIndex)) { + this->actor.objBankIndex = this->bankIndex; + DoorSpiral_SetSpiralType(this, globalCtx); + } +} + +/** + * Finds the distance between the stairs and the player. + */ +f32 DoorSpiral_GetDistFromPlayer(GlobalContext* globalCtx, DoorSpiral* this, f32 yOffset, f32 spiralWidth, + f32 spiralHeight) { + ActorPlayer* player = PLAYER; + Vec3f target; + Vec3f offset; + + target.x = player->base.world.pos.x; + target.y = player->base.world.pos.y + yOffset; + target.z = player->base.world.pos.z; + + Actor_CalcOffsetOrientedToDrawRotation(&this->actor, &offset, &target); + + if ((spiralWidth < fabsf(offset.x)) || (spiralHeight < fabsf(offset.y))) { + return 3.4028235e38f; // TODO FLT_MAX + } + + return offset.z; +} + +/** + * Checks if the player should climb the stairs. + */ +s32 DoorSpiral_PlayerShouldClimb(DoorSpiral* this, GlobalContext* globalCtx) { + ActorPlayer* player = PLAYER; + + if (!(func_801233E4(globalCtx))) { + SpiralInfo* spiralInfo = &sSpiralInfo[this->spiralType]; + f32 dist = + DoorSpiral_GetDistFromPlayer(globalCtx, this, 0.0f, spiralInfo->spiralWidth, spiralInfo->spiralHeight); + + if (fabsf(dist) < 64.0f) { + s16 angle = player->base.shape.rot.y - this->actor.shape.rot.y; + + if (dist > 0.0f) { + angle = 0x8000 - angle; + } + + if (ABS_ALT(angle) < 0x3000) { + return (dist >= 0.0f) ? 1.0f : -1.0f; + } + } + } + + return 0; +} + +/** + * Wait for the player to interact with the stairs. + */ +void DoorSpiral_Wait(DoorSpiral* this, GlobalContext* globalCtx) { + ActorPlayer* player; + s32 transition; + + if (this->shouldClimb) { + DoorSpiral_SetupAction(this, DoorSpiral_PlayerClimb); + } else if (DoorSpiral_PlayerShouldClimb(this, globalCtx)) { + player = PLAYER; + + player->doorType = 4; + player->doorDirection = this->orientation; + player->doorActor = &this->actor; + transition = GET_TRANSITION_ID_PARAM(this); + player->unk37F = ((u16)globalCtx->transitionActorList[transition].params) >> 10; + + func_80122F28(player, globalCtx, &this->actor); + } +} + +/** + * Player is climbing the stairs. + */ +void DoorSpiral_PlayerClimb(DoorSpiral* this, GlobalContext* globalCtx) { + ActorPlayer* player = PLAYER; + + if (!(player->stateFlags1 & 0x20000000)) { + DoorSpiral_SetupAction(this, DoorSpiral_WaitForObject); + this->shouldClimb = 0; + } +} + +void DoorSpiral_Update(Actor* thisx, GlobalContext* globalCtx) { + DoorSpiral* this = (DoorSpiral*)thisx; + s32 pad; + ActorPlayer* player = PLAYER; + + if ((!(player->stateFlags1 & 0x100004C0)) || (this->actionFunc == DoorSpiral_WaitForObject)) { + this->actionFunc(this, globalCtx); + } +} + +void DoorSpiral_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + DoorSpiral* this = (DoorSpiral*)thisx; + + if (this->actor.objBankIndex == this->bankIndex) { + SpiralInfo* spiralInfo = &sSpiralInfo[this->spiralType]; + Gfx* dList; + + // Set the model to render based on the orientation of the stairs (upward or downward) + dList = spiralInfo->spiralDL[this->orientation]; + + if (dList != NULL) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + gSPMatrix(POLY_OPA_DISP++, SysMatrix_AppendStateToPolyOpaDisp(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, spiralInfo->spiralDL[this->orientation]); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } + } +} diff --git a/src/overlays/actors/ovl_Door_Spiral/z_door_spiral.h b/src/overlays/actors/ovl_Door_Spiral/z_door_spiral.h index a84d28f98d..6b5f0e2ffe 100644 --- a/src/overlays/actors/ovl_Door_Spiral/z_door_spiral.h +++ b/src/overlays/actors/ovl_Door_Spiral/z_door_spiral.h @@ -5,9 +5,18 @@ struct DoorSpiral; +typedef void (*DoorSpiralActionFunc)(struct DoorSpiral*, GlobalContext*); + typedef struct DoorSpiral { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0xC]; + /* 0x144 */ u8 shouldClimb; // Flag used to determine if the player should climb the stairs + /* 0x145 */ u8 unk145; + /* 0x146 */ u8 orientation; // Upward or downward staircase + /* 0x147 */ u8 objectType; // Index to list of objects + /* 0x148 */ u8 spiralType; // Type of skin the staircase should use + /* 0x149 */ s8 bankIndex; // Object bank to use + /* 0x14A */ s8 unk14A; + /* 0x14C */ DoorSpiralActionFunc actionFunc; } DoorSpiral; // size = 0x150 extern const ActorInit Door_Spiral_InitVars; diff --git a/src/overlays/actors/ovl_En_Po_Fusen/z_en_po_fusen.c b/src/overlays/actors/ovl_En_Po_Fusen/z_en_po_fusen.c index 38ac7ff14a..cb3ed9cdc4 100644 --- a/src/overlays/actors/ovl_En_Po_Fusen/z_en_po_fusen.c +++ b/src/overlays/actors/ovl_En_Po_Fusen/z_en_po_fusen.c @@ -5,6 +5,9 @@ #define THIS ((EnPoFusen*)thisx) +#define GET_FUSE_LEN_PARAM(this) (((Actor*)(this))->params & 0x3FF) +#define GET_IS_FUSE_TYPE_PARAM(this) (((Actor*)(this))->params & 0x8000) + void EnPoFusen_Init(Actor* thisx, GlobalContext* globalCtx); void EnPoFusen_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnPoFusen_Update(Actor* thisx, GlobalContext* globalCtx); @@ -36,9 +39,9 @@ static ColliderSphereInit sSphereInit = { { 0, { { 0, 0, 0 }, 200 }, 100 }, }; -DamageTable EnPoFusenDamageTable = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0xF1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0xF1, 0xF1, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +DamageTable EnPoFusenDamageTable = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0xF1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0xF1, 0xF1, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; void EnPoFusen_Init(Actor *thisx, GlobalContext *globalCtx) { @@ -111,7 +114,7 @@ u16 EnPoFusen_CheckParent(EnPoFusen *this, GlobalContext *globalCtx) { return 0; } -u16 EnPoFusen_CheckCollision(EnPoFusen *this, GlobalContext *gCtx) { +u16 EnPoFusen_CheckCollision(EnPoFusen *this, GlobalContext *gCtx) { if ((u32) this->actionFunc == (u32) EnPoFusen_IdleFuse ) { return 0; } @@ -120,7 +123,7 @@ u16 EnPoFusen_CheckCollision(EnPoFusen *this, GlobalContext *gCtx) { this->collider.dim.worldSphere.center.y = (this->actor.world.pos.y + 20.0f); this->collider.dim.worldSphere.center.z = this->actor.world.pos.z; - if (((this->collider.base.acFlags & 2) != 0) + if (((this->collider.base.acFlags & 2) != 0) && (this->actor.colChkInfo.damageEffect == 0xF)) { this->collider.base.acFlags &= ~0x2; return 1; @@ -175,7 +178,7 @@ void EnPoFusen_IncrementMalonPop(EnPoFusen *this) { Actor* parent = this->actor.parent; EnMa4* romani; - if ((parent != 0) && (parent->id == ACTOR_EN_MA4)) { + if ((parent != 0) && (parent->id == ACTOR_EN_MA4)) { romani = (EnMa4*) parent; romani->unk338++; } @@ -186,7 +189,7 @@ void EnPoFusen_IncrementMalonPop(EnPoFusen *this) { void EnPoFusen_Pop(EnPoFusen *this, GlobalContext *gCtx) { Actor_Spawn(&gCtx->actorCtx, gCtx, ACTOR_EN_CLEAR_TAG, - this->actor.world.pos.x, this->actor.world.pos.y + 20.0f, this->actor.world.pos.z, + this->actor.world.pos.x, this->actor.world.pos.y + 20.0f, this->actor.world.pos.z, 255, 255, 200, 2); Audio_PlayActorSound2(&this->actor, 0x180E); // NA_SE_IT_BOMB_EXPLOSION sfx Actor_MarkForDeath(&this->actor); @@ -200,7 +203,7 @@ void EnPoFusen_InitFuse(EnPoFusen *this) { this->actionFunc = EnPoFusen_IdleFuse; } -void EnPoFusen_IdleFuse(EnPoFusen *this, GlobalContext *gCtx) { +void EnPoFusen_IdleFuse(EnPoFusen *this, GlobalContext *gCtx) { EnPoFusen_Idle(this, gCtx); if (this->fuse-- == 0) { EnPoFusen_IncrementMalonPop(this); @@ -262,6 +265,6 @@ void EnPoFusen_Draw(Actor *thisx, GlobalContext *globalCtx) { EnPoFusen* this = THIS; func_8012C28C(globalCtx->state.gfxCtx); func_801343C0(globalCtx, this->anime.skeleton, - this->anime.limbDrawTbl, this->anime.dListCount, + this->anime.limbDrawTbl, this->anime.dListCount, EnPoFusen_OverrideLimbDraw, EnPoFusen_PostLimbDraw, EnPoFusen_UnkActorDraw, &this->actor); } diff --git a/src/overlays/actors/ovl_En_Po_Fusen/z_en_po_fusen.h b/src/overlays/actors/ovl_En_Po_Fusen/z_en_po_fusen.h index 245a44baa9..7c2da63d4b 100644 --- a/src/overlays/actors/ovl_En_Po_Fusen/z_en_po_fusen.h +++ b/src/overlays/actors/ovl_En_Po_Fusen/z_en_po_fusen.h @@ -32,7 +32,4 @@ extern AnimationHeader D_060024F0; extern const ActorInit En_Po_Fusen_InitVars; -#define GET_FUSE_LEN_PARAM(thisx) ((this)->actor.params & 0x3FF) -#define GET_IS_FUSE_TYPE_PARAM(thisx) ((this)->actor.params & 0x8000) - #endif // Z_EN_PO_FUSEN_H