mirror of
https://github.com/zeldaret/oot
synced 2026-05-23 06:54:24 -04:00
z_bg_haka_zou documentation pass (#2687)
* document z_bg_haka_zou * suggestions * dragorn suggestions
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* File: z_bg_haka_zou.c
|
||||
* Overlay: ovl_Bg_Haka_Zou
|
||||
* Description: Statue and Wall (Shadow Temple)
|
||||
* Description: Bombable Shadow Temple themed objects
|
||||
*/
|
||||
|
||||
#include "z_bg_haka_zou.h"
|
||||
@@ -20,26 +20,19 @@
|
||||
|
||||
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
|
||||
|
||||
typedef enum ShadowTempleAssetsType {
|
||||
/* 0x0 */ STA_GIANT_BIRD_STATUE,
|
||||
/* 0x1 */ STA_BOMBABLE_SKULL_WALL,
|
||||
/* 0x2 */ STA_BOMBABLE_RUBBLE,
|
||||
/* 0x3 */ STA_UNKNOWN
|
||||
} ShadowTempleAssetsType;
|
||||
|
||||
void BgHakaZou_Init(Actor* thisx, PlayState* play);
|
||||
void BgHakaZou_Destroy(Actor* thisx, PlayState* play);
|
||||
void BgHakaZou_Update(Actor* thisx, PlayState* play);
|
||||
void BgHakaZou_Draw(Actor* thisx, PlayState* play);
|
||||
|
||||
void BgHakaZou_Wait(BgHakaZou* this, PlayState* play);
|
||||
void func_80882BDC(BgHakaZou* this, PlayState* play);
|
||||
void func_80883000(BgHakaZou* this, PlayState* play);
|
||||
void func_80883104(BgHakaZou* this, PlayState* play);
|
||||
void func_80883144(BgHakaZou* this, PlayState* play);
|
||||
void func_80883254(BgHakaZou* this, PlayState* play);
|
||||
void func_80883328(BgHakaZou* this, PlayState* play);
|
||||
void func_808834D8(BgHakaZou* this, PlayState* play);
|
||||
void BgHakaZou_WaitForObject(BgHakaZou* this, PlayState* play);
|
||||
void BgHakaZou_CrumbleSkullWall(BgHakaZou* this, PlayState* play);
|
||||
void BgHakaZou_WaitForHit(BgHakaZou* this, PlayState* play);
|
||||
void BgHakaZou_IdleKill(BgHakaZou* this, PlayState* play);
|
||||
void BgHakaZou_BirdStatueAnim_Explode(BgHakaZou* this, PlayState* play);
|
||||
void BgHakaZou_BirdStatueAnim_Shear(BgHakaZou* this, PlayState* play);
|
||||
void BgHakaZou_BirdStatueAnim_Topple(BgHakaZou* this, PlayState* play);
|
||||
void BgHakaZou_BirdStatueAnim_Settle(BgHakaZou* this, PlayState* play);
|
||||
void BgHakaZou_DoNothing(BgHakaZou* this, PlayState* play);
|
||||
|
||||
static ColliderCylinderInit sCylinderInit = {
|
||||
@@ -90,7 +83,7 @@ void BgHakaZou_Init(Actor* thisx, PlayState* play) {
|
||||
this->switchFlag = PARAMS_GET_U(thisx->params, 8, 8);
|
||||
thisx->params &= 0xFF;
|
||||
|
||||
if (thisx->params == STA_UNKNOWN) {
|
||||
if (thisx->params == BGHAKAZOU_TYPE_SKULL_WALL_RUBBLE) {
|
||||
Actor_SetScale(thisx, (Rand_ZeroOne() * 0.005f) + 0.025f);
|
||||
|
||||
thisx->speed = Rand_ZeroOne();
|
||||
@@ -105,36 +98,38 @@ void BgHakaZou_Init(Actor* thisx, PlayState* play) {
|
||||
|
||||
DynaPolyActor_Init(&this->dyna, 0);
|
||||
|
||||
if (thisx->params == STA_GIANT_BIRD_STATUE) {
|
||||
if (thisx->params == BGHAKAZOU_TYPE_GIANT_BIRD_STATUE) {
|
||||
thisx->cullingVolumeDistance = 2000.0f;
|
||||
thisx->cullingVolumeScale = 3000.0f;
|
||||
thisx->cullingVolumeDownward = 3000.0f;
|
||||
}
|
||||
}
|
||||
|
||||
this->requiredObjectSlot = (thisx->params == STA_BOMBABLE_RUBBLE)
|
||||
this->requiredObjectSlot = (thisx->params == BGHAKAZOU_TYPE_BOMBABLE_RUBBLE)
|
||||
? Object_GetSlot(&play->objectCtx, OBJECT_HAKACH_OBJECTS)
|
||||
: Object_GetSlot(&play->objectCtx, OBJECT_HAKA_OBJECTS);
|
||||
|
||||
if (this->requiredObjectSlot < 0) {
|
||||
Actor_Kill(thisx);
|
||||
} else if ((thisx->params != STA_UNKNOWN) && Flags_GetSwitch(play, this->switchFlag)) {
|
||||
if (thisx->params != STA_GIANT_BIRD_STATUE) {
|
||||
} else if (thisx->params != BGHAKAZOU_TYPE_SKULL_WALL_RUBBLE && Flags_GetSwitch(play, this->switchFlag)) {
|
||||
if (thisx->params != BGHAKAZOU_TYPE_GIANT_BIRD_STATUE) {
|
||||
// Object has already been destroyed
|
||||
Actor_Kill(thisx);
|
||||
} else {
|
||||
// Initialize the statue toppled over
|
||||
thisx->shape.rot.x = -0x4000;
|
||||
thisx->world.pos.z -= 80.0f;
|
||||
thisx->world.pos.y -= 54.0f;
|
||||
thisx->world.pos.y -= 40 + 14;
|
||||
}
|
||||
}
|
||||
|
||||
this->actionFunc = BgHakaZou_Wait;
|
||||
this->actionFunc = BgHakaZou_WaitForObject;
|
||||
}
|
||||
|
||||
void BgHakaZou_Destroy(Actor* thisx, PlayState* play) {
|
||||
BgHakaZou* this = (BgHakaZou*)thisx;
|
||||
|
||||
if (this->dyna.actor.params != STA_UNKNOWN) {
|
||||
if (this->dyna.actor.params != BGHAKAZOU_TYPE_SKULL_WALL_RUBBLE) {
|
||||
DynaPoly_DeleteBgActor(play, &play->colCtx.dyna, this->dyna.bgId);
|
||||
Collider_DestroyCylinder(play, &this->collider);
|
||||
}
|
||||
@@ -165,48 +160,49 @@ void func_808828F4(BgHakaZou* this, PlayState* play) {
|
||||
}
|
||||
}
|
||||
|
||||
void BgHakaZou_Wait(BgHakaZou* this, PlayState* play) {
|
||||
CollisionHeader* colHeader;
|
||||
void BgHakaZou_WaitForObject(BgHakaZou* this, PlayState* play) {
|
||||
|
||||
if (Object_IsLoaded(&play->objectCtx, this->requiredObjectSlot)) {
|
||||
this->dyna.actor.objectSlot = this->requiredObjectSlot;
|
||||
this->dyna.actor.draw = BgHakaZou_Draw;
|
||||
|
||||
if (this->dyna.actor.params == STA_UNKNOWN) {
|
||||
this->actionFunc = func_80882BDC;
|
||||
if (this->dyna.actor.params == BGHAKAZOU_TYPE_SKULL_WALL_RUBBLE) {
|
||||
this->actionFunc = BgHakaZou_CrumbleSkullWall;
|
||||
} else {
|
||||
Actor_SetObjectDependency(play, &this->dyna.actor);
|
||||
CollisionHeader* colHeader;
|
||||
|
||||
Actor_SetObjectDependency(play, &this->dyna.actor);
|
||||
colHeader = NULL;
|
||||
|
||||
if (this->dyna.actor.params == STA_GIANT_BIRD_STATUE) {
|
||||
CollisionHeader_GetVirtual(&object_haka_objects_Col_006F70, &colHeader);
|
||||
if (this->dyna.actor.params == BGHAKAZOU_TYPE_GIANT_BIRD_STATUE) {
|
||||
CollisionHeader_GetVirtual(&gShadowTempleBirdStatueCol, &colHeader);
|
||||
this->collider.dim.radius = 80;
|
||||
this->collider.dim.height = 100;
|
||||
this->collider.dim.yShift = -30;
|
||||
this->collider.dim.pos.x -= 56;
|
||||
this->collider.dim.pos.z += 56;
|
||||
this->dyna.actor.cullingVolumeScale = 1500.0f;
|
||||
} else if (this->dyna.actor.params == STA_BOMBABLE_SKULL_WALL) {
|
||||
CollisionHeader_GetVirtual(&object_haka_objects_Col_005E30, &colHeader);
|
||||
} else if (this->dyna.actor.params == BGHAKAZOU_TYPE_BOMBABLE_SKULL_WALL) {
|
||||
CollisionHeader_GetVirtual(&gShadowTempleSkullWallCol, &colHeader);
|
||||
this->collider.dim.yShift = -50;
|
||||
} else {
|
||||
CollisionHeader_GetVirtual(&gBotwBombSpotCol, &colHeader);
|
||||
} else /* BGHAKAZOU_TYPE_BOMBABLE_RUBBLE */ {
|
||||
CollisionHeader_GetVirtual(&gBotwBombableRubbleCol, &colHeader);
|
||||
this->collider.dim.radius = 55;
|
||||
this->collider.dim.height = 20;
|
||||
}
|
||||
|
||||
this->dyna.bgId = DynaPoly_SetBgActor(play, &play->colCtx.dyna, &this->dyna.actor, colHeader);
|
||||
|
||||
if ((this->dyna.actor.params == STA_GIANT_BIRD_STATUE) && Flags_GetSwitch(play, this->switchFlag)) {
|
||||
if ((this->dyna.actor.params == BGHAKAZOU_TYPE_GIANT_BIRD_STATUE) &&
|
||||
Flags_GetSwitch(play, this->switchFlag)) {
|
||||
this->actionFunc = BgHakaZou_DoNothing;
|
||||
} else {
|
||||
this->actionFunc = func_80883000;
|
||||
this->actionFunc = BgHakaZou_WaitForHit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void func_80882BDC(BgHakaZou* this, PlayState* play) {
|
||||
void BgHakaZou_CrumbleSkullWall(BgHakaZou* this, PlayState* play) {
|
||||
if (this->timer != 0) {
|
||||
this->timer--;
|
||||
}
|
||||
@@ -230,7 +226,7 @@ void func_80882BDC(BgHakaZou* this, PlayState* play) {
|
||||
}
|
||||
}
|
||||
|
||||
void func_80882CC4(BgHakaZou* this, PlayState* play) {
|
||||
void BgHakaZou_SpawnSkullWallRubble(BgHakaZou* this, PlayState* play) {
|
||||
s32 i;
|
||||
s32 j;
|
||||
Vec3f actorSpawnPos;
|
||||
@@ -248,13 +244,14 @@ void func_80882CC4(BgHakaZou* this, PlayState* play) {
|
||||
actorSpawnPos.y = this->dyna.actor.world.pos.y + (i - 1) * 55;
|
||||
|
||||
Actor_Spawn(&play->actorCtx, play, ACTOR_BG_HAKA_ZOU, actorSpawnPos.x, actorSpawnPos.y, actorSpawnPos.z, 0,
|
||||
this->dyna.actor.shape.rot.y, 0, this->dyna.actor.params + 2);
|
||||
this->dyna.actor.shape.rot.y, 0,
|
||||
this->dyna.actor.params + 2); // this passes BGHAKAZOU_TYPE_SKULL_WALL_RUBBLE into params
|
||||
func_800286CC(play, &actorSpawnPos, &sZeroVec, &sZeroVec, 1000, 50);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void func_80882E54(BgHakaZou* this, PlayState* play) {
|
||||
void BgHakaZou_SpawnRubbleParticles(BgHakaZou* this, PlayState* play) {
|
||||
Vec3f fragmentPos;
|
||||
s32 i;
|
||||
s32 j;
|
||||
@@ -264,44 +261,44 @@ void func_80882E54(BgHakaZou* this, PlayState* play) {
|
||||
fragmentPos.y = this->collider.dim.pos.y;
|
||||
fragmentPos.z = this->collider.dim.pos.z;
|
||||
|
||||
EffectSsHahen_SpawnBurst(play, &fragmentPos, 10.0f, 0, 10, 10, 4, 141, 40, gBotwBombSpotDL);
|
||||
EffectSsHahen_SpawnBurst(play, &fragmentPos, 10.0f, 0, 10, 10, 4, 141, 40, gBotwBombableRubbleDL);
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
for (j = 0; j < 2; j++) {
|
||||
fragmentPos.x = this->collider.dim.pos.x + (((j * 2) - 1) * num);
|
||||
fragmentPos.z = this->collider.dim.pos.z + (((i * 2) - 1) * num);
|
||||
EffectSsHahen_SpawnBurst(play, &fragmentPos, 10.0f, 0, 10, 10, 4, 141, 40, gBotwBombSpotDL);
|
||||
EffectSsHahen_SpawnBurst(play, &fragmentPos, 10.0f, 0, 10, 10, 4, 141, 40, gBotwBombableRubbleDL);
|
||||
func_800286CC(play, &fragmentPos, &sZeroVec, &sZeroVec, 1000, 50);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void func_80883000(BgHakaZou* this, PlayState* play) {
|
||||
void BgHakaZou_WaitForHit(BgHakaZou* this, PlayState* play) {
|
||||
if (this->collider.base.acFlags & AC_HIT) {
|
||||
Flags_SetSwitch(play, this->switchFlag);
|
||||
|
||||
if (this->dyna.actor.params == STA_GIANT_BIRD_STATUE) {
|
||||
if (this->dyna.actor.params == BGHAKAZOU_TYPE_GIANT_BIRD_STATUE) {
|
||||
this->timer = 20;
|
||||
this->actionFunc = func_80883144;
|
||||
this->actionFunc = BgHakaZou_BirdStatueAnim_Explode;
|
||||
OnePointCutscene_Init(play, 3400, 999, &this->dyna.actor, CAM_ID_MAIN);
|
||||
} else if (this->dyna.actor.params == 2) {
|
||||
func_80882E54(this, play);
|
||||
} else if (this->dyna.actor.params == BGHAKAZOU_TYPE_BOMBABLE_RUBBLE) {
|
||||
BgHakaZou_SpawnRubbleParticles(this, play);
|
||||
this->dyna.actor.draw = NULL;
|
||||
this->timer = 1;
|
||||
Actor_PlaySfx(&this->dyna.actor, NA_SE_EV_EXPLOSION);
|
||||
this->actionFunc = func_80883104;
|
||||
} else {
|
||||
func_80882CC4(this, play);
|
||||
this->actionFunc = BgHakaZou_IdleKill;
|
||||
} else /* BGHAKAZOU_TYPE_BOMBABLE_SKULL_WALL */ {
|
||||
BgHakaZou_SpawnSkullWallRubble(this, play);
|
||||
this->timer = 1;
|
||||
Actor_PlaySfx(&this->dyna.actor, NA_SE_EV_WALL_BROKEN);
|
||||
this->actionFunc = func_80883104;
|
||||
this->actionFunc = BgHakaZou_IdleKill;
|
||||
}
|
||||
} else {
|
||||
CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider.base);
|
||||
}
|
||||
}
|
||||
|
||||
void func_80883104(BgHakaZou* this, PlayState* play) {
|
||||
void BgHakaZou_IdleKill(BgHakaZou* this, PlayState* play) {
|
||||
if (this->timer != 0) {
|
||||
this->timer--;
|
||||
}
|
||||
@@ -311,7 +308,7 @@ void func_80883104(BgHakaZou* this, PlayState* play) {
|
||||
}
|
||||
}
|
||||
|
||||
void func_80883144(BgHakaZou* this, PlayState* play) {
|
||||
void BgHakaZou_BirdStatueAnim_Explode(BgHakaZou* this, PlayState* play) {
|
||||
Vec3f explosionPos;
|
||||
|
||||
if (this->timer != 0) {
|
||||
@@ -329,11 +326,11 @@ void func_80883144(BgHakaZou* this, PlayState* play) {
|
||||
|
||||
if (this->timer == 0) {
|
||||
this->timer = 20;
|
||||
this->actionFunc = func_80883254;
|
||||
this->actionFunc = BgHakaZou_BirdStatueAnim_Shear;
|
||||
}
|
||||
}
|
||||
|
||||
void func_80883254(BgHakaZou* this, PlayState* play) {
|
||||
void BgHakaZou_BirdStatueAnim_Shear(BgHakaZou* this, PlayState* play) {
|
||||
f32 moveDist = (Rand_ZeroOne() * 0.5f) + 0.5f;
|
||||
|
||||
Math_StepToF(&this->dyna.actor.world.pos.z, this->dyna.actor.home.pos.z - 80.0f, 2.0f * moveDist);
|
||||
@@ -346,14 +343,14 @@ void func_80883254(BgHakaZou* this, PlayState* play) {
|
||||
if (this->timer == 0) {
|
||||
this->timer = 60;
|
||||
this->dyna.actor.world.rot.x = 8;
|
||||
this->actionFunc = func_80883328;
|
||||
this->actionFunc = BgHakaZou_BirdStatueAnim_Topple;
|
||||
}
|
||||
} else {
|
||||
func_808828F4(this, play);
|
||||
}
|
||||
}
|
||||
|
||||
void func_80883328(BgHakaZou* this, PlayState* play) {
|
||||
void BgHakaZou_BirdStatueAnim_Topple(BgHakaZou* this, PlayState* play) {
|
||||
Vec3f effectPos;
|
||||
s32 i;
|
||||
s32 j;
|
||||
@@ -377,19 +374,30 @@ void func_80883328(BgHakaZou* this, PlayState* play) {
|
||||
|
||||
Actor_PlaySfx(&this->dyna.actor, NA_SE_EV_STONE_BOUND);
|
||||
this->timer = 25;
|
||||
this->actionFunc = func_808834D8;
|
||||
this->actionFunc = BgHakaZou_BirdStatueAnim_Settle;
|
||||
}
|
||||
}
|
||||
|
||||
void func_808834D8(BgHakaZou* this, PlayState* play) {
|
||||
void BgHakaZou_BirdStatueAnim_Settle(BgHakaZou* this, PlayState* play) {
|
||||
f32 moveDist;
|
||||
|
||||
if (this->timer != 0) {
|
||||
this->timer--;
|
||||
}
|
||||
|
||||
// The idea is to shake the pillar up and down on alternate frames, with the magnitude of the shaking decreasing
|
||||
// linearly as the timer approaches zero. With an even numbered starting timer, the pillar will go up one frame,
|
||||
// down the next with the same magnitude, cancelling out any movement (except perhaps for some miniscule rounding
|
||||
// error). However, the starting timer is set to 25, (an odd number). This skips the increment step and shifts the
|
||||
// pillar down an extra -14.4 units.
|
||||
//
|
||||
// The programmer was likely aware of a discrepancy as BgHakaZou_Init subtracts 14 units to account for this
|
||||
// (resulting in a 0.4 unit discrepancy between post animation and the next time the actor is reloaded). Lowering
|
||||
// the statue 14 units causes the model to clip into the ground, but it is also enough to make the pillar low enough
|
||||
// for Link to climb on top of it if the player is missing keys.
|
||||
|
||||
moveDist = (this->timer % 2) ? 15.0f : -15.0f;
|
||||
this->dyna.actor.world.pos.y += ((this->timer & 0xFE) * 0.04f * moveDist);
|
||||
this->dyna.actor.world.pos.y += ((this->timer & 0xFE) * (1.0f / 25) * moveDist);
|
||||
|
||||
if (this->timer == 0) {
|
||||
this->actionFunc = BgHakaZou_DoNothing;
|
||||
@@ -404,17 +412,17 @@ void BgHakaZou_Update(Actor* thisx, PlayState* play) {
|
||||
|
||||
this->actionFunc(this, play);
|
||||
|
||||
if (this->dyna.actor.params == 3) {
|
||||
if (this->dyna.actor.params == BGHAKAZOU_TYPE_SKULL_WALL_RUBBLE) {
|
||||
Actor_MoveXZGravity(&this->dyna.actor);
|
||||
}
|
||||
}
|
||||
|
||||
void BgHakaZou_Draw(Actor* thisx, PlayState* play) {
|
||||
static Gfx* dLists[] = {
|
||||
object_haka_objects_DL_0064E0,
|
||||
object_haka_objects_DL_005CE0,
|
||||
gBotwBombSpotDL,
|
||||
object_haka_objects_DL_005CE0,
|
||||
gShadowTempleBirdStatueDL,
|
||||
gShadowTempleSkullWallDL,
|
||||
gBotwBombableRubbleDL,
|
||||
gShadowTempleSkullWallDL,
|
||||
};
|
||||
|
||||
Gfx_DrawDListOpa(play, dLists[thisx->params]);
|
||||
|
||||
@@ -4,6 +4,13 @@
|
||||
#include "ultra64.h"
|
||||
#include "actor.h"
|
||||
|
||||
typedef enum BgHakaZouType {
|
||||
/* 0x0 */ BGHAKAZOU_TYPE_GIANT_BIRD_STATUE,
|
||||
/* 0x1 */ BGHAKAZOU_TYPE_BOMBABLE_SKULL_WALL,
|
||||
/* 0x2 */ BGHAKAZOU_TYPE_BOMBABLE_RUBBLE,
|
||||
/* 0x3 */ BGHAKAZOU_TYPE_SKULL_WALL_RUBBLE
|
||||
} BgHakaZouType;
|
||||
|
||||
struct BgHakaZou;
|
||||
|
||||
typedef void (*BgHakaZouActionFunc)(struct BgHakaZou*, struct PlayState*);
|
||||
|
||||
Reference in New Issue
Block a user