1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2025-08-06 14:20:11 +00:00

ovl_Door_Shutter OK (#413)

* Initial progress

* Some more progress

* Fix merge

* OK

* Small improvements

* Further improvements

* Some documentation, ran formatter

* Small fix

* Several review suggestions

Co-authored-by: Dragorn421 <Dragorn421@users.noreply.github.com>

* Further review changes

* Space out declarations, better boolean comparisons

Co-authored-by: Dragorn421 <Dragorn421@users.noreply.github.com>

* Some ands to modulos

* Swap condition

Co-authored-by: Dragorn421 <Dragorn421@users.noreply.github.com>

* Fix merge, PR suggestions

* review

Co-authored-by: Dragorn421 <Dragorn421@users.noreply.github.com>
Co-authored-by: fig <fig02srl@gmail.com>
This commit is contained in:
Tharo 2020-12-03 21:55:01 +00:00 committed by GitHub
parent 80c803b9ec
commit 26c38834ec
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
44 changed files with 752 additions and 2326 deletions

View file

@ -108,7 +108,7 @@ void func_80889ACC(BgHidanKousi* this) {
void func_80889B5C(BgHidanKousi* this, GlobalContext* globalCtx) {
if (Flags_GetSwitch(globalCtx, (this->dyna.actor.params >> 8) & 0xFF)) {
BgHidanKousi_SetupAction(this, func_80889BC0);
func_80080480(globalCtx, this);
func_80080480(globalCtx, &this->dyna.actor);
this->unk_168 = 0xC8;
}
}

View file

@ -106,7 +106,7 @@ void func_80891CF4(BgIceShutter* this, GlobalContext* globalCtx) {
Audio_PlaySoundAtPosition(globalCtx, &this->dyna.actor.posRot.pos, 30, NA_SE_EV_SLIDE_DOOR_OPEN);
this->actionFunc = func_80891DD4;
if (this->dyna.actor.shape.rot.x == 0) {
func_80080480(globalCtx, this);
func_80080480(globalCtx, &this->dyna.actor);
}
}
}
@ -115,7 +115,7 @@ void func_80891D6C(BgIceShutter* this, GlobalContext* globalCtx) {
if (Flags_GetSwitch(globalCtx, this->dyna.actor.params)) {
Audio_PlaySoundAtPosition(globalCtx, &this->dyna.actor.posRot.pos, 30, NA_SE_EV_SLIDE_DOOR_OPEN);
this->actionFunc = func_80891DD4;
func_80080480(globalCtx, this);
func_80080480(globalCtx, &this->dyna.actor);
}
}

View file

@ -87,7 +87,7 @@ void func_808AE5B4(BgSpot05Soko* this, GlobalContext* globalCtx) {
if (Flags_GetSwitch(globalCtx, this->switchFlag)) {
Audio_PlaySoundAtPosition(globalCtx, &thisx->posRot.pos, 30, NA_SE_EV_METALDOOR_CLOSE);
Actor_SetHeight(thisx, 50.0f);
func_80080480(globalCtx, thisx);
func_80080480(globalCtx, &this->dyna.actor);
this->actionFunc = func_808AE630;
thisx->speedXZ = 0.5f;
}

View file

@ -8,7 +8,9 @@ struct BossGoma;
typedef struct BossGoma {
/* 0x0000 */ Actor actor;
/* 0x014C */ char unk_14C[0x9D0];
/* 0x014C */ char unk_14C[0x70];
/* 0x01BC */ s16 subCameraId;
/* 0x01BE */ char unk_1BE[0x95E];
} BossGoma; // size = 0x0B1C
extern const ActorInit Boss_Goma_InitVars;

View file

@ -1,4 +1,11 @@
/*
* File: z_door_shutter.c
* Overlay: ovl_Door_Shutter
* Description: Sliding doors, Phantom Ganon room bars, Gohma room rock slab
*/
#include "z_door_shutter.h"
#include "overlays/actors/ovl_Boss_Goma/z_boss_goma.h"
#define FLAGS 0x00000010
@ -9,7 +16,22 @@ void DoorShutter_Destroy(Actor* thisx, GlobalContext* globalCtx);
void DoorShutter_Update(Actor* thisx, GlobalContext* globalCtx);
void DoorShutter_Draw(Actor* thisx, GlobalContext* globalCtx);
/*
void func_8099803C(GlobalContext* globalCtx, s16 y, s16 countdown, s16 arg3);
void DoorShutter_SetupType(DoorShutter* this, GlobalContext* globalCtx);
void func_80996A54(DoorShutter* this, GlobalContext* globalCtx);
void func_80996B00(DoorShutter* this, GlobalContext* globalCtx);
void func_80996B0C(DoorShutter* this, GlobalContext* globalCtx);
void func_80996EE8(DoorShutter* this, GlobalContext* globalCtx);
void func_80996F98(DoorShutter* this, GlobalContext* globalCtx);
void func_80997004(DoorShutter* this, GlobalContext* globalCtx);
void func_80997150(DoorShutter* this, GlobalContext* globalCtx);
void func_809973E8(DoorShutter* this, GlobalContext* globalCtx);
void func_80997528(DoorShutter* this, GlobalContext* globalCtx);
void func_80997568(DoorShutter* this, GlobalContext* globalCtx);
void func_809975C0(DoorShutter* this, GlobalContext* globalCtx);
void func_809976B8(DoorShutter* this, GlobalContext* globalCtx);
void func_80997744(DoorShutter* this, GlobalContext* globalCtx);
const ActorInit Door_Shutter_InitVars = {
ACTOR_DOOR_SHUTTER,
ACTORTYPE_DOOR,
@ -21,61 +43,689 @@ const ActorInit Door_Shutter_InitVars = {
(ActorFunc)DoorShutter_Update,
(ActorFunc)DoorShutter_Draw,
};
*/
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Door_Shutter/func_809962A0.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Door_Shutter/func_809962AC.s")
typedef struct {
s16 objectId;
u8 index1;
u8 index2;
} ShutterObjectInfo;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Door_Shutter/DoorShutter_Init.s")
static ShutterObjectInfo D_809980F0[] = {
{ OBJECT_GND, 4, 4 },
{ OBJECT_GOMA, 5, 5 },
{ OBJECT_YDAN_OBJECTS, 0, 1 },
{ OBJECT_DDAN_OBJECTS, 2, 2 },
{ OBJECT_BDAN_OBJECTS, 3, 3 },
{ OBJECT_GAMEPLAY_KEEP, 8, 8 },
{ OBJECT_BDOOR, 7, 7 },
{ OBJECT_GAMEPLAY_KEEP, 8, 8 },
{ OBJECT_HIDAN_OBJECTS, 9, 10 },
{ OBJECT_GANON_OBJECTS, 11, 11 },
{ OBJECT_JYA_DOOR, 6, 6 },
{ OBJECT_MIZU_OBJECTS, 12, 13 },
{ OBJECT_HAKA_DOOR, 14, 15 },
{ OBJECT_ICE_OBJECTS, 16, 16 },
{ OBJECT_MENKURI_OBJECTS, 17, 17 },
{ OBJECT_DEMO_KEKKAI, 18, 18 },
{ OBJECT_OUKE_HAKA, 19, 19 },
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Door_Shutter/DoorShutter_Destroy.s")
typedef struct {
/* 0x0000 */ Gfx* a;
/* 0x0004 */ Gfx* b;
/* 0x0008 */ u8 c;
/* 0x0009 */ u8 translateZ;
/* 0x000A */ u8 e;
/* 0x000B */ u8 f;
} ShutterInfo;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Door_Shutter/func_8099670C.s")
static ShutterInfo D_80998134[] = {
{ 0x060067A0, 0x0404B0D0, 130, 12, 20, 15 }, { 0x06006910, 0x0404B0D0, 130, 12, 20, 15 },
{ 0x060000C0, 0x060001F0, 240, 14, 70, 15 }, { 0x06000590, 0x06006460, 0, 110, 50, 15 },
{ 0x06012AB0, NULL, 130, 12, 50, 15 }, { 0x0601EC20, NULL, 130, 12, 50, 15 },
{ 0x06000100, 0x060001F0, 240, 14, 50, 15 }, { 0x060010C0, NULL, 130, 12, 50, 15 },
{ 0x04049FE0, 0x0404B0D0, 130, 12, 20, 15 }, { 0x06010CB0, 0x0404B0D0, 130, 12, 20, 15 },
{ 0x06011F20, 0x0404B0D0, 130, 12, 20, 15 }, { 0x060000C0, 0x0404B0D0, 130, 12, 20, 15 },
{ 0x06005D90, 0x0404B0D0, 130, 12, 20, 15 }, { 0x06007000, 0x0404B0D0, 130, 12, 20, 15 },
{ 0x06002620, 0x0404B0D0, 130, 12, 20, 15 }, { 0x06003890, 0x0404B0D0, 130, 12, 20, 15 },
{ 0x06001D10, 0x0404B0D0, 130, 12, 20, 15 }, { 0x060010D0, 0x0404B0D0, 130, 12, 20, 15 },
{ 0x060020D0, 0x0404B0D0, 130, 12, 20, 15 }, { 0x060000C0, 0x0404B0D0, 130, 12, 20, 15 },
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Door_Shutter/func_80996840.s")
static s8 D_80998224[] = {
-1, -1, -1, -1, 0, 6, 1, -1, 0, -1, -1, -1,
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Door_Shutter/func_809968D4.s")
static InitChainEntry sInitChain[] = {
ICHAIN_VEC3F(scale, 1, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneScale, 100, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneDownward, 400, ICHAIN_STOP),
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Door_Shutter/func_80996A54.s")
typedef struct {
s16 sceneNum;
u8 index;
} ShutterSceneInfo;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Door_Shutter/func_80996B00.s")
static ShutterSceneInfo D_80998240[] = {
{ SCENE_YDAN, 0x02 }, { SCENE_DDAN, 0x03 }, { SCENE_DDAN_BOSS, 0x03 },
{ SCENE_BDAN, 0x04 }, { SCENE_BMORI1, 0x05 }, { SCENE_HIDAN, 0x08 },
{ SCENE_GANON, 0x09 }, { SCENE_GANON_BOSS, 0x09 }, { SCENE_JYASINZOU, 0x0A },
{ SCENE_JYASINBOSS, 0x0A }, { SCENE_MIZUSIN, 0x0B }, { SCENE_HAKADAN, 0x0C },
{ SCENE_HAKADANCH, 0x0C }, { SCENE_ICE_DOUKUTO, 0x0D }, { SCENE_MEN, 0x0E },
{ SCENE_GANONTIKA, 0x0F }, { SCENE_HAKAANA_OUKE, 0x10 }, { -1, 0x07 },
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Door_Shutter/func_80996B0C.s")
typedef struct {
s16 dungeonScene;
s16 bossScene;
u8 index;
} BossDoorInfo;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Door_Shutter/func_80996C60.s")
static BossDoorInfo D_80998288[] = {
{ SCENE_HIDAN, SCENE_FIRE_BS, 0x01 },
{ SCENE_MIZUSIN, SCENE_MIZUSIN_BS, 0x02 },
{ SCENE_HAKADAN, SCENE_HAKADAN_BS, 0x03 },
{ SCENE_GANON, SCENE_GANON_BOSS, 0x04 },
{ SCENE_BMORI1, SCENE_MORIBOSSROOM, 0x05 },
{ SCENE_JYASINZOU, SCENE_JYASINBOSS, 0x06 },
{ -1, -1, 0x00 },
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Door_Shutter/func_80996D14.s")
static Gfx* D_809982B4[] = {
0x06000590, 0x06000BF0, 0x06002BD0, 0x060018B0, 0x06001F10, 0x060018B0, 0x06001250, 0x06000BF0,
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Door_Shutter/func_80996E08.s")
// boss door textures?
static UNK_PTR D_809982D4[] = {
0x060065C0, 0x060035C0, 0x060055C0, 0x060045C0, 0x06000000, 0x060025C0, 0x060015C0,
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Door_Shutter/func_80996EE8.s")
extern ColHeader D_0601EDD0; // gohma block collision header
extern ColHeader D_06012FD0; // phantom ganon bars collision header
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Door_Shutter/func_80996F98.s")
void DoorShutter_SetupAction(DoorShutter* this, DoorShutterActionFunc actionFunc) {
this->actionFunc = actionFunc;
this->unk_16F = 0;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Door_Shutter/func_80997004.s")
s32 DoorShutter_SetupDoor(DoorShutter* this, GlobalContext* globalCtx) {
TransitionActorEntry* transitionEntry = &globalCtx->transitionActorList[(u16)this->dyna.actor.params >> 0xA];
s8 frontRoom = transitionEntry->sides[0].room;
s32 doorType = this->doorType;
ShutterObjectInfo* temp_t0 = &D_809980F0[this->unk_16B];
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Door_Shutter/func_80997150.s")
if (doorType != SHUTTER_KEY_LOCKED) {
if (frontRoom == transitionEntry->sides[1].room) {
if (ABS((s16)(this->dyna.actor.shape.rot.y - this->dyna.actor.yawTowardsLink)) < 0x4000) {
frontRoom = -1;
}
}
if (frontRoom == this->dyna.actor.room) {
if (doorType == SHUTTER_FRONT_SWITCH_BACK_CLEAR) { // Swap the back clear to the front clear
doorType = SHUTTER_FRONT_CLEAR;
} else {
doorType = (doorType == SHUTTER_BOSS) ? SHUTTER_BACK_LOCKED : SHUTTER;
}
}
}
this->unk_16C = (doorType == SHUTTER) ? temp_t0->index1 : temp_t0->index2;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Door_Shutter/func_80997220.s")
if (doorType == SHUTTER_FRONT_CLEAR) {
if (!Flags_GetClear(globalCtx, this->dyna.actor.room)) {
DoorShutter_SetupAction(this, func_80996A54);
this->unk_170 = 1.0f;
return true;
}
} else if (doorType == SHUTTER_FRONT_SWITCH || doorType == SHUTTER_FRONT_SWITCH_BACK_CLEAR) {
if (!Flags_GetSwitch(globalCtx, this->dyna.actor.params & 0x3F)) {
DoorShutter_SetupAction(this, func_80996EE8);
this->unk_170 = 1.0f;
return true;
}
DoorShutter_SetupAction(this, func_80996F98);
return false;
} else if (doorType == SHUTTER_BACK_LOCKED) {
DoorShutter_SetupAction(this, func_80996B00);
return false;
}
DoorShutter_SetupAction(this, func_80996B0C);
return false;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Door_Shutter/func_809973E8.s")
void DoorShutter_Init(Actor* thisx, GlobalContext* globalCtx) {
DoorShutter* this = THIS;
GlobalContext* globalCtx2 = globalCtx;
s32 phi_a3;
s32 pad;
s32 objectIndex;
s32 i;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Door_Shutter/func_80997528.s")
Actor_ProcessInitChain(&this->dyna.actor, sInitChain);
this->dyna.actor.initPosRot.pos.z = this->dyna.actor.shape.unk_08;
DynaPolyInfo_SetActorMove(&this->dyna, DPM_UNK);
this->doorType = (this->dyna.actor.params >> 6) & 0xF;
phi_a3 = D_80998224[this->doorType];
if (phi_a3 < 0) {
ShutterSceneInfo* phi_v1;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Door_Shutter/func_80997568.s")
for (phi_v1 = &D_80998240[0], i = 0; i < ARRAY_COUNT(D_80998240) - 1; i++, phi_v1++) {
if (globalCtx2->sceneNum == phi_v1->sceneNum) {
break;
}
}
phi_a3 = phi_v1->index;
} else if (phi_a3 == 6) {
BossDoorInfo* phi_v1_2;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Door_Shutter/func_809975C0.s")
for (phi_v1_2 = &D_80998288[0], i = 0; i < ARRAY_COUNT(D_80998288) - 1; i++, phi_v1_2++) {
if (globalCtx2->sceneNum == phi_v1_2->dungeonScene || globalCtx2->sceneNum == phi_v1_2->bossScene) {
break;
}
}
this->unk_168 = phi_v1_2->index;
} else {
this->dyna.actor.room = -1;
}
if (this->requiredObjBankIndex = objectIndex = Object_GetIndex(&globalCtx2->objectCtx, D_809980F0[phi_a3].objectId),
(s8)objectIndex < 0) {
Actor_Kill(&this->dyna.actor);
return;
}
DoorShutter_SetupAction(this, DoorShutter_SetupType);
this->unk_16B = phi_a3;
if (this->doorType == SHUTTER_KEY_LOCKED || this->doorType == SHUTTER_BOSS) {
if (!Flags_GetSwitch(globalCtx2, this->dyna.actor.params & 0x3F)) {
this->unk_16E = 10;
}
Actor_SetHeight(&this->dyna.actor, 60.0f);
} else if (phi_a3 == 4) {
Actor_SetScale(&this->dyna.actor, 0.1f);
this->unk_166 = 100;
this->dyna.actor.uncullZoneScale = 200.0f;
Actor_SetHeight(&this->dyna.actor, 0.0f);
} else {
Actor_SetHeight(&this->dyna.actor, 60.0f);
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Door_Shutter/func_809976B8.s")
void DoorShutter_Destroy(Actor* thisx, GlobalContext* globalCtx) {
DoorShutter* this = THIS;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Door_Shutter/func_80997744.s")
DynaPolyInfo_Free(globalCtx, &globalCtx->colCtx.dyna, this->dyna.dynaPolyId);
if (this->dyna.actor.room >= 0) {
s32 transitionActorId = (u16)this->dyna.actor.params >> 0xA;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Door_Shutter/DoorShutter_Update.s")
globalCtx->transitionActorList[transitionActorId].id *= -1;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Door_Shutter/func_80997838.s")
void DoorShutter_SetupType(DoorShutter* this, GlobalContext* globalCtx) {
if (Object_IsLoaded(&globalCtx->objectCtx, this->requiredObjBankIndex)) {
this->dyna.actor.objBankIndex = this->requiredObjBankIndex;
if (this->doorType == SHUTTER_PG_BARS || this->doorType == SHUTTER_GOHMA_BLOCK) {
// Init dynapoly for shutters of the type that uses it
UNK_TYPE temp = 0;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Door_Shutter/func_80997A34.s")
Actor_SetObjectDependency(globalCtx, &this->dyna.actor);
this->unk_16C = D_809980F0[this->unk_16B].index1;
DynaPolyInfo_Alloc((this->doorType == SHUTTER_GOHMA_BLOCK) ? &D_0601EDD0 : &D_06012FD0, &temp);
this->dyna.dynaPolyId =
DynaPolyInfo_RegisterActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, temp);
if (this->doorType == SHUTTER_GOHMA_BLOCK) {
this->dyna.actor.velocity.y = 0.0f;
this->dyna.actor.gravity = -2.0f;
Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_SLIDE_DOOR_CLOSE);
DoorShutter_SetupAction(this, func_809975C0);
} else {
DoorShutter_SetupAction(this, func_80997744);
this->unk_164 = 7;
}
} else {
DoorShutter_SetupDoor(this, globalCtx);
}
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Door_Shutter/DoorShutter_Draw.s")
f32 func_80996840(GlobalContext* globalCtx, DoorShutter* this, f32 arg2, f32 arg3, f32 arg4) {
s32 pad;
Vec3f sp28;
Vec3f sp1C;
Player* player = PLAYER;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Door_Shutter/func_8099803C.s")
sp28.x = player->actor.posRot.pos.x;
sp28.y = player->actor.posRot.pos.y + arg2;
sp28.z = player->actor.posRot.pos.z;
func_8002DBD0(&this->dyna.actor, &sp1C, &sp28);
if (arg3 < fabsf(sp1C.x) || arg4 < fabsf(sp1C.y)) {
return FLT_MAX;
} else {
return sp1C.z;
}
}
s32 func_809968D4(DoorShutter* this, GlobalContext* globalCtx) {
Player* player = PLAYER;
if (!Player_InCsMode(globalCtx)) {
ShutterInfo* temp_v1 = &D_80998134[this->unk_16C];
f32 temp_f2 = func_80996840(globalCtx, this, (this->unk_16C != 3) ? 0.0f : 80.0f, temp_v1->e, temp_v1->f);
if (fabsf(temp_f2) < 50.0f) {
s16 phi_v0 = player->actor.shape.rot.y - this->dyna.actor.shape.rot.y;
if (temp_f2 > 0.0f) {
phi_v0 = 0x8000 - phi_v0;
}
if (ABS(phi_v0) < 0x3000) {
return (temp_f2 >= 0.0f) ? 1.0f : -1.0f;
}
}
}
return 0.0f;
}
void func_80996A54(DoorShutter* this, GlobalContext* globalCtx) {
if (Flags_GetClear(globalCtx, this->dyna.actor.room) || Flags_GetTempClear(globalCtx, this->dyna.actor.room)) {
Flags_SetClear(globalCtx, this->dyna.actor.room);
DoorShutter_SetupAction(this, func_80997150);
func_80080480(globalCtx, &this->dyna.actor);
func_80080480(globalCtx, &PLAYER->actor);
this->unk_16F = -100;
} else if (func_809968D4(this, globalCtx) != 0) {
Player* player = PLAYER;
player->naviTextId = -0x202;
}
}
void func_80996B00(DoorShutter* this, GlobalContext* globalCtx) {
}
void func_80996B0C(DoorShutter* this, GlobalContext* globalCtx) {
if (this->unk_164 != 0) {
DoorShutter_SetupAction(this, func_80997004);
this->dyna.actor.velocity.y = 0.0f;
if (this->unk_16E != 0) {
Flags_SetSwitch(globalCtx, this->dyna.actor.params & 0x3F);
if (this->doorType != SHUTTER_BOSS) {
gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex]--;
Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_CHAIN_KEY_UNLOCK);
} else {
Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_CHAIN_KEY_UNLOCK_B);
}
}
} else {
s32 doorDirection = func_809968D4(this, globalCtx);
if (doorDirection != 0) {
Player* player = PLAYER;
if (this->unk_16E != 0) {
if (this->doorType == SHUTTER_BOSS) {
if (!CHECK_DUNGEON_ITEM(DUNGEON_KEY_BOSS, gSaveContext.mapIndex)) {
player->naviTextId = -0x204;
return;
}
} else if (gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex] <= 0) {
player->naviTextId = -0x203;
return;
}
player->doorTimer = 10;
}
player->doorType = 2;
player->doorDirection = doorDirection;
player->doorActor = &this->dyna.actor;
}
}
}
void func_80996C60(DoorShutter* this, GlobalContext* globalCtx) {
if (this->dyna.actor.type == ACTORTYPE_DOOR) {
Player* player = PLAYER;
s32 sp38 = this->unk_16C;
s32 sp34 = 0xF;
if (DoorShutter_SetupDoor(this, globalCtx)) {
sp34 = 0x20;
}
DoorShutter_SetupAction(this, func_80997004);
this->unk_16C = sp38;
this->unk_170 = 0.0f;
func_8005AD40(globalCtx->cameraPtrs[0], &this->dyna.actor, player->unk_46A, 0.0f, 12, sp34, 10);
}
}
s32 func_80996D14(DoorShutter* this, GlobalContext* globalCtx) {
if (this->unk_16C != 3) {
if (this->dyna.actor.velocity.y == 0.0f) {
Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_SLIDE_DOOR_OPEN);
func_80996C60(this, globalCtx);
}
Math_ApproxF(&this->dyna.actor.velocity.y, 15.0f, 3.0f);
if (Math_ApproxF(&this->dyna.actor.posRot.pos.y, this->dyna.actor.initPosRot.pos.y + 200.0f,
this->dyna.actor.velocity.y)) {
return true;
}
} else {
if (this->unk_166 == 100) {
Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BUYODOOR_OPEN);
func_80996C60(this, globalCtx);
}
if (Math_ApproxS(&this->unk_166, 0, 10)) {
return true;
}
}
return false;
}
s32 func_80996E08(DoorShutter* this, GlobalContext* globalCtx, f32 arg2) {
if (this->unk_170 == 1.0f - arg2) {
if (this->unk_16C != 3) {
if (arg2 == 1.0f) {
Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_METALDOOR_CLOSE);
} else {
Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_METALDOOR_OPEN);
}
} else {
if (arg2 == 1.0f) {
Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BUYOSHUTTER_CLOSE);
} else {
Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BUYOSHUTTER_OPEN);
}
}
}
if (Math_ApproxF(&this->unk_170, arg2, 0.2f)) {
return true;
}
return false;
}
void func_80996EE8(DoorShutter* this, GlobalContext* globalCtx) {
if (func_80996E08(this, globalCtx, 1.0f)) {
if (Flags_GetSwitch(globalCtx, this->dyna.actor.params & 0x3F)) {
DoorShutter_SetupAction(this, func_80997150);
func_80080480(globalCtx, &this->dyna.actor);
this->unk_16F = -100;
} else if (func_809968D4(this, globalCtx)) {
Player* player = PLAYER;
// Jabu navi text for switch doors is different
player->naviTextId = (globalCtx->sceneNum == SCENE_BDAN) ? -0x20B : -0x202;
}
}
}
void func_80996F98(DoorShutter* this, GlobalContext* globalCtx) {
if (this->unk_164 == 0 && !Flags_GetSwitch(globalCtx, this->dyna.actor.params & 0x3F)) {
DoorShutter_SetupAction(this, func_80996EE8);
} else {
func_80996B0C(this, globalCtx);
}
}
void func_80997004(DoorShutter* this, GlobalContext* globalCtx) {
if (DECR(this->unk_16E) == 0 && globalCtx->roomCtx.status == 0 && func_80996D14(this, globalCtx) != 0) {
if (((this->doorType == SHUTTER_BOSS) ? 20.0f : 50.0f) < this->dyna.actor.xzDistFromLink) {
if (DoorShutter_SetupDoor(this, globalCtx)) {
this->dyna.actor.velocity.y = 30.0f;
}
if (this->unk_16C != 3) {
Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_SLIDE_DOOR_CLOSE);
DoorShutter_SetupAction(this, func_809973E8);
} else {
Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BUYODOOR_CLOSE);
if ((this->doorType == SHUTTER_FRONT_SWITCH || this->doorType == SHUTTER_FRONT_SWITCH_BACK_CLEAR) &&
!Flags_GetSwitch(globalCtx, this->dyna.actor.params & 0x3F)) {
Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BUYOSHUTTER_CLOSE);
}
DoorShutter_SetupAction(this, func_80997528);
}
}
}
}
void func_80997150(DoorShutter* this, GlobalContext* globalCtx) {
if (this->unk_16F != 0) {
if (this->unk_16F < 0) {
if (globalCtx->state.frames % 2 != 0) {
this->unk_16F++;
}
if (this->dyna.actor.type == func_8005B198() || this->unk_16F == 0) {
this->unk_16F = 5;
}
} else {
this->unk_16F--;
}
} else if (func_80996E08(this, globalCtx, 0.0f)) {
if (!(this->doorType == SHUTTER || this->doorType == SHUTTER_FRONT_CLEAR)) {
DoorShutter_SetupAction(this, func_80996F98);
} else {
DoorShutter_SetupAction(this, func_80996B0C);
}
func_800F5B58();
}
}
void func_80997220(DoorShutter* this, GlobalContext* globalCtx) {
Player* player = PLAYER;
s8 room = this->dyna.actor.room;
if (this->dyna.actor.room >= 0) {
Vec3f vec;
func_8002DBD0(&this->dyna.actor, &vec, &player->actor.posRot.pos);
this->dyna.actor.room =
globalCtx->transitionActorList[(u16)this->dyna.actor.params >> 0xA].sides[(vec.z < 0.0f) ? 0 : 1].room;
if (room != this->dyna.actor.room) {
Room tempRoom = globalCtx->roomCtx.curRoom;
globalCtx->roomCtx.curRoom = globalCtx->roomCtx.prevRoom;
globalCtx->roomCtx.prevRoom = tempRoom;
globalCtx->roomCtx.unk_30 ^= 1;
}
func_80097534(globalCtx, &globalCtx->roomCtx);
Gameplay_SetupRespawnPoint(globalCtx, RESPAWN_MODE_DOWN, 0x0EFF);
}
this->unk_164 = 0;
this->dyna.actor.velocity.y = 0.0f;
if (DoorShutter_SetupDoor(this, globalCtx) && !(player->stateFlags1 & 0x800)) {
DoorShutter_SetupAction(this, func_80997568);
func_8002DF54(globalCtx, NULL, 2);
}
}
void func_809973E8(DoorShutter* this, GlobalContext* globalCtx) {
s32 quakeId;
if (this->dyna.actor.velocity.y < 20.0f) {
Math_ApproxF(&this->dyna.actor.velocity.y, 20.0f, 8.0f);
}
if (Math_ApproxF(&this->dyna.actor.posRot.pos.y, this->dyna.actor.initPosRot.pos.y, this->dyna.actor.velocity.y)) {
if (this->dyna.actor.velocity.y > 20.0f) {
this->dyna.actor.groundY = this->dyna.actor.initPosRot.pos.y;
func_80033260(globalCtx, &this->dyna.actor, &this->dyna.actor.posRot.pos, 45.0f, 0xA, 8.0f, 0x1F4, 0xA, 0);
}
Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_STONE_BOUND);
quakeId = Quake_Add(Gameplay_GetCamera(globalCtx, 0), 3);
Quake_SetSpeed(quakeId, -32536);
Quake_SetQuakeValues(quakeId, 2, 0, 0, 0);
Quake_SetCountdown(quakeId, 10);
func_800AA000(this->dyna.actor.xyzDistFromLinkSq, 0xB4, 0x14, 0x64);
func_80997220(this, globalCtx);
}
}
void func_80997528(DoorShutter* this, GlobalContext* globalCtx) {
if (Math_ApproxS(&this->unk_166, 0x64, 0xA)) {
func_80997220(this, globalCtx);
}
}
void func_80997568(DoorShutter* this, GlobalContext* globalCtx) {
if ((this->unk_16F++ < 0x1F) ^ 1) {
func_8002DF54(globalCtx, NULL, 7);
DoorShutter_SetupDoor(this, globalCtx);
}
}
void func_809975C0(DoorShutter* this, GlobalContext* globalCtx) {
Actor_MoveForward(&this->dyna.actor);
func_8002E4B4(globalCtx, &this->dyna.actor, 0.0f, 0.0f, 0.0f, 4);
if (this->dyna.actor.bgCheckFlags & 1) {
DoorShutter_SetupAction(this, func_809976B8);
if (!(gSaveContext.eventChkInf[7] & 1)) {
BossGoma* parent = (BossGoma*)this->dyna.actor.parent;
this->unk_164 = 10;
Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_STONE_BOUND);
func_8099803C(globalCtx, 2, 10, parent->subCameraId);
func_80033260(globalCtx, &this->dyna.actor, &this->dyna.actor.posRot.pos, 70.0f, 20, 8.0f, 500, 10, 1);
}
}
}
void func_809976B8(DoorShutter* this, GlobalContext* globalCtx) {
f32 mult;
if (this->unk_164 != 0) {
this->unk_164--;
mult = sinf(this->unk_164 * 250.0f / 100.0f);
this->dyna.actor.shape.unk_08 = this->unk_164 * 3.0f / 10.0f * mult;
}
}
void func_80997744(DoorShutter* this, GlobalContext* globalCtx) {
f32 phi_f0;
osSyncPrintf("FHG SAKU START !!\n");
if (this->unk_164 != 0) {
this->unk_164--;
}
phi_f0 = (this->unk_164 % 2 != 0) ? -3.0f : 0.0f;
Math_SmoothScaleMaxMinF(&this->dyna.actor.posRot.pos.y, -34.0f + phi_f0, 1.0f, 20.0f, 0.0f);
osSyncPrintf("FHG SAKU END !!\n");
}
void DoorShutter_Update(Actor* thisx, GlobalContext* globalCtx) {
DoorShutter* this = THIS;
Player* player = PLAYER;
if (!(player->stateFlags1 & 0x100004C0) || (this->actionFunc == DoorShutter_SetupType)) {
this->actionFunc(this, globalCtx);
}
}
Gfx* func_80997838(GlobalContext* globalCtx, DoorShutter* this, Gfx* p) {
MtxF mtx;
f32 angle = 0.0f;
f32 yScale = this->unk_166 * 0.01f;
s32 i;
Matrix_Get(&mtx);
for (i = 0; i < ARRAY_COUNT(D_809982B4); i++) {
Matrix_RotateZ(angle, MTXMODE_APPLY);
if (i % 2 == 0) {
Matrix_Translate(0.0f, 800.0f, 0.0f, MTXMODE_APPLY);
} else if (i == 1 || i == 7) {
Matrix_Translate(0.0f, 848.52f, 0.0f, MTXMODE_APPLY);
} else {
Matrix_Translate(0.0f, 989.94f, 0.0f, MTXMODE_APPLY);
}
if (this->unk_166 != 100) {
Matrix_Scale(1.0f, yScale, 1.0f, MTXMODE_APPLY);
}
gSPMatrix(p++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_door_shutter.c", 1991),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(p++, D_809982B4[i]);
angle -= M_PI / 4;
Matrix_Put(&mtx);
}
return p;
}
s32 func_80997A34(DoorShutter* this, GlobalContext* globalCtx) {
s32 phi_a1;
s32 phi_a0;
if (Player_InCsMode(globalCtx)) {
return true;
}
phi_a0 = (s16)(func_8002DAC0(&this->dyna.actor, &globalCtx->view.eye) - this->dyna.actor.shape.rot.y);
phi_a1 = (s16)(this->dyna.actor.yawTowardsLink - this->dyna.actor.shape.rot.y);
phi_a0 = ABS(phi_a0);
phi_a1 = ABS(phi_a1);
if ((phi_a1 < 0x4000 && phi_a0 > 0x4000) || (phi_a1 > 0x4000 && phi_a0 < 0x4000)) {
return false;
}
return true;
}
void DoorShutter_Draw(Actor* thisx, GlobalContext* globalCtx) {
DoorShutter* this = THIS;
if (this->dyna.actor.objBankIndex == this->requiredObjBankIndex &&
(this->unk_16B == 0 || func_80997A34(this, globalCtx) != 0)) {
s32 pad[2];
ShutterInfo* sp70 = &D_80998134[this->unk_16C];
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_door_shutter.c", 2048);
func_80093D18(globalCtx->state.gfxCtx);
if (this->unk_16C == 3) {
POLY_OPA_DISP = func_80997838(globalCtx, this, POLY_OPA_DISP);
if (this->unk_170 != 0.0f) {
f32 sp58 = (this->unk_166 * 0.01f) * this->unk_170;
func_80093D18(globalCtx->state.gfxCtx);
gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 255.0f * sp58);
Matrix_Translate(0, 0, sp70->translateZ, MTXMODE_APPLY);
Matrix_Scale(sp58, sp58, sp58, MTXMODE_APPLY);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_door_shutter.c", 2069),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_OPA_DISP++, sp70->b);
}
} else {
if (sp70->b != NULL) {
TransitionActorEntry* transitionEntry =
&globalCtx->transitionActorList[(u16)this->dyna.actor.params >> 0xA];
if (globalCtx->roomCtx.prevRoom.num >= 0 ||
transitionEntry->sides[0].room == transitionEntry->sides[1].room) {
s32 yaw = Math_Vec3f_Yaw(&globalCtx->view.eye, &this->dyna.actor.posRot.pos);
if (ABS((s16)(this->dyna.actor.shape.rot.y - yaw)) < 0x4000) {
Matrix_RotateY(M_PI, MTXMODE_APPLY);
}
} else if (this->dyna.actor.room == transitionEntry->sides[0].room) {
Matrix_RotateY(M_PI, MTXMODE_APPLY);
}
} else if (this->doorType == SHUTTER_BOSS) {
gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(D_809982D4[this->unk_168]));
}
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_door_shutter.c", 2109),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_OPA_DISP++, sp70->a);
if (this->unk_170 != 0.0f && sp70->b != NULL) {
Matrix_Translate(0, sp70->c * (1.0f - this->unk_170), sp70->translateZ, MTXMODE_APPLY);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_door_shutter.c", 2119),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_OPA_DISP++, sp70->b);
}
}
if (this->unk_16E != 0) {
Matrix_Scale(0.01f, 0.01f, 0.025f, MTXMODE_APPLY);
Actor_DrawDoorLock(globalCtx, this->unk_16E,
(this->doorType == SHUTTER_BOSS) ? 1 : ((this->unk_16C == 6) ? 2 : 0));
}
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_door_shutter.c", 2135);
}
}
void func_8099803C(GlobalContext* globalCtx, s16 y, s16 countdown, s16 camId) {
s16 quakeId = Quake_Add(Gameplay_GetCamera(globalCtx, camId), 3);
func_800A9F6C(0.0f, 180, 20, 100);
Quake_SetSpeed(quakeId, 20000);
Quake_SetQuakeValues(quakeId, y, 0, 0, 0);
Quake_SetCountdown(quakeId, countdown);
}

