mirror of
https://github.com/zeldaret/oot.git
synced 2025-07-03 22:44:30 +00:00
Match and fully document bg_ddan_jd (#386)
* match and fully document bg_ddan_jd * fix comment * implemented suggested changes, minor fixes * more changes * implement requested changes, tweak wording on ySpeed comments * more minor tweaks
This commit is contained in:
parent
e93d604ff7
commit
83fc21fea6
13 changed files with 157 additions and 454 deletions
|
@ -15,11 +15,12 @@ void BgDdanJd_Destroy(Actor* thisx, GlobalContext* globalCtx);
|
|||
void BgDdanJd_Update(Actor* thisx, GlobalContext* globalCtx);
|
||||
void BgDdanJd_Draw(Actor* thisx, GlobalContext* globalCtx);
|
||||
|
||||
void func_80870B88(BgDdanJd* this, GlobalContext* globalCtx);
|
||||
void func_80870D2C(BgDdanJd* this, GlobalContext* globalCtx);
|
||||
void func_80870F00(BgDdanJd* this, GlobalContext* globalCtx);
|
||||
void BgDdanJd_Idle(BgDdanJd* this, GlobalContext* globalCtx);
|
||||
void BgDdanJd_Move(BgDdanJd* this, GlobalContext* globalCtx);
|
||||
|
||||
extern Gfx D_060037B8[];
|
||||
extern ColHeader D_06003CE0;
|
||||
|
||||
/*
|
||||
const ActorInit Bg_Ddan_Jd_InitVars = {
|
||||
ACTOR_BG_DDAN_JD,
|
||||
ACTORTYPE_BG,
|
||||
|
@ -31,17 +32,152 @@ const ActorInit Bg_Ddan_Jd_InitVars = {
|
|||
(ActorFunc)BgDdanJd_Update,
|
||||
(ActorFunc)BgDdanJd_Draw,
|
||||
};
|
||||
*/
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Ddan_Jd/BgDdanJd_Init.s")
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Ddan_Jd/BgDdanJd_Destroy.s")
|
||||
static InitChainEntry sInitChain[] = {
|
||||
ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP),
|
||||
};
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Ddan_Jd/func_80870B88.s")
|
||||
typedef enum {
|
||||
STATE_GO_BOTTOM,
|
||||
STATE_GO_MIDDLE_FROM_BOTTOM,
|
||||
STATE_GO_MIDDLE_FROM_TOP,
|
||||
STATE_GO_TOP,
|
||||
} BgDdanJdState;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Ddan_Jd/func_80870D2C.s")
|
||||
#define MOVE_HEIGHT_MIDDLE 140.0f
|
||||
#define MOVE_HEIGHT_TOP 700.0f
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Ddan_Jd/func_80870F00.s")
|
||||
#define IDLE_FRAMES 100
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Ddan_Jd/BgDdanJd_Update.s")
|
||||
// Since ySpeed is used to determine if the platform should rise to the top of the dungeon, these must be assigned
|
||||
// different values in order for the shortcut to work correctly
|
||||
#define DEFAULT_Y_SPEED 1
|
||||
#define SHORTCUT_Y_SPEED 5
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Ddan_Jd/BgDdanJd_Draw.s")
|
||||
void BgDdanJd_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
BgDdanJd* this = THIS;
|
||||
s32 pad;
|
||||
ColHeader* colHeader = NULL;
|
||||
|
||||
Actor_ProcessInitChain(thisx, sInitChain);
|
||||
DynaPolyInfo_SetActorMove(thisx, DPM_PLAYER);
|
||||
DynaPolyInfo_Alloc(&D_06003CE0, &colHeader);
|
||||
this->dyna.dynaPolyId = DynaPolyInfo_RegisterActor(globalCtx, &globalCtx->colCtx.dyna, thisx, colHeader);
|
||||
this->idleTimer = IDLE_FRAMES;
|
||||
this->state = STATE_GO_BOTTOM;
|
||||
|
||||
// Missing check for actor.params < 0x40. This will cause inconsistent behavior if params >= 0x40 and the bound
|
||||
// switch state is turned on while in the same room, as the shortcut behavior won't become enabled until the actor
|
||||
// is reloaded.
|
||||
if (Flags_GetSwitch(globalCtx, this->dyna.actor.params)) {
|
||||
this->ySpeed = SHORTCUT_Y_SPEED;
|
||||
} else {
|
||||
this->ySpeed = DEFAULT_Y_SPEED;
|
||||
}
|
||||
this->actionFunc = BgDdanJd_Idle;
|
||||
}
|
||||
|
||||
void BgDdanJd_Destroy(Actor* thisx, GlobalContext* globalCtx) {
|
||||
BgDdanJd* this = THIS;
|
||||
|
||||
DynaPolyInfo_Free(globalCtx, &globalCtx->colCtx.dyna, this->dyna.dynaPolyId);
|
||||
}
|
||||
|
||||
void BgDdanJd_Idle(BgDdanJd* this, GlobalContext* globalCtx) {
|
||||
if (this->idleTimer != 0) {
|
||||
this->idleTimer--;
|
||||
}
|
||||
|
||||
// if this is the platform that rises all the way to the top, and the switch state has just changed to on
|
||||
if (this->ySpeed == DEFAULT_Y_SPEED && this->dyna.actor.params < 0x40 &&
|
||||
Flags_GetSwitch(globalCtx, this->dyna.actor.params)) {
|
||||
this->ySpeed = SHORTCUT_Y_SPEED;
|
||||
this->state = STATE_GO_MIDDLE_FROM_BOTTOM;
|
||||
this->idleTimer = 0;
|
||||
this->dyna.actor.posRot.pos.y = this->dyna.actor.initPosRot.pos.y + MOVE_HEIGHT_MIDDLE;
|
||||
func_800800F8(globalCtx, 0xBF4, -0x63, &this->dyna.actor, 0);
|
||||
}
|
||||
if (this->idleTimer == 0) {
|
||||
this->idleTimer = IDLE_FRAMES;
|
||||
if (this->state == STATE_GO_BOTTOM) {
|
||||
this->state = STATE_GO_MIDDLE_FROM_BOTTOM;
|
||||
this->targetY = this->dyna.actor.initPosRot.pos.y + MOVE_HEIGHT_MIDDLE;
|
||||
} else if (this->state == STATE_GO_MIDDLE_FROM_BOTTOM) {
|
||||
// If the platform has been activated as a shortcut
|
||||
if (this->ySpeed != DEFAULT_Y_SPEED) {
|
||||
this->state = STATE_GO_TOP;
|
||||
this->targetY = this->dyna.actor.initPosRot.pos.y + MOVE_HEIGHT_TOP;
|
||||
} else {
|
||||
this->state = STATE_GO_BOTTOM;
|
||||
this->targetY = this->dyna.actor.initPosRot.pos.y;
|
||||
}
|
||||
} else if (this->state == STATE_GO_MIDDLE_FROM_TOP) {
|
||||
// If the platform has been activated as a shortcut
|
||||
if (this->ySpeed != DEFAULT_Y_SPEED) {
|
||||
this->state = STATE_GO_TOP;
|
||||
this->targetY = this->dyna.actor.initPosRot.pos.y + MOVE_HEIGHT_TOP;
|
||||
} else {
|
||||
this->state = STATE_GO_BOTTOM;
|
||||
this->targetY = this->dyna.actor.initPosRot.pos.y;
|
||||
}
|
||||
} else if (this->state == STATE_GO_TOP) {
|
||||
this->state = STATE_GO_MIDDLE_FROM_TOP;
|
||||
this->targetY = this->dyna.actor.initPosRot.pos.y + MOVE_HEIGHT_MIDDLE;
|
||||
}
|
||||
this->actionFunc = BgDdanJd_Move;
|
||||
}
|
||||
}
|
||||
|
||||
// Handles dust particles and sfx when moving
|
||||
void BgDdanJd_MoveEffects(BgDdanJd* this, GlobalContext* globalCtx) {
|
||||
Vec3f dustPos;
|
||||
|
||||
// Generate random dust particles at the platform's base.
|
||||
dustPos.y = this->dyna.actor.initPosRot.pos.y;
|
||||
if (globalCtx->gameplayFrames & 1) {
|
||||
dustPos.x = this->dyna.actor.posRot.pos.x + 65.0f;
|
||||
dustPos.z = Math_Rand_CenteredFloat(110.0f) + this->dyna.actor.posRot.pos.z;
|
||||
func_80033480(globalCtx, &dustPos, 5.0f, 1, 20, 60, 1);
|
||||
dustPos.x = this->dyna.actor.posRot.pos.x - 65.0f;
|
||||
dustPos.z = Math_Rand_CenteredFloat(110.0f) + this->dyna.actor.posRot.pos.z;
|
||||
func_80033480(globalCtx, &dustPos, 5.0f, 1, 20, 60, 1);
|
||||
} else {
|
||||
dustPos.x = Math_Rand_CenteredFloat(110.0f) + this->dyna.actor.posRot.pos.x;
|
||||
dustPos.z = this->dyna.actor.posRot.pos.z + 65.0f;
|
||||
func_80033480(globalCtx, &dustPos, 5.0f, 1, 20, 60, 1);
|
||||
dustPos.x = Math_Rand_CenteredFloat(110.0f) + this->dyna.actor.posRot.pos.x;
|
||||
dustPos.z = this->dyna.actor.posRot.pos.z - 65.0f;
|
||||
func_80033480(globalCtx, &dustPos, 5.0f, 1, 20, 60, 1);
|
||||
}
|
||||
if (this->ySpeed == SHORTCUT_Y_SPEED) {
|
||||
func_8002F974(&this->dyna.actor, NA_SE_EV_ELEVATOR_MOVE - SFX_FLAG);
|
||||
}
|
||||
}
|
||||
|
||||
// Implements the platform's movement state
|
||||
void BgDdanJd_Move(BgDdanJd* this, GlobalContext* globalCtx) {
|
||||
// if this is the platform that rises all the way to the top, and the switch state has just changed to on
|
||||
if (this->ySpeed == DEFAULT_Y_SPEED && this->dyna.actor.params < 0x40 &&
|
||||
Flags_GetSwitch(globalCtx, this->dyna.actor.params)) {
|
||||
this->ySpeed = SHORTCUT_Y_SPEED;
|
||||
this->state = STATE_GO_MIDDLE_FROM_BOTTOM;
|
||||
this->dyna.actor.posRot.pos.y = this->dyna.actor.initPosRot.pos.y + MOVE_HEIGHT_MIDDLE;
|
||||
this->idleTimer = 0;
|
||||
this->actionFunc = BgDdanJd_Idle;
|
||||
func_800800F8(globalCtx, 0xBF4, -0x63, &this->dyna.actor, 0);
|
||||
} else if (Math_ApproxF(&this->dyna.actor.posRot.pos.y, this->targetY, this->ySpeed)) {
|
||||
Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_PILLAR_MOVE_STOP);
|
||||
this->actionFunc = BgDdanJd_Idle;
|
||||
}
|
||||
BgDdanJd_MoveEffects(this, globalCtx);
|
||||
}
|
||||
|
||||
void BgDdanJd_Update(Actor* thisx, GlobalContext* globalCtx) {
|
||||
BgDdanJd* this = THIS;
|
||||
|
||||
this->actionFunc(this, globalCtx);
|
||||
}
|
||||
|
||||
void BgDdanJd_Draw(Actor* thisx, GlobalContext* globalCtx) {
|
||||
Gfx_DrawDListOpa(globalCtx, D_060037B8);
|
||||
}
|
||||
|
|
|
@ -11,7 +11,10 @@ typedef void (*BgDdanJdActionFunc)(struct BgDdanJd*, GlobalContext*);
|
|||
typedef struct BgDdanJd {
|
||||
/* 0x0000 */ DynaPolyActor dyna;
|
||||
/* 0x0164 */ BgDdanJdActionFunc actionFunc;
|
||||
/* 0x0168 */ char unk_168[0x8];
|
||||
/* 0x0168 */ u8 state;
|
||||
/* 0x0169 */ u8 ySpeed; // also differentiates between normal and shortcut platform behavior
|
||||
/* 0x016A */ s16 idleTimer;
|
||||
/* 0x016C */ f32 targetY;
|
||||
} BgDdanJd; // size = 0x0170
|
||||
|
||||
extern const ActorInit Bg_Ddan_Jd_InitVars;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue