Document BgCraceMovebg (sliding doors in Deku Shrine) and object_crace_object (#1101)

* Document BgCraceMovebg (sliding doors in Deku Shrine) and object_crace_object

* Respond to Elliptic's review

* Fix build issue

* Respond to Elliptic's second review

* ACTUALLY put the BSS above the data, forgot the InitVars were data

* Respond to hensldm's review
This commit is contained in:
Tom Overton 2022-09-30 12:15:43 -07:00 committed by GitHub
parent 1be5a7d2c7
commit 42a8bf6876
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 265 additions and 203 deletions

View File

@ -1,8 +1,9 @@
<Root>
<!-- Assets for the sliding doors in the Deku Shrine -->
<File Name="object_crace_object" Segment="6">
<DList Name="object_crace_object_DL_0003A0" Offset="0x3A0" />
<Texture Name="object_crace_object_TLUT_000540" OutName="tlut_000540" Format="rgba16" Width="4" Height="4" Offset="0x540" />
<Texture Name="object_crace_object_Tex_000560" OutName="tex_000560" Format="ci4" Width="32" Height="128" Offset="0x560" />
<Collision Name="object_crace_object_Colheader_000E00" Offset="0xE00" />
<DList Name="gDekuShrineSlidingDoorDL" Offset="0x3A0" /> <!-- Original name is "Y2_DANPEI_shutter_model" -->
<Texture Name="gDekuShrineSlidingDoorTLUT" OutName="deku_shrine_sliding_door_tlut" Format="rgba16" Width="4" Height="4" Offset="0x540" />
<Texture Name="gDekuShrineSlidingDoorTex" OutName="deku_shrine_sliding_door" Format="ci4" Width="32" Height="128" Offset="0x560" />
<Collision Name="gDekuShrineSlidingDoorCol" Offset="0xE00" />
</File>
</Root>

View File

@ -5,6 +5,7 @@
*/
#include "z_bg_crace_movebg.h"
#include "overlays/actors/ovl_En_Dno/z_en_dno.h"
#define FLAGS (ACTOR_FLAG_10)
@ -15,22 +16,30 @@ void BgCraceMovebg_Destroy(Actor* thisx, PlayState* play);
void BgCraceMovebg_Update(Actor* thisx, PlayState* play);
void BgCraceMovebg_Draw(Actor* thisx, PlayState* play);
s32 func_80A7090C(PlayState* play);
void func_80A70970(BgCraceMovebg* this, PlayState* play);
void func_80A7099C(BgCraceMovebg* this, PlayState* play);
void func_80A709E4(BgCraceMovebg* this, PlayState* play);
void func_80A70A08(BgCraceMovebg* this, PlayState* play);
void func_80A70A84(BgCraceMovebg* this, PlayState* play);
void func_80A70A9C(BgCraceMovebg* this, PlayState* play);
void func_80A70C04(BgCraceMovebg* this, PlayState* play);
void func_80A70D74(BgCraceMovebg* this, PlayState* play);
void func_80A70DA8(BgCraceMovebg* this, PlayState* play);
void func_80A70E2C(BgCraceMovebg* this, PlayState* play);
void func_80A70E70(BgCraceMovebg* this, PlayState* play);
void func_80A70F14(BgCraceMovebg* this, PlayState* play);
void func_80A70F2C(BgCraceMovebg* this, PlayState* play);
void func_80A70FF4(BgCraceMovebg* this, PlayState* play);
void func_80A71040(BgCraceMovebg* this, PlayState* play);
s32 BgCraceMovebg_GetRaceStatus(PlayState* play);
void BgCraceMovebg_OpeningDoor_SetupIdle(BgCraceMovebg* this, PlayState* play);
void BgCraceMovebg_OpeningDoor_Idle(BgCraceMovebg* this, PlayState* play);
void BgCraceMovebg_OpeningDoor_SetupOpen(BgCraceMovebg* this, PlayState* play);
void BgCraceMovebg_OpeningDoor_Open(BgCraceMovebg* this, PlayState* play);
void BgCraceMovebg_OpeningDoor_SetupDoNothing(BgCraceMovebg* this, PlayState* play);
void BgCraceMovebg_OpeningDoor_DoNothing(BgCraceMovebg* this, PlayState* play);
void BgCraceMovebg_ClosingDoor_CheckIfPlayerIsBeyondDoor(BgCraceMovebg* this, PlayState* play);
void BgCraceMovebg_ClosingDoor_SetupIdle(BgCraceMovebg* this, PlayState* play);
void BgCraceMovebg_ClosingDoor_Idle(BgCraceMovebg* this, PlayState* play);
void BgCraceMovebg_ClosingDoor_SetupWaitToClose(BgCraceMovebg* this, PlayState* play);
void BgCraceMovebg_ClosingDoor_WaitToClose(BgCraceMovebg* this, PlayState* play);
void BgCraceMovebg_ClosingDoor_SetupClose(BgCraceMovebg* this, PlayState* play);
void BgCraceMovebg_ClosingDoor_Close(BgCraceMovebg* this, PlayState* play);
void BgCraceMovebg_ClosingDoor_SetupDoNothing(BgCraceMovebg* this, PlayState* play);
void BgCraceMovebg_ClosingDoor_DoNothing(BgCraceMovebg* this, PlayState* play);
typedef enum {
/* 0 */ BG_CRACE_MOVEBG_RACE_STATUS_BUTLER_NOT_PRESENT,
/* 1 */ BG_CRACE_MOVEBG_RACE_STATUS_FIRST_RACE,
/* 2 */ BG_CRACE_MOVEBG_RACE_STATUS_SUBSEQUENT_RACE
} BgCraceMovebgRaceStatus;
u8 sIsLoaded[32];
const ActorInit Bg_Crace_Movebg_InitVars = {
ACTOR_BG_CRACE_MOVEBG,
@ -44,13 +53,14 @@ const ActorInit Bg_Crace_Movebg_InitVars = {
(ActorFunc)BgCraceMovebg_Draw,
};
static u8 D_80A710A0 = 0;
static u8 D_80A710A4 = 0;
static u8 sHasInitializedIsLoaded = 0;
static u8 sLoadedDoorCount = 0;
static InitChainEntry sInitChain[] = {
ICHAIN_VEC3F_DIV1000(scale, 1000, ICHAIN_STOP),
};
static Vec3f D_80A710AC[] = { 0.0f, 0.0f, 1.0f };
u8 D_80A711B0[32];
static Vec3f sUnitVecZ = { 0.0f, 0.0f, 1.0f };
void BgCraceMovebg_Init(Actor* thisx, PlayState* play) {
BgCraceMovebg* this = THIS;
@ -58,122 +68,138 @@ void BgCraceMovebg_Init(Actor* thisx, PlayState* play) {
s32 j;
Actor_ProcessInitChain(&this->dyna.actor, sInitChain);
if (D_80A710A0 == 0) {
for (i = 0; i < ARRAY_COUNT(D_80A711B0); i++) {
D_80A711B0[i] = 0;
if (!sHasInitializedIsLoaded) {
for (i = 0; i < ARRAY_COUNT(sIsLoaded); i++) {
sIsLoaded[i] = 0;
}
D_80A710A0 = 1;
sHasInitializedIsLoaded = true;
}
DynaPolyActor_Init(&this->dyna, 1);
DynaPolyActor_LoadMesh(play, &this->dyna, &object_crace_object_Colheader_000E00);
DynaPolyActor_LoadMesh(play, &this->dyna, &gDekuShrineSlidingDoorCol);
this->unk184 = this->dyna.actor.world.rot.x;
this->unk16C = this->dyna.actor.world.rot.z;
this->index = BG_CRACE_MOVEBG_GET_INDEX(&this->dyna.actor);
this->openSpeed = BG_CRACE_MOVEBG_GET_OPEN_SPEED(&this->dyna.actor);
this->dyna.actor.world.rot.x = 0;
this->dyna.actor.world.rot.z = 0;
this->dyna.actor.home.rot.x = 0;
this->dyna.actor.home.rot.z = 0;
this->dyna.actor.flags |= ACTOR_FLAG_10000000;
switch (BGCRACEMOVEBG_GET_F(&this->dyna.actor)) {
case 0:
case 2:
for (j = 0; j < D_80A710A4; j++) {
if (D_80A711B0[j] == this->unk184) {
this->unk170 |= 8;
switch (BG_CRACE_MOVEBG_GET_TYPE(&this->dyna.actor)) {
case BG_CRACE_MOVEBG_TYPE_CLOSING:
case BG_CRACE_MOVEBG_TYPE_UNUSED_CLOSING:
for (j = 0; j < sLoadedDoorCount; j++) {
if (sIsLoaded[j] == this->index) {
this->stateFlags |= BG_CRACE_MOVEBG_FLAG_ALREADY_LOADED;
Actor_MarkForDeath(&this->dyna.actor);
return;
}
}
if (D_80A710A4 < ARRAY_COUNT(D_80A711B0)) {
D_80A711B0[(s32)D_80A710A4++] = this->unk184;
if (sLoadedDoorCount < ARRAY_COUNT(sIsLoaded)) {
sIsLoaded[(s32)sLoadedDoorCount] = this->index;
sLoadedDoorCount++;
}
this->dyna.actor.room = -1;
switch (func_80A7090C(play)) {
case 0:
func_80A70D74(this, play);
switch (BgCraceMovebg_GetRaceStatus(play)) {
case BG_CRACE_MOVEBG_RACE_STATUS_BUTLER_NOT_PRESENT:
BgCraceMovebg_ClosingDoor_SetupIdle(this, play);
break;
case 1:
func_80A70D74(this, play);
case BG_CRACE_MOVEBG_RACE_STATUS_FIRST_RACE:
BgCraceMovebg_ClosingDoor_SetupIdle(this, play);
break;
case 2:
Flags_UnsetSwitch(play, BGCRACEMOVEBG_GET_7F0(&this->dyna.actor) + 1);
func_80A70D74(this, play);
case BG_CRACE_MOVEBG_RACE_STATUS_SUBSEQUENT_RACE:
// Makes sure no lingering switch flags are set from the last time the player did a race.
Flags_UnsetSwitch(play, BG_CRACE_MOVEBG_GET_SWITCH_FLAG(&this->dyna.actor) + 1);
BgCraceMovebg_ClosingDoor_SetupIdle(this, play);
break;
}
break;
case 1:
func_80A70970(this, play);
case BG_CRACE_MOVEBG_TYPE_OPENING:
BgCraceMovebg_OpeningDoor_SetupIdle(this, play);
break;
default:
Actor_MarkForDeath(&this->dyna.actor);
break;
}
}
s32 func_80A7090C(PlayState* play) {
s32 BgCraceMovebg_GetRaceStatus(PlayState* play) {
s32 pad;
s32 returnVal = 0;
Actor* tempActor = SubS_FindActor(play, NULL, ACTORCAT_NPC, ACTOR_EN_DNO);
s32 raceStatus = BG_CRACE_MOVEBG_RACE_STATUS_BUTLER_NOT_PRESENT;
Actor* butler = SubS_FindActor(play, NULL, ACTORCAT_NPC, ACTOR_EN_DNO);
if (tempActor != NULL) {
if (Flags_GetSwitch(play, BGCRACEMOVEBG_GET_3F80(tempActor))) {
returnVal = 2;
if (butler != NULL) {
if (Flags_GetSwitch(play, EN_DNO_GET_RACE_STARTED_SWITCH_FLAG(butler))) {
raceStatus = BG_CRACE_MOVEBG_RACE_STATUS_SUBSEQUENT_RACE;
} else {
returnVal = 1;
raceStatus = BG_CRACE_MOVEBG_RACE_STATUS_FIRST_RACE;
}
}
return returnVal;
return raceStatus;
}
void func_80A70970(BgCraceMovebg* this, PlayState* play) {
this->unk164 = 0.0f;
this->unk160 = 0.0f;
this->actionFunc = func_80A7099C;
void BgCraceMovebg_OpeningDoor_SetupIdle(BgCraceMovebg* this, PlayState* play) {
this->targetDoorHeight = 0.0f;
this->doorHeight = 0.0f;
this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y;
this->actionFunc = BgCraceMovebg_OpeningDoor_Idle;
}
void func_80A7099C(BgCraceMovebg* this, PlayState* play) {
if (Flags_GetSwitch(play, BGCRACEMOVEBG_GET_7F0(&this->dyna.actor))) {
func_80A709E4(this, play);
/**
* Wait for this door's switch flag to be set, then start opening.
*/
void BgCraceMovebg_OpeningDoor_Idle(BgCraceMovebg* this, PlayState* play) {
if (Flags_GetSwitch(play, BG_CRACE_MOVEBG_GET_SWITCH_FLAG(&this->dyna.actor))) {
BgCraceMovebg_OpeningDoor_SetupOpen(this, play);
}
}
void func_80A709E4(BgCraceMovebg* this, PlayState* play) {
this->actionFunc = func_80A70A08;
this->unk164 = 180.0f;
void BgCraceMovebg_OpeningDoor_SetupOpen(BgCraceMovebg* this, PlayState* play) {
this->targetDoorHeight = 180.0f;
this->actionFunc = BgCraceMovebg_OpeningDoor_Open;
}
void func_80A70A08(BgCraceMovebg* this, PlayState* play) {
/**
* Silde open, then do nothing.
*/
void BgCraceMovebg_OpeningDoor_Open(BgCraceMovebg* this, PlayState* play) {
func_800B9010(&this->dyna.actor, NA_SE_EV_STONEDOOR_OPEN_S - SFX_FLAG);
Math_SmoothStepToF(&this->unk160, this->unk164, 2.0f, this->unk16C, 0.01f);
this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y + this->unk160;
if (this->unk160 == this->unk164) {
func_80A70A84(this, play);
Math_SmoothStepToF(&this->doorHeight, this->targetDoorHeight, 2.0f, this->openSpeed, 0.01f);
this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y + this->doorHeight;
if (this->doorHeight == this->targetDoorHeight) {
BgCraceMovebg_OpeningDoor_SetupDoNothing(this, play);
}
}
void func_80A70A84(BgCraceMovebg* this, PlayState* play) {
this->actionFunc = func_80A70A9C;
void BgCraceMovebg_OpeningDoor_SetupDoNothing(BgCraceMovebg* this, PlayState* play) {
this->actionFunc = BgCraceMovebg_OpeningDoor_DoNothing;
}
void func_80A70A9C(BgCraceMovebg* this, PlayState* play) {
void BgCraceMovebg_OpeningDoor_DoNothing(BgCraceMovebg* this, PlayState* play) {
}
void BgCraceMovebg_Destroy(Actor* thisx, PlayState* play) {
BgCraceMovebg* this = THIS;
DynaPoly_DeleteBgActor(play, &play->colCtx.dyna, this->dyna.bgId);
if (!(this->unk170 & 0x8)) {
switch (BGCRACEMOVEBG_GET_F(&this->dyna.actor)) {
case 0:
case 2:
Flags_UnsetSwitch(play, BGCRACEMOVEBG_GET_7F0(thisx));
Flags_UnsetSwitch(play, BGCRACEMOVEBG_GET_7F0(thisx) + 1);
if (!(this->stateFlags & BG_CRACE_MOVEBG_FLAG_ALREADY_LOADED)) {
switch (BG_CRACE_MOVEBG_GET_TYPE(&this->dyna.actor)) {
case BG_CRACE_MOVEBG_TYPE_CLOSING:
case BG_CRACE_MOVEBG_TYPE_UNUSED_CLOSING:
Flags_UnsetSwitch(play, BG_CRACE_MOVEBG_GET_SWITCH_FLAG(thisx));
Flags_UnsetSwitch(play, BG_CRACE_MOVEBG_GET_SWITCH_FLAG(thisx) + 1);
break;
case 1:
Flags_UnsetSwitch(play, BGCRACEMOVEBG_GET_7F0(thisx));
case BG_CRACE_MOVEBG_TYPE_OPENING:
Flags_UnsetSwitch(play, BG_CRACE_MOVEBG_GET_SWITCH_FLAG(thisx));
break;
}
}
@ -183,117 +209,147 @@ void BgCraceMovebg_Update(Actor* thisx, PlayState* play) {
BgCraceMovebg* this = THIS;
s32 pad;
Player* player = GET_PLAYER(play);
s16 tempRot;
s16 yawDiff;
switch (BGCRACEMOVEBG_GET_F(&this->dyna.actor)) {
case 0:
case 2:
tempRot = this->dyna.actor.yawTowardsPlayer - this->dyna.actor.home.rot.y;
if ((tempRot >= -0x4000) && (tempRot <= 0x4000)) {
switch (BG_CRACE_MOVEBG_GET_TYPE(&this->dyna.actor)) {
case BG_CRACE_MOVEBG_TYPE_CLOSING:
case BG_CRACE_MOVEBG_TYPE_UNUSED_CLOSING:
yawDiff = this->dyna.actor.yawTowardsPlayer - this->dyna.actor.home.rot.y;
if ((yawDiff >= -0x4000) && (yawDiff <= 0x4000)) {
this->dyna.actor.shape.rot.y = this->dyna.actor.home.rot.y;
} else {
this->dyna.actor.shape.rot.y = this->dyna.actor.home.rot.y + 0x8000;
}
break;
default:
this->actionFunc(this, play);
Math_Vec3f_Copy(&this->unk188, &player->bodyPartsPos[0]);
break;
}
this->actionFunc(this, play);
Math_Vec3f_Copy(&this->prevPlayerPos, &player->bodyPartsPos[0]);
}
void func_80A70C04(BgCraceMovebg* this, PlayState* play) {
/**
* Updates this door's flags if the player has moved beyond it. If the door is of type
* BG_CRACE_MOVEBG_TYPE_UNUSED_CLOSING, then nothing happens here, so the door never
* knows the player has moved beyond it.
*/
void BgCraceMovebg_ClosingDoor_CheckIfPlayerIsBeyondDoor(BgCraceMovebg* this, PlayState* play) {
s32 pad;
Player* player = GET_PLAYER(play);
Vec3f intersect;
Vec3f diff;
Vec3f posDiff;
if ((BGCRACEMOVEBG_GET_F(&this->dyna.actor) != 2) &&
SubS_LineSegVsPlane(&this->dyna.actor.home.pos, &this->dyna.actor.home.rot, D_80A710AC, &this->unk188,
if ((BG_CRACE_MOVEBG_GET_TYPE(&this->dyna.actor) != BG_CRACE_MOVEBG_TYPE_UNUSED_CLOSING) &&
SubS_LineSegVsPlane(&this->dyna.actor.home.pos, &this->dyna.actor.home.rot, &sUnitVecZ, &this->prevPlayerPos,
&player->bodyPartsPos[0], &intersect)) {
Matrix_RotateYS(-this->dyna.actor.home.rot.y, MTXMODE_NEW);
Math_Vec3f_Diff(&player->bodyPartsPos[0], &this->dyna.actor.home.pos, &diff);
Matrix_MultVec3f(&diff, &this->unk178);
if (fabsf(this->unk178.x) < 100.0f && this->unk178.y >= -10.0f && this->unk178.y <= 180.0f) {
if (this->unk178.z < 0.0f) {
Flags_SetSwitch(play, BGCRACEMOVEBG_GET_7F0(&this->dyna.actor) + 1);
this->unk170 |= 2;
Math_Vec3f_Diff(&player->bodyPartsPos[0], &this->dyna.actor.home.pos, &posDiff);
Matrix_MultVec3f(&posDiff, &this->intersectionOffsetFromHome);
if (fabsf(this->intersectionOffsetFromHome.x) < 100.0f && this->intersectionOffsetFromHome.y >= -10.0f &&
this->intersectionOffsetFromHome.y <= 180.0f) {
if (this->intersectionOffsetFromHome.z < 0.0f) {
Flags_SetSwitch(play, BG_CRACE_MOVEBG_GET_SWITCH_FLAG(&this->dyna.actor) + 1);
this->stateFlags |= BG_CRACE_MOVEBG_FLAG_PLAYER_IS_BEYOND_DOOR;
} else {
Flags_UnsetSwitch(play, BGCRACEMOVEBG_GET_7F0(&this->dyna.actor) + 1);
this->unk170 &= ~2;
Flags_UnsetSwitch(play, BG_CRACE_MOVEBG_GET_SWITCH_FLAG(&this->dyna.actor) + 1);
this->stateFlags &= ~BG_CRACE_MOVEBG_FLAG_PLAYER_IS_BEYOND_DOOR;
}
}
}
}
void func_80A70D74(BgCraceMovebg* this, PlayState* play) {
this->unk164 = 180.0f;
this->unk160 = 180.0f;
this->actionFunc = func_80A70DA8;
void BgCraceMovebg_ClosingDoor_SetupIdle(BgCraceMovebg* this, PlayState* play) {
this->targetDoorHeight = 180.0f;
this->doorHeight = 180.0f;
this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y + 180.0f;
this->actionFunc = BgCraceMovebg_ClosingDoor_Idle;
}
void func_80A70DA8(BgCraceMovebg* this, PlayState* play) {
this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y + this->unk160;
func_80A70C04(this, play);
if (this->unk170 & 1) {
func_80A70E2C(this, play);
/**
* Wait for the Deku Butler to move beyond the door, or wait for this door's switch flag
* to be set. In either case, start closing; how long to wait before closing depends on
* what triggered it to close.
*/
void BgCraceMovebg_ClosingDoor_Idle(BgCraceMovebg* this, PlayState* play) {
this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y + this->doorHeight;
BgCraceMovebg_ClosingDoor_CheckIfPlayerIsBeyondDoor(this, play);
if (this->stateFlags & BG_CRACE_MOVEBG_FLAG_BUTLER_IS_BEYOND_DOOR) {
BgCraceMovebg_ClosingDoor_SetupWaitToClose(this, play);
}
if (Flags_GetSwitch(play, BGCRACEMOVEBG_GET_7F0(&this->dyna.actor))) {
func_80A70F14(this, play);
if (Flags_GetSwitch(play, BG_CRACE_MOVEBG_GET_SWITCH_FLAG(&this->dyna.actor))) {
BgCraceMovebg_ClosingDoor_SetupClose(this, play);
}
}
void func_80A70E2C(BgCraceMovebg* this, PlayState* play) {
this->unk174 = BGCRACEMOVEBG_GET_F800(&this->dyna.actor) * 10;
this->unk164 = 180.0f;
this->unk160 = 180.0f;
this->actionFunc = func_80A70E70;
void BgCraceMovebg_ClosingDoor_SetupWaitToClose(BgCraceMovebg* this, PlayState* play) {
this->closeWaitTimer = BG_CRACE_MOVEBG_GET_CLOSE_WAIT_TIMER(&this->dyna.actor) * 10;
this->targetDoorHeight = 180.0f;
this->doorHeight = 180.0f;
this->actionFunc = BgCraceMovebg_ClosingDoor_WaitToClose;
}
void func_80A70E70(BgCraceMovebg* this, PlayState* play) {
if (this->unk174 > 0) {
this->unk174--;
/**
* Wait until the closeWaitTimer reaches 0, then set the door's switch flag and start closing.
*/
void BgCraceMovebg_ClosingDoor_WaitToClose(BgCraceMovebg* this, PlayState* play) {
if (this->closeWaitTimer > 0) {
this->closeWaitTimer--;
}
this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y + this->unk160;
func_80A70C04(this, play);
if (this->unk174 <= 0) {
this->unk160 = 180.0f;
this->unk164 = 0.0f;
this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y + this->doorHeight;
BgCraceMovebg_ClosingDoor_CheckIfPlayerIsBeyondDoor(this, play);
if (this->closeWaitTimer <= 0) {
this->doorHeight = 180.0f;
this->targetDoorHeight = 0.0f;
this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y + 180.0f;
Flags_SetSwitch(play, BGCRACEMOVEBG_GET_7F0(&this->dyna.actor));
func_80A70F14(this, play);
Flags_SetSwitch(play, BG_CRACE_MOVEBG_GET_SWITCH_FLAG(&this->dyna.actor));
BgCraceMovebg_ClosingDoor_SetupClose(this, play);
}
}
void func_80A70F14(BgCraceMovebg* this, PlayState* play) {
this->actionFunc = func_80A70F2C;
void BgCraceMovebg_ClosingDoor_SetupClose(BgCraceMovebg* this, PlayState* play) {
this->actionFunc = BgCraceMovebg_ClosingDoor_Close;
}
void func_80A70F2C(BgCraceMovebg* this, PlayState* play) {
this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y + this->unk160;
func_80A70C04(this, play);
if (Math_StepToF(&this->unk160, 0.0f, 1.0f)) {
if (!(this->unk170 & 2) && !Flags_GetSwitch(play, BGCRACEMOVEBG_GET_7F0(&this->dyna.actor) + 1)) {
/**
* Slowly slide closed, then check to see if the player is beyond the door. If the player has
* not moved beyond the door, trigger a voidout. Otherwise, do nothing.
*/
void BgCraceMovebg_ClosingDoor_Close(BgCraceMovebg* this, PlayState* play) {
this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y + this->doorHeight;
BgCraceMovebg_ClosingDoor_CheckIfPlayerIsBeyondDoor(this, play);
if (Math_StepToF(&this->doorHeight, 0.0f, 1.0f)) {
if (!(this->stateFlags & BG_CRACE_MOVEBG_FLAG_PLAYER_IS_BEYOND_DOOR) &&
!Flags_GetSwitch(play, BG_CRACE_MOVEBG_GET_SWITCH_FLAG(&this->dyna.actor) + 1)) {
play->unk_18845 = 1;
func_80169FDC(&play->state);
play_sound(NA_SE_OC_ABYSS);
}
func_80A70FF4(this, play);
BgCraceMovebg_ClosingDoor_SetupDoNothing(this, play);
} else {
func_800B9010(&this->dyna.actor, NA_SE_EV_STONEDOOR_CLOSE_S - SFX_FLAG);
}
}
void func_80A70FF4(BgCraceMovebg* this, PlayState* play) {
this->unk164 = 0.0f;
this->unk160 = 0.0f;
void BgCraceMovebg_ClosingDoor_SetupDoNothing(BgCraceMovebg* this, PlayState* play) {
this->targetDoorHeight = 0.0f;
this->doorHeight = 0.0f;
this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y;
Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_STONEDOOR_STOP);
this->actionFunc = func_80A71040;
this->actionFunc = BgCraceMovebg_ClosingDoor_DoNothing;
}
void func_80A71040(BgCraceMovebg* this, PlayState* play) {
void BgCraceMovebg_ClosingDoor_DoNothing(BgCraceMovebg* this, PlayState* play) {
}
void BgCraceMovebg_Draw(Actor* thisx, PlayState* play) {
Gfx_DrawDListOpa(play, object_crace_object_DL_0003A0);
Gfx_DrawDListOpa(play, gDekuShrineSlidingDoorDL);
}

View File

@ -8,23 +8,34 @@ struct BgCraceMovebg;
typedef void (*BgCraceMovebgActionFunc)(struct BgCraceMovebg*, PlayState*);
#define BGCRACEMOVEBG_GET_F(thisx) (((thisx)->params) & 0xF)
#define BGCRACEMOVEBG_GET_7F0(thisx) (((thisx)->params >> 4) & 0x7F)
#define BGCRACEMOVEBG_GET_3F80(thisx) (((thisx)->params >> 7) & 0x7F)
#define BGCRACEMOVEBG_GET_F800(thisx) (((thisx)->params >> 0xB) & 0x1F)
#define BG_CRACE_MOVEBG_GET_TYPE(thisx) (((thisx)->params) & 0xF)
#define BG_CRACE_MOVEBG_GET_SWITCH_FLAG(thisx) (((thisx)->params >> 4) & 0x7F)
#define BG_CRACE_MOVEBG_GET_CLOSE_WAIT_TIMER(thisx) (((thisx)->params >> 0xB) & 0x1F)
#define BG_CRACE_MOVEBG_GET_INDEX(thisx) ((thisx)->world.rot.x)
#define BG_CRACE_MOVEBG_GET_OPEN_SPEED(thisx) ((thisx)->world.rot.z)
#define BG_CRACE_MOVEBG_FLAG_BUTLER_IS_BEYOND_DOOR (1 << 0)
#define BG_CRACE_MOVEBG_FLAG_PLAYER_IS_BEYOND_DOOR (1 << 1)
#define BG_CRACE_MOVEBG_FLAG_ALREADY_LOADED (1 << 3)
typedef enum {
/* 0 */ BG_CRACE_MOVEBG_TYPE_CLOSING,
/* 1 */ BG_CRACE_MOVEBG_TYPE_OPENING,
/* 2 */ BG_CRACE_MOVEBG_TYPE_UNUSED_CLOSING // Not triggered to close by the Deku Butler, and triggers a voidout no matter which side of the door they're on.
} BgCraceMovebgType;
typedef struct BgCraceMovebg {
/* 0x000 */ DynaPolyActor dyna;
/* 0x15C */ BgCraceMovebgActionFunc actionFunc;
/* 0x160 */ f32 unk160;
/* 0x164 */ f32 unk164;
/* 0x160 */ f32 doorHeight;
/* 0x164 */ f32 targetDoorHeight;
/* 0x168 */ UNK_TYPE1 pad168[0x4];
/* 0x16C */ f32 unk16C;
/* 0x170 */ s32 unk170;
/* 0x174 */ s32 unk174;
/* 0x178 */ Vec3f unk178;
/* 0x184 */ u8 unk184;
/* 0x188 */ Vec3f unk188;
/* 0x16C */ f32 openSpeed;
/* 0x170 */ s32 stateFlags;
/* 0x174 */ s32 closeWaitTimer;
/* 0x178 */ Vec3f intersectionOffsetFromHome;
/* 0x184 */ u8 index;
/* 0x188 */ Vec3f prevPlayerPos;
} BgCraceMovebg; // size = 0x194
extern const ActorInit Bg_Crace_Movebg_InitVars;

View File

@ -122,8 +122,8 @@ void func_80A714B4(EnDno* this, PlayState* play) {
do {
actor = SubS_FindActor(play, actor, ACTORCAT_BG, ACTOR_BG_CRACE_MOVEBG);
if (actor != NULL) {
if (ENDNO_GET_F(actor) == ENDNO_GET_F_1) {
Flags_SetSwitch(play, ENDNO_GET_7F0(actor));
if (BG_CRACE_MOVEBG_GET_TYPE(actor) == BG_CRACE_MOVEBG_TYPE_OPENING) {
Flags_SetSwitch(play, BG_CRACE_MOVEBG_GET_SWITCH_FLAG(actor));
}
actor = actor->next;
}
@ -152,14 +152,15 @@ void func_80A715DC(EnDno* this, PlayState* play) {
do {
crace = (BgCraceMovebg*)SubS_FindActor(play, &crace->dyna.actor, ACTORCAT_BG, ACTOR_BG_CRACE_MOVEBG);
if (crace != NULL) {
if (ENDNO_GET_F(&crace->dyna.actor) == ENDNO_GET_F_0 && !(crace->unk170 & 1)) {
if (BG_CRACE_MOVEBG_GET_TYPE(&crace->dyna.actor) == BG_CRACE_MOVEBG_TYPE_CLOSING &&
!(crace->stateFlags & BG_CRACE_MOVEBG_FLAG_BUTLER_IS_BEYOND_DOOR)) {
if (SubS_LineSegVsPlane(&crace->dyna.actor.home.pos, &crace->dyna.actor.home.rot, &D_80A73B2C,
&this->actor.prevPos, &this->actor.world.pos, &sp88)) {
Math_Vec3f_Diff(&this->actor.world.pos, &crace->dyna.actor.home.pos, &sp7C);
Matrix_RotateYS(-crace->dyna.actor.home.rot.y, MTXMODE_NEW);
Matrix_MultVec3f(&sp7C, &sp70);
if ((fabsf(sp70.x) < 100.0f) && (sp70.y >= -10.0f) && (sp70.y <= 180.0f) && (sp70.z < 0.0f)) {
crace->unk170 |= 1;
crace->stateFlags |= BG_CRACE_MOVEBG_FLAG_BUTLER_IS_BEYOND_DOOR;
}
}
}
@ -174,7 +175,7 @@ void func_80A71788(EnDno* this, PlayState* play) {
do {
actor = SubS_FindActor(play, actor, ACTORCAT_BG, ACTOR_BG_CRACE_MOVEBG);
if (actor != NULL) {
Flags_UnsetSwitch(play, ENDNO_GET_7F0(actor));
Flags_UnsetSwitch(play, BG_CRACE_MOVEBG_GET_SWITCH_FLAG(actor));
actor = actor->next;
}
} while (actor != NULL);
@ -212,8 +213,8 @@ void EnDno_Init(Actor* thisx, PlayState* play) {
this->unk_468 = 99;
this->skelAnime.playSpeed = 0.0f;
switch (ENDNO_GET_C000(thisx)) {
case ENDNO_GET_C000_0:
switch (EN_DNO_GET_C000(thisx)) {
case EN_DNO_GET_C000_0:
func_80A71788(this, play);
if (!(gSaveContext.save.weekEventReg[23] & 0x20) || (gSaveContext.save.weekEventReg[93] & 2)) {
Actor_MarkForDeath(thisx);
@ -228,7 +229,7 @@ void EnDno_Init(Actor* thisx, PlayState* play) {
}
break;
case ENDNO_GET_C000_1:
case EN_DNO_GET_C000_1:
if (gSaveContext.save.weekEventReg[23] & 0x20) {
Actor_MarkForDeath(thisx);
} else {
@ -502,7 +503,7 @@ void func_80A72438(EnDno* this, PlayState* play) {
this->unk_452 = 1;
SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 14, &this->unk_32C);
this->actor.textId = 0;
if (Flags_GetSwitch(play, ENDNO_GET_3F80(&this->actor))) {
if (Flags_GetSwitch(play, EN_DNO_GET_RACE_STARTED_SWITCH_FLAG(&this->actor))) {
this->unk_454 = 1.0f;
}
this->actionFunc = func_80A724B8;
@ -549,7 +550,7 @@ void func_80A725F8(EnDno* this, PlayState* play) {
SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 5, &this->unk_32C);
}
} else if ((this->unk_32C == 5) && Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
if (Flags_GetSwitch(play, ENDNO_GET_3F80(&this->actor))) {
if (Flags_GetSwitch(play, EN_DNO_GET_RACE_STARTED_SWITCH_FLAG(&this->actor))) {
Message_StartTextbox(play, 0x801, &this->actor);
} else if (Player_GetMask(play) == PLAYER_MASK_SCENTS) {
Message_StartTextbox(play, 0x806, &this->actor);
@ -692,13 +693,13 @@ void func_80A72C04(EnDno* this, PlayState* play) {
this->actor.flags &= ~(ACTOR_FLAG_1 | ACTOR_FLAG_8);
Math_Vec3f_Copy(&this->unk_334, &this->actor.world.pos);
SubS_ActorPathing_Init(play, &this->unk_334, &this->actor, &this->actorPath, play->setupPathList,
ENDNO_GET_7F(&this->actor), 1, 0, 1, 0);
EN_DNO_GET_7F(&this->actor), 1, 0, 1, 0);
SubS_ActorPathing_ComputePointInfo(play, &this->actorPath);
this->actor.world.rot.y = this->actorPath.rotToCurPoint.y;
this->actor.world.rot.x = this->actorPath.rotToCurPoint.x;
Flags_SetSwitch(play, ENDNO_GET_3F80(&this->actor));
Flags_SetSwitch(play, EN_DNO_GET_RACE_STARTED_SWITCH_FLAG(&this->actor));
this->actionFunc = func_80A730A0;
}
@ -820,7 +821,7 @@ void func_80A73244(EnDno* this, PlayState* play) {
this->actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_8);
this->unk_328 = 2;
this->actor.speedXZ = 0.0f;
Flags_UnsetSwitch(play, ENDNO_GET_3F80(&this->actor));
Flags_UnsetSwitch(play, EN_DNO_GET_RACE_STARTED_SWITCH_FLAG(&this->actor));
gSaveContext.timerStates[TIMER_ID_MINIGAME_1] = TIMER_STATE_STOP;
this->unk_44E = 0;
this->actionFunc = func_80A732C8;

View File

@ -7,21 +7,14 @@ struct EnDno;
typedef void (*EnDnoActionFunc)(struct EnDno*, PlayState*);
#define ENDNO_GET_F(thisx) ((thisx)->params & 0xF)
#define ENDNO_GET_7F(thisx) ((thisx)->params & 0x7F)
#define ENDNO_GET_7F0(thisx) (((thisx)->params >> 4) & 0x7F)
#define ENDNO_GET_3F80(thisx) (((thisx)->params >> 7) & 0x7F)
#define ENDNO_GET_C000(thisx) (((thisx)->params >> 0xE) & 0x3)
#define EN_DNO_GET_7F(thisx) ((thisx)->params & 0x7F)
#define EN_DNO_GET_RACE_STARTED_SWITCH_FLAG(thisx) (((thisx)->params >> 7) & 0x7F)
#define EN_DNO_GET_C000(thisx) (((thisx)->params >> 0xE) & 0x3)
enum {
/* 0x0 */ ENDNO_GET_F_0,
/* 0x1 */ ENDNO_GET_F_1,
};
enum {
/* 0x0 */ ENDNO_GET_C000_0,
/* 0x1 */ ENDNO_GET_C000_1,
};
typedef enum {
/* 0x0 */ EN_DNO_GET_C000_0,
/* 0x1 */ EN_DNO_GET_C000_1,
} EnDnoUnkC000;
typedef struct EnDno {
/* 0x000 */ Actor actor;

View File

@ -10960,24 +10960,24 @@
0x80A702B0:("EnMm3_PostLimbDraw",),
0x80A702F0:("EnMm3_Draw",),
0x80A706F0:("BgCraceMovebg_Init",),
0x80A7090C:("func_80A7090C",),
0x80A70970:("func_80A70970",),
0x80A7099C:("func_80A7099C",),
0x80A709E4:("func_80A709E4",),
0x80A70A08:("func_80A70A08",),
0x80A70A84:("func_80A70A84",),
0x80A70A9C:("func_80A70A9C",),
0x80A7090C:("BgCraceMovebg_GetRaceStatus",),
0x80A70970:("BgCraceMovebg_OpeningDoor_SetupIdle",),
0x80A7099C:("BgCraceMovebg_OpeningDoor_WaitToOpen",),
0x80A709E4:("BgCraceMovebg_OpeningDoor_SetupOpen",),
0x80A70A08:("BgCraceMovebg_OpeningDoor_Open",),
0x80A70A84:("BgCraceMovebg_OpeningDoor_SetupDoNothing",),
0x80A70A9C:("BgCraceMovebg_OpeningDoor_DoNothing",),
0x80A70AAC:("BgCraceMovebg_Destroy",),
0x80A70B60:("BgCraceMovebg_Update",),
0x80A70C04:("func_80A70C04",),
0x80A70D74:("func_80A70D74",),
0x80A70DA8:("func_80A70DA8",),
0x80A70E2C:("func_80A70E2C",),
0x80A70E70:("func_80A70E70",),
0x80A70F14:("func_80A70F14",),
0x80A70F2C:("func_80A70F2C",),
0x80A70FF4:("func_80A70FF4",),
0x80A71040:("func_80A71040",),
0x80A70C04:("BgCraceMovebg_ClosingDoor_CheckIfPlayerIsBeyondDoor",),
0x80A70D74:("BgCraceMovebg_ClosingDoor_SetupIdle",),
0x80A70DA8:("BgCraceMovebg_ClosingDoor_Idle",),
0x80A70E2C:("BgCraceMovebg_ClosingDoor_SetupWaitToClose",),
0x80A70E70:("BgCraceMovebg_ClosingDoor_WaitToClose",),
0x80A70F14:("BgCraceMovebg_ClosingDoor_SetupClose",),
0x80A70F2C:("BgCraceMovebg_ClosingDoor_Close",),
0x80A70FF4:("BgCraceMovebg_ClosingDoor_SetupDoNothing",),
0x80A71040:("BgCraceMovebg_ClosingDoor_DoNothing",),
0x80A71050:("BgCraceMovebg_Draw",),
0x80A711D0:("func_80A711D0",),
0x80A71424:("func_80A71424",),

View File

@ -12095,12 +12095,12 @@
0x80A70510:("jtbl_80A70510","UNK_PTR","",0x4),
0x80A7056C:("jtbl_80A7056C","UNK_PTR","",0x4),
0x80A71080:("Bg_Crace_Movebg_InitVars","UNK_TYPE1","",0x1),
0x80A710A0:("D_80A710A0","UNK_TYPE1","",0x1),
0x80A710A4:("D_80A710A4","UNK_TYPE1","",0x1),
0x80A710A8:("D_80A710A8","UNK_TYPE1","",0x1),
0x80A710AC:("D_80A710AC","UNK_TYPE1","",0x1),
0x80A710A0:("sHasInitializedIsLoaded","UNK_TYPE1","",0x1),
0x80A710A4:("sLoadedDoorCount","UNK_TYPE1","",0x1),
0x80A710A8:("sInitChain","UNK_TYPE1","",0x1),
0x80A710AC:("sUnitVecZ","UNK_TYPE1","",0x1),
0x80A710C0:("D_80A710C0","f32","",0x4),
0x80A711B0:("D_80A711B0","UNK_TYPE1","",0x1),
0x80A711B0:("sIsLoaded","UNK_TYPE1","",0x1),
0x80A739A0:("D_80A739A0","UNK_PTR","",0x4),
0x80A73AE0:("En_Dno_InitVars","UNK_TYPE1","",0x1),
0x80A73B00:("D_80A73B00","UNK_TYPE1","",0x1),