View file

@ -4,13 +4,58 @@
#include "ultra64.h"
#include "global.h"
/**
* Actor Parameters
*
* | | |
* | Transition Index | Type | Switch Flag
* |------------------|---------|-------------
* | 0 0 0 0 0 0 | 0 0 0 0 | 0 0 0 0 0 0
* | 6 | 4 | 6
* |
*
* Transition Index 1111110000000000 Set by the actor engine when the door is spawned
* Type 0000001111000000
* Switch Flag 0000000000111111
*
*/
typedef enum {
/* 0x00 */ SHUTTER,
/* 0x01 */ SHUTTER_FRONT_CLEAR,
/* 0x02 */ SHUTTER_FRONT_SWITCH,
/* 0x03 */ SHUTTER_BACK_LOCKED,
/* 0x04 */ SHUTTER_PG_BARS,
/* 0x05 */ SHUTTER_BOSS,
/* 0x06 */ SHUTTER_GOHMA_BLOCK,
/* 0x07 */ SHUTTER_FRONT_SWITCH_BACK_CLEAR,
/* 0x08 */ SHUTTER_8,
/* 0x09 */ SHUTTER_9,
/* 0x0A */ SHUTTER_A,
/* 0x0B */ SHUTTER_KEY_LOCKED,
/* 0x0C */ SHUTTER_C,
/* 0x0D */ SHUTTER_D,
/* 0x0E */ SHUTTER_E,
/* 0x0F */ SHUTTER_F
} DoorShutterType;
struct DoorShutter;
typedef void (*DoorShutterActionFunc)(struct DoorShutter*, GlobalContext*);
typedef struct DoorShutter {
/* 0x0000 */ Actor actor;
/* 0x014C */ char unk_14C[0x18];
/* 0x0000 */ DynaPolyActor dyna;
/* 0x0164 */ s16 unk_164;
/* 0x0166 */ char unk_166[0x12];
/* 0x0166 */ s16 unk_166;
/* 0x0168 */ s16 unk_168;
/* 0x016A */ u8 doorType;
/* 0x016B */ u8 unk_16B;
/* 0x016C */ u8 unk_16C;
/* 0x016D */ s8 requiredObjBankIndex;
/* 0x016E */ s8 unk_16E;
/* 0x016F */ s8 unk_16F;
/* 0x0170 */ f32 unk_170;
/* 0x0174 */ DoorShutterActionFunc actionFunc;
} DoorShutter; // size = 0x0178
extern const ActorInit Door_Shutter_InitVars;

