summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEllipticEllipsis <elliptic.ellipsis@gmail.com>2022-07-19 17:16:36 +0100
committerGitHub <noreply@github.com>2022-07-19 12:16:36 -0400
commit69e514b37e3459310ab2931d47963693bd8f58f0 (patch)
tree3d250aa9698df9369bca355fbacab301987b2e9b /src
parentbd94105568e111f801dcc70717d51042d2cf21c7 (diff)
EnBat OK and documented (#924)
* OK, start documentation * Name some more stuff * Name rest of functions and bss var, tidy up floats * Document object and paramflags * Cleanup bat * Cleanup crow * Cleanup firefly * Couple of minor things in arrow * Review 1 * PLAYER_STATE * Remove unnecessary f32 casts * Review * Review
Diffstat (limited to 'src')
-rw-r--r--src/overlays/actors/ovl_En_Arrow/z_en_arrow.c8
-rw-r--r--src/overlays/actors/ovl_En_Bat/z_en_bat.c570
-rw-r--r--src/overlays/actors/ovl_En_Bat/z_en_bat.h29
-rw-r--r--src/overlays/actors/ovl_En_Crow/z_en_crow.c253
-rw-r--r--src/overlays/actors/ovl_En_Crow/z_en_crow.h17
-rw-r--r--src/overlays/actors/ovl_En_Firefly/z_en_firefly.c137
-rw-r--r--src/overlays/actors/ovl_En_Firefly/z_en_firefly.h4
7 files changed, 750 insertions, 268 deletions
diff --git a/src/overlays/actors/ovl_En_Arrow/z_en_arrow.c b/src/overlays/actors/ovl_En_Arrow/z_en_arrow.c
index 1f0cb9a2b..ab68d8769 100644
--- a/src/overlays/actors/ovl_En_Arrow/z_en_arrow.c
+++ b/src/overlays/actors/ovl_En_Arrow/z_en_arrow.c
@@ -135,7 +135,7 @@ void EnArrow_Destroy(Actor* thisx, PlayState* play) {
Collider_DestroyQuad(play, &this->collider);
if ((this->unk_264 != NULL) && (this->unk_264->update != NULL)) {
- this->unk_264->flags &= ~0x8000;
+ this->unk_264->flags &= ~ACTOR_FLAG_8000;
}
if ((this->actor.params >= ENARROW_3) && (this->actor.params < ENARROW_6) && (this->actor.child == NULL)) {
@@ -496,14 +496,14 @@ void func_8088ACE0(EnArrow* this, PlayState* play) {
this->unk_264->world.pos.z = ((sp54.z <= sp9C.z) ? 1.0f : -1.0f) + sp9C.z;
Math_Vec3f_Diff(&this->unk_264->world.pos, &this->actor.world.pos, &this->unk_268);
- this->unk_264->flags &= ~0x8000;
+ this->unk_264->flags &= ~ACTOR_FLAG_8000;
this->unk_264 = NULL;
} else {
Math_Vec3f_Sum(&this->actor.world.pos, &this->unk_268, &this->unk_264->world.pos);
}
if ((this->unk_262 != 0) && (this->unk_264 != NULL)) {
- this->unk_264->flags &= ~0x8000;
+ this->unk_264->flags &= ~ACTOR_FLAG_8000;
this->unk_264 = NULL;
}
} else {
@@ -588,7 +588,7 @@ void func_8088B88C(PlayState* play, EnArrow* this, EnArrowUnkStruct* arg2) {
Matrix_MultVec3f(&sp4C[1], &sp34);
if (this->actor.params < ENARROW_8) {
sp30 = this->actor.params < ENARROW_6;
- if (this->unk_264 == 0) {
+ if (this->unk_264 == NULL) {
sp30 &= func_80126440(play, &this->collider, &this->unk_244, &sp40, &sp34);
} else if (sp30 && (sp40.x == this->unk_244.tip.x) && (sp40.y == this->unk_244.tip.y) &&
(sp40.z == this->unk_244.tip.z) && (sp34.x == this->unk_244.base.x) &&
diff --git a/src/overlays/actors/ovl_En_Bat/z_en_bat.c b/src/overlays/actors/ovl_En_Bat/z_en_bat.c
index c85cd3410..e81608721 100644
--- a/src/overlays/actors/ovl_En_Bat/z_en_bat.c
+++ b/src/overlays/actors/ovl_En_Bat/z_en_bat.c
@@ -5,22 +5,29 @@
*/
#include "z_en_bat.h"
+#include "objects/object_bat/object_bat.h"
#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_1000 | ACTOR_FLAG_4000)
#define THIS ((EnBat*)thisx)
+#define BAD_BAT_FLAP_FRAME 5
+
void EnBat_Init(Actor* thisx, PlayState* play);
void EnBat_Destroy(Actor* thisx, PlayState* play);
void EnBat_Update(Actor* thisx, PlayState* play);
void EnBat_Draw(Actor* thisx, PlayState* play);
-void func_80A438D4(EnBat* this, PlayState* play);
-void func_80A4392C(EnBat* this, PlayState* play);
-void func_80A43CE8(EnBat* this, PlayState* play);
-void func_80A44114(EnBat* this, PlayState* play);
+s32 EnBat_IsGraveyardOnSecondDay(PlayState* play);
+void EnBat_SetupPerch(EnBat* this);
+void EnBat_Perch(EnBat* this, PlayState* play);
+void EnBat_SetupFlyIdle(EnBat* this);
+void EnBat_FlyIdle(EnBat* this, PlayState* play);
+void EnBat_SetupDiveAttack(EnBat* this);
+void EnBat_DiveAttack(EnBat* this, PlayState* play);
+void EnBat_Die(EnBat* this, PlayState* play);
+void EnBat_Stunned(EnBat* this, PlayState* play);
-#if 0
const ActorInit En_Bat_InitVars = {
ACTOR_EN_BAT,
ACTORCAT_ENEMY,
@@ -33,99 +40,522 @@ const ActorInit En_Bat_InitVars = {
(ActorFunc)EnBat_Draw,
};
-// static ColliderSphereInit sSphereInit = {
-static ColliderSphereInit D_80A44A00 = {
- { COLTYPE_HIT3, AT_NONE | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_SPHERE, },
- { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x04 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_HARD, BUMP_ON, OCELEM_ON, },
+static ColliderSphereInit sSphereInit = {
+ {
+ COLTYPE_HIT3,
+ AT_NONE | AT_TYPE_ENEMY,
+ AC_ON | AC_TYPE_PLAYER,
+ OC1_ON | OC1_TYPE_ALL,
+ OC2_TYPE_1,
+ COLSHAPE_SPHERE,
+ },
+ {
+ ELEMTYPE_UNK0,
+ { 0xF7CFFFFF, 0x00, 0x04 },
+ { 0xF7CFFFFF, 0x00, 0x00 },
+ TOUCH_ON | TOUCH_SFX_HARD,
+ BUMP_ON,
+ OCELEM_ON,
+ },
{ 1, { { 0, 0, 0 }, 15 }, 100 },
};
-// static DamageTable sDamageTable = {
-static DamageTable D_80A44A2C = {
- /* Deku Nut */ DMG_ENTRY(0, 0x1),
- /* Deku Stick */ DMG_ENTRY(1, 0x0),
- /* Horse trample */ DMG_ENTRY(1, 0x0),
- /* Explosives */ DMG_ENTRY(1, 0x0),
- /* Zora boomerang */ DMG_ENTRY(1, 0x0),
- /* Normal arrow */ DMG_ENTRY(1, 0x0),
- /* UNK_DMG_0x06 */ DMG_ENTRY(0, 0x0),
- /* Hookshot */ DMG_ENTRY(1, 0x0),
- /* Goron punch */ DMG_ENTRY(1, 0x0),
- /* Sword */ DMG_ENTRY(1, 0x0),
- /* Goron pound */ DMG_ENTRY(1, 0x0),
- /* Fire arrow */ DMG_ENTRY(2, 0x2),
- /* Ice arrow */ DMG_ENTRY(2, 0x3),
- /* Light arrow */ DMG_ENTRY(2, 0x4),
- /* Goron spikes */ DMG_ENTRY(1, 0x0),
- /* Deku spin */ DMG_ENTRY(1, 0x0),
- /* Deku bubble */ DMG_ENTRY(1, 0x0),
- /* Deku launch */ DMG_ENTRY(2, 0x0),
- /* UNK_DMG_0x12 */ DMG_ENTRY(0, 0x1),
- /* Zora barrier */ DMG_ENTRY(0, 0x5),
- /* Normal shield */ DMG_ENTRY(0, 0x0),
- /* Light ray */ DMG_ENTRY(0, 0x0),
- /* Thrown object */ DMG_ENTRY(1, 0x0),
- /* Zora punch */ DMG_ENTRY(1, 0x0),
- /* Spin attack */ DMG_ENTRY(1, 0x0),
- /* Sword beam */ DMG_ENTRY(0, 0x0),
- /* Normal Roll */ DMG_ENTRY(0, 0x0),
- /* UNK_DMG_0x1B */ DMG_ENTRY(0, 0x0),
- /* UNK_DMG_0x1C */ DMG_ENTRY(0, 0x0),
- /* Unblockable */ DMG_ENTRY(0, 0x0),
- /* UNK_DMG_0x1E */ DMG_ENTRY(0, 0x0),
- /* Powder Keg */ DMG_ENTRY(1, 0x0),
+typedef enum {
+ /* 0 */ BAD_BAT_DMGEFF_NONE,
+ /* 1 */ BAD_BAT_DMGEFF_STUN,
+ /* 2 */ BAD_BAT_DMGEFF_FIRE,
+ /* 3 */ BAD_BAT_DMGEFF_ICE,
+ /* 4 */ BAD_BAT_DMGEFF_LIGHT,
+ /* 5 */ BAD_BAT_DMGEFF_ELECTRIC
+} BatDamageEffect;
+
+static DamageTable sDamageTable = {
+ /* Deku Nut */ DMG_ENTRY(0, BAD_BAT_DMGEFF_STUN),
+ /* Deku Stick */ DMG_ENTRY(1, BAD_BAT_DMGEFF_NONE),
+ /* Horse trample */ DMG_ENTRY(1, BAD_BAT_DMGEFF_NONE),
+ /* Explosives */ DMG_ENTRY(1, BAD_BAT_DMGEFF_NONE),
+ /* Zora boomerang */ DMG_ENTRY(1, BAD_BAT_DMGEFF_NONE),
+ /* Normal arrow */ DMG_ENTRY(1, BAD_BAT_DMGEFF_NONE),
+ /* UNK_DMG_0x06 */ DMG_ENTRY(0, BAD_BAT_DMGEFF_NONE),
+ /* Hookshot */ DMG_ENTRY(1, BAD_BAT_DMGEFF_NONE),
+ /* Goron punch */ DMG_ENTRY(1, BAD_BAT_DMGEFF_NONE),
+ /* Sword */ DMG_ENTRY(1, BAD_BAT_DMGEFF_NONE),
+ /* Goron pound */ DMG_ENTRY(1, BAD_BAT_DMGEFF_NONE),
+ /* Fire arrow */ DMG_ENTRY(2, BAD_BAT_DMGEFF_FIRE),
+ /* Ice arrow */ DMG_ENTRY(2, BAD_BAT_DMGEFF_ICE),
+ /* Light arrow */ DMG_ENTRY(2, BAD_BAT_DMGEFF_LIGHT),
+ /* Goron spikes */ DMG_ENTRY(1, BAD_BAT_DMGEFF_NONE),
+ /* Deku spin */ DMG_ENTRY(1, BAD_BAT_DMGEFF_NONE),
+ /* Deku bubble */ DMG_ENTRY(1, BAD_BAT_DMGEFF_NONE),
+ /* Deku launch */ DMG_ENTRY(2, BAD_BAT_DMGEFF_NONE),
+ /* UNK_DMG_0x12 */ DMG_ENTRY(0, BAD_BAT_DMGEFF_STUN),
+ /* Zora barrier */ DMG_ENTRY(0, BAD_BAT_DMGEFF_ELECTRIC),
+ /* Normal shield */ DMG_ENTRY(0, BAD_BAT_DMGEFF_NONE),
+ /* Light ray */ DMG_ENTRY(0, BAD_BAT_DMGEFF_NONE),
+ /* Thrown object */ DMG_ENTRY(1, BAD_BAT_DMGEFF_NONE),
+ /* Zora punch */ DMG_ENTRY(1, BAD_BAT_DMGEFF_NONE),
+ /* Spin attack */ DMG_ENTRY(1, BAD_BAT_DMGEFF_NONE),
+ /* Sword beam */ DMG_ENTRY(0, BAD_BAT_DMGEFF_NONE),
+ /* Normal Roll */ DMG_ENTRY(0, BAD_BAT_DMGEFF_NONE),
+ /* UNK_DMG_0x1B */ DMG_ENTRY(0, BAD_BAT_DMGEFF_NONE),
+ /* UNK_DMG_0x1C */ DMG_ENTRY(0, BAD_BAT_DMGEFF_NONE),
+ /* Unblockable */ DMG_ENTRY(0, BAD_BAT_DMGEFF_NONE),
+ /* UNK_DMG_0x1E */ DMG_ENTRY(0, BAD_BAT_DMGEFF_NONE),
+ /* Powder Keg */ DMG_ENTRY(1, BAD_BAT_DMGEFF_NONE),
};
-// sColChkInfoInit
-static CollisionCheckInfoInit D_80A44A4C = { 1, 15, 30, 10 };
+static CollisionCheckInfoInit sColChkInfoInit = { 1, 15, 30, 10 };
-// static InitChainEntry sInitChain[] = {
-static InitChainEntry D_80A44A54[] = {
+static InitChainEntry sInitChain[] = {
ICHAIN_S8(hintId, 96, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneForward, 3000, ICHAIN_CONTINUE),
ICHAIN_F32_DIV1000(gravity, -500, ICHAIN_CONTINUE),
ICHAIN_F32(targetArrowOffset, 2000, ICHAIN_STOP),
};
-#endif
+static Gfx* sWingsDLs[] = {
+ gBadBatWingsFrame0DL, gBadBatWingsFrame1DL, gBadBatWingsFrame2DL, gBadBatWingsFrame3DL, gBadBatWingsFrame4DL,
+ gBadBatWingsFrame5DL, gBadBatWingsFrame6DL, gBadBatWingsFrame7DL, gBadBatWingsFrame8DL,
+};
+
+#define BAD_BAT_MAX_NUMBER_ATTACKING 3
+
+s32 sNumberAttacking; //!< Limit number attacking player to at most `BAD_BAT_MAX_NUMBER_ATTACKING`
+s32 sAlreadySpawned; //!< used for those spawned with room -1 in Graveyard to avoid respawn on room change
+
+void EnBat_Init(Actor* thisx, PlayState* play) {
+ EnBat* this = THIS;
+
+ Actor_ProcessInitChain(thisx, sInitChain);
+ Collider_InitAndSetSphere(play, &this->collider, thisx, &sSphereInit);
+ this->collider.dim.worldSphere.radius = sSphereInit.dim.modelSphere.radius;
+ CollisionCheck_SetInfo(&thisx->colChkInfo, &sDamageTable, &sColChkInfoInit);
+ ActorShape_Init(&thisx->shape, 2000.0f, ActorShadow_DrawCircle, 25.0f);
+
+ this->animationFrame = Rand_ZeroOne() * 9.0f;
+
+ this->paramFlags = BAD_BAT_GET_PARAMFLAGS(thisx);
+ this->switchFlag = BAD_BAT_GET_SWITCHFLAG(thisx);
+ thisx->params = BAD_BAT_GET_TYPE(thisx);
+
+ thisx->depthInWater = BGCHECK_Y_MIN;
+ Actor_SetFocus(thisx, 20.0f);
+
+ if (sAlreadySpawned) {
+ Actor_MarkForDeath(thisx);
+ } else if (EnBat_IsGraveyardOnSecondDay(play)) {
+ if (Flags_GetSwitch(play, this->switchFlag)) {
+ Actor_MarkForDeath(thisx);
+ } else {
+ this->actor.room = -1;
+ }
+ }
+
+ if (this->paramFlags & BAD_BAT_PARAMFLAG_PERCH) {
+ thisx->params = 0;
+ EnBat_SetupPerch(this);
+ } else {
+ if (thisx->params == 0x1F) {
+ thisx->params = 0;
+ }
+ EnBat_SetupFlyIdle(this);
+ while (BAD_BAT_GET_NUMBER_TO_SPAWN(thisx) > 1) {
+ Actor_SpawnAsChildAndCutscene(
+ &play->actorCtx, play, ACTOR_EN_BAT, thisx->world.pos.x + randPlusMinusPoint5Scaled(200.0f),
+ thisx->world.pos.y + randPlusMinusPoint5Scaled(100.0f),
+ thisx->world.pos.z + randPlusMinusPoint5Scaled(200.0f), randPlusMinusPoint5Scaled(0x2000),
+ 0xFFFF * Rand_ZeroOne(), 0, BAD_BAT_PARAMS(this->switchFlag, this->paramFlags, 0), -1, thisx->unk20,
+ NULL);
+ BAD_BAT_GET_NUMBER_TO_SPAWN(thisx)--;
+ }
+ }
+}
+
+void EnBat_Destroy(Actor* thisx, PlayState* play) {
+ EnBat* this = THIS;
+
+ Collider_DestroySphere(play, &this->collider);
+}
+
+s32 EnBat_IsGraveyardOnSecondDay(PlayState* play) {
+ if ((CURRENT_DAY == 2) && (play->sceneNum == SCENE_BOTI)) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+void EnBat_StepAnimation(EnBat* this, s32 frameStep) {
+ s32 prevFrame = this->animationFrame;
+
+ this->animationFrame += frameStep;
+ if (this->animationFrame >= ARRAY_COUNT(sWingsDLs)) {
+ this->animationFrame -= ARRAY_COUNT(sWingsDLs);
+ }
+ if ((prevFrame < BAD_BAT_FLAP_FRAME) && (this->animationFrame >= BAD_BAT_FLAP_FRAME)) {
+ Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FFLY_FLY);
+ }
+}
+
+void EnBat_SetupPerch(EnBat* this) {
+ this->collider.base.acFlags |= AC_ON;
+ this->collider.base.atFlags |= AT_ON;
+ this->collider.dim.worldSphere.center.x = this->actor.focus.pos.x;
+ this->collider.dim.worldSphere.center.y = this->actor.focus.pos.y;
+ this->collider.dim.worldSphere.center.z = this->actor.focus.pos.z;
+ this->actor.speedXZ = 0.0f;
+ this->actionFunc = EnBat_Perch;
+}
+
+void EnBat_Perch(EnBat* this, PlayState* play) {
+ EnBat_StepAnimation(this, 1);
+}
+
+void EnBat_SetupFlyIdle(EnBat* this) {
+ this->timer = 100;
+ this->collider.base.acFlags |= AC_ON;
+ this->actor.speedXZ = 3.5f;
+ this->actionFunc = EnBat_FlyIdle;
+}
+
+void EnBat_FlyIdle(EnBat* this, PlayState* play) {
+ s32 finishedRotStep;
+
+ EnBat_StepAnimation(this, 1);
+
+ finishedRotStep = Math_ScaledStepToS(&this->actor.shape.rot.y, this->yawTarget, 0x300);
+
+ if (this->actor.bgCheckFlags & 8) {
+ this->actor.bgCheckFlags &= ~8;
+ this->yawTarget = this->actor.wallYaw;
+ } else if (Math3D_XZDistanceSquared(this->actor.world.pos.x, this->actor.world.pos.z, this->actor.home.pos.x,
+ this->actor.home.pos.z) > SQ(300.0f)) {
+ this->yawTarget = Actor_YawToPoint(&this->actor, &this->actor.home.pos);
+ } else if (finishedRotStep && (Rand_ZeroOne() < 0.015f)) {
+ this->yawTarget =
+ this->actor.shape.rot.y + (((s32)(0x1000 * Rand_ZeroOne()) + 0x1000) * ((Rand_ZeroOne() < 0.5f) ? -1 : 1));
+ }
+
+ finishedRotStep = Math_ScaledStepToS(&this->actor.shape.rot.x, this->pitchTarget, 0x100);
+
+ if ((this->actor.bgCheckFlags & 1) || (this->actor.depthInWater > -40.0f)) {
+ this->pitchTarget = -0x1000;
+ } else if (this->actor.world.pos.y < (this->actor.home.pos.y - 100.0f)) {
+ this->pitchTarget = -((s32)(0x800 * Rand_ZeroOne()) + 0x800);
+ } else if ((this->actor.home.pos.y + 100.0f) < this->actor.world.pos.y) {
+ this->pitchTarget = (s32)(0x800 * Rand_ZeroOne()) + 0x800;
+ } else if ((finishedRotStep) && (Rand_ZeroOne() < 0.015f)) {
+ this->pitchTarget += (s16)(((s32)(0x400 * Rand_ZeroOne()) + 0x400) * ((Rand_ZeroOne() < 0.5f) ? -1 : 1));
+ this->pitchTarget = CLAMP(this->pitchTarget, -0x1000, 0x1000);
+ }
+
+ if (this->timer != 0) {
+ this->timer--;
+ }
+ if ((this->actor.xzDistToPlayer < 300.0f) && (this->timer == 0) && (Player_GetMask(play) != PLAYER_MASK_STONE) &&
+ (sNumberAttacking < BAD_BAT_MAX_NUMBER_ATTACKING) &&
+ (!(this->paramFlags & BAD_BAT_PARAMFLAG_CHECK_HEIGHTREL) || (fabsf(this->actor.playerHeightRel) < 150.0f))) {
+ EnBat_SetupDiveAttack(this);
+ }
+}
+
+void EnBat_SetupDiveAttack(EnBat* this) {
+ this->collider.base.atFlags |= AT_ON;
+ this->timer = 300;
+ this->actor.speedXZ = 4.0f;
+ sNumberAttacking++;
+ this->actionFunc = EnBat_DiveAttack;
+}
+
+void EnBat_DiveAttack(EnBat* this, PlayState* play) {
+ Player* player = GET_PLAYER(play);
+ s32 isFacingPlayer;
+ Vec3f preyPos;
+
+ EnBat_StepAnimation(this, 2);
+ isFacingPlayer = Actor_IsFacingPlayer(&this->actor, 0x2800);
+
+ if (isFacingPlayer) {
+ s16 pitchTarget;
+
+ preyPos.x = player->actor.world.pos.x;
+ preyPos.y = player->actor.world.pos.y + 20.0f;
+ preyPos.z = player->actor.world.pos.z;
+
+ pitchTarget = Actor_PitchToPoint(&this->actor, &preyPos);
+ pitchTarget = CLAMP(pitchTarget, -0x3000, 0x3000);
+ Math_SmoothStepToS(&this->actor.shape.rot.x, pitchTarget, 2, 0x400, 0x40);
+ } else {
+ Math_SmoothStepToS(&this->actor.shape.rot.x, -0x800, 2, 0x100, 0x10);
+ }
+ if (isFacingPlayer || (this->actor.xzDistToPlayer > 80.0f)) {
+ Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 4, 0xC00, 0xC0);
+ }
+
+ this->timer--;
+
+ if ((this->timer == 0) || (this->collider.base.atFlags & AT_HIT) || (Player_GetMask(play) == PLAYER_MASK_STONE) ||
+ (this->actor.bgCheckFlags & 1) || (player->stateFlags1 & PLAYER_STATE1_800000) ||
+ (this->actor.depthInWater > -40.0f)) {
+ if (this->collider.base.atFlags & AT_HIT) {
+ this->collider.base.atFlags &= ~AT_HIT;
+ Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FFLY_ATTACK);
+ }
+ this->collider.base.atFlags &= ~AT_ON;
+ sNumberAttacking--;
+ EnBat_SetupFlyIdle(this);
+ } else if ((this->actor.bgCheckFlags & 8) &&
+ (ABS_ALT(BINANG_SUB(this->actor.wallYaw, this->actor.yawTowardsPlayer)) > 0x6800)) {
+ sNumberAttacking--;
+ this->collider.base.atFlags &= ~AT_ON;
+ this->actor.bgCheckFlags &= ~8;
+ this->yawTarget = this->actor.wallYaw;
+ EnBat_SetupFlyIdle(this);
+ }
+}
+
+void EnBat_SetupDie(EnBat* this, PlayState* play) {
+ this->actor.flags &= ~ACTOR_FLAG_1;
+ Enemy_StartFinishingBlow(play, &this->actor);
+ this->actor.speedXZ *= Math_CosS(this->actor.world.rot.x);
+ this->actor.bgCheckFlags &= ~1;
+ this->actor.velocity.y = 0.0f;
+ Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FFLY_DEAD);
+
+ if (this->actor.colChkInfo.damageEffect == BAD_BAT_DMGEFF_ICE) {
+ this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX;
+ this->drawDmgEffAlpha = 1.0f;
+ this->drawDmgEffFrozenSteamScale = 60.0f * (0.45f / 40.0f);
+ this->drawDmgEffScale = 0.45f;
+ } else if (this->actor.colChkInfo.damageEffect == BAD_BAT_DMGEFF_LIGHT) {
+ this->drawDmgEffType = ACTOR_DRAW_DMGEFF_LIGHT_ORBS;
+ this->drawDmgEffAlpha = 4.0f;
+ this->drawDmgEffScale = 0.45f;
+ Actor_Spawn(&play->actorCtx, play, ACTOR_EN_CLEAR_TAG, this->collider.info.bumper.hitPos.x,
+ this->collider.info.bumper.hitPos.y, this->collider.info.bumper.hitPos.z, 0, 0, 0,
+ CLEAR_TAG_SMALL_LIGHT_RAYS);
+ } else if (this->actor.colChkInfo.damageEffect == BAD_BAT_DMGEFF_FIRE) {
+ this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE;
+ this->drawDmgEffAlpha = 4.0f;
+ this->drawDmgEffScale = 0.45f;
+ }
+
+ Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 40);
+
+ if (this->actor.flags & ACTOR_FLAG_8000) {
+ this->actor.speedXZ = 0.0f;
+ }
+
+ this->collider.base.acFlags &= ~AC_ON;
+ this->actor.flags |= ACTOR_FLAG_10;
+ this->actionFunc = EnBat_Die;
+}
+
+void EnBat_Die(EnBat* this, PlayState* play) {
+ Math_StepToF(&this->actor.speedXZ, 0.0f, 0.5f);
+ this->actor.colorFilterTimer = 40;
+
+ if (!(this->actor.flags & ACTOR_FLAG_8000)) { // Carried by arrow
+ if (this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) {
+ Math_ScaledStepToS(&this->actor.shape.rot.x, 0x4000, 0x200);
+ this->actor.shape.rot.z += 0x1780;
+ }
+
+ if ((this->actor.bgCheckFlags & 1) || (this->actor.floorHeight == BGCHECK_Y_MIN)) {
+ if (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) {
+ Actor_SpawnIceEffects(play, &this->actor, this->bodyPartPoss, ARRAY_COUNT(this->bodyPartPoss), 2, 0.2f,
+ 0.2f);
+ }
+
+ func_800B3030(play, &this->actor.world.pos, &gZeroVec3f, &gZeroVec3f, 100, 0, 0);
+ SoundSource_PlaySfxAtFixedWorldPos(play, &this->actor.world.pos, 11, NA_SE_EN_EXTINCT);
+ Actor_MarkForDeath(&this->actor);
+
+ if (this->actor.room == -1) {
+ Actor* enemy = NULL;
+
+ // Search for other EnBats. If find none, set switch flag.
+ do {
+ enemy = SubS_FindActor(play, enemy, ACTORCAT_ENEMY, ACTOR_EN_BAT);
+ if (enemy != NULL) {
+ if (enemy != &this->actor) {
+ break;
+ }
+ enemy = enemy->next;
+ }
+ } while (enemy != NULL);
+
+ if (enemy == NULL) {
+ Flags_SetSwitch(play, this->switchFlag);
+ }
+ }
+ }
+ }
+}
+
+void EnBat_SetupStunned(EnBat* this) {
+ if (this->actionFunc != EnBat_Stunned) {
+ this->actor.shape.yOffset = 700.0f;
+ this->actor.velocity.y = 0.0f;
+ this->actor.speedXZ = 0.0f;
+ this->actor.world.pos.y += 13.0f;
+ }
+ Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_FREEZE);
+ Actor_SetColorFilter(&this->actor, 0, 255, 0, this->timer);
+ this->actionFunc = EnBat_Stunned;
+}
+
+void EnBat_Stunned(EnBat* this, PlayState* play) {
+ Math_ScaledStepToS(&this->actor.shape.rot.x, 0, 0x100);
+ if ((this->actor.bgCheckFlags & 1) || (this->actor.floorHeight == BGCHECK_Y_MIN)) {
+ if (this->timer != 0) {
+ this->timer--;
+ }
+ if (this->timer == 0) {
+ EnBat_SetupFlyIdle(this);
+ }
+ } else {
+ this->actor.colorFilterTimer = 40;
+ if (this->drawDmgEffAlpha > 0.0f) {
+ this->drawDmgEffAlpha = 2.0f;
+ }
+ }
+}
+
+void EnBat_UpdateDamage(EnBat* this, PlayState* play) {
+ if (this->collider.base.acFlags & AC_HIT) {
+ this->collider.base.acFlags &= ~AC_HIT;
+
+ Actor_SetDropFlag(&this->actor, &this->collider.info);
+ this->collider.base.atFlags &= ~AT_ON;
+
+ if (this->actionFunc == EnBat_DiveAttack) {
+ sNumberAttacking--;
+ }
+
+ if (this->actor.colChkInfo.damageEffect == BAD_BAT_DMGEFF_ELECTRIC) {
+ this->timer = 40;
+ this->drawDmgEffType = ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_LARGE;
+ this->drawDmgEffAlpha = 2.0f;
+ this->drawDmgEffScale = 0.45f;
+ EnBat_SetupStunned(this);
+ } else if (this->actor.colChkInfo.damageEffect == BAD_BAT_DMGEFF_STUN) {
+ this->timer = 40;
+ EnBat_SetupStunned(this);
+ } else {
+ Actor_ApplyDamage(&this->actor);
+ EnBat_SetupDie(this, play);
+ }
+ }
+}
-extern ColliderSphereInit D_80A44A00;
-extern DamageTable D_80A44A2C;
-extern CollisionCheckInfoInit D_80A44A4C;
-extern InitChainEntry D_80A44A54[];
+void EnBat_Update(Actor* thisx, PlayState* play) {
+ s32 pad;
+ EnBat* this = THIS;
-extern UNK_TYPE D_060000A0;
+ if (this->actor.room == -1) {
+ sAlreadySpawned = true;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bat/EnBat_Init.s")
+ EnBat_UpdateDamage(this, play);
+ this->actionFunc(this, play);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bat/EnBat_Destroy.s")
+ if (this->actionFunc != EnBat_Stunned) {
+ Math_StepToF(&this->actor.shape.yOffset, 2000.0f, 200.0f);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bat/func_80A437CC.s")
+ if (this->actionFunc != EnBat_Perch) {
+ Vec3f prevPos;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bat/func_80A43810.s")
+ this->actor.world.rot.y = this->actor.shape.rot.y;
+ this->actor.world.rot.x = -this->actor.shape.rot.x;
+ Math_Vec3f_Copy(&prevPos, &this->actor.prevPos);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bat/func_80A43870.s")
+ if ((this->actor.colChkInfo.health != 0) && (this->actionFunc != EnBat_Stunned)) {
+ Actor_MoveWithoutGravity(&this->actor);
+ } else {
+ Actor_MoveWithGravity(&this->actor);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bat/func_80A438D4.s")
+ if (this->actionFunc == EnBat_DiveAttack) {
+ Actor_UpdateBgCheckInfo(play, &this->actor, 12.0f, 15.0f, 50.0f, 5);
+ } else if ((this->actionFunc != EnBat_FlyIdle) ||
+ ((this->actor.xzDistToPlayer < 400.0f) && (this->actor.projectedPos.z > 0.0f))) {
+ if (this->paramFlags & BAD_BAT_PARAMFLAG_0) {
+ Actor_UpdateBgCheckInfo(play, &this->actor, 12.0f, 15.0f, 50.0f, 5);
+ } else {
+ Actor_UpdateBgCheckInfo(play, &this->actor, 12.0f, 15.0f, 50.0f, 4);
+ }
+ } else {
+ Math_Vec3f_Copy(&this->actor.prevPos, &prevPos);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bat/func_80A438F8.s")
+ Actor_SetFocus(&this->actor, this->actor.shape.yOffset * 0.01f);
+ this->collider.dim.worldSphere.center.x = this->actor.focus.pos.x;
+ this->collider.dim.worldSphere.center.y = this->actor.focus.pos.y;
+ this->collider.dim.worldSphere.center.z = this->actor.focus.pos.z;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bat/func_80A4392C.s")
+ if (this->collider.base.atFlags & AT_ON) {
+ CollisionCheck_SetAT(play, &play->colChkCtx, &this->collider.base);
+ }
+ if (this->actionFunc == EnBat_DiveAttack) {
+ CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base);
+ }
+ if (this->collider.base.acFlags & AC_ON) {
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider.base);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bat/func_80A43CA0.s")
+ if (this->drawDmgEffAlpha > 0.0f) {
+ if (this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) {
+ Math_StepToF(&this->drawDmgEffAlpha, 0.0f, 0.05f);
+ this->drawDmgEffScale = (this->drawDmgEffAlpha + 1.0f) * 0.225f;
+ this->drawDmgEffScale = CLAMP_MAX(this->drawDmgEffScale, 0.45f);
+ } else if (!Math_StepToF(&this->drawDmgEffFrozenSteamScale, 0.45f, 0.45f / 40.0f)) {
+ func_800B9010(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG);
+ }
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bat/func_80A43CE8.s")
+void EnBat_Draw(Actor* thisx, PlayState* play) {
+ EnBat* this = THIS;
+ Gfx* gfx;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bat/func_80A43F60.s")
+ // Draw body and wings
+ if (this->actor.projectedPos.z > 0.0f) {
+ OPEN_DISPS(play->state.gfxCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bat/func_80A44114.s")
+ gfx = POLY_OPA_DISP;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bat/func_80A44294.s")
+ gSPDisplayList(&gfx[0], &sSetupDL[6 * 25]);
+ gSPMatrix(&gfx[1], Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(&gfx[2], gBadBatSetupDL);
+ gSPDisplayList(&gfx[3], gBadBatBodyDL);
+ gSPDisplayList(&gfx[4], sWingsDLs[this->animationFrame]);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bat/func_80A4431C.s")
+ POLY_OPA_DISP = &gfx[5];
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bat/func_80A443D8.s")
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bat/EnBat_Update.s")
+ // Draw damage effects
+ if (this->drawDmgEffAlpha > 0.0f) {
+ s16 rollAngle;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bat/EnBat_Draw.s")
+ if (this->animationFrame < BAD_BAT_FLAP_FRAME - 1) {
+ rollAngle = this->animationFrame * (15 * (0x10000 / 360));
+ } else {
+ rollAngle = (this->animationFrame >= BAD_BAT_FLAP_FRAME)
+ ? (this->animationFrame * (15 * (0x10000 / 360))) - (120 * (0x10000 / 360))
+ : 0;
+ }
+ Matrix_MultZero(&this->bodyPartPoss[0]);
+ Matrix_RotateZS(rollAngle, MTXMODE_APPLY);
+ Matrix_MultVecX(1700.0f, &this->bodyPartPoss[1]);
+ Matrix_RotateZS(-2 * rollAngle, MTXMODE_APPLY);
+ Matrix_MultVecX(-1700.0f, &this->bodyPartPoss[2]);
+ Actor_DrawDamageEffects(play, &this->actor, this->bodyPartPoss, ARRAY_COUNT(this->bodyPartPoss),
+ this->drawDmgEffScale, this->drawDmgEffFrozenSteamScale, this->drawDmgEffAlpha,
+ this->drawDmgEffType);
+ }
+}
diff --git a/src/overlays/actors/ovl_En_Bat/z_en_bat.h b/src/overlays/actors/ovl_En_Bat/z_en_bat.h
index 76356e83c..4f4ada810 100644
--- a/src/overlays/actors/ovl_En_Bat/z_en_bat.h
+++ b/src/overlays/actors/ovl_En_Bat/z_en_bat.h
@@ -3,6 +3,22 @@
#include "global.h"
+#define BAD_BAT_GET_TYPE(thisx) (((thisx)->params >> 0) & 0x1F)
+#define BAD_BAT_GET_PARAMFLAGS(thisx) (((thisx)->params >> 5) & 7)
+#define BAD_BAT_GET_SWITCHFLAG(thisx) (((thisx)->params >> 8) & 0xFF)
+#define BAD_BAT_PARAMS(switchFlag, paramflags, type) ((type) | ((paramflags) << 5) | ((switchFlag) << 8))
+
+//! PARAMFLAGS
+//! Affects which flags are used in Actor_UpdateBgCheckInfo in certain circumstances
+#define BAD_BAT_PARAMFLAG_0 (1 << 0)
+//! Whether to apply a height range check to attack
+#define BAD_BAT_PARAMFLAG_CHECK_HEIGHTREL (1 << 1)
+//! Spawn as perching instead of flying
+#define BAD_BAT_PARAMFLAG_PERCH (1 << 2)
+
+#define BAD_BAT_GET_NUMBER_TO_SPAWN(thisx) ((thisx)->params)
+#define BAD_BAT_SPAWN_COUNT(n) (n)
+
struct EnBat;
typedef void (*EnBatActionFunc)(struct EnBat*, PlayState*);
@@ -10,7 +26,18 @@ typedef void (*EnBatActionFunc)(struct EnBat*, PlayState*);
typedef struct EnBat {
/* 0x000 */ Actor actor;
/* 0x144 */ EnBatActionFunc actionFunc;
- /* 0x148 */ char unk_148[0x94];
+ /* 0x148 */ u8 drawDmgEffType;
+ /* 0x149 */ u8 paramFlags;
+ /* 0x14A */ s16 switchFlag;
+ /* 0x14C */ s16 timer;
+ /* 0x14E */ s16 pitchTarget;
+ /* 0x150 */ s16 yawTarget;
+ /* 0x152 */ s16 animationFrame; //!< Manual animation using displaylists
+ /* 0x154 */ f32 drawDmgEffScale;
+ /* 0x158 */ f32 drawDmgEffFrozenSteamScale;
+ /* 0x15C */ f32 drawDmgEffAlpha;
+ /* 0x160 */ Vec3f bodyPartPoss[3];
+ /* 0x184 */ ColliderSphere collider;
} EnBat; // size = 0x1DC
extern const ActorInit En_Bat_InitVars;
diff --git a/src/overlays/actors/ovl_En_Crow/z_en_crow.c b/src/overlays/actors/ovl_En_Crow/z_en_crow.c
index 29a4c62bf..e6980ba4f 100644
--- a/src/overlays/actors/ovl_En_Crow/z_en_crow.c
+++ b/src/overlays/actors/ovl_En_Crow/z_en_crow.c
@@ -68,42 +68,53 @@ static ColliderJntSphInit sJntSphInit = {
static CollisionCheckInfoInit sColChkInfoInit = { 1, 15, 30, 30 };
+typedef enum {
+ /* 0 */ GUAY_DMGEFF_NONE,
+ /* 1 */ GUAY_DMGEFF_STUN,
+ /* 2 */ GUAY_DMGEFF_FIRE,
+ /* 3 */ GUAY_DMGEFF_ICE,
+ /* 4 */ GUAY_DMGEFF_LIGHT,
+ /* 5 */ GUAY_DMGEFF_ELECTRIC,
+} GuayDamageEffect;
+
static DamageTable sDamageTable = {
- /* Deku Nut */ DMG_ENTRY(0, 0x1),
- /* Deku Stick */ DMG_ENTRY(1, 0x0),
- /* Horse trample */ DMG_ENTRY(1, 0x0),
- /* Explosives */ DMG_ENTRY(1, 0x0),
- /* Zora boomerang */ DMG_ENTRY(1, 0x0),
- /* Normal arrow */ DMG_ENTRY(1, 0x0),
- /* UNK_DMG_0x06 */ DMG_ENTRY(0, 0x0),
- /* Hookshot */ DMG_ENTRY(1, 0x0),
- /* Goron punch */ DMG_ENTRY(1, 0x0),
- /* Sword */ DMG_ENTRY(1, 0x0),
- /* Goron pound */ DMG_ENTRY(1, 0x0),
- /* Fire arrow */ DMG_ENTRY(2, 0x2),
- /* Ice arrow */ DMG_ENTRY(2, 0x3),
- /* Light arrow */ DMG_ENTRY(2, 0x4),
- /* Goron spikes */ DMG_ENTRY(1, 0x0),
- /* Deku spin */ DMG_ENTRY(1, 0x0),
- /* Deku bubble */ DMG_ENTRY(1, 0x0),
- /* Deku launch */ DMG_ENTRY(2, 0x0),
- /* UNK_DMG_0x12 */ DMG_ENTRY(0, 0x1),
- /* Zora barrier */ DMG_ENTRY(0, 0x5),
- /* Normal shield */ DMG_ENTRY(0, 0x0),
- /* Light ray */ DMG_ENTRY(0, 0x0),
- /* Thrown object */ DMG_ENTRY(1, 0x0),
- /* Zora punch */ DMG_ENTRY(1, 0x0),
- /* Spin attack */ DMG_ENTRY(1, 0x0),
- /* Sword beam */ DMG_ENTRY(0, 0x0),
- /* Normal Roll */ DMG_ENTRY(0, 0x0),
- /* UNK_DMG_0x1B */ DMG_ENTRY(0, 0x0),
- /* UNK_DMG_0x1C */ DMG_ENTRY(0, 0x0),
- /* Unblockable */ DMG_ENTRY(0, 0x0),
- /* UNK_DMG_0x1E */ DMG_ENTRY(0, 0x0),
- /* Powder Keg */ DMG_ENTRY(1, 0x0),
+ /* Deku Nut */ DMG_ENTRY(0, GUAY_DMGEFF_STUN),
+ /* Deku Stick */ DMG_ENTRY(1, GUAY_DMGEFF_NONE),
+ /* Horse trample */ DMG_ENTRY(1, GUAY_DMGEFF_NONE),
+ /* Explosives */ DMG_ENTRY(1, GUAY_DMGEFF_NONE),
+ /* Zora boomerang */ DMG_ENTRY(1, GUAY_DMGEFF_NONE),
+ /* Normal arrow */ DMG_ENTRY(1, GUAY_DMGEFF_NONE),
+ /* UNK_DMG_0x06 */ DMG_ENTRY(0, GUAY_DMGEFF_NONE),
+ /* Hookshot */ DMG_ENTRY(1, GUAY_DMGEFF_NONE),
+ /* Goron punch */ DMG_ENTRY(1, GUAY_DMGEFF_NONE),
+ /* Sword */ DMG_ENTRY(1, GUAY_DMGEFF_NONE),
+ /* Goron pound */ DMG_ENTRY(1, GUAY_DMGEFF_NONE),
+ /* Fire arrow */ DMG_ENTRY(2, GUAY_DMGEFF_FIRE),
+ /* Ice arrow */ DMG_ENTRY(2, GUAY_DMGEFF_ICE),
+ /* Light arrow */ DMG_ENTRY(2, GUAY_DMGEFF_LIGHT),
+ /* Goron spikes */ DMG_ENTRY(1, GUAY_DMGEFF_NONE),
+ /* Deku spin */ DMG_ENTRY(1, GUAY_DMGEFF_NONE),
+ /* Deku bubble */ DMG_ENTRY(1, GUAY_DMGEFF_NONE),
+ /* Deku launch */ DMG_ENTRY(2, GUAY_DMGEFF_NONE),
+ /* UNK_DMG_0x12 */ DMG_ENTRY(0, GUAY_DMGEFF_STUN),
+ /* Zora barrier */ DMG_ENTRY(0, GUAY_DMGEFF_ELECTRIC),
+ /* Normal shield */ DMG_ENTRY(0, GUAY_DMGEFF_NONE),
+ /* Light ray */ DMG_ENTRY(0, GUAY_DMGEFF_NONE),
+ /* Thrown object */ DMG_ENTRY(1, GUAY_DMGEFF_NONE),
+ /* Zora punch */ DMG_ENTRY(1, GUAY_DMGEFF_NONE),
+ /* Spin attack */ DMG_ENTRY(1, GUAY_DMGEFF_NONE),
+ /* Sword beam */ DMG_ENTRY(0, GUAY_DMGEFF_NONE),
+ /* Normal Roll */ DMG_ENTRY(0, GUAY_DMGEFF_NONE),
+ /* UNK_DMG_0x1B */ DMG_ENTRY(0, GUAY_DMGEFF_NONE),
+ /* UNK_DMG_0x1C */ DMG_ENTRY(0, GUAY_DMGEFF_NONE),
+ /* Unblockable */ DMG_ENTRY(0, GUAY_DMGEFF_NONE),
+ /* UNK_DMG_0x1E */ DMG_ENTRY(0, GUAY_DMGEFF_NONE),
+ /* Powder Keg */ DMG_ENTRY(1, GUAY_DMGEFF_NONE),
};
-static s32 D_8099C0CC = 0;
+#define GUAY_NUMBER_OF_DEAD_TO_SPAWN_MEGAGUAY 10
+
+static s32 sDeadCount = 0;
static InitChainEntry sInitChain[] = {
ICHAIN_F32(uncullZoneForward, 3000, ICHAIN_CONTINUE),
@@ -122,7 +133,9 @@ void EnCrow_Init(Actor* thisx, PlayState* play) {
this->collider.elements->dim.worldSphere.radius = sJntSphInit.elements[0].dim.modelSphere.radius;
CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit);
ActorShape_Init(&this->actor.shape, 2000.0f, ActorShadow_DrawCircle, 20.0f);
- D_8099C0CC = 0;
+
+ sDeadCount = 0;
+
if (this->actor.parent != NULL) {
this->actor.flags &= ~ACTOR_FLAG_1;
}
@@ -162,40 +175,40 @@ void EnCrow_FlyIdle(EnCrow* this, PlayState* play) {
}
if (this->actor.bgCheckFlags & 8) {
- this->aimRotY = this->actor.wallYaw;
+ this->yawTarget = this->actor.wallYaw;
} else if (Actor_XZDistanceToPoint(&this->actor, &this->actor.home.pos) > 300.0f) {
- this->aimRotY = Actor_YawToPoint(&this->actor, &this->actor.home.pos);
+ this->yawTarget = Actor_YawToPoint(&this->actor, &this->actor.home.pos);
}
- if ((Math_SmoothStepToS(&this->actor.shape.rot.y, this->aimRotY, 5, 0x300, 0x10) == 0) && onInitialAnimFrame &&
+ if ((Math_SmoothStepToS(&this->actor.shape.rot.y, this->yawTarget, 5, 0x300, 0x10) == 0) && onInitialAnimFrame &&
(Rand_ZeroOne() < 0.1f)) {
yaw = (Actor_YawToPoint(&this->actor, &this->actor.home.pos) - this->actor.shape.rot.y);
if (yaw > 0) {
- this->aimRotY += Rand_S16Offset(0x1000, 0x1000);
+ this->yawTarget += Rand_S16Offset(0x1000, 0x1000);
} else {
- this->aimRotY -= Rand_S16Offset(0x1000, 0x1000);
+ this->yawTarget -= Rand_S16Offset(0x1000, 0x1000);
}
Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_KAICHO_CRY);
}
if ((this->actor.depthInWater > -40.0f) || (this->actor.bgCheckFlags & 1)) {
- this->aimRotX = -0x1000;
+ this->pitchTarget = -0x1000;
} else if (this->actor.world.pos.y < (this->actor.home.pos.y - 50.0f)) {
- this->aimRotX = -Rand_S16Offset(0x800, 0x800);
+ this->pitchTarget = -Rand_S16Offset(0x800, 0x800);
} else if (this->actor.world.pos.y > (this->actor.home.pos.y + 50.0f)) {
- this->aimRotX = Rand_S16Offset(0x800, 0x800);
+ this->pitchTarget = Rand_S16Offset(0x800, 0x800);
}
- if ((Math_SmoothStepToS(&this->actor.shape.rot.x, this->aimRotX, 0xA, 0x100, 8) == 0) && onInitialAnimFrame &&
+ if ((Math_SmoothStepToS(&this->actor.shape.rot.x, this->pitchTarget, 0xA, 0x100, 8) == 0) && onInitialAnimFrame &&
(Rand_ZeroOne() < 0.1f)) {
if (this->actor.home.pos.y < this->actor.world.pos.y) {
- this->aimRotX -= Rand_S16Offset(0x400, 0x400);
+ this->pitchTarget -= Rand_S16Offset(0x400, 0x400);
} else {
- this->aimRotX += Rand_S16Offset(0x400, 0x400);
+ this->pitchTarget += Rand_S16Offset(0x400, 0x400);
}
- this->aimRotX = CLAMP(this->aimRotX, -0x1000, 0x1000);
+ this->pitchTarget = CLAMP(this->pitchTarget, -0x1000, 0x1000);
}
if (this->actor.bgCheckFlags & 1) {
@@ -206,7 +219,7 @@ void EnCrow_FlyIdle(EnCrow* this, PlayState* play) {
this->timer--;
}
if ((this->timer == 0) &&
- (((this->actor.xzDistToPlayer < 300.0f) && !(player->stateFlags1 & 0x800000)) || (dist < 300.0f)) &&
+ (((this->actor.xzDistToPlayer < 300.0f) && !(player->stateFlags1 & PLAYER_STATE1_800000)) || (dist < 300.0f)) &&
(this->actor.depthInWater < -40.0f) && (Player_GetMask(play) != PLAYER_MASK_STONE)) {
if (dist < this->actor.xzDistToPlayer) {
this->actor.child = this->actor.parent;
@@ -227,9 +240,7 @@ void EnCrow_SetupDiveAttack(EnCrow* this) {
void EnCrow_DiveAttack(EnCrow* this, PlayState* play) {
Player* player = GET_PLAYER(play);
s32 isFacingActor;
- Vec3f pos;
- s16 pitch;
- s16 pitchTarget;
+ Vec3f targetPos;
SkelAnime_Update(&this->skelAnime);
if (this->timer != 0) {
@@ -238,27 +249,30 @@ void EnCrow_DiveAttack(EnCrow* this, PlayState* play) {
isFacingActor = Actor_ActorAIsFacingActorB(&this->actor, this->actor.child, 0x2800);
if (isFacingActor) {
+ s16 pitchTarget;
+
if (&player->actor == this->actor.child) {
- pos.y = this->actor.child->world.pos.y + 20.0f;
+ targetPos.y = this->actor.child->world.pos.y + 20.0f;
} else {
- pos.y = this->actor.child->world.pos.y + 40.0f;
+ targetPos.y = this->actor.child->world.pos.y + 40.0f;
}
- pos.x = this->actor.child->world.pos.x;
- pos.z = this->actor.child->world.pos.z;
- pitch = Actor_PitchToPoint(&this->actor, &pos);
- pitchTarget = CLAMP(pitch, -0x3000, 0x3000);
- Math_SmoothStepToS(&this->actor.shape.rot.x, pitchTarget, 2, 0x400, 64);
+ targetPos.x = this->actor.child->world.pos.x;
+ targetPos.z = this->actor.child->world.pos.z;
+ pitchTarget = Actor_PitchToPoint(&this->actor, &targetPos);
+ pitchTarget = CLAMP(pitchTarget, -0x3000, 0x3000);
+ Math_SmoothStepToS(&this->actor.shape.rot.x, pitchTarget, 2, 0x400, 0x40);
} else {
- Math_SmoothStepToS(&this->actor.shape.rot.x, -0x800, 2, 0x100, 16);
+ Math_SmoothStepToS(&this->actor.shape.rot.x, -0x800, 2, 0x100, 0x10);
}
if (isFacingActor || (Actor_XZDistanceBetweenActors(&this->actor, this->actor.child) > 80.0f)) {
Math_SmoothStepToS(&this->actor.shape.rot.y, Actor_YawBetweenActors(&this->actor, this->actor.child), 4, 0xC00,
0xC0);
}
+
if (((this->timer == 0) || ((&player->actor != this->actor.child) && (this->actor.child->home.rot.z != 0)) ||
((&player->actor == this->actor.child) &&
- ((Player_GetMask(play) == PLAYER_MASK_STONE) || (player->stateFlags1 & 0x800000))) ||
+ ((Player_GetMask(play) == PLAYER_MASK_STONE) || (player->stateFlags1 & PLAYER_STATE1_800000))) ||
((this->collider.base.atFlags & AT_HIT) || (this->actor.bgCheckFlags & 9))) ||
(this->actor.depthInWater > -40.0f)) {
@@ -271,9 +285,9 @@ void EnCrow_DiveAttack(EnCrow* this, PlayState* play) {
}
void EnCrow_CheckIfFrozen(EnCrow* this, PlayState* play) {
- if (this->deathMode == 10) {
- this->deathMode = 0;
- this->effectAlpha = 0.0f;
+ if (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) {
+ this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE;
+ this->drawDmgEffAlpha = 0.0f;
Actor_SpawnIceEffects(play, &this->actor, this->bodyPartsPos, 4, 2, 0.2f, 0.2f);
}
}
@@ -291,22 +305,22 @@ void EnCrow_SetupDamaged(EnCrow* this, PlayState* play) {
this->actor.world.pos.y += 20.0f * scale;
Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_KAICHO_DEAD);
- if (this->actor.colChkInfo.damageEffect == 3) {
- this->deathMode = 10; // Ice arrows
- this->effectAlpha = 1.0f;
- this->effectScale = 0.75f;
- this->steamScale = 0.5f;
- } else if (this->actor.colChkInfo.damageEffect == 4) {
- this->deathMode = 20; // Light Arrows
- this->effectAlpha = 4.0f;
- this->steamScale = 0.5f;
+ if (this->actor.colChkInfo.damageEffect == GUAY_DMGEFF_ICE) {
+ this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX;
+ this->drawDmgEffAlpha = 1.0f;
+ this->drawDmgEffScale = 0.75f;
+ this->drawDmgEffFrozenSteamScale = 0.5f;
+ } else if (this->actor.colChkInfo.damageEffect == GUAY_DMGEFF_LIGHT) {
+ this->drawDmgEffType = ACTOR_DRAW_DMGEFF_LIGHT_ORBS;
+ this->drawDmgEffAlpha = 4.0f;
+ this->drawDmgEffFrozenSteamScale = 0.5f;
Actor_Spawn(&play->actorCtx, play, ACTOR_EN_CLEAR_TAG, this->collider.elements->info.bumper.hitPos.x,
this->collider.elements->info.bumper.hitPos.y, this->collider.elements->info.bumper.hitPos.z, 0, 0,
0, CLEAR_TAG_SMALL_LIGHT_RAYS);
- } else if (this->actor.colChkInfo.damageEffect == 2) {
- this->deathMode = 0; // Fire arrows
- this->effectAlpha = 4.0f;
- this->steamScale = 0.5f;
+ } else if (this->actor.colChkInfo.damageEffect == GUAY_DMGEFF_FIRE) {
+ this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE;
+ this->drawDmgEffAlpha = 4.0f;
+ this->drawDmgEffFrozenSteamScale = 0.5f;
}
Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 40);
@@ -325,7 +339,7 @@ void EnCrow_Damaged(EnCrow* this, PlayState* play) {
this->actor.colorFilterTimer = 40;
if (!(this->actor.flags & ACTOR_FLAG_8000)) {
- if (this->deathMode != 10) {
+ if (this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) {
Math_ScaledStepToS(&this->actor.shape.rot.x, 0x4000, 0x200);
this->actor.shape.rot.z += 0x1780;
}
@@ -351,14 +365,14 @@ void EnCrow_SetupDie(EnCrow* this) {
void EnCrow_Die(EnCrow* this, PlayState* play) {
f32 stepScale;
- if (this->actor.params != 0) {
+ if (this->actor.params != GUAY_TYPE_NORMAL) {
stepScale = 0.006f;
} else {
stepScale = 0.002f;
}
- if (Math_StepToF(&this->actor.scale.x, 0.0f, stepScale) != 0) {
- if (this->actor.params == 0) {
- D_8099C0CC++;
+ if (Math_StepToF(&this->actor.scale.x, 0.0f, stepScale)) {
+ if (this->actor.params == GUAY_TYPE_NORMAL) {
+ sDeadCount++;
Item_DropCollectibleRandom(play, &this->actor, &this->actor.world.pos, 0x80);
} else {
Item_DropCollectibleRandom(play, &this->actor, &this->actor.world.pos, 0x90);
@@ -370,11 +384,11 @@ void EnCrow_Die(EnCrow* this, PlayState* play) {
void EnCrow_SetupTurnAway(EnCrow* this) {
this->timer = 100;
- this->aimRotX = -0x1000;
+ this->pitchTarget = -0x1000;
this->actor.speedXZ = 3.5f;
- this->aimRotY = this->actor.yawTowardsPlayer + 0x8000;
+ this->yawTarget = this->actor.yawTowardsPlayer + 0x8000;
this->skelAnime.playSpeed = 2.0f;
- if (this->actor.colChkInfo.damageEffect == 1) {
+ if (this->actor.colChkInfo.damageEffect == GUAY_DMGEFF_STUN) {
Actor_SetColorFilter(&this->actor, 0, 255, 0, 40);
} else {
Actor_SetColorFilter(&this->actor, 0, 255, 0, 40);
@@ -387,13 +401,13 @@ void EnCrow_TurnAway(EnCrow* this, PlayState* play) {
SkelAnime_Update(&this->skelAnime);
if (this->actor.bgCheckFlags & 8) {
- this->aimRotY = this->actor.wallYaw;
+ this->yawTarget = this->actor.wallYaw;
} else {
- this->aimRotY = this->actor.yawTowardsPlayer + 0x8000;
+ this->yawTarget = this->actor.yawTowardsPlayer + 0x8000;
}
- Math_SmoothStepToS(&this->actor.shape.rot.y, this->aimRotY, 3, 0xC00, 0xC0);
- Math_SmoothStepToS(&this->actor.shape.rot.x, this->aimRotX, 5, 0x100, 0x10);
+ Math_SmoothStepToS(&this->actor.shape.rot.y, this->yawTarget, 3, 0xC00, 0xC0);
+ Math_SmoothStepToS(&this->actor.shape.rot.x, this->pitchTarget, 5, 0x100, 0x10);
if (this->timer != 0) {
this->timer--;
@@ -405,12 +419,12 @@ void EnCrow_TurnAway(EnCrow* this, PlayState* play) {
}
void EnCrow_SetupRespawn(EnCrow* this) {
- if (D_8099C0CC == 10) {
- this->actor.params = 1;
- D_8099C0CC = 0;
+ if (sDeadCount == GUAY_NUMBER_OF_DEAD_TO_SPAWN_MEGAGUAY) {
+ this->actor.params = GUAY_TYPE_MEGA;
+ sDeadCount = 0;
this->collider.elements->dim.worldSphere.radius = sJntSphInit.elements->dim.modelSphere.radius * 0.03f * 100.0f;
} else {
- this->actor.params = 0;
+ this->actor.params = GUAY_TYPE_NORMAL;
this->collider.elements->dim.worldSphere.radius = sJntSphInit.elements->dim.modelSphere.radius;
}
Animation_PlayLoop(&this->skelAnime, &gGuayFlyAnim);
@@ -421,12 +435,12 @@ void EnCrow_SetupRespawn(EnCrow* this) {
this->actor.draw = NULL;
this->actor.shape.yOffset = 2000.0f;
this->actor.targetArrowOffset = 2000.0;
- this->effectAlpha = 0.0f;
+ this->drawDmgEffAlpha = 0.0f;
this->actionFunc = EnCrow_Respawn;
}
void EnCrow_Respawn(EnCrow* this, PlayState* play) {
- f32 target;
+ f32 scaleTarget;
if (this->timer != 0) {
this->timer--;
@@ -434,12 +448,12 @@ void EnCrow_Respawn(EnCrow* this, PlayState* play) {
if (this->timer == 0) {
SkelAnime_Update(&this->skelAnime);
this->actor.draw = EnCrow_Draw;
- if (this->actor.params != 0) {
- target = 0.03f;
+ if (this->actor.params != GUAY_TYPE_NORMAL) {
+ scaleTarget = 0.03f;
} else {
- target = 0.01f;
+ scaleTarget = 0.01f;
}
- if (Math_StepToF(&this->actor.scale.x, target, target * 0.1f)) {
+ if (Math_StepToF(&this->actor.scale.x, scaleTarget, scaleTarget * 0.1f)) {
this->actor.flags |= ACTOR_FLAG_1;
this->actor.flags &= ~ACTOR_FLAG_10;
this->actor.colChkInfo.health = 1;
@@ -450,18 +464,17 @@ void EnCrow_Respawn(EnCrow* this, PlayState* play) {
}
void EnCrow_UpdateDamage(EnCrow* this, PlayState* play) {
-
if (this->collider.base.acFlags & AT_HIT) {
this->collider.base.acFlags &= ~AT_HIT;
Actor_SetDropFlag(&this->actor, &this->collider.elements->info);
- if (this->actor.colChkInfo.damageEffect == 1) {
+ if (this->actor.colChkInfo.damageEffect == GUAY_DMGEFF_STUN) {
EnCrow_SetupTurnAway(this);
- } else if (this->actor.colChkInfo.damageEffect == 5) {
- this->deathMode = 31; // Stunned via deku nuts or zora barrier
- this->effectAlpha = 2.0f;
- this->steamScale = 0.5f;
+ } else if (this->actor.colChkInfo.damageEffect == GUAY_DMGEFF_ELECTRIC) {
+ this->drawDmgEffType = ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_MEDIUM;
+ this->drawDmgEffAlpha = 2.0f;
+ this->drawDmgEffFrozenSteamScale = 0.5f;
EnCrow_SetupTurnAway(this);
} else {
@@ -475,7 +488,7 @@ void EnCrow_UpdateDamage(EnCrow* this, PlayState* play) {
void EnCrow_Update(Actor* thisx, PlayState* play) {
f32 pad;
- EnCrow* this = (EnCrow*)thisx;
+ EnCrow* this = THIS;
f32 height;
f32 scale;
@@ -517,23 +530,23 @@ void EnCrow_Update(Actor* thisx, PlayState* play) {
if ((this->actor.colChkInfo.health != 0) && (Animation_OnFrame(&this->skelAnime, 3.0f))) {
Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_KAICHO_FLUTTER);
}
- if (this->effectAlpha > 0.0f) {
- if (this->deathMode != 10) {
- Math_StepToF(&this->effectAlpha, 0.0f, 0.05f);
- this->steamScale = (this->effectAlpha + 1.0f) * 0.25f;
- if (this->steamScale > 0.5f) {
- this->steamScale = 0.5f;
+ if (this->drawDmgEffAlpha > 0.0f) {
+ if (this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) {
+ Math_StepToF(&this->drawDmgEffAlpha, 0.0f, 0.05f);
+ this->drawDmgEffFrozenSteamScale = (this->drawDmgEffAlpha + 1.0f) * 0.25f;
+ if (this->drawDmgEffFrozenSteamScale > 0.5f) {
+ this->drawDmgEffFrozenSteamScale = 0.5f;
} else {
- this->steamScale = this->steamScale;
+ this->drawDmgEffFrozenSteamScale = this->drawDmgEffFrozenSteamScale;
}
- } else if (Math_StepToF(&this->effectScale, 0.5f, 0.0125f) == 0) {
+ } else if (!Math_StepToF(&this->drawDmgEffScale, 0.5f, 0.5f * 0.025f)) {
func_800B9010(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG);
}
}
}
s32 EnCrow_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) {
- EnCrow* this = (EnCrow*)thisx;
+ EnCrow* this = THIS;
if (this->actor.colChkInfo.health != 0) {
if (limbIndex == OBJECT_CROW_LIMB_UPPER_TAIL) {
@@ -546,25 +559,23 @@ s32 EnCrow_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f*
}
void EnCrow_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) {
- EnCrow* this = (EnCrow*)thisx;
+ EnCrow* this = THIS;
if (limbIndex == OBJECT_CROW_LIMB_BODY) {
Matrix_MultVecX(2500.0f, this->bodyPartsPos);
- return;
- }
- if ((limbIndex == OBJECT_CROW_LIMB_RIGHT_WING_TIP) || (limbIndex == OBJECT_CROW_LIMB_LEFT_WING_TIP) ||
- (limbIndex == OBJECT_CROW_LIMB_TAIL)) {
+ } else if ((limbIndex == OBJECT_CROW_LIMB_RIGHT_WING_TIP) || (limbIndex == OBJECT_CROW_LIMB_LEFT_WING_TIP) ||
+ (limbIndex == OBJECT_CROW_LIMB_TAIL)) {
Matrix_MultZero(&this->bodyPartsPos[(limbIndex >> 1) - 1]);
}
}
void EnCrow_Draw(Actor* thisx, PlayState* play) {
- EnCrow* this = (EnCrow*)thisx;
+ EnCrow* this = THIS;
func_8012C28C(play->state.gfxCtx);
SkelAnime_DrawFlexOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount,
EnCrow_OverrideLimbDraw, EnCrow_PostLimbDraw, &this->actor);
Actor_DrawDamageEffects(play, &this->actor, this->bodyPartsPos, ARRAY_COUNT(this->bodyPartsPos),
- this->actor.scale.x * 100.0f * this->steamScale, this->effectScale, this->effectAlpha,
- this->deathMode);
+ this->actor.scale.x * 100.0f * this->drawDmgEffFrozenSteamScale, this->drawDmgEffScale,
+ this->drawDmgEffAlpha, this->drawDmgEffType);
}
diff --git a/src/overlays/actors/ovl_En_Crow/z_en_crow.h b/src/overlays/actors/ovl_En_Crow/z_en_crow.h
index 306f41055..86ffba903 100644
--- a/src/overlays/actors/ovl_En_Crow/z_en_crow.h
+++ b/src/overlays/actors/ovl_En_Crow/z_en_crow.h
@@ -4,6 +4,11 @@
#include "global.h"
#include "objects/object_crow/object_crow.h"
+typedef enum {
+ /* 0 */ GUAY_TYPE_NORMAL,
+ /* 1 */ GUAY_TYPE_MEGA
+} GuayType;
+
struct EnCrow;
typedef void (*EnCrowActionFunc)(struct EnCrow*, PlayState*);
@@ -12,18 +17,18 @@ typedef struct EnCrow {
/* 0x000 */ Actor actor;
/* 0x144 */ SkelAnime skelAnime;
/* 0x188 */ EnCrowActionFunc actionFunc;
- /* 0x18C */ u8 deathMode;
+ /* 0x18C */ u8 drawDmgEffType;
/* 0x18E */ s16 timer;
- /* 0x190 */ s16 aimRotX;
- /* 0x192 */ s16 aimRotY;
+ /* 0x190 */ s16 pitchTarget;
+ /* 0x192 */ s16 yawTarget;
/* 0x194 */ Vec3s jointTable[OBJECT_CROW_LIMB_MAX];
/* 0x1CA */ Vec3s morphTable[OBJECT_CROW_LIMB_MAX];
/* 0x200 */ ColliderJntSph collider;
/* 0x220 */ ColliderJntSphElement colliderItems[1];
/* 0x260 */ Vec3f bodyPartsPos[4];
- /* 0x290 */ f32 effectAlpha;
- /* 0x294 */ f32 steamScale;
- /* 0x298 */ f32 effectScale;
+ /* 0x290 */ f32 drawDmgEffAlpha;
+ /* 0x294 */ f32 drawDmgEffFrozenSteamScale;
+ /* 0x298 */ f32 drawDmgEffScale;
} EnCrow; // size = 0x29C
extern const ActorInit En_Crow_InitVars;
diff --git a/src/overlays/actors/ovl_En_Firefly/z_en_firefly.c b/src/overlays/actors/ovl_En_Firefly/z_en_firefly.c
index 9c6044685..d8cbe91f5 100644
--- a/src/overlays/actors/ovl_En_Firefly/z_en_firefly.c
+++ b/src/overlays/actors/ovl_En_Firefly/z_en_firefly.c
@@ -78,39 +78,48 @@ static ColliderSphereInit sSphereInit = {
static CollisionCheckInfoInit sColChkInfoInit = { 1, 10, 10, 10 };
+typedef enum {
+ /* 0 */ KEESE_DMGEFF_NONE,
+ /* 1 */ KEESE_DMGEFF_STUN,
+ /* 2 */ KEESE_DMGEFF_FIRE,
+ /* 3 */ KEESE_DMGEFF_ICE,
+ /* 4 */ KEESE_DMGEFF_LIGHT,
+ /* 5 */ KEESE_DMGEFF_ELECTRIC
+} BatDamageEffect;
+
static DamageTable sDamageTable = {
- /* Deku Nut */ DMG_ENTRY(0, 0x1),
- /* Deku Stick */ DMG_ENTRY(1, 0x0),
- /* Horse trample */ DMG_ENTRY(0, 0x0),
- /* Explosives */ DMG_ENTRY(1, 0x0),
- /* Zora boomerang */ DMG_ENTRY(1, 0x0),
- /* Normal arrow */ DMG_ENTRY(1, 0x0),
- /* UNK_DMG_0x06 */ DMG_ENTRY(0, 0x0),
- /* Hookshot */ DMG_ENTRY(1, 0x0),
- /* Goron punch */ DMG_ENTRY(1, 0x0),
- /* Sword */ DMG_ENTRY(1, 0x0),
- /* Goron pound */ DMG_ENTRY(1, 0x0),
- /* Fire arrow */ DMG_ENTRY(2, 0x2),
- /* Ice arrow */ DMG_ENTRY(2, 0x3),
- /* Light arrow */ DMG_ENTRY(2, 0x4),
- /* Goron spikes */ DMG_ENTRY(1, 0x0),
- /* Deku spin */ DMG_ENTRY(1, 0x0),
- /* Deku bubble */ DMG_ENTRY(1, 0x0),
- /* Deku launch */ DMG_ENTRY(2, 0x0),
- /* UNK_DMG_0x12 */ DMG_ENTRY(0, 0x1),
- /* Zora barrier */ DMG_ENTRY(0, 0x5),
- /* Normal shield */ DMG_ENTRY(0, 0x0),
- /* Light ray */ DMG_ENTRY(0, 0x0),
- /* Thrown object */ DMG_ENTRY(1, 0x0),
- /* Zora punch */ DMG_ENTRY(1, 0x0),
- /* Spin attack */ DMG_ENTRY(1, 0x0),
- /* Sword beam */ DMG_ENTRY(0, 0x0),
- /* Normal Roll */ DMG_ENTRY(0, 0x0),
- /* UNK_DMG_0x1B */ DMG_ENTRY(0, 0x0),
- /* UNK_DMG_0x1C */ DMG_ENTRY(0, 0x0),
- /* Unblockable */ DMG_ENTRY(0, 0x0),
- /* UNK_DMG_0x1E */ DMG_ENTRY(0, 0x0),
- /* Powder Keg */ DMG_ENTRY(1, 0x0),
+ /* Deku Nut */ DMG_ENTRY(0, KEESE_DMGEFF_STUN),
+ /* Deku Stick */ DMG_ENTRY(1, KEESE_DMGEFF_NONE),
+ /* Horse trample */ DMG_ENTRY(0, KEESE_DMGEFF_NONE),
+ /* Explosives */ DMG_ENTRY(1, KEESE_DMGEFF_NONE),
+ /* Zora boomerang */ DMG_ENTRY(1, KEESE_DMGEFF_NONE),
+ /* Normal arrow */ DMG_ENTRY(1, KEESE_DMGEFF_NONE),
+ /* UNK_DMG_0x06 */ DMG_ENTRY(0, KEESE_DMGEFF_NONE),
+ /* Hookshot */ DMG_ENTRY(1, KEESE_DMGEFF_NONE),
+ /* Goron punch */ DMG_ENTRY(1, KEESE_DMGEFF_NONE),
+ /* Sword */ DMG_ENTRY(1, KEESE_DMGEFF_NONE),
+ /* Goron pound */ DMG_ENTRY(1, KEESE_DMGEFF_NONE),
+ /* Fire arrow */ DMG_ENTRY(2, KEESE_DMGEFF_FIRE),
+ /* Ice arrow */ DMG_ENTRY(2, KEESE_DMGEFF_ICE),
+ /* Light arrow */ DMG_ENTRY(2, KEESE_DMGEFF_LIGHT),
+ /* Goron spikes */ DMG_ENTRY(1, KEESE_DMGEFF_NONE),
+ /* Deku spin */ DMG_ENTRY(1, KEESE_DMGEFF_NONE),
+ /* Deku bubble */ DMG_ENTRY(1, KEESE_DMGEFF_NONE),
+ /* Deku launch */ DMG_ENTRY(2, KEESE_DMGEFF_NONE),
+ /* UNK_DMG_0x12 */ DMG_ENTRY(0, KEESE_DMGEFF_STUN),
+ /* Zora barrier */ DMG_ENTRY(0, KEESE_DMGEFF_ELECTRIC),
+ /* Normal shield */ DMG_ENTRY(0, KEESE_DMGEFF_NONE),
+ /* Light ray */ DMG_ENTRY(0, KEESE_DMGEFF_NONE),
+ /* Thrown object */ DMG_ENTRY(1, KEESE_DMGEFF_NONE),
+ /* Zora punch */ DMG_ENTRY(1, KEESE_DMGEFF_NONE),
+ /* Spin attack */ DMG_ENTRY(1, KEESE_DMGEFF_NONE),
+ /* Sword beam */ DMG_ENTRY(0, KEESE_DMGEFF_NONE),
+ /* Normal Roll */ DMG_ENTRY(0, KEESE_DMGEFF_NONE),
+ /* UNK_DMG_0x1B */ DMG_ENTRY(0, KEESE_DMGEFF_NONE),
+ /* UNK_DMG_0x1C */ DMG_ENTRY(0, KEESE_DMGEFF_NONE),
+ /* Unblockable */ DMG_ENTRY(0, KEESE_DMGEFF_NONE),
+ /* UNK_DMG_0x1E */ DMG_ENTRY(0, KEESE_DMGEFF_NONE),
+ /* Powder Keg */ DMG_ENTRY(1, KEESE_DMGEFF_NONE),
};
static InitChainEntry sInitChain[] = {
@@ -265,7 +274,7 @@ void EnFirefly_SetupFlyIdle(EnFirefly* this) {
this->timer = Rand_S16Offset(70, 100);
this->actor.speedXZ = (Rand_ZeroOne() * 1.5f) + 1.5f;
Math_ScaledStepToS(&this->actor.shape.rot.y, Actor_YawToPoint(&this->actor, &this->actor.home.pos), 0x300);
- this->targetPitch = ((this->maxAltitude < this->actor.world.pos.y) ? 0xC00 : -0xC00) + 0x1554;
+ this->pitchTarget = ((this->maxAltitude < this->actor.world.pos.y) ? 0xC00 : -0xC00) + 0x1554;
this->skelAnime.playSpeed = 1.0f;
this->actionFunc = EnFirefly_FlyIdle;
}
@@ -295,25 +304,25 @@ void EnFirefly_FlyIdle(EnFirefly* this, PlayState* play) {
// Climb if too close to ground
if (this->actor.world.pos.y < this->actor.floorHeight + 20.0f) {
- this->targetPitch = 0x954;
+ this->pitchTarget = 0x954;
// Descend if above maxAltitude
} else if (this->maxAltitude < this->actor.world.pos.y) {
- this->targetPitch = 0x2154;
+ this->pitchTarget = 0x2154;
// Otherwise ascend or descend at random, biased towards ascending
} else if (Rand_ZeroOne() > 0.35f) {
- this->targetPitch = 0x954;
+ this->pitchTarget = 0x954;
} else {
- this->targetPitch = 0x2154;
+ this->pitchTarget = 0x2154;
}
} else {
if (this->actor.bgCheckFlags & 1) {
- this->targetPitch = 0x954;
+ this->pitchTarget = 0x954;
} else if ((this->actor.bgCheckFlags & 0x10) || (this->maxAltitude < this->actor.world.pos.y)) {
- this->targetPitch = 0x2154;
+ this->pitchTarget = 0x2154;
}
}
- Math_ScaledStepToS(&this->actor.shape.rot.x, this->targetPitch, 0x100);
+ Math_ScaledStepToS(&this->actor.shape.rot.x, this->pitchTarget, 0x100);
}
if (this->actor.bgCheckFlags & 8) {
@@ -338,19 +347,19 @@ void EnFirefly_SetupFall(EnFirefly* this, PlayState* play) {
Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 40);
}
- if (this->actor.colChkInfo.damageEffect == 3) {
+ if (this->actor.colChkInfo.damageEffect == KEESE_DMGEFF_ICE) {
this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX;
this->drawDmgEffAlpha = 1.0f;
this->drawDmgEffScale = 0.55f;
- this->drawDmgEffFrozenSteamScale = 0.82500005f;
- } else if (this->actor.colChkInfo.damageEffect == 4) {
+ this->drawDmgEffFrozenSteamScale = 0.55f * 1.5f;
+ } else if (this->actor.colChkInfo.damageEffect == KEESE_DMGEFF_LIGHT) {
this->drawDmgEffType = ACTOR_DRAW_DMGEFF_LIGHT_ORBS;
this->drawDmgEffAlpha = 4.0f;
this->drawDmgEffScale = 0.55f;
Actor_Spawn(&play->actorCtx, play, ACTOR_EN_CLEAR_TAG, this->collider.info.bumper.hitPos.x,
this->collider.info.bumper.hitPos.y, this->collider.info.bumper.hitPos.z, 0, 0, 0,
CLEAR_TAG_SMALL_LIGHT_RAYS);
- } else if (this->actor.colChkInfo.damageEffect == 2) {
+ } else if (this->actor.colChkInfo.damageEffect == KEESE_DMGEFF_FIRE) {
this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE;
this->drawDmgEffAlpha = 4.0f;
this->drawDmgEffScale = 0.55f;
@@ -409,7 +418,7 @@ void EnFirefly_Die(EnFirefly* this, PlayState* play) {
void EnFirefly_SetupDiveAttack(EnFirefly* this) {
this->timer = Rand_S16Offset(70, 100);
this->skelAnime.playSpeed = 1.0f;
- this->targetPitch = ((this->actor.playerHeightRel > 0.0f) ? -0xC00 : 0xC00) + 0x1554;
+ this->pitchTarget = ((this->actor.playerHeightRel > 0.0f) ? -0xC00 : 0xC00) + 0x1554;
this->actionFunc = EnFirefly_DiveAttack;
}
@@ -427,7 +436,7 @@ void EnFirefly_DiveAttack(EnFirefly* this, PlayState* play) {
if (this->actor.bgCheckFlags & 8) {
Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.wallYaw, 2, 0xC00, 0x300);
- Math_ScaledStepToS(&this->actor.shape.rot.x, this->targetPitch, 0x100);
+ Math_ScaledStepToS(&this->actor.shape.rot.x, this->pitchTarget, 0x100);
} else if (Actor_IsFacingPlayer(&this->actor, 0x2800)) {
if (Animation_OnFrame(&this->skelAnime, 4.0f)) {
this->skelAnime.playSpeed = 0.0f;
@@ -447,19 +456,19 @@ void EnFirefly_DiveAttack(EnFirefly* this, PlayState* play) {
}
if (this->actor.bgCheckFlags & 1) {
- this->targetPitch = 0x954;
+ this->pitchTarget = 0x954;
}
if ((this->actor.bgCheckFlags & 0x10) || (this->maxAltitude < this->actor.world.pos.y)) {
- this->targetPitch = 0x2154;
+ this->pitchTarget = 0x2154;
} else {
- this->targetPitch = 0x954;
+ this->pitchTarget = 0x954;
}
- Math_ScaledStepToS(&this->actor.shape.rot.x, this->targetPitch, 0x100);
+ Math_ScaledStepToS(&this->actor.shape.rot.x, this->pitchTarget, 0x100);
}
- if ((this->timer == 0) || (Player_GetMask(play) == PLAYER_MASK_STONE) || (player->stateFlags2 & 0x80) ||
+ if ((this->timer == 0) || (Player_GetMask(play) == PLAYER_MASK_STONE) || (player->stateFlags2 & PLAYER_STATE2_80) ||
(player->actor.freezeTimer > 0)) {
EnFirefly_SetupFlyAway(this);
}
@@ -491,7 +500,7 @@ void EnFirefly_Rebound(EnFirefly* this, PlayState* play) {
void EnFirefly_SetupFlyAway(EnFirefly* this) {
this->timer = 150;
- this->targetPitch = 0x954;
+ this->pitchTarget = 0x954;
this->actionFunc = EnFirefly_FlyAway;
this->skelAnime.playSpeed = 1.0f;
}
@@ -513,11 +522,11 @@ void EnFirefly_FlyAway(EnFirefly* this, PlayState* play) {
Math_StepToF(&this->actor.speedXZ, 3.0f, 0.3f);
if (this->actor.bgCheckFlags & 1) {
- this->targetPitch = 0x954;
+ this->pitchTarget = 0x954;
} else if ((this->actor.bgCheckFlags & 0x10) || (this->maxAltitude < this->actor.world.pos.y)) {
- this->targetPitch = 0x2154;
+ this->pitchTarget = 0x2154;
} else {
- this->targetPitch = 0x954;
+ this->pitchTarget = 0x954;
}
if (this->actor.bgCheckFlags & 8) {
@@ -526,7 +535,7 @@ void EnFirefly_FlyAway(EnFirefly* this, PlayState* play) {
Math_ScaledStepToS(&this->actor.shape.rot.y, Actor_YawToPoint(&this->actor, &this->actor.home.pos), 0x300);
}
- Math_ScaledStepToS(&this->actor.shape.rot.x, this->targetPitch, 0x100);
+ Math_ScaledStepToS(&this->actor.shape.rot.x, this->pitchTarget, 0x100);
}
void EnFirefly_SetupStunned(EnFirefly* this) {
@@ -632,10 +641,10 @@ void EnFirefly_UpdateDamage(EnFirefly* this, PlayState* play) {
this->collider.base.acFlags &= ~AC_HIT;
Actor_SetDropFlag(&this->actor, &this->collider.info);
- if (this->actor.colChkInfo.damageEffect == 1) {
+ if (this->actor.colChkInfo.damageEffect == KEESE_DMGEFF_STUN) {
this->timer = 40;
EnFirefly_SetupStunned(this);
- } else if (this->actor.colChkInfo.damageEffect == 5) {
+ } else if (this->actor.colChkInfo.damageEffect == KEESE_DMGEFF_ELECTRIC) {
this->timer = 40;
this->drawDmgEffType = ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_MEDIUM;
this->drawDmgEffAlpha = 2.0f;
@@ -647,9 +656,9 @@ void EnFirefly_UpdateDamage(EnFirefly* this, PlayState* play) {
this->actor.flags &= ~ACTOR_FLAG_1;
// Negate effects of fire on Fire Keese and Ice on Ice Keese
- if (((this->currentType == KEESE_FIRE) && (this->actor.colChkInfo.damageEffect == 2)) ||
- ((this->currentType == KEESE_ICE) && (this->actor.colChkInfo.damageEffect == 3))) {
- this->actor.colChkInfo.damageEffect = 0;
+ if (((this->currentType == KEESE_FIRE) && (this->actor.colChkInfo.damageEffect == KEESE_DMGEFF_FIRE)) ||
+ ((this->currentType == KEESE_ICE) && (this->actor.colChkInfo.damageEffect == KEESE_DMGEFF_ICE))) {
+ this->actor.colChkInfo.damageEffect = KEESE_DMGEFF_NONE;
}
EnFirefly_SetupFall(this, play);
@@ -714,7 +723,7 @@ void EnFirefly_Update(Actor* thisx, PlayState* play2) {
Math_StepToF(&this->drawDmgEffAlpha, 0.0f, 0.05f);
this->drawDmgEffScale = (this->drawDmgEffAlpha + 1.0f) * 0.275f;
this->drawDmgEffScale = CLAMP_MAX(this->drawDmgEffScale, 0.55f);
- } else if (!Math_StepToF(&this->drawDmgEffFrozenSteamScale, 0.55f, 0.01375f)) {
+ } else if (!Math_StepToF(&this->drawDmgEffFrozenSteamScale, 0.55f, 0.55f / 40.0f)) {
func_800B9010(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG);
}
}
@@ -755,7 +764,7 @@ void EnFirefly_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s*
if ((this->currentType != KEESE_FIRE) && (limbIndex == 27)) {
gSPDisplayList((*gfx)++, object_firefly_DL_001678);
- } else if ((this->unk_2F4 != play->gameplayFrames) &&
+ } else if ((this->lastDrawnFrame != play->gameplayFrames) &&
((this->auraType == KEESE_AURA_FIRE) || (this->auraType == KEESE_AURA_ICE)) &&
((limbIndex == 15) || (limbIndex == 21))) {
if (this->actionFunc != EnFirefly_Die) {
@@ -832,7 +841,7 @@ void EnFirefly_Draw(Actor* thisx, PlayState* play) {
Actor_DrawDamageEffects(play, NULL, this->limbPos, ARRAY_COUNT(this->limbPos),
this->drawDmgEffScale * this->actor.scale.y * 200.0f, this->drawDmgEffFrozenSteamScale,
this->drawDmgEffAlpha, this->drawDmgEffType);
- this->unk_2F4 = play->gameplayFrames;
+ this->lastDrawnFrame = play->gameplayFrames;
CLOSE_DISPS(play->state.gfxCtx);
}
diff --git a/src/overlays/actors/ovl_En_Firefly/z_en_firefly.h b/src/overlays/actors/ovl_En_Firefly/z_en_firefly.h
index cb6019d5e..ffb295e6a 100644
--- a/src/overlays/actors/ovl_En_Firefly/z_en_firefly.h
+++ b/src/overlays/actors/ovl_En_Firefly/z_en_firefly.h
@@ -26,14 +26,14 @@ typedef struct EnFirefly {
/* 0x18E */ u8 isInvisible;
/* 0x18F */ u8 drawDmgEffType;
/* 0x190 */ s16 timer;
- /* 0x192 */ s16 targetPitch;
+ /* 0x192 */ s16 pitchTarget;
/* 0x194 */ Vec3s jointTable[28];
/* 0x23C */ Vec3s morphTable[28];
/* 0x2E4 */ f32 maxAltitude;
/* 0x2E8 */ f32 drawDmgEffAlpha;
/* 0x2E8 */ f32 drawDmgEffScale;
/* 0x2E8 */ f32 drawDmgEffFrozenSteamScale;
- /* 0x2F4 */ u32 unk_2F4;
+ /* 0x2F4 */ u32 lastDrawnFrame;
/* 0x2F8 */ Vec3f limbPos[3];
/* 0x31C */ ColliderSphere collider;
} EnFirefly; // size = 0x374