Merge remote-tracking branch 'upstream/master' into ovl_Eff_Dust

This commit is contained in:
angie
2021-01-30 16:55:51 -03:00
46 changed files with 1020 additions and 2588 deletions
@@ -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);
+78 -83
View File
@@ -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;
+359 -17
View File
@@ -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);
}
+22 -1
View File
@@ -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;