mirror of
https://github.com/zeldaret/oot
synced 2026-05-23 06:54:24 -04:00
bg_haka_trap documentation pass (#2683)
* document pass on bg_haka_trap * formatting * suggestions * dragorn suggestions
This commit is contained in:
@@ -70,34 +70,34 @@
|
||||
</Array>
|
||||
<DList Name="gShadowTempleBirdStatueDL" Offset="0x64E0"/>
|
||||
<Collision Name="gShadowTempleBirdStatueCol" Offset="0x6F70"/>
|
||||
<Array Name="object_haka_objects_Vtx_006FA0" Count="50" Offset="0x6FA0">
|
||||
<Array Name="gShadowTempleFanBladeVtx" Count="50" Offset="0x6FA0">
|
||||
<Vtx/>
|
||||
</Array>
|
||||
<DList Name="object_haka_objects_DL_0072C0" Offset="0x72C0"/>
|
||||
<Array Name="object_haka_objects_Vtx_0074B0" Count="22" Offset="0x74B0">
|
||||
<DList Name="gShadowTempleFanBladeDL" Offset="0x72C0"/>
|
||||
<Array Name="gShadowTempleGuillotineVtx" Count="22" Offset="0x74B0">
|
||||
<Vtx/>
|
||||
</Array>
|
||||
<DList Name="object_haka_objects_DL_007610" Offset="0x7610"/>
|
||||
<Array Name="object_haka_objects_Vtx_007770" Count="120" Offset="0x7770">
|
||||
<DList Name="gShadowTempleGuillotineDL" Offset="0x7610"/>
|
||||
<Array Name="gShadowTempleSpikedWallEastVtx" Count="120" Offset="0x7770">
|
||||
<Vtx/>
|
||||
</Array>
|
||||
<DList Name="object_haka_objects_DL_007EF0" Offset="0x7EF0"/>
|
||||
<Collision Name="object_haka_objects_Col_0081D0" Offset="0x81D0"/>
|
||||
<Array Name="object_haka_objects_Vtx_008200" Count="130" Offset="0x8200">
|
||||
<DList Name="gShadowTempleSpikedWallEastDL" Offset="0x7EF0"/>
|
||||
<Collision Name="gShadowTempleSpikedWallEastCol" Offset="0x81D0"/>
|
||||
<Array Name="gShadowTempleSpikedWallWestVtx" Count="130" Offset="0x8200">
|
||||
<Vtx/>
|
||||
</Array>
|
||||
<DList Name="object_haka_objects_DL_008A20" Offset="0x8A20"/>
|
||||
<Collision Name="object_haka_objects_Col_008D10" Offset="0x8D10"/>
|
||||
<DList Name="gShadowTempleSpikedWallWestDL" Offset="0x8A20"/>
|
||||
<Collision Name="gShadowTempleSpikedWallWestCol" Offset="0x8D10"/>
|
||||
<Array Name="object_haka_objects_Vtx_008D40" Count="23" Offset="0x8D40">
|
||||
<Vtx/>
|
||||
</Array>
|
||||
<DList Name="object_haka_objects_DL_008EB0" Offset="0x8EB0"/>
|
||||
<Collision Name="object_haka_objects_Col_009168" Offset="0x9168"/>
|
||||
<Array Name="object_haka_objects_Vtx_0091A0" Count="108" Offset="0x91A0">
|
||||
<Array Name="gShadowTempleSpikedCrusherVtx" Count="108" Offset="0x91A0">
|
||||
<Vtx/>
|
||||
</Array>
|
||||
<DList Name="object_haka_objects_DL_009860" Offset="0x9860"/>
|
||||
<Collision Name="object_haka_objects_Col_009CD0" Offset="0x9CD0"/>
|
||||
<DList Name="gShadowTempleSpikedCrusherDL" Offset="0x9860"/>
|
||||
<Collision Name="gShadowTempleSpikedCrusherCol" Offset="0x9CD0"/>
|
||||
<Array Name="object_haka_objects_Vtx_009D00" Count="74" Offset="0x9D00">
|
||||
<Vtx/>
|
||||
</Array>
|
||||
|
||||
@@ -1,7 +1,27 @@
|
||||
/*
|
||||
* File: z_bg_haka_trap.c
|
||||
* Overlay: ovl_Bg_Haka_Trap
|
||||
* Description: Shadow Temple Objects
|
||||
* Description: Shadow Temple traps
|
||||
*
|
||||
* HAKA_TRAP_GUILLOTINE:
|
||||
* A guillotine blade attached to a chain, drops from the ceiling.
|
||||
*
|
||||
* HAKA_TRAP_GUILLOTINE_FAST: (spawn only param)
|
||||
* Enables a flag making the guillotine move faster.
|
||||
*
|
||||
* HAKA_TRAP_SPIKED_CRUSHER:
|
||||
* A square shaped platform suspended by a chain with spikes underneath, intended to crush the player. A pushblock can
|
||||
* be used to prevent it from decending completely. Rotating this actor may prevent correct hit detection of the block.
|
||||
*
|
||||
* HAKA_TRAP_SPIKED_WALL_EAST:
|
||||
* HAKA_TRAP_SPIKED_WALL_WEST:
|
||||
*
|
||||
* Two wooden spike walls that come together to crush the player. The one to the east has extra holes to reveal the
|
||||
* chest behind it.
|
||||
*
|
||||
* HAKA_TRAP_FAN_BLADE:
|
||||
* A small fan blade that pushes the player away when turned on. `world.rot.z` is used to store the angular
|
||||
* velocity of the fan
|
||||
*/
|
||||
|
||||
#include "z_bg_haka_trap.h"
|
||||
@@ -26,20 +46,20 @@ void BgHakaTrap_Destroy(Actor* thisx, PlayState* play);
|
||||
void BgHakaTrap_Update(Actor* thisx, PlayState* play);
|
||||
void BgHakaTrap_Draw(Actor* thisx, PlayState* play);
|
||||
|
||||
void func_8087FFC0(BgHakaTrap* this, PlayState* play);
|
||||
void func_808801B8(BgHakaTrap* this, PlayState* play);
|
||||
void func_808802D8(BgHakaTrap* this, PlayState* play);
|
||||
void func_80880484(BgHakaTrap* this, PlayState* play);
|
||||
void func_808805C0(BgHakaTrap* this, PlayState* play);
|
||||
void func_808806BC(BgHakaTrap* this, PlayState* play);
|
||||
void func_808808F4(BgHakaTrap* this, PlayState* play);
|
||||
void func_808809B0(BgHakaTrap* this, PlayState* play);
|
||||
void func_808809E4(BgHakaTrap* this, PlayState* play, s16 arg2);
|
||||
void func_80880AE8(BgHakaTrap* this, PlayState* play);
|
||||
void func_80880C0C(BgHakaTrap* this, PlayState* play);
|
||||
void func_80880D68(BgHakaTrap* this);
|
||||
void BgHakaTrap_UpdateBodyColliderPos(BgHakaTrap* this, PlayState* play);
|
||||
void BgHakaTrap_SpikedWall_CloseIn(BgHakaTrap* this, PlayState* play);
|
||||
void BgHakaTrap_SpikedWall_Burn(BgHakaTrap* this, PlayState* play);
|
||||
void BgHakaTrap_Guillotine_Fall(BgHakaTrap* this, PlayState* play);
|
||||
void BgHakaTrap_Guillotine_Lift(BgHakaTrap* this, PlayState* play);
|
||||
void BgHakaTrap_SpikedCrusher_Fall(BgHakaTrap* this, PlayState* play);
|
||||
void BgHakaTrap_SpikedCrusher_Lift(BgHakaTrap* this, PlayState* play);
|
||||
void BgHakaTrap_FanBlade_Idle(BgHakaTrap* this, PlayState* play);
|
||||
void BgHakaTrap_PushPlayer(BgHakaTrap* this, PlayState* play, s16 angularVelocity);
|
||||
void BgHakaTrap_FanBlade_ToggleFanGust(BgHakaTrap* this, PlayState* play);
|
||||
void BgHakaTrap_FanBlade_FullGust(BgHakaTrap* this, PlayState* play);
|
||||
void BgHakaTrap_SpikedWall_UpdateCollider(BgHakaTrap* this);
|
||||
|
||||
static UNK_TYPE D_80880F30 = 0;
|
||||
static s32 sIsSpikeWallBurning = false;
|
||||
|
||||
ActorProfile Bg_Haka_Trap_Profile = {
|
||||
/**/ ACTOR_BG_HAKA_TRAP,
|
||||
@@ -73,7 +93,7 @@ static ColliderCylinderInit sCylinderInit = {
|
||||
{ 30, 90, 0, { 0, 0, 0 } },
|
||||
};
|
||||
|
||||
static ColliderTrisElementInit sTrisElementsInit[] = {
|
||||
static ColliderTrisElementInit sSpikedWallTrisElementsInit[] = {
|
||||
{
|
||||
{
|
||||
ELEM_MATERIAL_UNK0,
|
||||
@@ -98,7 +118,7 @@ static ColliderTrisElementInit sTrisElementsInit[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static ColliderTrisInit sTrisInit = {
|
||||
static ColliderTrisInit sSpikedWallTrisInit = {
|
||||
{
|
||||
COL_MATERIAL_NONE,
|
||||
AT_NONE,
|
||||
@@ -107,8 +127,8 @@ static ColliderTrisInit sTrisInit = {
|
||||
OC2_TYPE_2,
|
||||
COLSHAPE_TRIS,
|
||||
},
|
||||
ARRAY_COUNT(sTrisElementsInit),
|
||||
sTrisElementsInit,
|
||||
ARRAY_COUNT(sSpikedWallTrisElementsInit),
|
||||
sSpikedWallTrisElementsInit,
|
||||
};
|
||||
|
||||
static CollisionCheckInfoInit sColChkInfoInit = { 0, 80, 100, MASS_IMMOVABLE };
|
||||
@@ -118,7 +138,7 @@ static InitChainEntry sInitChain[] = {
|
||||
};
|
||||
|
||||
void BgHakaTrap_Init(Actor* thisx, PlayState* play) {
|
||||
static UNK_TYPE D_80881014 = 0;
|
||||
static s32 sSpikedCrusherFlip = false;
|
||||
BgHakaTrap* this = (BgHakaTrap*)thisx;
|
||||
s32 pad;
|
||||
CollisionHeader* colHeader = NULL;
|
||||
@@ -126,54 +146,65 @@ void BgHakaTrap_Init(Actor* thisx, PlayState* play) {
|
||||
Actor_ProcessInitChain(thisx, sInitChain);
|
||||
thisx->params &= 0xFF;
|
||||
|
||||
if (thisx->params != HAKA_TRAP_PROPELLER) {
|
||||
if (thisx->params != HAKA_TRAP_FAN_BLADE) {
|
||||
Collider_InitCylinder(play, &this->colliderCylinder);
|
||||
Collider_SetCylinder(play, &this->colliderCylinder, thisx, &sCylinderInit);
|
||||
|
||||
if ((thisx->params == HAKA_TRAP_GUILLOTINE_SLOW) || (thisx->params == HAKA_TRAP_GUILLOTINE_FAST)) {
|
||||
if ((thisx->params == HAKA_TRAP_GUILLOTINE) || (thisx->params == HAKA_TRAP_GUILLOTINE_FAST)) {
|
||||
this->timer = 20;
|
||||
this->colliderCylinder.dim.yShift = 10;
|
||||
thisx->velocity.y = 0.1f;
|
||||
|
||||
if (thisx->params == HAKA_TRAP_GUILLOTINE_FAST) {
|
||||
thisx->params = HAKA_TRAP_GUILLOTINE_SLOW;
|
||||
this->unk_16A = 1;
|
||||
thisx->params = HAKA_TRAP_GUILLOTINE;
|
||||
this->isGuillotineFast = true;
|
||||
}
|
||||
|
||||
this->actionFunc = func_80880484;
|
||||
this->actionFunc = BgHakaTrap_Guillotine_Fall;
|
||||
} else {
|
||||
DynaPolyActor_Init(&this->dyna, DYNA_TRANSFORM_POS);
|
||||
thisx->flags |= ACTOR_FLAG_UPDATE_CULLING_DISABLED;
|
||||
|
||||
if (thisx->params == HAKA_TRAP_SPIKED_BOX) {
|
||||
CollisionHeader_GetVirtual(&object_haka_objects_Col_009CD0, &colHeader);
|
||||
if (thisx->params == HAKA_TRAP_SPIKED_CRUSHER) {
|
||||
CollisionHeader_GetVirtual(&gShadowTempleSpikedCrusherCol, &colHeader);
|
||||
this->timer = 30;
|
||||
|
||||
if (D_80881014 != 0) {
|
||||
this->actionFunc = func_808808F4;
|
||||
D_80881014 = 0;
|
||||
// Instances alternate between starting off in the up or down position.
|
||||
if (sSpikedCrusherFlip) {
|
||||
this->actionFunc = BgHakaTrap_SpikedCrusher_Lift;
|
||||
sSpikedCrusherFlip = false;
|
||||
} else {
|
||||
D_80881014 = 1;
|
||||
this->actionFunc = func_808806BC;
|
||||
sSpikedCrusherFlip = true;
|
||||
this->actionFunc = BgHakaTrap_SpikedCrusher_Fall;
|
||||
thisx->velocity.y = 0.5f;
|
||||
}
|
||||
|
||||
thisx->floorHeight = thisx->home.pos.y - 225.0f;
|
||||
this->unk_16A = (thisx->floorHeight + 50.0f) - 25.0f;
|
||||
// Assign the minimum height of the crusher. The crusher intentionally clips through the floor by 25
|
||||
// units to allow the spikes to pierce the floor
|
||||
thisx->floorHeight = thisx->home.pos.y - (200 + 25);
|
||||
|
||||
// Assigns the height the crusher rises on first "tug". The final -25 offset is missing in other
|
||||
// calculations of this variable.
|
||||
this->spikedCrusherStepY = (thisx->floorHeight + 50.0f) - 25.0f;
|
||||
|
||||
this->colliderCylinder.dim.radius = 10;
|
||||
this->colliderCylinder.dim.height = 40;
|
||||
} else {
|
||||
if (thisx->params == HAKA_TRAP_SPIKED_WALL) {
|
||||
CollisionHeader_GetVirtual(&object_haka_objects_Col_0081D0, &colHeader);
|
||||
if (thisx->params == HAKA_TRAP_SPIKED_WALL_EAST) {
|
||||
CollisionHeader_GetVirtual(&gShadowTempleSpikedWallEastCol, &colHeader);
|
||||
// Shift the home position toward the center of the room. This will become the target position that
|
||||
// triggers the crush.
|
||||
thisx->home.pos.x -= 200.0f;
|
||||
} else {
|
||||
} else /* HAKA_TRAP_SPIKED_WALL_WEST */ {
|
||||
// Shift the home position toward the center of the room. This will become the target position that
|
||||
// triggers the crush.
|
||||
thisx->home.pos.x += 200.0f;
|
||||
CollisionHeader_GetVirtual(&object_haka_objects_Col_008D10, &colHeader);
|
||||
CollisionHeader_GetVirtual(&gShadowTempleSpikedWallWestCol, &colHeader);
|
||||
}
|
||||
|
||||
Collider_InitTris(play, &this->spikesCollider);
|
||||
Collider_SetTris(play, &this->spikesCollider, thisx, &sTrisInit, this->spikesColliderElements);
|
||||
Collider_SetTris(play, &this->spikesCollider, thisx, &sSpikedWallTrisInit,
|
||||
this->spikesColliderElements);
|
||||
|
||||
this->colliderCylinder.dim.radius = 18;
|
||||
this->colliderCylinder.dim.height = 115;
|
||||
@@ -181,14 +212,15 @@ void BgHakaTrap_Init(Actor* thisx, PlayState* play) {
|
||||
this->colliderCylinder.elem.atElemFlags &= ~ATELEM_SFX_NORMAL;
|
||||
this->colliderCylinder.elem.atElemFlags |= ATELEM_SFX_WOOD;
|
||||
|
||||
this->actionFunc = func_808801B8;
|
||||
this->actionFunc = BgHakaTrap_SpikedWall_CloseIn;
|
||||
}
|
||||
|
||||
this->dyna.bgId = DynaPoly_SetBgActor(play, &play->colCtx.dyna, thisx, colHeader);
|
||||
}
|
||||
} else {
|
||||
// Initialize HAKA_TRAP_FAN_BLADE
|
||||
this->timer = 40;
|
||||
this->actionFunc = func_808809B0;
|
||||
this->actionFunc = BgHakaTrap_FanBlade_Idle;
|
||||
thisx->cullingVolumeScale = 500.0f;
|
||||
}
|
||||
|
||||
@@ -198,11 +230,11 @@ void BgHakaTrap_Init(Actor* thisx, PlayState* play) {
|
||||
void BgHakaTrap_Destroy(Actor* thisx, PlayState* play) {
|
||||
BgHakaTrap* this = (BgHakaTrap*)thisx;
|
||||
|
||||
if (this->dyna.actor.params != HAKA_TRAP_PROPELLER) {
|
||||
if (this->dyna.actor.params != HAKA_TRAP_GUILLOTINE_SLOW) {
|
||||
if (this->dyna.actor.params != HAKA_TRAP_FAN_BLADE) {
|
||||
if (this->dyna.actor.params != HAKA_TRAP_GUILLOTINE) {
|
||||
DynaPoly_DeleteBgActor(play, &play->colCtx.dyna, this->dyna.bgId);
|
||||
if ((this->dyna.actor.params == HAKA_TRAP_SPIKED_WALL) ||
|
||||
(this->dyna.actor.params == HAKA_TRAP_SPIKED_WALL_2)) {
|
||||
if ((this->dyna.actor.params == HAKA_TRAP_SPIKED_WALL_EAST) ||
|
||||
(this->dyna.actor.params == HAKA_TRAP_SPIKED_WALL_WEST)) {
|
||||
Collider_DestroyTris(play, &this->spikesCollider);
|
||||
}
|
||||
}
|
||||
@@ -210,61 +242,68 @@ void BgHakaTrap_Destroy(Actor* thisx, PlayState* play) {
|
||||
Collider_DestroyCylinder(play, &this->colliderCylinder);
|
||||
}
|
||||
|
||||
Audio_StopSfxByPos(&this->unk_16C);
|
||||
Audio_StopSfxByPos(&this->chainLiftSfxPos);
|
||||
}
|
||||
|
||||
void func_8087FFC0(BgHakaTrap* this, PlayState* play) {
|
||||
f32 cosine;
|
||||
Vec3f sp28;
|
||||
f32 sine;
|
||||
f32 zNonNegative;
|
||||
// Updates body collider for HAKA_TRAP_GUILLOTINE, HAKA_TRAP_SPIKED_WALL_EAST, HAKA_TRAP_SPIKED_WALL_WEST
|
||||
void BgHakaTrap_UpdateBodyColliderPos(BgHakaTrap* this, PlayState* play) {
|
||||
f32 cos;
|
||||
Vec3f colOff;
|
||||
f32 sin;
|
||||
f32 zSign;
|
||||
Player* player = GET_PLAYER(play);
|
||||
|
||||
Actor_WorldToActorCoords(&this->dyna.actor, &sp28, &player->actor.world.pos);
|
||||
Actor_WorldToActorCoords(&this->dyna.actor, &colOff, &player->actor.world.pos);
|
||||
|
||||
sine = Math_SinS(this->dyna.actor.shape.rot.y);
|
||||
cosine = Math_CosS(this->dyna.actor.shape.rot.y);
|
||||
if (this->dyna.actor.params == HAKA_TRAP_GUILLOTINE_SLOW) {
|
||||
sp28.x = CLAMP(sp28.x, -50.0f, 50.0f);
|
||||
zNonNegative = (sp28.z >= 0.0f) ? 1.0f : -1.0f;
|
||||
sp28.z = zNonNegative * -15.0f;
|
||||
sin = Math_SinS(this->dyna.actor.shape.rot.y);
|
||||
cos = Math_CosS(this->dyna.actor.shape.rot.y);
|
||||
|
||||
if (this->dyna.actor.params == HAKA_TRAP_GUILLOTINE) {
|
||||
colOff.x = CLAMP(colOff.x, -50.0f, 50.0f);
|
||||
zSign = (colOff.z >= 0.0f) ? 1.0f : -1.0f;
|
||||
colOff.z = zSign * -15.0f;
|
||||
} else {
|
||||
sp28.x = -CLAMP(sp28.x, -162.0f, 162.0f);
|
||||
zNonNegative = (sp28.z >= 0.0f) ? 1.0f : -1.0f;
|
||||
sp28.z = zNonNegative * 15.0f;
|
||||
colOff.x = -CLAMP(colOff.x, -162.0f, 162.0f);
|
||||
zSign = (colOff.z >= 0.0f) ? 1.0f : -1.0f;
|
||||
colOff.z = zSign * 15.0f;
|
||||
}
|
||||
|
||||
this->colliderCylinder.dim.pos.x = this->dyna.actor.world.pos.x + sp28.x * cosine + sp28.z * sine;
|
||||
this->colliderCylinder.dim.pos.z = this->dyna.actor.world.pos.z + sp28.x * sine + sp28.z * cosine;
|
||||
this->colliderCylinder.dim.pos.x = this->dyna.actor.world.pos.x + colOff.x * cos + colOff.z * sin;
|
||||
this->colliderCylinder.dim.pos.z = this->dyna.actor.world.pos.z + colOff.x * sin + colOff.z * cos;
|
||||
}
|
||||
|
||||
void func_808801B8(BgHakaTrap* this, PlayState* play) {
|
||||
static UNK_TYPE D_80881018 = 0;
|
||||
#define BGHAKATRAP_SPIKEDWALL_HITEAST (1 << 0)
|
||||
#define BGHAKATRAP_SPIKEDWALL_HITWEST (1 << 1)
|
||||
#define BGHAKATRAP_SPIKEDWALL_CRUSH_PLAYER 4
|
||||
|
||||
void BgHakaTrap_SpikedWall_CloseIn(BgHakaTrap* this, PlayState* play) {
|
||||
static s32 sSpikedWallFlags = 0;
|
||||
Player* player = GET_PLAYER(play);
|
||||
|
||||
if ((D_80880F30 == 0) && (!Player_InCsMode(play))) {
|
||||
if (!sIsSpikeWallBurning && !Player_InCsMode(play)) {
|
||||
// Step towards the home position. If we haven't reached it, play the sliding sfx
|
||||
if (!Math_StepToF(&this->dyna.actor.world.pos.x, this->dyna.actor.home.pos.x, 0.5f)) {
|
||||
Actor_PlaySfx_Flagged(&this->dyna.actor, NA_SE_EV_TRAP_OBJ_SLIDE - SFX_FLAG);
|
||||
} else if (this->dyna.actor.params == HAKA_TRAP_SPIKED_WALL) {
|
||||
D_80881018 |= 1;
|
||||
} else if (this->dyna.actor.params == HAKA_TRAP_SPIKED_WALL_2) {
|
||||
D_80881018 |= 2;
|
||||
} else if (this->dyna.actor.params == HAKA_TRAP_SPIKED_WALL_EAST) {
|
||||
sSpikedWallFlags |= BGHAKATRAP_SPIKEDWALL_HITEAST;
|
||||
} else if (this->dyna.actor.params == HAKA_TRAP_SPIKED_WALL_WEST) {
|
||||
sSpikedWallFlags |= BGHAKATRAP_SPIKEDWALL_HITWEST;
|
||||
}
|
||||
}
|
||||
|
||||
func_8087FFC0(this, play);
|
||||
BgHakaTrap_UpdateBodyColliderPos(this, play);
|
||||
|
||||
if (this->spikesCollider.base.acFlags & AC_HIT) {
|
||||
this->timer = 20;
|
||||
D_80880F30 = 1;
|
||||
this->actionFunc = func_808802D8;
|
||||
} else if (D_80881018 == 3) {
|
||||
D_80881018 = 4;
|
||||
sIsSpikeWallBurning = true;
|
||||
this->actionFunc = BgHakaTrap_SpikedWall_Burn;
|
||||
} else if (sSpikedWallFlags == (BGHAKATRAP_SPIKEDWALL_HITEAST | BGHAKATRAP_SPIKEDWALL_HITWEST)) {
|
||||
sSpikedWallFlags = BGHAKATRAP_SPIKEDWALL_CRUSH_PLAYER;
|
||||
player->actor.bgCheckFlags |= BGCHECKFLAG_CRUSHED;
|
||||
}
|
||||
}
|
||||
|
||||
void func_808802D8(BgHakaTrap* this, PlayState* play) {
|
||||
void BgHakaTrap_SpikedWall_Burn(BgHakaTrap* this, PlayState* play) {
|
||||
static Vec3f zeroVec = { 0.0f, 0.0f, 0.0f };
|
||||
Vec3f vector;
|
||||
f32 xScale;
|
||||
@@ -279,7 +318,7 @@ void func_808802D8(BgHakaTrap* this, PlayState* play) {
|
||||
for (i = 0; i < 2; i++) {
|
||||
f32 rand = Rand_ZeroOne();
|
||||
|
||||
xScale = (this->dyna.actor.params == HAKA_TRAP_SPIKED_WALL) ? -30.0f : 30.0f;
|
||||
xScale = (this->dyna.actor.params == HAKA_TRAP_SPIKED_WALL_EAST) ? -30.0f : 30.0f;
|
||||
|
||||
vector.x = xScale * rand + this->dyna.actor.world.pos.x;
|
||||
vector.y = Rand_ZeroOne() * 10.0f + this->dyna.actor.world.pos.y + 30.0f;
|
||||
@@ -289,16 +328,16 @@ void func_808802D8(BgHakaTrap* this, PlayState* play) {
|
||||
}
|
||||
|
||||
if (this->timer == 0) {
|
||||
D_80880F30 = 0;
|
||||
sIsSpikeWallBurning = false;
|
||||
Actor_Kill(&this->dyna.actor);
|
||||
}
|
||||
}
|
||||
|
||||
void func_80880484(BgHakaTrap* this, PlayState* play) {
|
||||
s32 sp24;
|
||||
void BgHakaTrap_Guillotine_Fall(BgHakaTrap* this, PlayState* play) {
|
||||
s32 isDoneFalling;
|
||||
s32 timer;
|
||||
|
||||
if (this->unk_16A) {
|
||||
if (this->isGuillotineFast) {
|
||||
this->dyna.actor.velocity.y *= 3.0f;
|
||||
} else {
|
||||
this->dyna.actor.velocity.y *= 2.0f;
|
||||
@@ -308,34 +347,35 @@ void func_80880484(BgHakaTrap* this, PlayState* play) {
|
||||
this->timer -= 1;
|
||||
}
|
||||
|
||||
sp24 =
|
||||
isDoneFalling =
|
||||
Math_StepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.home.pos.y - 185.0f, this->dyna.actor.velocity.y);
|
||||
timer = this->timer;
|
||||
|
||||
if ((timer == 10 && !this->unk_16A) || (timer == 13 && this->unk_16A)) {
|
||||
if ((timer == 10 && !this->isGuillotineFast) || (timer == 13 && this->isGuillotineFast)) {
|
||||
Actor_PlaySfx(&this->dyna.actor, NA_SE_EV_GUILLOTINE_BOUND);
|
||||
}
|
||||
|
||||
if (this->timer == 0) {
|
||||
this->dyna.actor.velocity.y = 0.0f;
|
||||
this->timer = (this->unk_16A) ? 10 : 40;
|
||||
this->timer = (this->isGuillotineFast) ? 10 : 40;
|
||||
Actor_PlaySfx(&this->dyna.actor, NA_SE_EV_GUILLOTINE_UP);
|
||||
this->actionFunc = func_808805C0;
|
||||
this->actionFunc = BgHakaTrap_Guillotine_Lift;
|
||||
}
|
||||
|
||||
func_8087FFC0(this, play);
|
||||
BgHakaTrap_UpdateBodyColliderPos(this, play);
|
||||
|
||||
if (sp24 == 0) {
|
||||
if (!isDoneFalling) {
|
||||
CollisionCheck_SetAT(play, &play->colChkCtx, &this->colliderCylinder.base);
|
||||
}
|
||||
}
|
||||
|
||||
void func_808805C0(BgHakaTrap* this, PlayState* play) {
|
||||
void BgHakaTrap_Guillotine_Lift(BgHakaTrap* this, PlayState* play) {
|
||||
if (this->timer != 0) {
|
||||
this->timer--;
|
||||
}
|
||||
|
||||
if (this->unk_16A) {
|
||||
if (this->isGuillotineFast) {
|
||||
|
||||
Math_StepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.home.pos.y, 27.0f);
|
||||
} else {
|
||||
if (this->timer > 20) {
|
||||
@@ -353,13 +393,13 @@ void func_808805C0(BgHakaTrap* this, PlayState* play) {
|
||||
this->timer = 20;
|
||||
this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y;
|
||||
this->dyna.actor.velocity.y = 0.1f;
|
||||
this->actionFunc = func_80880484;
|
||||
this->actionFunc = BgHakaTrap_Guillotine_Fall;
|
||||
}
|
||||
|
||||
func_8087FFC0(this, play);
|
||||
BgHakaTrap_UpdateBodyColliderPos(this, play);
|
||||
}
|
||||
|
||||
void func_808806BC(BgHakaTrap* this, PlayState* play) {
|
||||
void BgHakaTrap_SpikedCrusher_Fall(BgHakaTrap* this, PlayState* play) {
|
||||
Vec3f vector;
|
||||
f32 floorHeight;
|
||||
f32 yIntersect;
|
||||
@@ -372,10 +412,17 @@ void func_808806BC(BgHakaTrap* this, PlayState* play) {
|
||||
this->timer--;
|
||||
}
|
||||
|
||||
// Perform a collision check for the "stone umbrella" block
|
||||
// Because of the shape of the room and the size of the block we only need to check three positions,
|
||||
// the center of the east edge, the centerpoint, and the center of the west edge of the crusher.
|
||||
//
|
||||
// The y coordinate is offset by 25 units, as the crusher is allowed to clip into the floor for visual effect.
|
||||
|
||||
vector.x = this->dyna.actor.world.pos.x + 90.0f;
|
||||
vector.y = (this->dyna.actor.world.pos.y + 1.0f) + 25.0f;
|
||||
vector.z = this->dyna.actor.world.pos.z;
|
||||
|
||||
// actor.floorHeight is storing the minimum y position of the crusher
|
||||
floorHeight = this->dyna.actor.floorHeight;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
@@ -403,77 +450,87 @@ void func_808806BC(BgHakaTrap* this, PlayState* play) {
|
||||
if (this->timer == 0) {
|
||||
this->dyna.actor.velocity.y = 0.0f;
|
||||
this->timer = 30;
|
||||
this->unk_16A = (s16)this->dyna.actor.world.pos.y + 50.0f;
|
||||
this->unk_16A = CLAMP_MAX(this->unk_16A, this->dyna.actor.home.pos.y);
|
||||
this->spikedCrusherStepY = (s16)this->dyna.actor.world.pos.y + 50.0f;
|
||||
this->spikedCrusherStepY = CLAMP_MAX(this->spikedCrusherStepY, this->dyna.actor.home.pos.y);
|
||||
|
||||
this->actionFunc = func_808808F4;
|
||||
this->actionFunc = BgHakaTrap_SpikedCrusher_Lift;
|
||||
}
|
||||
}
|
||||
|
||||
void func_808808F4(BgHakaTrap* this, PlayState* play) {
|
||||
void BgHakaTrap_SpikedCrusher_Lift(BgHakaTrap* this, PlayState* play) {
|
||||
if (this->timer != 0) {
|
||||
this->timer--;
|
||||
}
|
||||
|
||||
if (this->timer > 20) {
|
||||
this->unk_169 = Math_StepToF(&this->dyna.actor.world.pos.y, this->unk_16A, 15.0f);
|
||||
this->isSpikedCrusherStationary = Math_StepToF(&this->dyna.actor.world.pos.y, this->spikedCrusherStepY, 15.0f);
|
||||
} else {
|
||||
this->unk_169 = Math_StepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.home.pos.y, 20.0f);
|
||||
this->isSpikedCrusherStationary =
|
||||
Math_StepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.home.pos.y, 20.0f);
|
||||
}
|
||||
|
||||
if (this->timer == 0) {
|
||||
this->timer = 30;
|
||||
this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y;
|
||||
this->dyna.actor.velocity.y = 0.5f;
|
||||
this->actionFunc = func_808806BC;
|
||||
this->actionFunc = BgHakaTrap_SpikedCrusher_Fall;
|
||||
}
|
||||
}
|
||||
|
||||
void func_808809B0(BgHakaTrap* this, PlayState* play) {
|
||||
void BgHakaTrap_FanBlade_Idle(BgHakaTrap* this, PlayState* play) {
|
||||
if (this->timer != 0) {
|
||||
this->timer -= 1;
|
||||
}
|
||||
|
||||
if (this->timer == 0) {
|
||||
this->actionFunc = func_80880AE8;
|
||||
// this->timer = 0, which signals the fan to turn on and speed up
|
||||
this->actionFunc = BgHakaTrap_FanBlade_ToggleFanGust;
|
||||
}
|
||||
}
|
||||
|
||||
void func_808809E4(BgHakaTrap* this, PlayState* play, s16 arg2) {
|
||||
void BgHakaTrap_PushPlayer(BgHakaTrap* this, PlayState* play, s16 angularVelocity) {
|
||||
Player* player = GET_PLAYER(play);
|
||||
Vec3f sp18;
|
||||
Vec3f playerRelOff;
|
||||
|
||||
Actor_WorldToActorCoords(&this->dyna.actor, &sp18, &player->actor.world.pos);
|
||||
Actor_WorldToActorCoords(&this->dyna.actor, &playerRelOff, &player->actor.world.pos);
|
||||
|
||||
if ((fabsf(sp18.x) < 70.0f) && (fabsf(sp18.y) < 100.0f) && (sp18.z < 500.0f) &&
|
||||
if ((fabsf(playerRelOff.x) < 70.0f) && (fabsf(playerRelOff.y) < 100.0f) && (playerRelOff.z < 500.0f) &&
|
||||
(GET_PLAYER(play)->currentBoots != PLAYER_BOOTS_IRON)) {
|
||||
player->pushedSpeed = ((500.0f - sp18.z) * 0.06f + 5.0f) * arg2 * (1.0f / 0x3A00) * (2.0f / 3.0f);
|
||||
player->pushedSpeed =
|
||||
((500.0f - playerRelOff.z) * 0.06f + 5.0f) * angularVelocity * (1.0f / 0x3A00) * (2.0f / 3.0f);
|
||||
player->pushedYaw = this->dyna.actor.shape.rot.y;
|
||||
}
|
||||
}
|
||||
|
||||
void func_80880AE8(BgHakaTrap* this, PlayState* play) {
|
||||
void BgHakaTrap_FanBlade_ToggleFanGust(BgHakaTrap* this, PlayState* play) {
|
||||
// this->timer stores the current fan behavior.
|
||||
// if 1, the fan is on and is ramping down to the off state.
|
||||
// if 0, the fan is off and is ramping up to the full on state.
|
||||
|
||||
// world.rot.z is the current angular velocity of the fan
|
||||
if (this->timer != 0) {
|
||||
// Fan winds down
|
||||
if (Math_ScaledStepToS(&this->dyna.actor.world.rot.z, 0, this->dyna.actor.world.rot.z * 0.03f + 5.0f)) {
|
||||
this->timer = 40;
|
||||
this->actionFunc = func_808809B0;
|
||||
this->actionFunc = BgHakaTrap_FanBlade_Idle;
|
||||
}
|
||||
} else {
|
||||
// Fan speeds up
|
||||
if (Math_ScaledStepToS(&this->dyna.actor.world.rot.z, 0x3A00, this->dyna.actor.world.rot.z * 0.03f + 5.0f)) {
|
||||
this->timer = 100;
|
||||
this->actionFunc = func_80880C0C;
|
||||
this->actionFunc = BgHakaTrap_FanBlade_FullGust;
|
||||
}
|
||||
}
|
||||
|
||||
this->dyna.actor.shape.rot.z += this->dyna.actor.world.rot.z;
|
||||
if (this->dyna.actor.world.rot.z >= 0x1801) {
|
||||
if (this->dyna.actor.world.rot.z > 0x1800) {
|
||||
Actor_PlaySfx_Flagged(&this->dyna.actor, NA_SE_EV_WIND_TRAP - SFX_FLAG);
|
||||
}
|
||||
|
||||
func_808809E4(this, play, this->dyna.actor.world.rot.z);
|
||||
BgHakaTrap_PushPlayer(this, play, this->dyna.actor.world.rot.z);
|
||||
}
|
||||
|
||||
void func_80880C0C(BgHakaTrap* this, PlayState* play) {
|
||||
void BgHakaTrap_FanBlade_FullGust(BgHakaTrap* this, PlayState* play) {
|
||||
if (this->timer != 0) {
|
||||
this->timer--;
|
||||
}
|
||||
@@ -481,12 +538,13 @@ void func_80880C0C(BgHakaTrap* this, PlayState* play) {
|
||||
Actor_PlaySfx_Flagged(&this->dyna.actor, NA_SE_EV_WIND_TRAP - SFX_FLAG);
|
||||
|
||||
if (this->timer == 0) {
|
||||
this->timer = 1;
|
||||
this->actionFunc = func_80880AE8;
|
||||
this->timer = 1; // setting this signals the fan to turn off and slow down
|
||||
this->actionFunc = BgHakaTrap_FanBlade_ToggleFanGust;
|
||||
}
|
||||
|
||||
// world.rot.z is the current angular velocity of the fan
|
||||
this->dyna.actor.shape.rot.z += this->dyna.actor.world.rot.z;
|
||||
func_808809E4(this, play, this->dyna.actor.world.rot.z);
|
||||
BgHakaTrap_PushPlayer(this, play, this->dyna.actor.world.rot.z);
|
||||
}
|
||||
|
||||
void BgHakaTrap_Update(Actor* thisx, PlayState* play) {
|
||||
@@ -495,14 +553,14 @@ void BgHakaTrap_Update(Actor* thisx, PlayState* play) {
|
||||
|
||||
this->actionFunc(this, play);
|
||||
|
||||
if ((this->dyna.actor.params != HAKA_TRAP_PROPELLER) && (thisx->params != HAKA_TRAP_SPIKED_BOX)) {
|
||||
if ((this->dyna.actor.params != HAKA_TRAP_FAN_BLADE) && (thisx->params != HAKA_TRAP_SPIKED_CRUSHER)) {
|
||||
this->colliderCylinder.dim.pos.y = actorPos->y;
|
||||
|
||||
if ((thisx->params == HAKA_TRAP_GUILLOTINE_SLOW) || (thisx->params == HAKA_TRAP_GUILLOTINE_FAST)) {
|
||||
if ((thisx->params == HAKA_TRAP_GUILLOTINE) || (thisx->params == HAKA_TRAP_GUILLOTINE_FAST)) {
|
||||
CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderCylinder.base);
|
||||
CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderCylinder.base);
|
||||
} else {
|
||||
if (this->actionFunc == func_808801B8) {
|
||||
if (this->actionFunc == BgHakaTrap_SpikedWall_CloseIn) {
|
||||
CollisionCheck_SetAC(play, &play->colChkCtx, &this->spikesCollider.base);
|
||||
}
|
||||
|
||||
@@ -511,50 +569,49 @@ void BgHakaTrap_Update(Actor* thisx, PlayState* play) {
|
||||
}
|
||||
}
|
||||
|
||||
void func_80880D68(BgHakaTrap* this) {
|
||||
Vec3f vec3;
|
||||
Vec3f vec2;
|
||||
Vec3f vec1;
|
||||
void BgHakaTrap_SpikedWall_UpdateCollider(BgHakaTrap* this) {
|
||||
Vec3f vtx[3];
|
||||
|
||||
Matrix_MultVec3f(&sTrisElementsInit[0].dim.vtx[0], &vec1);
|
||||
Matrix_MultVec3f(&sTrisElementsInit[0].dim.vtx[1], &vec2);
|
||||
Matrix_MultVec3f(&sTrisElementsInit[0].dim.vtx[2], &vec3);
|
||||
Collider_SetTrisVertices(&this->spikesCollider, 0, &vec1, &vec2, &vec3);
|
||||
Matrix_MultVec3f(&sSpikedWallTrisElementsInit[0].dim.vtx[0], &vtx[0]);
|
||||
Matrix_MultVec3f(&sSpikedWallTrisElementsInit[0].dim.vtx[1], &vtx[1]);
|
||||
Matrix_MultVec3f(&sSpikedWallTrisElementsInit[0].dim.vtx[2], &vtx[2]);
|
||||
Collider_SetTrisVertices(&this->spikesCollider, 0, &vtx[0], &vtx[1], &vtx[2]);
|
||||
|
||||
Matrix_MultVec3f(&sTrisElementsInit[1].dim.vtx[2], &vec2);
|
||||
Collider_SetTrisVertices(&this->spikesCollider, 1, &vec1, &vec3, &vec2);
|
||||
Matrix_MultVec3f(&sSpikedWallTrisElementsInit[1].dim.vtx[2], &vtx[1]);
|
||||
Collider_SetTrisVertices(&this->spikesCollider, 1, &vtx[0], &vtx[2], &vtx[1]);
|
||||
}
|
||||
|
||||
void BgHakaTrap_Draw(Actor* thisx, PlayState* play) {
|
||||
static Gfx* sDLists[5] = {
|
||||
object_haka_objects_DL_007610, object_haka_objects_DL_009860, object_haka_objects_DL_007EF0,
|
||||
object_haka_objects_DL_008A20, object_haka_objects_DL_0072C0,
|
||||
gShadowTempleGuillotineDL, gShadowTempleSpikedCrusherDL, gShadowTempleSpikedWallEastDL,
|
||||
gShadowTempleSpikedWallWestDL, gShadowTempleFanBladeDL,
|
||||
};
|
||||
static Color_RGBA8 D_8088103C = { 0, 0, 0, 0 };
|
||||
static Color_RGBA8 sFogBlack = { 0, 0, 0, 0 };
|
||||
BgHakaTrap* this = (BgHakaTrap*)thisx;
|
||||
s32 pad;
|
||||
Vec3f sp2C;
|
||||
|
||||
if (this->actionFunc == func_808802D8) {
|
||||
func_80026230(play, &D_8088103C, this->timer + 20, 0x28);
|
||||
if (this->actionFunc == BgHakaTrap_SpikedWall_Burn) {
|
||||
func_80026230(play, &sFogBlack, this->timer + 20, 40);
|
||||
}
|
||||
|
||||
Gfx_DrawDListOpa(play, sDLists[this->dyna.actor.params]);
|
||||
|
||||
if (this->actionFunc == func_808801B8) {
|
||||
func_80880D68(this);
|
||||
if (this->actionFunc == BgHakaTrap_SpikedWall_CloseIn) {
|
||||
BgHakaTrap_SpikedWall_UpdateCollider(this);
|
||||
}
|
||||
|
||||
if (this->actionFunc == func_808802D8) {
|
||||
if (this->actionFunc == BgHakaTrap_SpikedWall_Burn) {
|
||||
func_80026608(play);
|
||||
}
|
||||
|
||||
if ((this->actionFunc == func_808808F4) && !this->unk_169) {
|
||||
sp2C.x = this->dyna.actor.world.pos.x;
|
||||
sp2C.z = this->dyna.actor.world.pos.z;
|
||||
sp2C.y = this->dyna.actor.world.pos.y + 110.0f;
|
||||
if ((this->actionFunc == BgHakaTrap_SpikedCrusher_Lift) && !this->isSpikedCrusherStationary) {
|
||||
Vec3f sfxPos;
|
||||
|
||||
SkinMatrix_Vec3fMtxFMultXYZ(&play->viewProjectionMtxF, &sp2C, &this->unk_16C);
|
||||
Sfx_PlaySfxAtPos(&this->unk_16C, NA_SE_EV_BRIDGE_CLOSE - SFX_FLAG);
|
||||
sfxPos.x = this->dyna.actor.world.pos.x;
|
||||
sfxPos.z = this->dyna.actor.world.pos.z;
|
||||
sfxPos.y = this->dyna.actor.world.pos.y + 110.0f;
|
||||
|
||||
SkinMatrix_Vec3fMtxFMultXYZ(&play->viewProjectionMtxF, &sfxPos, &this->chainLiftSfxPos);
|
||||
Sfx_PlaySfxAtPos(&this->chainLiftSfxPos, NA_SE_EV_BRIDGE_CLOSE - SFX_FLAG);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
#include "actor.h"
|
||||
|
||||
typedef enum HakaTrapType {
|
||||
/* 0x00 */ HAKA_TRAP_GUILLOTINE_SLOW,
|
||||
/* 0x01 */ HAKA_TRAP_SPIKED_BOX,
|
||||
/* 0x02 */ HAKA_TRAP_SPIKED_WALL,
|
||||
/* 0x03 */ HAKA_TRAP_SPIKED_WALL_2,
|
||||
/* 0x04 */ HAKA_TRAP_PROPELLER,
|
||||
/* 0x00 */ HAKA_TRAP_GUILLOTINE,
|
||||
/* 0x01 */ HAKA_TRAP_SPIKED_CRUSHER,
|
||||
/* 0x02 */ HAKA_TRAP_SPIKED_WALL_EAST,
|
||||
/* 0x03 */ HAKA_TRAP_SPIKED_WALL_WEST,
|
||||
/* 0x04 */ HAKA_TRAP_FAN_BLADE,
|
||||
/* 0x05 */ HAKA_TRAP_GUILLOTINE_FAST
|
||||
} HakaTrapType;
|
||||
|
||||
@@ -21,9 +21,13 @@ typedef struct BgHakaTrap {
|
||||
/* 0x0000 */ DynaPolyActor dyna;
|
||||
/* 0x0164 */ BgHakaTrapActionFunc actionFunc;
|
||||
/* 0x0168 */ u8 timer;
|
||||
/* 0x0169 */ u8 unk_169;
|
||||
/* 0x016A */ s16 unk_16A; // used as boolean for HAKA_TRAP_GUILLOTINE_SLOW/FAST, s16 for HAKA_TRAP_SPIKED_BOX
|
||||
/* 0x016C */ Vec3f unk_16C;
|
||||
/* 0x0169 */ u8 isSpikedCrusherStationary;
|
||||
/* 0x016A */ union {
|
||||
s16 isGuillotineFast; // 0 slow, 1 fast
|
||||
s16 spikedCrusherStepY; // when lifting the crusher, it will pause briefly at this height before being
|
||||
// lifted to its maximum height
|
||||
};
|
||||
/* 0x016C */ Vec3f chainLiftSfxPos;
|
||||
/* 0x0178 */ ColliderCylinder colliderCylinder;
|
||||
/* 0x01C4 */ ColliderTris spikesCollider;
|
||||
/* 0x01E4 */ ColliderTrisElement spikesColliderElements[2];
|
||||
|
||||
Reference in New Issue
Block a user