View file

@ -134,7 +134,7 @@ void func_80BADF0C(ShotSun* this, GlobalContext* globalCtx) {
if ((params == 0x40 && globalCtx->msgCtx.unk_E3EC == 9) ||
(params == 0x41 && globalCtx->msgCtx.unk_E3EC == 0xB)) {
this->actionFunc = ShotSun_TriggerFairy;
func_80080480(globalCtx, this);
func_80080480(globalCtx, &this->actor);
this->timer = 0;
} else {
this->unk_1A4 = 0;

View file

@ -4174,7 +4174,7 @@ s32 func_80839800(Player* this, GlobalContext* globalCtx) {
if (this->doorType == 2) {
doorShutter = (DoorShutter*)doorActor;
this->currentYaw = doorShutter->actor.initPosRot.rot.y;
this->currentYaw = doorShutter->dyna.actor.initPosRot.rot.y;
if (sp7C > 0) {
this->currentYaw -= 0x8000;
}
@ -4206,8 +4206,8 @@ s32 func_80839800(Player* this, GlobalContext* globalCtx) {
this->linearVelocity = 0.1f;
}
if (doorShutter->actor.type == ACTORTYPE_DOOR) {
this->unk_46A = globalCtx->transitionActorList[(u16)doorShutter->actor.params >> 10]
if (doorShutter->dyna.actor.type == ACTORTYPE_DOOR) {
this->unk_46A = globalCtx->transitionActorList[(u16)doorShutter->dyna.actor.params >> 10]
.sides[(sp7C > 0) ? 0 : 1]
.effects;