mirror of
https://github.com/zeldaret/oot
synced 2026-07-28 23:27:31 -04:00
Merge remote-tracking branch 'upstream/master' into ovl_Eff_Dust
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
#include "z_en_blkobj.h"
|
||||
#include "objects/object_blkobj/object_blkobj.h"
|
||||
|
||||
#define FLAGS 0x00000030
|
||||
|
||||
@@ -49,10 +50,6 @@ static Gfx sSetupXluDL[] = {
|
||||
gsSPEndDisplayList(),
|
||||
};
|
||||
|
||||
extern Gfx D_060014E0[];
|
||||
extern Gfx D_060053D0[];
|
||||
extern CollisionHeader D_06007564;
|
||||
|
||||
void EnBlkobj_SetupAction(EnBlkobj* this, EnBlkobjActionFunc actionFunc) {
|
||||
this->actionFunc = actionFunc;
|
||||
this->timer = 0;
|
||||
@@ -69,7 +66,7 @@ void EnBlkobj_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
this->alpha = 255;
|
||||
EnBlkobj_SetupAction(this, EnBlkobj_DoNothing);
|
||||
} else {
|
||||
CollisionHeader_GetVirtual(&D_06007564, &colHeader);
|
||||
CollisionHeader_GetVirtual(&gIllusionRoomCol, &colHeader);
|
||||
this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, colHeader);
|
||||
EnBlkobj_SetupAction(this, EnBlkobj_Wait);
|
||||
}
|
||||
@@ -168,11 +165,11 @@ void EnBlkobj_Draw(Actor* thisx, GlobalContext* globalCtx) {
|
||||
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
|
||||
if (this->alpha != 0) {
|
||||
EnBlkobj_DrawAlpha(globalCtx, D_060014E0, this->alpha);
|
||||
EnBlkobj_DrawAlpha(globalCtx, gIllusionRoomNormalDL, this->alpha);
|
||||
}
|
||||
illusionAlpha = 255 - this->alpha;
|
||||
if (illusionAlpha != 0) {
|
||||
EnBlkobj_DrawAlpha(globalCtx, D_060053D0, illusionAlpha);
|
||||
EnBlkobj_DrawAlpha(globalCtx, gIllusionRoomIllusionDL, illusionAlpha);
|
||||
}
|
||||
|
||||
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_en_blkobj.c", 375);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "z_en_geldb.h"
|
||||
#include "objects/object_geldb/object_geldb.h"
|
||||
|
||||
#define FLAGS 0x00000015
|
||||
|
||||
@@ -22,7 +23,7 @@ typedef enum {
|
||||
/* 14 */ GELDB_ROLL_FORWARD,
|
||||
/* 15 */ GELDB_STUNNED,
|
||||
/* 16 */ GELDB_SPIN_DODGE
|
||||
} EnGeldBActionState;
|
||||
} EnGeldBAction;
|
||||
|
||||
void EnGeldB_Init(Actor* thisx, GlobalContext* globalCtx);
|
||||
void EnGeldB_Destroy(Actor* thisx, GlobalContext* globalCtx);
|
||||
@@ -64,19 +65,6 @@ void EnGeldB_Block(EnGeldB* this, GlobalContext* globalCtx);
|
||||
void EnGeldB_Sidestep(EnGeldB* this, GlobalContext* globalCtx);
|
||||
void EnGeldB_Defeated(EnGeldB* this, GlobalContext* globalCtx);
|
||||
|
||||
extern FlexSkeletonHeader D_0600A458;
|
||||
extern AnimationHeader D_0600ADF8;
|
||||
extern AnimationHeader D_0600B6D4;
|
||||
extern AnimationHeader D_0600A814;
|
||||
extern AnimationHeader D_06001390;
|
||||
extern AnimationHeader D_060024E8;
|
||||
extern AnimationHeader D_060003CC;
|
||||
extern AnimationHeader D_06000F5C;
|
||||
extern AnimationHeader D_06002280;
|
||||
extern AnimationHeader D_06001E10;
|
||||
extern AnimationHeader D_0600ADF8;
|
||||
extern AnimationHeader D_06001578;
|
||||
|
||||
const ActorInit En_GeldB_InitVars = {
|
||||
ACTOR_EN_GELDB,
|
||||
ACTORCAT_ENEMY,
|
||||
@@ -240,7 +228,8 @@ void EnGeldB_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
thisx->params &= 0xFF;
|
||||
this->blinkState = 0;
|
||||
this->unkFloat = 10.0f;
|
||||
SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_0600A458, &D_0600B6D4, this->jointTable, this->morphTable, 24);
|
||||
SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gGerudoRedSkel, &gGerudoRedNeutralAnim, this->jointTable,
|
||||
this->morphTable, 24);
|
||||
Collider_InitCylinder(globalCtx, &this->bodyCollider);
|
||||
Collider_SetCylinder(globalCtx, &this->bodyCollider, thisx, &sBodyCylInit);
|
||||
Collider_InitTris(globalCtx, &this->blockCollider);
|
||||
@@ -257,7 +246,7 @@ void EnGeldB_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
blureInit.unkFlag = 0;
|
||||
blureInit.calcMode = 2;
|
||||
|
||||
Effect_Add(globalCtx, &this->blureIdx, EFFECT_BLURE1, 0, 0, &blureInit);
|
||||
Effect_Add(globalCtx, &this->blureIndex, EFFECT_BLURE1, 0, 0, &blureInit);
|
||||
Actor_SetScale(thisx, 0.012499999f);
|
||||
EnGeldB_SetupWait(this);
|
||||
if ((this->keyFlag != 0) && Flags_GetCollectible(globalCtx, this->keyFlag >> 8)) {
|
||||
@@ -270,7 +259,7 @@ void EnGeldB_Destroy(Actor* thisx, GlobalContext* globalCtx) {
|
||||
EnGeldB* this = THIS;
|
||||
|
||||
func_800F5B58();
|
||||
Effect_Delete(globalCtx, this->blureIdx);
|
||||
Effect_Delete(globalCtx, this->blureIndex);
|
||||
Collider_DestroyTris(globalCtx, &this->blockCollider);
|
||||
Collider_DestroyCylinder(globalCtx, &this->bodyCollider);
|
||||
Collider_DestroyQuad(globalCtx, &this->swordCollider);
|
||||
@@ -348,11 +337,11 @@ s32 EnGeldB_ReactToPlayer(GlobalContext* globalCtx, EnGeldB* this, s16 arg2) {
|
||||
}
|
||||
|
||||
void EnGeldB_SetupWait(EnGeldB* this) {
|
||||
Animation_PlayOnceSetSpeed(&this->skelAnime, &D_0600ADF8, 0.0f);
|
||||
Animation_PlayOnceSetSpeed(&this->skelAnime, &gGerudoRedJumpAnim, 0.0f);
|
||||
this->actor.world.pos.y = this->actor.home.pos.y + 120.0f;
|
||||
this->timer = 10;
|
||||
this->invisible = true;
|
||||
this->actionState = GELDB_WAIT;
|
||||
this->action = GELDB_WAIT;
|
||||
this->actor.bgCheckFlags &= ~3;
|
||||
this->actor.gravity = -2.0f;
|
||||
this->actor.flags &= ~1;
|
||||
@@ -386,11 +375,12 @@ void EnGeldB_Wait(EnGeldB* this, GlobalContext* globalCtx) {
|
||||
}
|
||||
|
||||
void EnGeldB_SetupFlee(EnGeldB* this) {
|
||||
Animation_Change(&this->skelAnime, &D_0600ADF8, -2.0f, Animation_GetLastFrame(&D_0600ADF8), 0.0f,
|
||||
ANIMMODE_ONCE_INTERP, -4.0f);
|
||||
f32 lastFrame = Animation_GetLastFrame(&gGerudoRedJumpAnim);
|
||||
|
||||
Animation_Change(&this->skelAnime, &gGerudoRedJumpAnim, -2.0f, lastFrame, 0.0f, ANIMMODE_ONCE_INTERP, -4.0f);
|
||||
this->timer = 20;
|
||||
this->invisible = false;
|
||||
this->actionState = GELDB_WAIT;
|
||||
this->action = GELDB_WAIT;
|
||||
this->actor.shape.rot.y = this->actor.world.rot.y = this->actor.yawTowardsPlayer;
|
||||
EnGeldB_SetupAction(this, EnGeldB_Flee);
|
||||
}
|
||||
@@ -414,8 +404,8 @@ void EnGeldB_Flee(EnGeldB* this, GlobalContext* globalCtx) {
|
||||
}
|
||||
|
||||
void EnGeldB_SetupReady(EnGeldB* this) {
|
||||
Animation_MorphToLoop(&this->skelAnime, &D_0600B6D4, -4.0f);
|
||||
this->actionState = GELDB_READY;
|
||||
Animation_MorphToLoop(&this->skelAnime, &gGerudoRedNeutralAnim, -4.0f);
|
||||
this->action = GELDB_READY;
|
||||
this->timer = Rand_ZeroOne() * 10.0f + 5.0f;
|
||||
this->actor.speedXZ = 0.0f;
|
||||
this->actor.world.rot.y = this->actor.shape.rot.y;
|
||||
@@ -478,9 +468,10 @@ void EnGeldB_Ready(EnGeldB* this, GlobalContext* globalCtx) {
|
||||
}
|
||||
|
||||
void EnGeldB_SetupAdvance(EnGeldB* this, GlobalContext* globalCtx) {
|
||||
Animation_Change(&this->skelAnime, &D_060024E8, 1.0f, 0.0f, Animation_GetLastFrame(&D_060024E8),
|
||||
ANIMMODE_LOOP_INTERP, -4.0f);
|
||||
this->actionState = GELDB_ADVANCE;
|
||||
f32 lastFrame = Animation_GetLastFrame(&gGerudoRedWalkAnim);
|
||||
|
||||
Animation_Change(&this->skelAnime, &gGerudoRedWalkAnim, 1.0f, 0.0f, lastFrame, ANIMMODE_LOOP_INTERP, -4.0f);
|
||||
this->action = GELDB_ADVANCE;
|
||||
EnGeldB_SetupAction(this, EnGeldB_Advance);
|
||||
}
|
||||
|
||||
@@ -562,11 +553,12 @@ void EnGeldB_Advance(EnGeldB* this, GlobalContext* globalCtx) {
|
||||
}
|
||||
|
||||
void EnGeldB_SetupRollForward(EnGeldB* this) {
|
||||
Animation_Change(&this->skelAnime, &D_06001390, -1.0f, Animation_GetLastFrame(&D_06001390), 0.0f, ANIMMODE_ONCE,
|
||||
-3.0f);
|
||||
f32 lastFrame = Animation_GetLastFrame(&gGerudoRedFlipAnim);
|
||||
|
||||
Animation_Change(&this->skelAnime, &gGerudoRedFlipAnim, -1.0f, lastFrame, 0.0f, ANIMMODE_ONCE, -3.0f);
|
||||
this->timer = 0;
|
||||
this->invisible = true;
|
||||
this->actionState = GELDB_ROLL_FORWARD;
|
||||
this->action = GELDB_ROLL_FORWARD;
|
||||
this->actor.world.rot.y = this->actor.shape.rot.y = this->actor.yawTowardsPlayer;
|
||||
this->actor.speedXZ = 10.0f;
|
||||
Audio_PlayActorSound2(&this->actor, NA_SE_EN_STAL_JUMP);
|
||||
@@ -599,8 +591,8 @@ void EnGeldB_RollForward(EnGeldB* this, GlobalContext* globalCtx) {
|
||||
}
|
||||
|
||||
void EnGeldB_SetupPivot(EnGeldB* this) {
|
||||
Animation_MorphToLoop(&this->skelAnime, &D_0600A814, -4.0f);
|
||||
this->actionState = GELDB_PIVOT;
|
||||
Animation_MorphToLoop(&this->skelAnime, &gGerudoRedSidestepAnim, -4.0f);
|
||||
this->action = GELDB_PIVOT;
|
||||
EnGeldB_SetupAction(this, EnGeldB_Pivot);
|
||||
}
|
||||
|
||||
@@ -636,13 +628,14 @@ void EnGeldB_Pivot(EnGeldB* this, GlobalContext* globalCtx) {
|
||||
}
|
||||
|
||||
void EnGeldB_SetupCircle(EnGeldB* this) {
|
||||
Animation_Change(&this->skelAnime, &D_0600A814, 1.0f, 0.0f, Animation_GetLastFrame(&D_0600A814),
|
||||
ANIMMODE_LOOP_INTERP, 0.0f);
|
||||
f32 lastFrame = Animation_GetLastFrame(&gGerudoRedSidestepAnim);
|
||||
|
||||
Animation_Change(&this->skelAnime, &gGerudoRedSidestepAnim, 1.0f, 0.0f, lastFrame, ANIMMODE_LOOP_INTERP, 0.0f);
|
||||
this->actor.speedXZ = Rand_CenteredFloat(12.0f);
|
||||
this->actor.world.rot.y = this->actor.shape.rot.y;
|
||||
this->skelAnime.playSpeed = -this->actor.speedXZ * 0.5f;
|
||||
this->timer = Rand_ZeroOne() * 30.0f + 30.0f;
|
||||
this->actionState = GELDB_CIRCLE;
|
||||
this->action = GELDB_CIRCLE;
|
||||
this->approachRate = 0.0f;
|
||||
EnGeldB_SetupAction(this, EnGeldB_Circle);
|
||||
}
|
||||
@@ -739,9 +732,9 @@ void EnGeldB_Circle(EnGeldB* this, GlobalContext* globalCtx) {
|
||||
void EnGeldB_SetupSpinDodge(EnGeldB* this, GlobalContext* globalCtx) {
|
||||
s16 sp3E;
|
||||
Player* player = PLAYER;
|
||||
f32 lastFrame = Animation_GetLastFrame(&gGerudoRedSidestepAnim);
|
||||
|
||||
Animation_Change(&this->skelAnime, &D_0600A814, 1.0f, 0.0f, Animation_GetLastFrame(&D_0600A814),
|
||||
ANIMMODE_LOOP_INTERP, 0.0f);
|
||||
Animation_Change(&this->skelAnime, &gGerudoRedSidestepAnim, 1.0f, 0.0f, lastFrame, ANIMMODE_LOOP_INTERP, 0.0f);
|
||||
sp3E = player->actor.shape.rot.y;
|
||||
if (Math_SinS(sp3E - this->actor.shape.rot.y) > 0.0f) {
|
||||
this->actor.speedXZ = -10.0f;
|
||||
@@ -757,7 +750,7 @@ void EnGeldB_SetupSpinDodge(EnGeldB* this, GlobalContext* globalCtx) {
|
||||
this->timer = 6;
|
||||
this->approachRate = 0.0f;
|
||||
this->unkFloat = 0.0f;
|
||||
this->actionState = GELDB_SPIN_DODGE;
|
||||
this->action = GELDB_SPIN_DODGE;
|
||||
|
||||
EnGeldB_SetupAction(this, EnGeldB_SpinDodge);
|
||||
}
|
||||
@@ -836,9 +829,9 @@ void EnGeldB_SpinDodge(EnGeldB* this, GlobalContext* globalCtx) {
|
||||
}
|
||||
|
||||
void EnGeldB_SetupSlash(EnGeldB* this) {
|
||||
Animation_PlayOnce(&this->skelAnime, &D_060003CC);
|
||||
Animation_PlayOnce(&this->skelAnime, &gGerudoRedSlashAnim);
|
||||
this->swordCollider.base.atFlags &= ~AT_BOUNCED;
|
||||
this->actionState = GELDB_SLASH;
|
||||
this->action = GELDB_SLASH;
|
||||
this->spinAttackState = 0;
|
||||
this->actor.speedXZ = 0.0f;
|
||||
func_800F8A44(&this->actor.projectedPos, NA_SE_EN_GERUDOFT_BREATH);
|
||||
@@ -893,10 +886,11 @@ void EnGeldB_Slash(EnGeldB* this, GlobalContext* globalCtx) {
|
||||
}
|
||||
|
||||
void EnGeldB_SetupSpinAttack(EnGeldB* this) {
|
||||
Animation_Change(&this->skelAnime, &D_06000F5C, 1.0f, 0.0f, Animation_GetLastFrame(&D_06000F5C),
|
||||
ANIMMODE_ONCE_INTERP, 0.0f);
|
||||
f32 lastFrame = Animation_GetLastFrame(&gGerudoRedSpinAttackAnim);
|
||||
|
||||
Animation_Change(&this->skelAnime, &gGerudoRedSpinAttackAnim, 1.0f, 0.0f, lastFrame, ANIMMODE_ONCE_INTERP, 0.0f);
|
||||
this->swordCollider.base.atFlags &= ~(AT_HIT | AT_BOUNCED);
|
||||
this->actionState = GELDB_SPIN_ATTACK;
|
||||
this->action = GELDB_SPIN_ATTACK;
|
||||
this->spinAttackState = 0;
|
||||
this->actor.speedXZ = 0.0f;
|
||||
EnGeldB_SetupAction(this, EnGeldB_SpinAttack);
|
||||
@@ -974,10 +968,10 @@ void EnGeldB_SpinAttack(EnGeldB* this, GlobalContext* globalCtx) {
|
||||
}
|
||||
|
||||
void EnGeldB_SetupRollBack(EnGeldB* this) {
|
||||
Animation_MorphToPlayOnce(&this->skelAnime, &D_06001390, -3.0f);
|
||||
Animation_MorphToPlayOnce(&this->skelAnime, &gGerudoRedFlipAnim, -3.0f);
|
||||
this->timer = 0;
|
||||
this->invisible = true;
|
||||
this->actionState = GELDB_ROLL_BACK;
|
||||
this->action = GELDB_ROLL_BACK;
|
||||
this->actor.speedXZ = -8.0f;
|
||||
Audio_PlayActorSound2(&this->actor, NA_SE_EN_STAL_JUMP);
|
||||
this->actor.shape.rot.y = this->actor.world.rot.y = this->actor.yawTowardsPlayer;
|
||||
@@ -1004,14 +998,14 @@ void EnGeldB_SetupStunned(EnGeldB* this) {
|
||||
if (this->actor.bgCheckFlags & 1) {
|
||||
this->actor.speedXZ = 0.0f;
|
||||
}
|
||||
if ((this->damageEffect != GELDB_DMG_FREEZE) || (this->actionState == GELDB_SPIN_ATTACK)) {
|
||||
Animation_PlayOnceSetSpeed(&this->skelAnime, &D_06002280, 0.0f);
|
||||
if ((this->damageEffect != GELDB_DMG_FREEZE) || (this->action == GELDB_SPIN_ATTACK)) {
|
||||
Animation_PlayOnceSetSpeed(&this->skelAnime, &gGerudoRedDamageAnim, 0.0f);
|
||||
}
|
||||
if (this->damageEffect == GELDB_DMG_FREEZE) {
|
||||
this->iceTimer = 36;
|
||||
}
|
||||
Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOMA_JR_FREEZE);
|
||||
this->actionState = GELDB_STUNNED;
|
||||
this->action = GELDB_STUNNED;
|
||||
EnGeldB_SetupAction(this, EnGeldB_Stunned);
|
||||
}
|
||||
|
||||
@@ -1035,7 +1029,7 @@ void EnGeldB_Stunned(EnGeldB* this, GlobalContext* globalCtx) {
|
||||
}
|
||||
|
||||
void EnGeldB_SetupDamaged(EnGeldB* this) {
|
||||
Animation_MorphToPlayOnce(&this->skelAnime, &D_06002280, -4.0f);
|
||||
Animation_MorphToPlayOnce(&this->skelAnime, &gGerudoRedDamageAnim, -4.0f);
|
||||
if (this->actor.bgCheckFlags & 1) {
|
||||
this->invisible = false;
|
||||
this->actor.speedXZ = -4.0f;
|
||||
@@ -1045,7 +1039,7 @@ void EnGeldB_SetupDamaged(EnGeldB* this) {
|
||||
this->lookTimer = 0;
|
||||
this->actor.world.rot.y = this->actor.yawTowardsPlayer;
|
||||
Audio_PlayActorSound2(&this->actor, NA_SE_EN_GERUDOFT_DAMAGE);
|
||||
this->actionState = GELDB_DAMAGED;
|
||||
this->action = GELDB_DAMAGED;
|
||||
EnGeldB_SetupAction(this, EnGeldB_Damaged);
|
||||
}
|
||||
|
||||
@@ -1079,11 +1073,12 @@ void EnGeldB_Damaged(EnGeldB* this, GlobalContext* globalCtx) {
|
||||
}
|
||||
|
||||
void EnGeldB_SetupJump(EnGeldB* this) {
|
||||
Animation_Change(&this->skelAnime, &D_06001390, -1.0f, Animation_GetLastFrame(&D_06001390), 0.0f, ANIMMODE_ONCE,
|
||||
-3.0f);
|
||||
f32 lastFrame = Animation_GetLastFrame(&gGerudoRedFlipAnim);
|
||||
|
||||
Animation_Change(&this->skelAnime, &gGerudoRedFlipAnim, -1.0f, lastFrame, 0.0f, ANIMMODE_ONCE, -3.0f);
|
||||
this->timer = 0;
|
||||
this->invisible = false;
|
||||
this->actionState = GELDB_JUMP;
|
||||
this->action = GELDB_JUMP;
|
||||
this->actor.speedXZ = 6.5f;
|
||||
this->actor.velocity.y = 15.0f;
|
||||
Audio_PlayActorSound2(&this->actor, NA_SE_EN_STAL_JUMP);
|
||||
@@ -1112,16 +1107,15 @@ void EnGeldB_Jump(EnGeldB* this, GlobalContext* globalCtx) {
|
||||
}
|
||||
|
||||
void EnGeldB_SetupBlock(EnGeldB* this) {
|
||||
f32 lastFrame;
|
||||
f32 lastFrame = Animation_GetLastFrame(&gGerudoRedBlockAnim);
|
||||
|
||||
lastFrame = Animation_GetLastFrame(&D_06001578);
|
||||
if (this->swordState != 0) {
|
||||
this->swordState = -1;
|
||||
}
|
||||
this->actor.speedXZ = 0.0f;
|
||||
this->actionState = GELDB_BLOCK;
|
||||
this->action = GELDB_BLOCK;
|
||||
this->timer = (s32)Rand_CenteredFloat(10.0f) + 10;
|
||||
Animation_Change(&this->skelAnime, &D_06001578, 0.0f, 0.0f, lastFrame, ANIMMODE_ONCE, 0.0f);
|
||||
Animation_Change(&this->skelAnime, &gGerudoRedBlockAnim, 0.0f, 0.0f, lastFrame, ANIMMODE_ONCE, 0.0f);
|
||||
EnGeldB_SetupAction(this, EnGeldB_Block);
|
||||
}
|
||||
|
||||
@@ -1181,9 +1175,9 @@ void EnGeldB_Block(EnGeldB* this, GlobalContext* globalCtx) {
|
||||
void EnGeldB_SetupSidestep(EnGeldB* this, GlobalContext* globalCtx) {
|
||||
s16 linkAngle;
|
||||
Player* player;
|
||||
f32 lastFrame = Animation_GetLastFrame(&gGerudoRedSidestepAnim);
|
||||
|
||||
Animation_Change(&this->skelAnime, &D_0600A814, 1.0f, 0.0f, Animation_GetLastFrame(&D_0600A814),
|
||||
ANIMMODE_LOOP_INTERP, 0.0f);
|
||||
Animation_Change(&this->skelAnime, &gGerudoRedSidestepAnim, 1.0f, 0.0f, lastFrame, ANIMMODE_LOOP_INTERP, 0.0f);
|
||||
player = PLAYER;
|
||||
Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 1, 0xFA0, 1);
|
||||
linkAngle = player->actor.shape.rot.y;
|
||||
@@ -1198,7 +1192,7 @@ void EnGeldB_SetupSidestep(EnGeldB* this, GlobalContext* globalCtx) {
|
||||
this->approachRate = 0.0f;
|
||||
this->actor.world.rot.y = this->actor.shape.rot.y + 0x3FFF;
|
||||
this->timer = Rand_ZeroOne() * 10.0f + 5.0f;
|
||||
this->actionState = GELDB_SIDESTEP;
|
||||
this->action = GELDB_SIDESTEP;
|
||||
EnGeldB_SetupAction(this, EnGeldB_Sidestep);
|
||||
}
|
||||
|
||||
@@ -1309,7 +1303,7 @@ void EnGeldB_Sidestep(EnGeldB* this, GlobalContext* globalCtx) {
|
||||
}
|
||||
|
||||
void EnGeldB_SetupDefeated(EnGeldB* this) {
|
||||
Animation_MorphToPlayOnce(&this->skelAnime, &D_06001E10, -4.0f);
|
||||
Animation_MorphToPlayOnce(&this->skelAnime, &gGerudoRedDefeatAnim, -4.0f);
|
||||
this->actor.world.rot.y = this->actor.shape.rot.y = this->actor.yawTowardsPlayer;
|
||||
if (this->actor.bgCheckFlags & 1) {
|
||||
this->invisible = false;
|
||||
@@ -1317,7 +1311,7 @@ void EnGeldB_SetupDefeated(EnGeldB* this) {
|
||||
} else {
|
||||
this->invisible = true;
|
||||
}
|
||||
this->actionState = GELDB_DEFEAT;
|
||||
this->action = GELDB_DEFEAT;
|
||||
this->actor.flags &= ~1;
|
||||
Audio_PlayActorSound2(&this->actor, NA_SE_EN_GERUDOFT_DEAD);
|
||||
EnGeldB_SetupAction(this, EnGeldB_Defeated);
|
||||
@@ -1339,11 +1333,11 @@ void EnGeldB_Defeated(EnGeldB* this, GlobalContext* globalCtx) {
|
||||
}
|
||||
}
|
||||
|
||||
void func_80A391D8(EnGeldB* this, GlobalContext* globalCtx) {
|
||||
if ((this->actionState == GELDB_READY) && (this->lookTimer != 0)) {
|
||||
void EnGeldB_TurnHead(EnGeldB* this, GlobalContext* globalCtx) {
|
||||
if ((this->action == GELDB_READY) && (this->lookTimer != 0)) {
|
||||
this->headRot.y = Math_SinS(this->lookTimer * 0x1068) * 8920.0f;
|
||||
} else if (this->actionState != GELDB_STUNNED) {
|
||||
if ((this->actionState != GELDB_SLASH) && (this->actionState != GELDB_SPIN_ATTACK)) {
|
||||
} else if (this->action != GELDB_STUNNED) {
|
||||
if ((this->action != GELDB_SLASH) && (this->action != GELDB_SPIN_ATTACK)) {
|
||||
Math_SmoothStepToS(&this->headRot.y, this->actor.yawTowardsPlayer - this->actor.shape.rot.y, 1, 0x1F4, 0);
|
||||
this->headRot.y = CLAMP(this->headRot.y, -0x256F, 0x256F);
|
||||
} else {
|
||||
@@ -1352,14 +1346,14 @@ void func_80A391D8(EnGeldB* this, GlobalContext* globalCtx) {
|
||||
}
|
||||
}
|
||||
|
||||
void func_80A392D8(EnGeldB* this, GlobalContext* globalCtx) {
|
||||
void EnGeldB_CollisionCheck(EnGeldB* this, GlobalContext* globalCtx) {
|
||||
s32 pad;
|
||||
EnItem00* key;
|
||||
|
||||
if (this->blockCollider.base.acFlags & AC_BOUNCED) {
|
||||
this->blockCollider.base.acFlags &= ~AC_BOUNCED;
|
||||
this->bodyCollider.base.acFlags &= ~AC_HIT;
|
||||
} else if ((this->bodyCollider.base.acFlags & AC_HIT) && (this->actionState >= GELDB_READY) &&
|
||||
} else if ((this->bodyCollider.base.acFlags & AC_HIT) && (this->action >= GELDB_READY) &&
|
||||
(this->spinAttackState < 2)) {
|
||||
this->bodyCollider.base.acFlags &= ~AC_HIT;
|
||||
if (this->actor.colChkInfo.damageEffect != GELDB_DMG_UNK_6) {
|
||||
@@ -1368,7 +1362,7 @@ void func_80A392D8(EnGeldB* this, GlobalContext* globalCtx) {
|
||||
func_800F8A44(&this->actor.projectedPos, NA_SE_EN_GERUDOFT_BREATH);
|
||||
if ((this->actor.colChkInfo.damageEffect == GELDB_DMG_STUN) ||
|
||||
(this->actor.colChkInfo.damageEffect == GELDB_DMG_FREEZE)) {
|
||||
if (this->actionState != GELDB_STUNNED) {
|
||||
if (this->action != GELDB_STUNNED) {
|
||||
func_8003426C(&this->actor, 0, 0x78, 0, 0x50);
|
||||
Actor_ApplyDamage(&this->actor);
|
||||
EnGeldB_SetupStunned(this);
|
||||
@@ -1399,22 +1393,22 @@ void EnGeldB_Update(Actor* thisx, GlobalContext* globalCtx) {
|
||||
s32 pad;
|
||||
EnGeldB* this = THIS;
|
||||
|
||||
func_80A392D8(this, globalCtx);
|
||||
EnGeldB_CollisionCheck(this, globalCtx);
|
||||
if (this->actor.colChkInfo.damageEffect != GELDB_DMG_UNK_6) {
|
||||
Actor_MoveForward(&this->actor);
|
||||
Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 15.0f, 30.0f, 60.0f, 0x1D);
|
||||
this->actionFunc(this, globalCtx);
|
||||
this->actor.focus.pos = this->actor.world.pos;
|
||||
this->actor.focus.pos.y += 40.0f;
|
||||
func_80A391D8(this, globalCtx);
|
||||
EnGeldB_TurnHead(this, globalCtx);
|
||||
}
|
||||
Collider_UpdateCylinder(&this->actor, &this->bodyCollider);
|
||||
CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->bodyCollider.base);
|
||||
if ((this->actionState >= GELDB_READY) && (this->spinAttackState < 2) &&
|
||||
if ((this->action >= GELDB_READY) && (this->spinAttackState < 2) &&
|
||||
((this->actor.colorFilterTimer == 0) || !(this->actor.colorFilterParams & 0x4000))) {
|
||||
CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->bodyCollider.base);
|
||||
}
|
||||
if ((this->actionState == GELDB_BLOCK) && (this->skelAnime.curFrame == 0.0f)) {
|
||||
if ((this->action == GELDB_BLOCK) && (this->skelAnime.curFrame == 0.0f)) {
|
||||
CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->blockCollider.base);
|
||||
}
|
||||
if (this->swordState > 0) {
|
||||
@@ -1478,12 +1472,11 @@ void EnGeldB_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList,
|
||||
Matrix_MultVec3f(&swordTipOffset, &swordTip);
|
||||
Matrix_MultVec3f(&swordHiltOffset, &swordHilt);
|
||||
|
||||
if ((this->swordState < 0) ||
|
||||
((this->actionState != GELDB_SLASH) && (this->actionState != GELDB_SPIN_ATTACK))) {
|
||||
EffectBlure_AddSpace(Effect_GetByIndex(this->blureIdx));
|
||||
if ((this->swordState < 0) || ((this->action != GELDB_SLASH) && (this->action != GELDB_SPIN_ATTACK))) {
|
||||
EffectBlure_AddSpace(Effect_GetByIndex(this->blureIndex));
|
||||
this->swordState = 0;
|
||||
} else if (this->swordState > 0) {
|
||||
EffectBlure_AddVertex(Effect_GetByIndex(this->blureIdx), &swordTip, &swordHilt);
|
||||
EffectBlure_AddVertex(Effect_GetByIndex(this->blureIndex), &swordTip, &swordHilt);
|
||||
}
|
||||
} else {
|
||||
Actor_SetFeetPos(&this->actor, limbIndex, 19, &footOffset, 22, &footOffset);
|
||||
@@ -1547,7 +1540,8 @@ void EnGeldB_Draw(Actor* thisx, GlobalContext* globalCtx) {
|
||||
{ 3000.0f, 0.0f, 1600.0f },
|
||||
{ 3000.0f, 6000.0f, 1600.0f },
|
||||
};
|
||||
static Gfx* eyeDLists[4] = { 0x06005FE8, 0x060065A8, 0x06006D28, 0x060065A8 };
|
||||
static u64* eyeDLists[4] = { gGerudoRedEyeOpenTex, gGerudoRedEyeHalfTex, gGerudoRedEyeShutTex,
|
||||
gGerudoRedEyeHalfTex };
|
||||
s32 pad;
|
||||
EnGeldB* this = THIS;
|
||||
|
||||
@@ -1556,7 +1550,8 @@ void EnGeldB_Draw(Actor* thisx, GlobalContext* globalCtx) {
|
||||
|
||||
if ((this->spinAttackState >= 2) && SkelAnime_Update(&this->skelAnime)) {
|
||||
if (this->spinAttackState == 2) {
|
||||
Animation_Change(&this->skelAnime, &D_06000F5C, 0.5f, 0.0f, 12.0f, ANIMMODE_ONCE_INTERP, 4.0f);
|
||||
Animation_Change(&this->skelAnime, &gGerudoRedSpinAttackAnim, 0.5f, 0.0f, 12.0f, ANIMMODE_ONCE_INTERP,
|
||||
4.0f);
|
||||
this->spinAttackState++;
|
||||
thisx->world.rot.y = thisx->shape.rot.y = thisx->yawTowardsPlayer;
|
||||
} else {
|
||||
@@ -1575,12 +1570,12 @@ void EnGeldB_Draw(Actor* thisx, GlobalContext* globalCtx) {
|
||||
}
|
||||
}
|
||||
|
||||
if ((this->actionState != GELDB_WAIT) || !this->invisible) {
|
||||
if ((this->action != GELDB_WAIT) || !this->invisible) {
|
||||
func_80093D18(globalCtx->state.gfxCtx);
|
||||
gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(eyeDLists[this->blinkState]));
|
||||
SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable,
|
||||
this->skelAnime.dListCount, EnGeldB_OverrideLimbDraw, EnGeldB_PostLimbDraw, this);
|
||||
if (this->actionState == GELDB_BLOCK) {
|
||||
if (this->action == GELDB_BLOCK) {
|
||||
s32 i;
|
||||
Vec3f blockTrisVtx0[3];
|
||||
Vec3f blockTrisVtx1[3];
|
||||
@@ -1599,8 +1594,8 @@ void EnGeldB_Draw(Actor* thisx, GlobalContext* globalCtx) {
|
||||
if ((this->iceTimer % 4) == 0) {
|
||||
s32 iceIndex = this->iceTimer >> 2;
|
||||
|
||||
EffectSsEnIce_SpawnFlyingVec3s(globalCtx, thisx, &this->bodyPartsPos[iceIndex], 0x96, 0x96, 0x96, 0xFA,
|
||||
0xEB, 0xF5, 0xFF, 1.5f);
|
||||
EffectSsEnIce_SpawnFlyingVec3s(globalCtx, thisx, &this->bodyPartsPos[iceIndex], 150, 150, 150, 250, 235,
|
||||
245, 255, 1.5f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ typedef struct EnGeldB {
|
||||
/* 0x0188 */ SkelAnime skelAnime;
|
||||
/* 0x01CC */ Vec3s jointTable[24];
|
||||
/* 0x025C */ Vec3s morphTable[24];
|
||||
/* 0x02EC */ s32 actionState;
|
||||
/* 0x02EC */ s32 action;
|
||||
/* 0x02F0 */ char unk_2F0[4];
|
||||
/* 0x02F4 */ EnGeldBActionFunc actionFunc;
|
||||
/* 0x02F8 */ s16 unkTimer;
|
||||
@@ -31,7 +31,7 @@ typedef struct EnGeldB {
|
||||
/* 0x0316 */ char unk_316[2];
|
||||
/* 0x0318 */ s16 invisible;
|
||||
/* 0x031A */ u8 blinkState;
|
||||
/* 0x031C */ s32 blureIdx;
|
||||
/* 0x031C */ s32 blureIndex;
|
||||
/* 0x0320 */ ColliderCylinder bodyCollider;
|
||||
/* 0x036C */ ColliderQuad swordCollider;
|
||||
/* 0x03EC */ ColliderTris blockCollider;
|
||||
|
||||
@@ -18,7 +18,11 @@ typedef struct EnHorse {
|
||||
/* 0x0214 */ f32 unk_214;
|
||||
/* 0x0218 */ char unk_218[0x040];
|
||||
/* 0x0258 */ Vec3f unk_258;
|
||||
/* 0x0264 */ char unk_264[0x198];
|
||||
/* 0x0264 */ char unk_264[0x124];
|
||||
/* 0x0388 */ s32 unk_388;
|
||||
/* 0x038C */ char unk_38C[0x14];
|
||||
/* 0x03A0 */ s32 unk_3A0;
|
||||
/* 0x03A4 */ char unk_3A4[0x58];
|
||||
} EnHorse; // size = 0x03FC
|
||||
|
||||
#define EN_HORSE_CHECK_1(horseActor) \
|
||||
|
||||
@@ -5,17 +5,50 @@
|
||||
*/
|
||||
|
||||
#include "z_en_horse_game_check.h"
|
||||
#include "overlays/actors/ovl_En_Horse/z_en_horse.h"
|
||||
|
||||
#define FLAGS 0x00000010
|
||||
|
||||
#define THIS ((EnHorseGameCheck*)thisx)
|
||||
#define THIS ((EnHorseGameCheckBase*)thisx)
|
||||
#define AT_FINISH_LINE(actor) \
|
||||
(Math3D_PointInSquare2D(sFinishLine[0], sFinishLine[1], sFinishLine[2], sFinishLine[3], (actor)->world.pos.x, \
|
||||
(actor)->world.pos.z))
|
||||
#define AT_RANCH_EXIT(actor) \
|
||||
(Math3D_PointInSquare2D(sRanchExit[0], sRanchExit[1], sRanchExit[2], sRanchExit[3], (actor)->world.pos.x, \
|
||||
(actor)->world.pos.z))
|
||||
|
||||
#define INGORACE_PLAYER_MOVE (1 << 0)
|
||||
#define INGORACE_SET_TIMER (1 << 1)
|
||||
#define INGORACE_INGO_MOVE (1 << 2)
|
||||
|
||||
typedef enum {
|
||||
/* 0 */ INGORACE_NO_RESULT,
|
||||
/* 1 */ INGORACE_PLAYER_WIN,
|
||||
/* 2 */ INGORACE_INGO_WIN,
|
||||
/* 3 */ INGORACE_TIME_UP
|
||||
} HorseGameIngoRaceResult;
|
||||
|
||||
#define MALONRACE_PLAYER_MOVE (1 << 0)
|
||||
#define MALONRACE_SET_TIMER (1 << 1)
|
||||
#define MALONRACE_SECOND_LAP (1 << 2)
|
||||
#define MALONRACE_BROKE_RULE (1 << 3)
|
||||
#define MALONRACE_START_SFX (1 << 4)
|
||||
#define MALONRACE_PLAYER_START (1 << 5)
|
||||
#define MALONRACE_PLAYER_ON_MARK (1 << 6)
|
||||
|
||||
typedef enum {
|
||||
/* 0 */ MALONRACE_NO_RESULT,
|
||||
/* 1 */ MALONRACE_SUCCESS,
|
||||
/* 2 */ MALONRACE_TIME_UP,
|
||||
/* 3 */ MALONRACE_UNUSED,
|
||||
/* 4 */ MALONRACE_FAILURE
|
||||
} HorseGameMalonRaceResult;
|
||||
|
||||
void EnHorseGameCheck_Init(Actor* thisx, GlobalContext* globalCtx);
|
||||
void EnHorseGameCheck_Destroy(Actor* thisx, GlobalContext* globalCtx);
|
||||
void EnHorseGameCheck_Update(Actor* thisx, GlobalContext* globalCtx);
|
||||
void EnHorseGameCheck_Draw(Actor* thisx, GlobalContext* globalCtx);
|
||||
|
||||
/*
|
||||
const ActorInit En_Horse_Game_Check_InitVars = {
|
||||
ACTOR_EN_HORSE_GAME_CHECK,
|
||||
ACTORCAT_BG,
|
||||
@@ -27,39 +60,410 @@ const ActorInit En_Horse_Game_Check_InitVars = {
|
||||
(ActorFunc)EnHorseGameCheck_Update,
|
||||
(ActorFunc)EnHorseGameCheck_Draw,
|
||||
};
|
||||
*/
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Horse_Game_Check/func_80A67550.s")
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Horse_Game_Check/func_80A67608.s")
|
||||
static Vec3f sIngoRaceCheckpoints[] = {
|
||||
{ 1700.0f, 1.0f, -540.0f },
|
||||
{ 117.0f, 1.0f, 488.0f },
|
||||
{ -1700.0f, 1.0f, -540.0f },
|
||||
};
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Horse_Game_Check/func_80A67618.s")
|
||||
static f32 sFinishLine[4] = { -200.0f, 80.0f, -2300.0f, -1470.0f };
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Horse_Game_Check/func_80A67764.s")
|
||||
static f32 sRanchExit[4] = { 800.0f, 1000.0f, -2900.0f, -2700.0f };
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Horse_Game_Check/func_80A67BDC.s")
|
||||
static Vec3f sUnusedZeroVec = { 0.0f, 0.0f, 0.0f };
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Horse_Game_Check/func_80A67BF8.s")
|
||||
static Vec3f sFencePos[] = {
|
||||
{ 820.0f, -44.0f, -1655.0f }, { 1497.0f, -21.0f, -1198.0f }, { 1655.0f, -44.0f, -396.0f },
|
||||
{ 1291.0f, -44.0f, 205.0f }, { 379.0f, -21.0f, 455.0f }, { -95.0f, -21.0f, 455.0f },
|
||||
{ -939.0f, 1.0f, 455.0f }, { -1644.0f, -21.0f, -1035.0f },
|
||||
};
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Horse_Game_Check/func_80A67C08.s")
|
||||
s32 EnHorseGameCheck_InitIngoRace(EnHorseGameCheckBase* base, GlobalContext* globalCtx) {
|
||||
EnHorseGameCheckIngoRace* this = (EnHorseGameCheckIngoRace*)base;
|
||||
s32 i;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Horse_Game_Check/func_80A67C50.s")
|
||||
this->base.type = HORSEGAME_INGO_RACE;
|
||||
this->startFlags = 0;
|
||||
for (i = 0; i < 3; i++) {
|
||||
this->playerCheck[i] = 0;
|
||||
}
|
||||
this->ingoHorse =
|
||||
Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_HORSE, -250.0f, 1.0f, -1650.0f, 0, 0x4000, 0, 0x8003);
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Horse_Game_Check/func_80A67C68.s")
|
||||
if (this->ingoHorse == NULL) {
|
||||
LogUtils_HungupThread("../z_en_horse_game_check.c", 385);
|
||||
}
|
||||
this->startTimer = 0;
|
||||
this->finishTimer = 0;
|
||||
this->result = INGORACE_NO_RESULT;
|
||||
this->playerFinish = 0;
|
||||
this->ingoFinish = 0;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Horse_Game_Check/func_80A67C78.s")
|
||||
return true;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Horse_Game_Check/func_80A67C88.s")
|
||||
s32 EnHorseGameCheck_DestroyIngoRace(EnHorseGameCheckBase* base, GlobalContext* globalCtx) {
|
||||
return true;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Horse_Game_Check/func_80A67CD4.s")
|
||||
void EnHorseGameCheck_FinishIngoRace(EnHorseGameCheckIngoRace* this, GlobalContext* globalCtx) {
|
||||
gSaveContext.cutsceneIndex = 0;
|
||||
if (this->result == INGORACE_PLAYER_WIN) {
|
||||
globalCtx->nextEntranceIndex = 0x4CE;
|
||||
if (gSaveContext.eventInf[0] & 0x40) {
|
||||
gSaveContext.eventInf[0] = (gSaveContext.eventInf[0] & ~0xF) | 6;
|
||||
gSaveContext.eventInf[0] = (gSaveContext.eventInf[0] & ~0x8000) | 0x8000;
|
||||
globalCtx->fadeTransition = 3;
|
||||
func_800775F0(0x42);
|
||||
} else {
|
||||
gSaveContext.eventInf[0] = (gSaveContext.eventInf[0] & ~0xF) | 4;
|
||||
gSaveContext.eventInf[0] = (gSaveContext.eventInf[0] & ~0x8000) | 0x8000;
|
||||
func_800775F0(0x42);
|
||||
globalCtx->fadeTransition = 0x2E;
|
||||
}
|
||||
} else {
|
||||
globalCtx->nextEntranceIndex = 0x558;
|
||||
gSaveContext.eventInf[0] = (gSaveContext.eventInf[0] & ~0xF) | 3;
|
||||
globalCtx->fadeTransition = 0x20;
|
||||
gSaveContext.eventInf[0] = (gSaveContext.eventInf[0] & ~0x8000) | 0x8000;
|
||||
}
|
||||
DREG(25) = 0;
|
||||
globalCtx->sceneLoadFlag = 0x14;
|
||||
gSaveContext.timer1State = 0;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Horse_Game_Check/func_80A67CE4.s")
|
||||
s32 EnHorseGameCheck_UpdateIngoRace(EnHorseGameCheckBase* base, GlobalContext* globalCtx) {
|
||||
EnHorseGameCheckIngoRace* this = (EnHorseGameCheckIngoRace*)base;
|
||||
Player* player = PLAYER;
|
||||
s32 i;
|
||||
EnHorse* ingoHorse;
|
||||
EnHorse* horse;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Horse_Game_Check/func_80A67DFC.s")
|
||||
if ((this->startTimer > 50) && !(this->startFlags & INGORACE_SET_TIMER)) {
|
||||
this->startFlags |= INGORACE_SET_TIMER;
|
||||
func_80088B34(0);
|
||||
} else if ((this->startTimer > 80) && (player->rideActor != NULL) && !(this->startFlags & INGORACE_PLAYER_MOVE)) {
|
||||
this->startFlags |= INGORACE_PLAYER_MOVE;
|
||||
horse = (EnHorse*)player->rideActor;
|
||||
horse->unk_388 = 1;
|
||||
} else if ((this->startTimer > 81) && !(this->startFlags & INGORACE_INGO_MOVE)) {
|
||||
ingoHorse = (EnHorse*)this->ingoHorse;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Horse_Game_Check/EnHorseGameCheck_Init.s")
|
||||
ingoHorse->unk_388 = 1;
|
||||
this->startFlags |= INGORACE_INGO_MOVE;
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_START_SHOT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Horse_Game_Check/EnHorseGameCheck_Destroy.s")
|
||||
this->startTimer++;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Horse_Game_Check/EnHorseGameCheck_Update.s")
|
||||
for (i = 0; i < 3; i++) {
|
||||
if ((player->rideActor != NULL) &&
|
||||
(Math3D_Vec3f_DistXYZ(&sIngoRaceCheckpoints[i], &player->rideActor->world.pos) < 400.0f)) {
|
||||
if ((i > 0) && (this->playerCheck[i - 1] == 1)) {
|
||||
this->playerCheck[i] = 1;
|
||||
} else if (i == 0) {
|
||||
this->playerCheck[i] = 1;
|
||||
}
|
||||
}
|
||||
if (Math3D_Vec3f_DistXYZ(&sIngoRaceCheckpoints[i], &this->ingoHorse->world.pos) < 400.0f) {
|
||||
if ((i > 0) && (this->ingoCheck[i - 1] == 1)) {
|
||||
this->ingoCheck[i] = 1;
|
||||
} else if (i == 0) {
|
||||
this->ingoCheck[i] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Horse_Game_Check/EnHorseGameCheck_Draw.s")
|
||||
if (this->result == INGORACE_NO_RESULT) {
|
||||
Player* player2 = player;
|
||||
|
||||
if ((player2->rideActor != NULL) && (this->playerCheck[2] == 1) && AT_FINISH_LINE(player2->rideActor)) {
|
||||
this->playerFinish++;
|
||||
if (this->playerFinish > 0) {
|
||||
this->result = INGORACE_PLAYER_WIN;
|
||||
this->finishTimer = 55;
|
||||
Audio_SetBGM(0x41);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_START_SHOT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
}
|
||||
for (i = 0; i < 3; i++) {
|
||||
this->playerCheck[i] = 0;
|
||||
}
|
||||
}
|
||||
if ((this->ingoHorse != NULL) && (this->ingoCheck[2] == 1) && AT_FINISH_LINE(this->ingoHorse)) {
|
||||
this->ingoFinish++;
|
||||
if (this->ingoFinish > 0) {
|
||||
ingoHorse = (EnHorse*)this->ingoHorse;
|
||||
|
||||
this->result = INGORACE_INGO_WIN;
|
||||
this->finishTimer = 70;
|
||||
ingoHorse->unk_1F0 |= 0x800000;
|
||||
Audio_SetBGM(0x41);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_START_SHOT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
}
|
||||
for (i = 0; i < 3; i++) {
|
||||
this->ingoCheck[i] = 0;
|
||||
}
|
||||
}
|
||||
if (((player2->rideActor != NULL) && AT_RANCH_EXIT(player2->rideActor)) || AT_RANCH_EXIT(&player2->actor)) {
|
||||
Audio_SetBGM(0x41);
|
||||
this->result = INGORACE_INGO_WIN;
|
||||
this->finishTimer = 20;
|
||||
}
|
||||
if ((gSaveContext.timer1Value >= 180) && (this->startFlags & 2)) {
|
||||
Audio_SetBGM(0x41);
|
||||
this->result = INGORACE_TIME_UP;
|
||||
this->finishTimer = 20;
|
||||
}
|
||||
} else {
|
||||
if (this->finishTimer > 0) {
|
||||
this->finishTimer--;
|
||||
} else {
|
||||
EnHorseGameCheck_FinishIngoRace(this, globalCtx);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
s32 EnHorseGameCheck_InitGerudoArchery(EnHorseGameCheckBase* base, GlobalContext* globalCtx) {
|
||||
EnHorseGameCheckGerudoArchery* this = (EnHorseGameCheckGerudoArchery*)base;
|
||||
|
||||
this->base.type = HORSEGAME_GERUDO_ARCHERY;
|
||||
this->unk_150 = 0;
|
||||
this->startTimer = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
s32 EnHorseGameCheck_DestroyGerudoArchery(EnHorseGameCheckBase* base, GlobalContext* globalCtx) {
|
||||
return true;
|
||||
}
|
||||
|
||||
s32 EnHorseGameCheck_UpdateGerudoArchery(EnHorseGameCheckBase* base, GlobalContext* globalCtx) {
|
||||
EnHorseGameCheckGerudoArchery* this = (EnHorseGameCheckGerudoArchery*)base;
|
||||
Player* player = PLAYER;
|
||||
EnHorse* horse = (EnHorse*)player->rideActor;
|
||||
|
||||
if (horse == NULL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (this->startTimer > 90) {
|
||||
if (globalCtx) {}
|
||||
horse->unk_3A0 = 1;
|
||||
}
|
||||
this->startTimer++;
|
||||
return true;
|
||||
}
|
||||
|
||||
s32 EnHorseGameCheck_InitType3(EnHorseGameCheckBase* base, GlobalContext* globalCtx) {
|
||||
EnHorseGameCheck3* this = (EnHorseGameCheck3*)base;
|
||||
|
||||
this->base.type = HORSEGAME_TYPE3;
|
||||
this->unk_150 = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
s32 EnHorseGameCheck_DestroyType3(EnHorseGameCheckBase* base, GlobalContext* globalCtx) {
|
||||
return true;
|
||||
}
|
||||
|
||||
s32 EnHorseGameCheck_UpdateType3(EnHorseGameCheckBase* base, GlobalContext* globalCtx) {
|
||||
return true;
|
||||
}
|
||||
|
||||
s32 EnHorseGameCheck_InitMalonRace(EnHorseGameCheckBase* base, GlobalContext* globalCtx) {
|
||||
EnHorseGameCheckMalonRace* this = (EnHorseGameCheckMalonRace*)base;
|
||||
s32 i;
|
||||
|
||||
this->base.type = HORSEGAME_MALON_RACE;
|
||||
this->raceFlags = 0;
|
||||
this->finishTimer = 0;
|
||||
this->result = MALONRACE_NO_RESULT;
|
||||
for (i = 0; i < 16; i++) {
|
||||
this->fenceCheck[i] = 0;
|
||||
}
|
||||
this->lapCount = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
s32 EnHorseGameCheck_DestroyMalonRace(EnHorseGameCheckBase* base, GlobalContext* globalCtx) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void EnHorseGameCheck_FinishMalonRace(EnHorseGameCheckMalonRace* this, GlobalContext* globalCtx) {
|
||||
if ((this->result == MALONRACE_SUCCESS) || (this->result == MALONRACE_TIME_UP)) {
|
||||
gSaveContext.cutsceneIndex = 0;
|
||||
globalCtx->nextEntranceIndex = 0x4CE;
|
||||
globalCtx->fadeTransition = 0x2E;
|
||||
globalCtx->sceneLoadFlag = 0x14;
|
||||
} else if (this->result == MALONRACE_FAILURE) {
|
||||
gSaveContext.timer1Value = 240;
|
||||
gSaveContext.timer1State = 0xF;
|
||||
gSaveContext.cutsceneIndex = 0;
|
||||
globalCtx->nextEntranceIndex = 0x4CE;
|
||||
globalCtx->fadeTransition = 0x2E;
|
||||
globalCtx->sceneLoadFlag = 0x14;
|
||||
} else {
|
||||
// not supported
|
||||
osSyncPrintf("En_HGC_Spot20_Ta_end():対応せず\n");
|
||||
gSaveContext.cutsceneIndex = 0;
|
||||
globalCtx->nextEntranceIndex = 0x157;
|
||||
globalCtx->fadeTransition = 0x2E;
|
||||
globalCtx->sceneLoadFlag = 0x14;
|
||||
}
|
||||
}
|
||||
|
||||
s32 EnHorseGameCheck_UpdateMalonRace(EnHorseGameCheckBase* base, GlobalContext* globalCtx) {
|
||||
EnHorseGameCheckMalonRace* this = (EnHorseGameCheckMalonRace*)base;
|
||||
s32 i;
|
||||
Player* player = PLAYER;
|
||||
EnHorse* horse;
|
||||
|
||||
if (!(this->raceFlags & MALONRACE_PLAYER_ON_MARK) && AT_FINISH_LINE(player->rideActor)) {
|
||||
this->raceFlags |= MALONRACE_PLAYER_ON_MARK;
|
||||
} else if ((this->raceFlags & MALONRACE_PLAYER_ON_MARK) && !(this->raceFlags & MALONRACE_PLAYER_START) && !AT_FINISH_LINE(player->rideActor)) {
|
||||
this->raceFlags |= MALONRACE_PLAYER_START;
|
||||
}
|
||||
if ((this->startTimer > 50) && !(this->raceFlags & MALONRACE_SET_TIMER)) {
|
||||
this->raceFlags |= MALONRACE_SET_TIMER;
|
||||
func_80088B34(0);
|
||||
} else if ((this->startTimer > 80) && (player->rideActor != NULL) && !(this->raceFlags & MALONRACE_PLAYER_MOVE)) {
|
||||
this->raceFlags |= MALONRACE_PLAYER_MOVE;
|
||||
horse = (EnHorse*)player->rideActor;
|
||||
|
||||
horse->unk_388 = 1;
|
||||
} else if ((this->startTimer > 81) && !(this->raceFlags & MALONRACE_START_SFX)) {
|
||||
this->raceFlags |= MALONRACE_START_SFX;
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_START_SHOT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
}
|
||||
|
||||
this->startTimer++;
|
||||
if (this->result == MALONRACE_NO_RESULT) {
|
||||
Player* player2 = player;
|
||||
f32 dist;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
if ((this->lapCount == 0) && (i >= 8)) {
|
||||
break;
|
||||
}
|
||||
dist = Math_Vec3f_DistXZ(&sFencePos[i % 8], &player2->rideActor->world.pos);
|
||||
if ((player->rideActor != NULL) && (dist < 250.0f)) {
|
||||
horse = (EnHorse*)player2->rideActor;
|
||||
|
||||
if (horse->unk_1F0 & 4) {
|
||||
if ((i > 0) && (this->fenceCheck[i - 1] == 1)) {
|
||||
this->fenceCheck[i] = 1;
|
||||
} else if (i == 0) {
|
||||
this->fenceCheck[i] = 1;
|
||||
}
|
||||
|
||||
if ((this->fenceCheck[i - 1] == 0) && !(this->raceFlags & MALONRACE_BROKE_RULE)) {
|
||||
this->raceFlags |= MALONRACE_BROKE_RULE;
|
||||
func_8010B680(globalCtx, 0x208C, NULL);
|
||||
this->result = 4;
|
||||
this->finishTimer = 30;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((player2->rideActor != NULL) && (this->raceFlags & MALONRACE_PLAYER_START) && AT_FINISH_LINE(player2->rideActor)) {
|
||||
if ((this->lapCount == 1) && (this->fenceCheck[15] == 0) && (player2->rideActor->prevPos.x < -200.0f)) {
|
||||
this->raceFlags |= MALONRACE_BROKE_RULE;
|
||||
func_8010B680(globalCtx, 0x208C, NULL);
|
||||
this->result = MALONRACE_FAILURE;
|
||||
this->finishTimer = 30;
|
||||
} else if (this->fenceCheck[15] == 1) {
|
||||
this->lapCount = 2;
|
||||
Audio_SetBGM(0x41);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_START_SHOT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
this->result = MALONRACE_SUCCESS;
|
||||
this->finishTimer = 70;
|
||||
gSaveContext.timer1State = 0xF;
|
||||
} else if ((this->fenceCheck[7] == 1) && !(this->raceFlags & MALONRACE_SECOND_LAP)) {
|
||||
this->lapCount = 1;
|
||||
this->raceFlags |= MALONRACE_SECOND_LAP;
|
||||
func_8010B680(globalCtx, 0x208D, NULL);
|
||||
} else if (this->fenceCheck[7] == 0) {
|
||||
this->raceFlags |= MALONRACE_BROKE_RULE;
|
||||
func_8010B680(globalCtx, 0x208C, NULL);
|
||||
this->result = MALONRACE_FAILURE;
|
||||
this->finishTimer = 30;
|
||||
} else if (player2->rideActor->prevPos.x > 80.0f) {
|
||||
this->raceFlags |= MALONRACE_BROKE_RULE;
|
||||
func_8010B680(globalCtx, 0x208C, NULL);
|
||||
this->result = MALONRACE_FAILURE;
|
||||
this->finishTimer = 30;
|
||||
}
|
||||
}
|
||||
if ((gSaveContext.timer1Value >= 180) && (this->raceFlags & MALONRACE_SET_TIMER)) {
|
||||
gSaveContext.timer1Value = 240;
|
||||
this->result = MALONRACE_TIME_UP;
|
||||
this->finishTimer = 30;
|
||||
gSaveContext.timer1State = 0;
|
||||
}
|
||||
} else {
|
||||
if (this->finishTimer > 0) {
|
||||
this->finishTimer--;
|
||||
} else {
|
||||
EnHorseGameCheck_FinishMalonRace(this, globalCtx);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static EnHorseGameCheckFunc sInitFuncs[] = {
|
||||
NULL,
|
||||
EnHorseGameCheck_InitIngoRace,
|
||||
EnHorseGameCheck_InitGerudoArchery,
|
||||
EnHorseGameCheck_InitType3,
|
||||
EnHorseGameCheck_InitMalonRace,
|
||||
};
|
||||
|
||||
static EnHorseGameCheckFunc sDestroyFuncs[] = {
|
||||
NULL,
|
||||
EnHorseGameCheck_DestroyIngoRace,
|
||||
EnHorseGameCheck_DestroyGerudoArchery,
|
||||
EnHorseGameCheck_DestroyType3,
|
||||
EnHorseGameCheck_DestroyMalonRace,
|
||||
};
|
||||
|
||||
static EnHorseGameCheckFunc sUpdateFuncs[] = {
|
||||
NULL,
|
||||
EnHorseGameCheck_UpdateIngoRace,
|
||||
EnHorseGameCheck_UpdateGerudoArchery,
|
||||
EnHorseGameCheck_UpdateType3,
|
||||
EnHorseGameCheck_UpdateMalonRace,
|
||||
};
|
||||
|
||||
void EnHorseGameCheck_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
s32 pad;
|
||||
EnHorseGameCheckBase* this = THIS;
|
||||
|
||||
if ((globalCtx->sceneNum == SCENE_SPOT20) && (Flags_GetEventChkInf(0x18) || DREG(1))) {
|
||||
this->actor.params = HORSEGAME_MALON_RACE;
|
||||
}
|
||||
if (sInitFuncs[this->actor.params] != NULL) {
|
||||
sInitFuncs[this->actor.params](this, globalCtx);
|
||||
}
|
||||
}
|
||||
|
||||
void EnHorseGameCheck_Destroy(Actor* thisx, GlobalContext* globalCtx) {
|
||||
s32 pad;
|
||||
EnHorseGameCheckBase* this = THIS;
|
||||
|
||||
if (sDestroyFuncs[this->actor.params] != NULL) {
|
||||
sDestroyFuncs[this->actor.params](this, globalCtx);
|
||||
}
|
||||
}
|
||||
|
||||
void EnHorseGameCheck_Update(Actor* thisx, GlobalContext* globalCtx) {
|
||||
s32 pad;
|
||||
EnHorseGameCheckBase* this = THIS;
|
||||
|
||||
if (sUpdateFuncs[this->type] != NULL) {
|
||||
sUpdateFuncs[this->type](this, globalCtx);
|
||||
}
|
||||
}
|
||||
|
||||
void EnHorseGameCheck_Draw(Actor* thisx, GlobalContext* globalCtx) {
|
||||
}
|
||||
|
||||
@@ -4,13 +4,64 @@
|
||||
#include "ultra64.h"
|
||||
#include "global.h"
|
||||
|
||||
struct EnHorseGameCheck;
|
||||
struct EnHorseGameCheckBase;
|
||||
|
||||
typedef struct EnHorseGameCheck {
|
||||
typedef s32 (*EnHorseGameCheckFunc)(struct EnHorseGameCheckBase* this, GlobalContext* globalCtx);
|
||||
|
||||
typedef struct EnHorseGameCheckBase {
|
||||
/* 0x0000 */ Actor actor;
|
||||
/* 0x014C */ char unk_14C[0x58];
|
||||
/* 0x014C */ s32 type;
|
||||
} EnHorseGameCheckBase; // size = 0x0150
|
||||
|
||||
typedef struct EnHorseGameCheckIngoRace {
|
||||
/* 0x0000 */ EnHorseGameCheckBase base;
|
||||
/* 0x0150 */ s32 startFlags;
|
||||
/* 0x0154 */ s32 playerCheck[3];
|
||||
/* 0x0160 */ s32 ingoCheck[3];
|
||||
/* 0x016C */ Actor* ingoHorse;
|
||||
/* 0x0170 */ s32 startTimer;
|
||||
/* 0x0174 */ s32 result;
|
||||
/* 0x0178 */ s32 finishTimer;
|
||||
/* 0x017C */ s32 playerFinish;
|
||||
/* 0x0180 */ s32 ingoFinish;
|
||||
} EnHorseGameCheckIngoRace; // size = 0x0184
|
||||
|
||||
typedef struct EnHorseGameCheckGerudoArchery {
|
||||
/* 0x0000 */ EnHorseGameCheckBase base;
|
||||
/* 0x0150 */ s32 unk_150;
|
||||
/* 0x0154 */ u32 startTimer;
|
||||
} EnHorseGameCheckGerudoArchery; // size = 0x0158
|
||||
|
||||
typedef struct EnHorseGameCheck3 {
|
||||
/* 0x0000 */ EnHorseGameCheckBase base;
|
||||
/* 0x0150 */ s32 unk_150;
|
||||
} EnHorseGameCheck3; // size = 0x0154
|
||||
|
||||
typedef struct EnHorseGameCheckMalonRace {
|
||||
/* 0x0000 */ EnHorseGameCheckBase base;
|
||||
/* 0x0150 */ s32 startTimer;
|
||||
/* 0x0154 */ s32 raceFlags;
|
||||
/* 0x0158 */ s32 fenceCheck[16];
|
||||
/* 0x0198 */ s32 finishTimer;
|
||||
/* 0x019C */ s32 result;
|
||||
/* 0x01A0 */ s32 lapCount;
|
||||
} EnHorseGameCheckMalonRace; // size = 0x01A4
|
||||
|
||||
typedef union EnHorseGameCheck {
|
||||
EnHorseGameCheckIngoRace ingo;
|
||||
EnHorseGameCheckGerudoArchery gerudo;
|
||||
EnHorseGameCheck3 type3;
|
||||
EnHorseGameCheckMalonRace malon;
|
||||
} EnHorseGameCheck; // size = 0x01A4
|
||||
|
||||
typedef enum {
|
||||
/* 0 */ HORSEGAME_NONE,
|
||||
/* 1 */ HORSEGAME_INGO_RACE,
|
||||
/* 2 */ HORSEGAME_GERUDO_ARCHERY,
|
||||
/* 3 */ HORSEGAME_TYPE3,
|
||||
/* 4 */ HORSEGAME_MALON_RACE
|
||||
} EnHorseGameCheckType;
|
||||
|
||||
extern const ActorInit En_Horse_Game_Check_InitVars;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
#include "z_en_torch2.h"
|
||||
#include "objects/object_torch2/object_torch2.h"
|
||||
|
||||
#define FLAGS 0x00000035
|
||||
|
||||
@@ -53,8 +54,6 @@ void EnTorch2_Destroy(Actor* thisx, GlobalContext* globalCtx);
|
||||
void EnTorch2_Update(Actor* thisx, GlobalContext* globalCtx);
|
||||
void EnTorch2_Draw(Actor* thisx, GlobalContext* globalCtx);
|
||||
|
||||
extern FlexSkeletonHeader D_06004764;
|
||||
|
||||
const ActorInit En_Torch2_InitVars = {
|
||||
ACTOR_EN_TORCH2,
|
||||
ACTORCAT_BOSS,
|
||||
@@ -132,7 +131,7 @@ void EnTorch2_Init(Actor* thisx, GlobalContext* globalCtx2) {
|
||||
this->currentShield = PLAYER_SHIELD_HYLIAN;
|
||||
this->heldItemActionParam = this->heldItemId = PLAYER_AP_SWORD_MASTER;
|
||||
Player_SetModelGroup(this, 2);
|
||||
globalCtx->playerInit(this, globalCtx, &D_06004764);
|
||||
globalCtx->playerInit(this, globalCtx, &gDarkLinkSkel);
|
||||
this->actor.naviEnemyId = 0x26;
|
||||
this->cylinder.base.acFlags = AC_ON | AC_TYPE_PLAYER;
|
||||
this->swordQuads[0].base.atFlags = this->swordQuads[1].base.atFlags = AT_ON | AT_TYPE_ENEMY;
|
||||
|
||||
@@ -10,14 +10,31 @@
|
||||
|
||||
#define THIS ((EnTrap*)thisx)
|
||||
|
||||
#define BEGIN_MOVE_OUT 65535.0f
|
||||
|
||||
#define DIR_FWD 0
|
||||
#define DIR_LEFT 0x4000
|
||||
#define DIR_BACK -0x8000
|
||||
#define DIR_RIGHT -0x4000
|
||||
|
||||
// Linear motion
|
||||
#define vLinearVel upperParams
|
||||
#define vContinue genericVar2
|
||||
|
||||
// Circular motion
|
||||
#define vAngularVel upperParams
|
||||
#define vAngularPos genericVar1
|
||||
#define vRadius genericVar2
|
||||
|
||||
// Four-way motion
|
||||
#define vClosestDirection genericVar1 // relative to spike trap's facing angle if moving out, absolute if moving in
|
||||
#define vMovementMetric genericVar2
|
||||
|
||||
void EnTrap_Init(Actor* thisx, GlobalContext* globalCtx);
|
||||
void EnTrap_Destroy(Actor* thisx, GlobalContext* globalCtx);
|
||||
void EnTrap_Update(Actor* thisx, GlobalContext* globalCtx);
|
||||
void EnTrap_Draw(Actor* thisx, GlobalContext* globalCtx);
|
||||
|
||||
extern UNK_TYPE D_06001400;
|
||||
|
||||
/*
|
||||
const ActorInit En_Trap_InitVars = {
|
||||
ACTOR_EN_TRAP,
|
||||
ACTORCAT_BG,
|
||||
@@ -30,24 +47,349 @@ const ActorInit En_Trap_InitVars = {
|
||||
(ActorFunc)EnTrap_Draw,
|
||||
};
|
||||
|
||||
static ColliderCylinderInit D_80B25830 = {
|
||||
{ COLTYPE_HIT0, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_NO_PUSH | OC1_TYPE_1 | OC1_TYPE_2, OC2_TYPE_1,
|
||||
COLSHAPE_CYLINDER },
|
||||
static ColliderCylinderInit sCylinderInit = {
|
||||
{
|
||||
ELEMTYPE_UNK0,
|
||||
{ 0x00000000, 0x00, 0x00 },
|
||||
{ 0x00001000, 0x00, 0x00 },
|
||||
TOUCH_NONE,
|
||||
BUMP_ON,
|
||||
OCELEM_ON,
|
||||
COLTYPE_HIT0,
|
||||
AT_NONE,
|
||||
AC_ON | AC_TYPE_PLAYER,
|
||||
OC1_ON | OC1_NO_PUSH | OC1_TYPE_1 | OC1_TYPE_2,
|
||||
OC2_TYPE_1,
|
||||
COLSHAPE_CYLINDER,
|
||||
},
|
||||
{ ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x00001000, 0x00, 0x00 }, TOUCH_NONE, BUMP_ON, OCELEM_ON },
|
||||
{ 30, 20, 0, { 0, 0, 0 } },
|
||||
};
|
||||
*/
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Trap/EnTrap_Init.s")
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Trap/EnTrap_Destroy.s")
|
||||
extern Gfx D_06001400[];
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Trap/EnTrap_Update.s")
|
||||
void EnTrap_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
f32 trapDist;
|
||||
f32 trapSpeed;
|
||||
s16 zSpeed;
|
||||
s16 xSpeed;
|
||||
EnTrap* this = THIS;
|
||||
ColliderCylinder* unused = &this->collider; // required to match
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Trap/EnTrap_Draw.s")
|
||||
this->upperParams = (thisx->params >> 8) & 0xFF;
|
||||
thisx->params &= 0xFF;
|
||||
Actor_SetScale(thisx, 0.1f);
|
||||
thisx->gravity = -2.0f;
|
||||
if (thisx->params & SPIKETRAP_MODE_LINEAR) {
|
||||
thisx->speedXZ = this->moveSpeedForwardBack.z = this->upperParams & 0xF;
|
||||
Audio_PlayActorSound2(thisx, NA_SE_EV_SPINE_TRAP_MOVE);
|
||||
} else if (thisx->params & SPIKETRAP_MODE_CIRCULAR) {
|
||||
this->vRadius = (this->upperParams & 0xF) * 40.0f;
|
||||
this->vAngularVel = ((this->upperParams & 0xF0) + 0x10) << 5;
|
||||
thisx->world.pos.x = thisx->home.pos.x + (Math_SinS(0) * this->vRadius);
|
||||
thisx->world.pos.z = thisx->home.pos.z + (Math_CosS(0) * this->vRadius);
|
||||
} else { // Four-way motion
|
||||
if (this->upperParams != 0) {
|
||||
trapDist = (this->upperParams >> 4) * 40;
|
||||
trapSpeed = (this->upperParams & 0xF);
|
||||
} else {
|
||||
trapDist = 200.0f;
|
||||
trapSpeed = 10.0f;
|
||||
thisx->params = 0xF;
|
||||
}
|
||||
Actor_UpdateBgCheckInfo(globalCtx, thisx, 10.0f, 20.0f, 20.0f, 0x1D);
|
||||
thisx->home.pos = thisx->world.pos;
|
||||
this->targetPosLeft.x = thisx->world.pos.x + (trapDist * Math_CosS(thisx->world.rot.y));
|
||||
this->targetPosLeft.z = thisx->world.pos.z - (trapDist * Math_SinS(thisx->world.rot.y));
|
||||
this->targetPosRight.x = thisx->world.pos.x + (trapDist * Math_CosS(thisx->world.rot.y + 0x8000));
|
||||
this->targetPosRight.z = thisx->world.pos.z - (trapDist * Math_SinS(thisx->world.rot.y + 0x8000));
|
||||
this->targetPosFwd.x = thisx->world.pos.x + (trapDist * Math_SinS(thisx->world.rot.y));
|
||||
this->targetPosFwd.z = thisx->world.pos.z + (trapDist * Math_CosS(thisx->world.rot.y));
|
||||
this->targetPosBack.x = thisx->world.pos.x + (trapDist * Math_SinS(thisx->world.rot.y + 0x8000));
|
||||
this->targetPosBack.z = thisx->world.pos.z + (trapDist * Math_CosS(thisx->world.rot.y + 0x8000));
|
||||
|
||||
zSpeed = trapSpeed * Math_CosS(thisx->world.rot.y);
|
||||
xSpeed = trapSpeed * Math_SinS(thisx->world.rot.y);
|
||||
zSpeed = ABS(zSpeed);
|
||||
xSpeed = ABS(xSpeed);
|
||||
this->moveSpeedLeftRight.x = this->moveSpeedForwardBack.z = zSpeed;
|
||||
this->moveSpeedLeftRight.z = this->moveSpeedForwardBack.x = xSpeed;
|
||||
}
|
||||
thisx->focus.pos = thisx->world.pos;
|
||||
Collider_InitCylinder(globalCtx, &this->collider);
|
||||
Collider_SetCylinder(globalCtx, &this->collider, thisx, &sCylinderInit);
|
||||
ActorShape_Init(&thisx->shape, 0.0f, &ActorShadow_DrawCircle, 0.0f);
|
||||
thisx->targetMode = 3;
|
||||
thisx->colChkInfo.mass = 0xFF;
|
||||
}
|
||||
|
||||
void EnTrap_Destroy(Actor* thisx, GlobalContext* globalCtx) {
|
||||
EnTrap* this = THIS;
|
||||
Collider_DestroyCylinder(globalCtx, &this->collider);
|
||||
}
|
||||
|
||||
void EnTrap_Update(Actor* thisx, GlobalContext* globalCtx) {
|
||||
EnTrap* this = THIS;
|
||||
Vec3f posTemp;
|
||||
s16 angleToKnockPlayer;
|
||||
s16 angleToCollidedActor;
|
||||
s16 touchingActor;
|
||||
s16 blockedOnReturn;
|
||||
s32 pad;
|
||||
s16 angleToWall;
|
||||
Vec3f icePos;
|
||||
Vec3f posAhead;
|
||||
Vec3f colPoint; // unused return value from function
|
||||
CollisionPoly* colPoly; // unused return value from function
|
||||
s32 bgId; // unused return value from function
|
||||
f32 temp_cond;
|
||||
|
||||
touchingActor = false;
|
||||
blockedOnReturn = false;
|
||||
angleToWall = thisx->wallYaw - thisx->world.rot.y;
|
||||
if (this->collider.base.ocFlags1 & OC1_HIT) {
|
||||
this->collider.base.ocFlags1 &= ~OC1_HIT;
|
||||
angleToCollidedActor =
|
||||
thisx->world.rot.y + Math_Vec3f_Yaw(&this->collider.base.oc->world.pos, &thisx->world.pos);
|
||||
touchingActor = true;
|
||||
}
|
||||
// Freeze the trap if hit by ice arrows:
|
||||
if ((this->collider.base.acFlags & AC_HIT) != 0) {
|
||||
icePos = thisx->world.pos;
|
||||
this->collider.base.acFlags &= ~AC_HIT;
|
||||
func_8003426C(thisx, 0, 250, 0, 250);
|
||||
icePos.y += 10.0f;
|
||||
icePos.z += 10.0f;
|
||||
EffectSsEnIce_SpawnFlyingVec3f(globalCtx, thisx, &icePos, 150, 150, 150, 250, 235, 245, 255, 1.8f);
|
||||
icePos.x += 10.0f;
|
||||
icePos.z -= 20.0f;
|
||||
EffectSsEnIce_SpawnFlyingVec3f(globalCtx, thisx, &icePos, 150, 150, 150, 250, 235, 245, 255, 1.8f);
|
||||
icePos.x -= 20.0f;
|
||||
EffectSsEnIce_SpawnFlyingVec3f(globalCtx, thisx, &icePos, 150, 150, 150, 250, 235, 245, 255, 1.8f);
|
||||
}
|
||||
// If not frozen:
|
||||
if (thisx->colorFilterTimer == 0) {
|
||||
DECR(this->playerDmgTimer);
|
||||
// Handles damaging player:
|
||||
//! @bug there is no yDistToPlayer check for player being below. Therefore hitbox extends down infinitely
|
||||
if ((thisx->xzDistToPlayer <= 40.0f) && (this->playerDmgTimer == 0) && (thisx->yDistToPlayer <= 20.0f)) {
|
||||
if (!(thisx->params & (SPIKETRAP_MODE_LINEAR | SPIKETRAP_MODE_CIRCULAR))) { // if in 4-way mode:
|
||||
if ((s16)(this->vClosestDirection - thisx->yawTowardsPlayer) >= 0) {
|
||||
angleToKnockPlayer = this->vClosestDirection - 0x4000;
|
||||
} else {
|
||||
angleToKnockPlayer = this->vClosestDirection + 0x4000;
|
||||
}
|
||||
} else {
|
||||
angleToKnockPlayer = thisx->yawTowardsPlayer;
|
||||
}
|
||||
globalCtx->damagePlayer(globalCtx, -4);
|
||||
func_8002F7A0(globalCtx, thisx, 6.0f, angleToKnockPlayer, 6.0f);
|
||||
this->playerDmgTimer = 15;
|
||||
}
|
||||
if (thisx->params & SPIKETRAP_MODE_LINEAR) {
|
||||
this->vContinue = 1.0f;
|
||||
// If physically touching a wall and wall faces towards spike trap
|
||||
if ((thisx->bgCheckFlags & 8) && (ABS(angleToWall) >= 0x6000)) {
|
||||
this->vContinue = 0.0f;
|
||||
}
|
||||
// If there is a collision poly between current position and a position 30 units ahead of spike trap
|
||||
if (this->vContinue != 0.0f) {
|
||||
posAhead.x = (Math_SinS(thisx->world.rot.y) * 30.0f) + thisx->world.pos.x;
|
||||
posAhead.z = (Math_CosS(thisx->world.rot.y) * 30.0f) + thisx->world.pos.z;
|
||||
posAhead.y = thisx->world.pos.y;
|
||||
if (BgCheck_EntityLineTest1(&globalCtx->colCtx, &thisx->world.pos, &posAhead, &colPoint, &colPoly, 1, 1,
|
||||
0, 1, &bgId) == true) {
|
||||
this->vContinue = 0.0f;
|
||||
}
|
||||
}
|
||||
// If spike trap is touching an actor which is in the path of the spike trap
|
||||
if (touchingActor && (this->vContinue != 0.0f)) {
|
||||
angleToCollidedActor =
|
||||
Math_Vec3f_Yaw(&thisx->world.pos, &this->collider.base.oc->world.pos) - thisx->world.rot.y;
|
||||
if (ABS(angleToCollidedActor) < 0x1000) {
|
||||
this->vContinue = 0.0f;
|
||||
}
|
||||
}
|
||||
// If any of the above three conditions are met, turn around
|
||||
if (this->vContinue == 0.0f) {
|
||||
thisx->world.rot.y += 0x8000;
|
||||
Audio_PlayActorSound2(thisx, NA_SE_EV_SPINE_TRAP_MOVE);
|
||||
}
|
||||
} else if (thisx->params & SPIKETRAP_MODE_CIRCULAR) {
|
||||
temp_cond = Math_SinS(this->vAngularPos);
|
||||
this->vAngularPos += this->vAngularVel;
|
||||
// Every full circle make a sound:
|
||||
if ((temp_cond < 0.0f) && (Math_SinS(this->vAngularPos) >= 0.0f)) {
|
||||
Audio_PlayActorSound2(thisx, NA_SE_EV_ROUND_TRAP_MOVE);
|
||||
}
|
||||
thisx->world.pos.x = (this->vRadius * Math_SinS(this->vAngularPos)) + thisx->home.pos.x;
|
||||
thisx->world.pos.z = (this->vRadius * Math_CosS(this->vAngularPos)) + thisx->home.pos.z;
|
||||
thisx->world.pos.y = thisx->floorHeight;
|
||||
thisx->prevPos = thisx->world.pos;
|
||||
} else { // 4 way movement
|
||||
// if moving outwards:
|
||||
if (this->vMovementMetric != 0.0f) {
|
||||
switch (this->vClosestDirection) { // movement direction relative to spike trap
|
||||
case DIR_FWD:
|
||||
if (!(thisx->params & SPIKETRAP_FOURWAY_FWD_ALLOWED)) {
|
||||
this->vMovementMetric = 0.0f;
|
||||
} else if ((thisx->bgCheckFlags & 8) && (ABS(angleToWall) > 0x6000)) {
|
||||
this->vMovementMetric = 0.0f;
|
||||
}
|
||||
if (touchingActor && (this->vMovementMetric != 0.0f) && (ABS(angleToCollidedActor) > 0x6000)) {
|
||||
this->vMovementMetric = 0.0f;
|
||||
}
|
||||
if (this->vMovementMetric != 0.0f) {
|
||||
if (this->vMovementMetric == BEGIN_MOVE_OUT) {
|
||||
Audio_PlayActorSound2(thisx, NA_SE_EV_SPINE_TRAP_MOVE);
|
||||
}
|
||||
this->vMovementMetric = Math_SmoothStepToF(&thisx->world.pos.z, this->targetPosFwd.z, 1.0f,
|
||||
this->moveSpeedForwardBack.z, 0.0f);
|
||||
this->vMovementMetric += Math_SmoothStepToF(&thisx->world.pos.x, this->targetPosFwd.x, 1.0f,
|
||||
this->moveSpeedForwardBack.x, 0.0f);
|
||||
}
|
||||
break;
|
||||
case DIR_LEFT:
|
||||
if (!(thisx->params & SPIKETRAP_FOURWAY_LEFT_ALLOWED)) {
|
||||
this->vMovementMetric = 0.0f;
|
||||
} else if ((thisx->bgCheckFlags & 8) && (angleToWall < -0x2000) && (angleToWall > -0x6000)) {
|
||||
this->vMovementMetric = 0.0f;
|
||||
break;
|
||||
}
|
||||
if (touchingActor && (this->vMovementMetric != 0.0f) && (angleToCollidedActor <= -0x2000) &&
|
||||
(angleToCollidedActor > -0x6000)) {
|
||||
this->vMovementMetric = 0.0f;
|
||||
break;
|
||||
}
|
||||
if (this->vMovementMetric != 0.0f) {
|
||||
if (this->vMovementMetric == BEGIN_MOVE_OUT) {
|
||||
Audio_PlayActorSound2(thisx, NA_SE_EV_SPINE_TRAP_MOVE);
|
||||
}
|
||||
this->vMovementMetric = Math_SmoothStepToF(&thisx->world.pos.x, this->targetPosLeft.x, 1.0f,
|
||||
this->moveSpeedLeftRight.x, 0.0f);
|
||||
this->vMovementMetric += Math_SmoothStepToF(&thisx->world.pos.z, this->targetPosLeft.z,
|
||||
1.0f, this->moveSpeedLeftRight.z, 0.0f);
|
||||
}
|
||||
break;
|
||||
case DIR_BACK:
|
||||
if (!(thisx->params & SPIKETRAP_FOURWAY_BACK_ALLOWED)) {
|
||||
this->vMovementMetric = 0.0f;
|
||||
} else if ((thisx->bgCheckFlags & 8) && (ABS(angleToWall) < 0x2000)) {
|
||||
this->vMovementMetric = 0.0f;
|
||||
break;
|
||||
}
|
||||
if (touchingActor && (this->vMovementMetric != 0.0f) && (ABS(angleToCollidedActor) < 0x2000)) {
|
||||
this->vMovementMetric = 0.0f;
|
||||
break;
|
||||
}
|
||||
if (this->vMovementMetric != 0.0f) {
|
||||
if (this->vMovementMetric == BEGIN_MOVE_OUT) {
|
||||
Audio_PlayActorSound2(thisx, NA_SE_EV_SPINE_TRAP_MOVE);
|
||||
}
|
||||
this->vMovementMetric = Math_SmoothStepToF(&thisx->world.pos.z, this->targetPosBack.z, 1.0f,
|
||||
this->moveSpeedForwardBack.z, 0.0f);
|
||||
this->vMovementMetric += Math_SmoothStepToF(&thisx->world.pos.x, this->targetPosBack.x,
|
||||
1.0f, this->moveSpeedForwardBack.x, 0.0f);
|
||||
}
|
||||
break;
|
||||
case DIR_RIGHT:
|
||||
if (!(thisx->params & SPIKETRAP_FOURWAY_RIGHT_ALLOWED)) {
|
||||
this->vMovementMetric = 0.0f;
|
||||
} else if ((thisx->bgCheckFlags & 8) && (angleToWall > 0x2000) && (angleToWall < 0x6000)) {
|
||||
this->vMovementMetric = 0.0f;
|
||||
break;
|
||||
}
|
||||
if (touchingActor && (this->vMovementMetric != 0.0f) && (angleToCollidedActor > 0x2000) &&
|
||||
(angleToCollidedActor < 0x6000)) {
|
||||
this->vMovementMetric = 0.0f;
|
||||
break;
|
||||
}
|
||||
if (this->vMovementMetric != 0.0f) {
|
||||
if (this->vMovementMetric == BEGIN_MOVE_OUT) {
|
||||
Audio_PlayActorSound2(thisx, NA_SE_EV_SPINE_TRAP_MOVE);
|
||||
}
|
||||
this->vMovementMetric = Math_SmoothStepToF(&thisx->world.pos.x, this->targetPosRight.x,
|
||||
1.0f, this->moveSpeedLeftRight.x, 0.0f);
|
||||
this->vMovementMetric += Math_SmoothStepToF(&thisx->world.pos.z, this->targetPosRight.z,
|
||||
1.0f, this->moveSpeedLeftRight.z, 0.0f);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!func_800339B8(thisx, globalCtx, 50.0f, this->vClosestDirection)) {
|
||||
this->vMovementMetric = 0.0f;
|
||||
}
|
||||
// if in initial position:
|
||||
} else if ((thisx->world.pos.x == thisx->home.pos.x) && (thisx->world.pos.z == thisx->home.pos.z)) {
|
||||
// of the available 4-way directions, get the one which is closest to the direction of player:
|
||||
this->vClosestDirection = ((thisx->yawTowardsPlayer - thisx->world.rot.y) + 0x2000) & 0xC000;
|
||||
this->vMovementMetric = 0.0f;
|
||||
if (thisx->xzDistToPlayer < 200.0f) {
|
||||
this->vMovementMetric = BEGIN_MOVE_OUT;
|
||||
}
|
||||
// If returning to origin:
|
||||
} else {
|
||||
// Of the four real world compass directions, get the one which is closest to the movement direction of
|
||||
// the returning spike. Note that this is different from the previous usages of vClosestDirection
|
||||
this->vClosestDirection = (Math_Vec3f_Yaw(&thisx->world.pos, &thisx->home.pos) + 0x2000) & 0xC000;
|
||||
switch (this->vClosestDirection) {
|
||||
case 0: // movement is closest to +z direction
|
||||
if (thisx->bgCheckFlags & 8) {
|
||||
if (ABS(thisx->wallYaw) > 0x6000) {
|
||||
blockedOnReturn = true;
|
||||
}
|
||||
} else if (touchingActor && (ABS(angleToCollidedActor) > 0x6000)) {
|
||||
blockedOnReturn = true;
|
||||
}
|
||||
break;
|
||||
case 0x4000: // movement is closest to +x direction
|
||||
if (thisx->bgCheckFlags & 8) {
|
||||
if ((thisx->wallYaw < -0x2000) && (thisx->wallYaw > -0x6000)) {
|
||||
blockedOnReturn = true;
|
||||
}
|
||||
} else if (touchingActor && (angleToCollidedActor < -0x2000) &&
|
||||
(angleToCollidedActor > -0x6000)) {
|
||||
blockedOnReturn = true;
|
||||
}
|
||||
break;
|
||||
case -0x8000: // movement is closest to -z direction
|
||||
if (thisx->bgCheckFlags & 8) {
|
||||
if (ABS(thisx->wallYaw) < 0x2000) {
|
||||
blockedOnReturn = true;
|
||||
}
|
||||
} else if (touchingActor && (ABS(angleToCollidedActor) < 0x2000)) {
|
||||
blockedOnReturn = true;
|
||||
}
|
||||
break;
|
||||
case -0x4000: // movement is closest to -x direction
|
||||
if (thisx->bgCheckFlags & 8) {
|
||||
if ((thisx->wallYaw > 0x2000) && (thisx->wallYaw < 0x6000)) {
|
||||
blockedOnReturn = true;
|
||||
}
|
||||
} else if (touchingActor && (angleToCollidedActor > 0x2000) &&
|
||||
(angleToCollidedActor < 0x6000)) {
|
||||
blockedOnReturn = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!blockedOnReturn) {
|
||||
Math_SmoothStepToF(&thisx->world.pos.x, thisx->home.pos.x, 1.0f, 3.0f, 0.0f);
|
||||
Math_SmoothStepToF(&thisx->world.pos.z, thisx->home.pos.z, 1.0f, 3.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
Actor_MoveForward(thisx); // Only used by straight line logic
|
||||
// Adjust position using bgcheck, but do not adjust x, z position if in straight line mode:
|
||||
if (thisx->params & SPIKETRAP_MODE_LINEAR) {
|
||||
posTemp = thisx->world.pos;
|
||||
}
|
||||
Actor_UpdateBgCheckInfo(globalCtx, thisx, 25.0f, 20.0f, 20.0f, 0x1D);
|
||||
if (thisx->params & SPIKETRAP_MODE_LINEAR) {
|
||||
thisx->world.pos.x = posTemp.x;
|
||||
thisx->world.pos.z = posTemp.z;
|
||||
}
|
||||
}
|
||||
Collider_UpdateCylinder(thisx, &this->collider);
|
||||
CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
|
||||
if (thisx->colorFilterTimer == 0) {
|
||||
CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
|
||||
}
|
||||
}
|
||||
|
||||
void EnTrap_Draw(Actor* thisx, GlobalContext* globalCtx) {
|
||||
func_8002EBCC(thisx, globalCtx, 1);
|
||||
Gfx_DrawDListOpa(globalCtx, D_06001400);
|
||||
}
|
||||
|
||||
@@ -4,11 +4,32 @@
|
||||
#include "ultra64.h"
|
||||
#include "global.h"
|
||||
|
||||
// Different movement modes (set in params):
|
||||
#define SPIKETRAP_MODE_LINEAR 0x10
|
||||
#define SPIKETRAP_MODE_CIRCULAR 0x20
|
||||
#define SPIKETRAP_MODE_FOUR_WAY 0x30
|
||||
|
||||
// When four-way mode is set, these flags decide on which directions are allowed:
|
||||
#define SPIKETRAP_FOURWAY_FWD_ALLOWED (1 << 0)
|
||||
#define SPIKETRAP_FOURWAY_BACK_ALLOWED (1 << 1)
|
||||
#define SPIKETRAP_FOURWAY_LEFT_ALLOWED (1 << 2)
|
||||
#define SPIKETRAP_FOURWAY_RIGHT_ALLOWED (1 << 3)
|
||||
|
||||
struct EnTrap;
|
||||
|
||||
typedef struct EnTrap {
|
||||
/* 0x0000 */ Actor actor;
|
||||
/* 0x014C */ char unk_14C[0xA0];
|
||||
/* 0x014C */ s32 playerDmgTimer;
|
||||
/* 0x0150 */ s16 upperParams;
|
||||
/* 0x0152 */ s16 genericVar1;
|
||||
/* 0x0154 */ f32 genericVar2;
|
||||
/* 0x0158 */ Vec3f targetPosLeft;
|
||||
/* 0x0164 */ Vec3f targetPosRight;
|
||||
/* 0x0170 */ Vec3f targetPosFwd;
|
||||
/* 0x017C */ Vec3f targetPosBack;
|
||||
/* 0x0188 */ Vec3f moveSpeedLeftRight;
|
||||
/* 0x0194 */ Vec3f moveSpeedForwardBack;
|
||||
/* 0x01A0 */ ColliderCylinder collider;
|
||||
} EnTrap; // size = 0x01EC
|
||||
|
||||
extern const ActorInit En_Trap_InitVars;
|
||||
|
||||
Reference in New Issue
Block a user