diff --git a/assets/xml/objects/object_dog.xml b/assets/xml/objects/object_dog.xml
index 89eba9c96a..6941cb36c1 100644
--- a/assets/xml/objects/object_dog.xml
+++ b/assets/xml/objects/object_dog.xml
@@ -17,7 +17,7 @@
-
+
diff --git a/src/overlays/actors/ovl_En_Aob_01/z_en_aob_01.c b/src/overlays/actors/ovl_En_Aob_01/z_en_aob_01.c
index 797c7116f3..30ff27e696 100644
--- a/src/overlays/actors/ovl_En_Aob_01/z_en_aob_01.c
+++ b/src/overlays/actors/ovl_En_Aob_01/z_en_aob_01.c
@@ -118,17 +118,17 @@ void func_809C1158(EnAob01* this, PlayState* play) {
}
void func_809C11EC(EnAob01* this, PlayState* play) {
- s32 unk;
+ s32 enDgParams;
s16 i;
func_809C1158(this, play);
for (i = 0; i < ARRAY_COUNT(D_809C384C); i++) {
- unk = (this->unk_1D8[D_809C384C[i].unk_06]->unk1 << 0xA) | (i << 5);
+ enDgParams = ENDG_PARAMS(this->unk_1D8[D_809C384C[i].unk_06]->unk1, i);
this->unk_3F8[i] = Actor_SpawnAsChildAndCutscene(
&play->actorCtx, play, ACTOR_EN_DG, D_809C384C[i].unk_00.x, D_809C384C[i].unk_00.y, D_809C384C[i].unk_00.z,
- 0, D_809C384C[i].unk_04 * 182.04445f, 0, unk, 0xFFFF, this->actor.unk20, NULL);
+ 0, D_809C384C[i].unk_04 * 182.04445f, 0, enDgParams, 0xFFFF, this->actor.unk20, NULL);
}
}
diff --git a/src/overlays/actors/ovl_En_Dg/z_en_dg.c b/src/overlays/actors/ovl_En_Dg/z_en_dg.c
index 716d822fb2..310f398afd 100644
--- a/src/overlays/actors/ovl_En_Dg/z_en_dg.c
+++ b/src/overlays/actors/ovl_En_Dg/z_en_dg.c
@@ -15,26 +15,26 @@ void EnDg_Destroy(Actor* thisx, PlayState* play);
void EnDg_Update(Actor* thisx, PlayState* play);
void EnDg_Draw(Actor* thisx, PlayState* play);
-void func_8098A468(EnDg* this, PlayState* play);
-void func_8098A55C(EnDg* this, PlayState* play);
-void func_8098A618(EnDg* this, PlayState* play);
-void func_8098A70C(EnDg* this, PlayState* play);
-void func_8098A89C(EnDg* this, PlayState* play);
-void func_8098A938(EnDg* this, PlayState* play);
-void func_8098AB48(EnDg* this, PlayState* play);
-void func_8098AC34(EnDg* this, PlayState* play);
-void func_8098AF44(EnDg* this, PlayState* play);
-void func_8098AF98(EnDg* this, PlayState* play);
-void func_8098B004(EnDg* this, PlayState* play);
-void func_8098B198(EnDg* this, PlayState* play);
-void func_8098B28C(EnDg* this, PlayState* play);
-void func_8098B390(EnDg* this, PlayState* play);
-void func_8098B560(EnDg* this, PlayState* play);
-void func_8098B88C(EnDg* this, PlayState* play);
-void func_8098BA64(EnDg* this, PlayState* play);
-void func_8098BB10(EnDg* this, PlayState* play);
-void func_8098BBEC(EnDg* this, PlayState* play);
-void func_8098BC54(EnDg* this, PlayState* play);
+void EnDg_IdleMove(EnDg* this, PlayState* play);
+void EnDg_IdleBark(EnDg* this, PlayState* play);
+void EnDg_BackAwayFromGoron(EnDg* this, PlayState* play);
+void EnDg_RunAwayFromGoron(EnDg* this, PlayState* play);
+void EnDg_BarkAtGoron(EnDg* this, PlayState* play);
+void EnDg_ApproachPlayerToAttack(EnDg* this, PlayState* play);
+void EnDg_SitNextToPlayer(EnDg* this, PlayState* play);
+void EnDg_JumpAttack(EnDg* this, PlayState* play);
+void EnDg_SetupBremenMaskApproachPlayer(EnDg* this, PlayState* play);
+void EnDg_Fall(EnDg* this, PlayState* play);
+void EnDg_ApproachPlayer(EnDg* this, PlayState* play);
+void EnDg_SlowlyBackUpBeforeAttacking(EnDg* this, PlayState* play);
+void EnDg_BackAwayFromPlayer(EnDg* this, PlayState* play);
+void EnDg_BarkAtPlayer(EnDg* this, PlayState* play);
+void EnDg_Swim(EnDg* this, PlayState* play);
+void EnDg_JumpOutOfWater(EnDg* this, PlayState* play);
+void EnDg_Held(EnDg* this, PlayState* play);
+void EnDg_Thrown(EnDg* this, PlayState* play);
+void EnDg_SetupTalk(EnDg* this, PlayState* play);
+void EnDg_Talk(EnDg* this, PlayState* play);
const ActorInit En_Dg_InitVars = {
ACTOR_EN_DG,
@@ -48,14 +48,37 @@ const ActorInit En_Dg_InitVars = {
(ActorFunc)EnDg_Draw,
};
-static u8 D_8098C2A0 = 0;
+#define DOG_FLAG_NONE 0
+#define DOG_FLAG_HELD (1 << 0)
+#define DOG_FLAG_JUMP_ATTACKING (1 << 1)
+#define DOG_FLAG_SWIMMING (1 << 2)
+#define DOG_FLAG_BOUNCED (1 << 3)
+#define DOG_FLAG_THROWN (1 << 4)
+#define DOG_FLAG_FOLLOWING_BREMEN_MASK (1 << 5)
-typedef struct {
- s16 unk_00;
- s16 unk_02;
-} D_8098C2A4_s;
+#define ENDG_INDEX_NO_BREMEN_MASK_FOLLOWER 99
-static D_8098C2A4_s D_8098C2A4 = { 0x0063, 0x0000 };
+typedef enum {
+ /* 0 */ DOG_GRAB_STATE_NONE,
+ /* 1 */ DOG_GRAB_STATE_HELD,
+ /* 2 */ DOG_GRAB_STATE_THROWN_OR_SITTING_AFTER_THROW,
+} DogGrabState;
+
+typedef enum {
+ /* 0 */ DOG_BEHAVIOR_INITIAL, // Gets immediately replaced by DOG_BEHAVIOR_DEFAULT in EnDg_Update
+ /* 1 */ DOG_BEHAVIOR_HUMAN, // Gets immediately replaced by DOG_BEHAVIOR_DEFAULT in EnDg_Update
+ /* 2 */ DOG_BEHAVIOR_GORON,
+ /* 3 */ DOG_BEHAVIOR_GORON_WAIT,
+ /* 4 */ DOG_BEHAVIOR_ZORA,
+ /* 5 */ DOG_BEHAVIOR_ZORA_WAIT,
+ /* 6 */ DOG_BEHAVIOR_DEKU,
+ /* 7 */ DOG_BEHAVIOR_DEKU_WAIT,
+ /* 8 */ DOG_BEHAVIOR_DEFAULT,
+} DogBehavior;
+
+static u8 sIsAnyDogHeld = false;
+
+static s16 sBremenMaskFollowerIndex = ENDG_INDEX_NO_BREMEN_MASK_FOLLOWER;
/**
* Stores the state for the dogs milling about at the Doggy Racetrack.
@@ -80,7 +103,7 @@ static RacetrackDogInfo sRacetrackDogInfo[] = {
/**
* Stores the RacetrackDogInfo for the dog that is selected by the player. These values are just
- * placeholders, and the actual value gets grabbed from sRacetrackDogInfo in func_80989E18.
+ * placeholders, and the actual value gets grabbed from sRacetrackDogInfo in EnDg_TryPickUp.
*/
static RacetrackDogInfo sSelectedRacetrackDogInfo = { DOG_COLOR_DEFAULT, -1, 0x353E };
@@ -141,6 +164,26 @@ static DamageTable sDamageTable = {
/* Powder Keg */ DMG_ENTRY(0, 0x0),
};
+typedef enum {
+ /* 0 */ DOG_ANIMATION_WALK_AFTER_TALKING,
+ /* 1 */ DOG_ANIMATION_WALK,
+ /* 2 */ DOG_ANIMATION_RUN,
+ /* 3 */ DOG_ANIMATION_BARK,
+ /* 4 */ DOG_ANIMATION_SIT_DOWN_ONCE, // unused
+ /* 5 */ DOG_ANIMATION_SIT_DOWN,
+ /* 6 */ DOG_ANIMATION_LYING_DOWN_START_1, // unused
+ /* 7 */ DOG_ANIMATION_LYING_DOWN_LOOP, // unused
+ /* 8 */ DOG_ANIMATION_LYING_DOWN_START_2, // unused
+ /* 9 */ DOG_ANIMATION_LYING_DOWN_START_3, // unused
+ /* 10 */ DOG_ANIMATION_LYING_DOWN_START_4, // unused
+ /* 11 */ DOG_ANIMATION_WALK_BACKWARDS,
+ /* 12 */ DOG_ANIMATION_JUMP,
+ /* 13 */ DOG_ANIMATION_LONG_JUMP, // unused
+ /* 14 */ DOG_ANIMATION_JUMP_ATTACK,
+ /* 15 */ DOG_ANIMATION_SWIM,
+ /* 16 */ DOG_ANIMATION_MAX
+} DogAnimationIndex;
+
static AnimationInfoS sAnimations[] = {
{ &gDogWalkAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, { &gDogWalkAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -6 },
{ &gDogRunAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, { &gDogBarkAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -6 },
@@ -149,41 +192,44 @@ static AnimationInfoS sAnimations[] = {
{ &gDogLyingDownAnim, 1.0f, 0, 27, ANIMMODE_ONCE, -6 }, { &gDogLyingDownAnim, 1.0f, 28, -1, ANIMMODE_ONCE, -6 },
{ &gDogLyingDownAnim, 1.0f, 54, 54, ANIMMODE_ONCE, -6 }, { &gDogWalkAnim, -1.5f, -1, 0, ANIMMODE_LOOP, -6 },
{ &gDogJumpAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, { &gDogLongJumpAnim, 1.2f, 0, -1, ANIMMODE_ONCE, 0 },
- { &gDogJump2Anim, 1.2f, 0, -1, ANIMMODE_ONCE, 0 }, { &gDogWalkAnim, 0.5f, 0, -1, ANIMMODE_LOOP, 0 },
+ { &gDogJumpAttackAnim, 1.2f, 0, -1, ANIMMODE_ONCE, 0 }, { &gDogWalkAnim, 0.5f, 0, -1, ANIMMODE_LOOP, 0 },
};
static InitChainEntry sInitChain[] = {
ICHAIN_F32(uncullZoneForward, 1000, ICHAIN_STOP),
};
-void func_80989140(SkelAnime* skelAnime, AnimationInfoS arg1[], s32 arg2) {
+void EnDg_ChangeAnimation(SkelAnime* skelAnime, AnimationInfoS* animationInfo, s32 index) {
f32 frameCount;
- arg1 += arg2;
- if (arg1->frameCount < 0) {
- frameCount = Animation_GetLastFrame(arg1->animation);
+ animationInfo += index;
+ if (animationInfo->frameCount < 0) {
+ frameCount = Animation_GetLastFrame(animationInfo->animation);
} else {
- frameCount = arg1->frameCount;
+ frameCount = animationInfo->frameCount;
}
- Animation_Change(skelAnime, arg1->animation, arg1->playSpeed + (BREG(88) * 0.1f), arg1->startFrame, frameCount,
- arg1->mode, arg1->morphFrames);
+ Animation_Change(skelAnime, animationInfo->animation, animationInfo->playSpeed + (BREG(88) * 0.1f),
+ animationInfo->startFrame, frameCount, animationInfo->mode, animationInfo->morphFrames);
}
-void func_80989204(EnDg* this, PlayState* play) {
+void EnDg_UpdateCollision(EnDg* this, PlayState* play) {
Player* player = GET_PLAYER(play);
this->collider.dim.pos.x = this->actor.world.pos.x;
this->collider.dim.pos.y = this->actor.world.pos.y;
this->collider.dim.pos.z = this->actor.world.pos.z;
Collider_UpdateCylinder(&this->actor, &this->collider);
- if ((player->transformation == PLAYER_FORM_DEKU) && (this->actionFunc == func_8098AC34)) {
+
+ if ((player->transformation == PLAYER_FORM_DEKU) && (this->actionFunc == EnDg_JumpAttack)) {
CollisionCheck_SetAT(play, &play->colChkCtx, &this->collider.base);
} else {
Collider_ResetCylinderAT(play, &this->collider.base);
}
- if ((this->unk_290 != 1) && !(this->unk_280 & 2)) {
+ // The check for DOG_FLAG_JUMP_ATTACKING here makes it so the dog passes through the
+ // player if it hits them with their jump attack.
+ if ((this->grabState != DOG_GRAB_STATE_HELD) && !(this->dogFlags & DOG_FLAG_JUMP_ATTACKING)) {
CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base);
} else {
Collider_ResetCylinderOC(play, &this->collider.base);
@@ -192,63 +238,67 @@ void func_80989204(EnDg* this, PlayState* play) {
Actor_UpdateBgCheckInfo(play, &this->actor, 26.0f, 10.0f, 0.0f, 5);
}
-void func_8098933C(EnDg* this, Vec3f* arg1) {
- f32 sp24;
- f32 sp20;
- f32 sp1C;
+void EnDg_GetFloorRot(EnDg* this, Vec3f* floorRot) {
+ f32 nx;
+ f32 ny;
+ f32 nz;
if (this->actor.floorPoly != NULL) {
- sp24 = COLPOLY_GET_NORMAL(this->actor.floorPoly->normal.x);
- sp20 = COLPOLY_GET_NORMAL(this->actor.floorPoly->normal.y);
- sp1C = COLPOLY_GET_NORMAL(this->actor.floorPoly->normal.z);
+ nx = COLPOLY_GET_NORMAL(this->actor.floorPoly->normal.x);
+ ny = COLPOLY_GET_NORMAL(this->actor.floorPoly->normal.y);
+ nz = COLPOLY_GET_NORMAL(this->actor.floorPoly->normal.z);
sinf(0.0f);
cosf(0.0f);
- arg1->x = -Math_Acot2F(1.0f, -sp1C * sp20);
- arg1->z = Math_Acot2F(1.0f, -sp24 * sp20);
+ floorRot->x = -Math_Acot2F(1.0f, -nz * ny);
+ floorRot->z = Math_Acot2F(1.0f, -nx * ny);
}
}
-s32 func_80989418(EnDg* this, Path* arg1, s32 arg2) {
- Vec3s* sp5C = Lib_SegmentedToVirtual(arg1->points);
- s32 count = arg1->count;
- s32 idx = arg2;
- s32 sp50 = false;
- f32 phi_f12;
- f32 phi_f14;
- f32 sp44;
- f32 sp40;
- f32 sp3C;
- Vec3f sp30;
+s32 EnDg_HasReachedPoint(EnDg* this, Path* path, s32 pointIndex) {
+ Vec3s* points = Lib_SegmentedToVirtual(path->points);
+ s32 pathCount = path->count;
+ s32 currentPoint = pointIndex;
+ s32 reached = false;
+ f32 diffX;
+ f32 diffZ;
+ f32 px;
+ f32 pz;
+ f32 d;
+ Vec3f point;
- Math_Vec3s_ToVec3f(&sp30, &sp5C[idx]);
- if (idx == 0) {
- phi_f12 = sp5C[1].x - sp5C[0].x;
- phi_f14 = sp5C[1].z - sp5C[0].z;
- } else if (idx == count - 1) {
- phi_f12 = sp5C[count - 1].x - sp5C[count - 2].x;
- phi_f14 = sp5C[count - 1].z - sp5C[count - 2].z;
+ Math_Vec3s_ToVec3f(&point, &points[currentPoint]);
+ if (currentPoint == 0) {
+ diffX = points[1].x - points[0].x;
+ diffZ = points[1].z - points[0].z;
+ } else if (currentPoint == pathCount - 1) {
+ diffX = points[pathCount - 1].x - points[pathCount - 2].x;
+ diffZ = points[pathCount - 1].z - points[pathCount - 2].z;
} else {
- phi_f12 = sp5C[idx + 1].x - sp5C[idx - 1].x;
- phi_f14 = sp5C[idx + 1].z - sp5C[idx - 1].z;
+ diffX = points[currentPoint + 1].x - points[currentPoint - 1].x;
+ diffZ = points[currentPoint + 1].z - points[currentPoint - 1].z;
}
- func_8017B7F8(&sp30, RADF_TO_BINANG(func_80086B30(phi_f12, phi_f14)), &sp44, &sp40, &sp3C);
- if (((this->actor.world.pos.x * sp44) + (sp40 * this->actor.world.pos.z) + sp3C) > 0.0f) {
- sp50 = true;
+ func_8017B7F8(&point, RADF_TO_BINANG(func_80086B30(diffX, diffZ)), &px, &pz, &d);
+
+ if (((this->actor.world.pos.x * px) + (pz * this->actor.world.pos.z) + d) > 0.0f) {
+ reached = true;
}
- return sp50;
+ return reached;
}
-s16 func_809895B4(Path* path, s32 idx, Vec3f* pos, f32* distSQ) {
+/**
+ * Returns the Y-rotation the dog should have to move to the next point along its path.
+ */
+s16 EnDg_GetYRotation(Path* path, s32 index, Vec3f* pos, f32* distSq) {
Vec3s* points;
f32 diffX;
f32 diffZ;
if (path != NULL) {
points = Lib_SegmentedToVirtual(path->points);
- points = &points[idx];
+ points = &points[index];
diffX = points->x - pos->x;
diffZ = points->z - pos->z;
} else {
@@ -256,34 +306,38 @@ s16 func_809895B4(Path* path, s32 idx, Vec3f* pos, f32* distSQ) {
diffZ = 0.0f;
}
- *distSQ = SQ(diffX) + SQ(diffZ);
+ *distSq = SQ(diffX) + SQ(diffZ);
return RADF_TO_BINANG(Math_Acot2F(diffZ, diffX));
}
-void func_80989674(EnDg* this, PlayState* play) {
- s16 phi_a1;
- f32 sp30;
+/**
+ * Updates the dog's Y-rotation and speed so that it moves along its path.
+ */
+void EnDg_MoveAlongPath(EnDg* this, PlayState* play) {
+ s16 yRotation;
+ f32 distSq;
if (this->path != NULL) {
- phi_a1 = func_809895B4(this->path, this->unk_1E0, &this->actor.world.pos, &sp30);
+ yRotation = EnDg_GetYRotation(this->path, this->currentPoint, &this->actor.world.pos, &distSq);
if (this->actor.bgCheckFlags & 8) {
- phi_a1 = this->actor.wallYaw;
+ yRotation = this->actor.wallYaw;
}
- Math_SmoothStepToS(&this->actor.world.rot.y, phi_a1, 4, 0x3E8, 1);
+ Math_SmoothStepToS(&this->actor.world.rot.y, yRotation, 4, 0x3E8, 1);
this->actor.shape.rot.y = this->actor.world.rot.y;
- if (func_80989418(this, this->path, this->unk_1E0)) {
- if (this->unk_1E0 >= (this->path->count - 1)) {
- this->unk_1E0 = 0;
+ if (EnDg_HasReachedPoint(this, this->path, this->currentPoint)) {
+ if (this->currentPoint >= (this->path->count - 1)) {
+ this->currentPoint = 0;
} else {
- this->unk_1E0++;
+ this->currentPoint++;
}
}
- if ((this->index == 21) || ((this->index == 20) && (play->sceneNum == SCENE_OMOYA))) {
+ if ((this->index == ENDG_INDEX_SWAMP_SPIDER_HOUSE) ||
+ ((this->index == ENDG_INDEX_ROMANI_RANCH) && (play->sceneNum == SCENE_OMOYA))) {
Math_ApproachF(&this->actor.speedXZ, 1.0f, 0.2f, 1.0f);
- } else if (this->index == 20) {
+ } else if (this->index == ENDG_INDEX_ROMANI_RANCH) {
Math_ApproachF(&this->actor.speedXZ, 3.5f, 0.2f, 1.0f);
} else if (play->sceneNum == SCENE_CLOCKTOWER) {
Math_ApproachF(&this->actor.speedXZ, 3.5f, 0.2f, 1.0f);
@@ -297,197 +351,232 @@ void func_80989674(EnDg* this, PlayState* play) {
}
}
-void func_80989864(EnDg* this, PlayState* play) {
- s16 frame = this->skelAnime.curFrame;
+void EnDg_SpawnFloorDustRing(EnDg* this, PlayState* play) {
+ s16 curFrame = this->skelAnime.curFrame;
s16 mod = (this->actor.speedXZ > 6.0f) ? 2 : 3;
- Vec3f sp38;
+ Vec3f pos;
- if (((this->index + frame) % mod) == 0) {
- sp38.x = randPlusMinusPoint5Scaled(15.0f) + this->actor.world.pos.x;
- sp38.y = this->actor.world.pos.y;
- sp38.z = randPlusMinusPoint5Scaled(15.0f) + this->actor.world.pos.z;
- Actor_SpawnFloorDustRing(play, &this->actor, &sp38, 10.0f, 0, 2.0f, 300, 0, 1);
+ if (((this->index + curFrame) % mod) == 0) {
+ pos.x = randPlusMinusPoint5Scaled(15.0f) + this->actor.world.pos.x;
+ pos.y = this->actor.world.pos.y;
+ pos.z = randPlusMinusPoint5Scaled(15.0f) + this->actor.world.pos.z;
+ Actor_SpawnFloorDustRing(play, &this->actor, &pos, 10.0f, 0, 2.0f, 300, 0, true);
}
}
-void func_80989974(EnDg* this) {
+void EnDg_PlaySfxWalk(EnDg* this) {
if (Animation_OnFrame(&this->skelAnime, 1.0f) || Animation_OnFrame(&this->skelAnime, 7.0f)) {
Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_MONKEY_WALK);
}
}
-void func_809899C8(EnDg* this, f32 arg1) {
- if (Animation_OnFrame(&this->skelAnime, arg1)) {
+void EnDg_PlaySfxBark(EnDg* this, f32 frame) {
+ if (Animation_OnFrame(&this->skelAnime, frame)) {
Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_SMALL_DOG_BARK);
}
}
-void func_80989A08(EnDg* this, f32 arg1) {
- if (Animation_OnFrame(&this->skelAnime, arg1)) {
+void EnDg_PlaySfxAngryBark(EnDg* this, f32 frame) {
+ if (Animation_OnFrame(&this->skelAnime, frame)) {
Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_SMALL_DOG_ANG_BARK);
}
}
-void func_80989A48(EnDg* this) {
+void EnDg_PlaySfxWhine(EnDg* this) {
if (Animation_OnFrame(&this->skelAnime, 23.0f) || Animation_OnFrame(&this->skelAnime, 28.0f)) {
Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_SMALL_DOG_WHINE);
}
}
-void func_80989A9C(EnDg* this, f32 arg1) {
- if (Animation_OnFrame(&this->skelAnime, arg1)) {
+void EnDg_PlaySfxGrowl(EnDg* this, f32 frame) {
+ if (Animation_OnFrame(&this->skelAnime, frame)) {
Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_SMALL_DOG_GROAN);
}
}
-void func_80989ADC(EnDg* this, PlayState* play) {
+void EnDg_SetupIdleMove(EnDg* this, PlayState* play) {
if (!(this->actor.bgCheckFlags & 0x20)) {
- if ((this->index == 21) || ((this->index == 20) && (play->sceneNum == SCENE_OMOYA))) {
- func_80989140(&this->skelAnime, sAnimations, 1);
- } else if (this->index == 20) {
- func_80989140(&this->skelAnime, sAnimations, 2);
+ if ((this->index == ENDG_INDEX_SWAMP_SPIDER_HOUSE) ||
+ ((this->index == ENDG_INDEX_ROMANI_RANCH) && (play->sceneNum == SCENE_OMOYA))) {
+ EnDg_ChangeAnimation(&this->skelAnime, sAnimations, DOG_ANIMATION_WALK);
+ } else if (this->index == ENDG_INDEX_ROMANI_RANCH) {
+ EnDg_ChangeAnimation(&this->skelAnime, sAnimations, DOG_ANIMATION_RUN);
} else if (play->sceneNum == SCENE_CLOCKTOWER) {
- func_80989140(&this->skelAnime, sAnimations, 2);
+ EnDg_ChangeAnimation(&this->skelAnime, sAnimations, DOG_ANIMATION_RUN);
} else if (sRacetrackDogInfo[this->index].textId & 0x11) {
- func_80989140(&this->skelAnime, sAnimations, 1);
+ EnDg_ChangeAnimation(&this->skelAnime, sAnimations, DOG_ANIMATION_WALK);
} else {
- func_80989140(&this->skelAnime, sAnimations, 2);
+ EnDg_ChangeAnimation(&this->skelAnime, sAnimations, DOG_ANIMATION_RUN);
}
- this->actionFunc = func_8098A468;
+
+ this->actionFunc = EnDg_IdleMove;
}
}
-void func_80989BF8(EnDg* this) {
+/**
+ * Updates the text ID in sRacetrackDogInfo based on what was set in the weekEventRegs by
+ * En_Aob_01. This makes it sp the proper message can be displayed when the player picks up
+ * the dog with the Mask of Truth equipped.
+ */
+void EnDg_UpdateTextId(EnDg* this) {
if (this->index < 14) {
+ // Assuming that the weekEventRegs haven't been tampered with, then this will produce a text ID in
+ // the range of 0x3538 to 0x3545.
if (this->index % 2) {
sRacetrackDogInfo[this->index].textId =
- 0x3538 + ((gSaveContext.save.weekEventReg[42 + (this->index / 2)] & (0x10 | 0x20 | 0x40 | 0x80)) >> 4);
+ 0x3538 + ((gSaveContext.save.weekEventReg[42 + (this->index / 2)] & 0xF0) >> 4);
} else {
sRacetrackDogInfo[this->index].textId =
- 0x3538 + (gSaveContext.save.weekEventReg[42 + (this->index / 2)] & (1 | 2 | 4 | 8));
+ 0x3538 + (gSaveContext.save.weekEventReg[42 + (this->index / 2)] & 0x0F);
}
} else {
Actor_MarkForDeath(&this->actor);
}
- if ((sRacetrackDogInfo[this->index].textId >= 0x3547) || (sRacetrackDogInfo[this->index].textId < 0x3538)) {
+ // As a sanity check, this makes sure the text ID is something in the expected range of 0x3538 to 0x3546.
+ if ((sRacetrackDogInfo[this->index].textId > 0x3546) || (sRacetrackDogInfo[this->index].textId < 0x3538)) {
sRacetrackDogInfo[this->index].textId = 0x353E;
}
+ // Text ID 0x353D is the text for the Romani Ranch dog, which is in the middle of the race dog block. If
+ // the dog ends up with this text ID, adjust it so the dog says a different message indcating it's in
+ // good condition.
if (sRacetrackDogInfo[this->index].textId == 0x353D) {
sRacetrackDogInfo[this->index].textId = 0x3538;
}
}
-void func_80989D38(EnDg* this, PlayState* play) {
- if (this->index == 21) {
+void EnDg_StartTextBox(EnDg* this, PlayState* play) {
+ if (this->index == ENDG_INDEX_SWAMP_SPIDER_HOUSE) {
if (CURRENT_DAY == 1) {
+ // Stupid master...
Message_StartTextbox(play, 0x91C, NULL);
} else {
+ // I miss the ranch...
Message_StartTextbox(play, 0x91E, NULL);
}
- } else if ((this->index >= 0) && (this->index < 14)) {
+ } else if ((this->index >= ENDG_INDEX_RACETRACK_0) && (this->index <= ENDG_INDEX_RACETRACK_13)) {
Message_StartTextbox(play, sRacetrackDogInfo[this->index].textId, NULL);
- } else if (this->index == 20) {
+ } else if (this->index == ENDG_INDEX_ROMANI_RANCH) {
+ // I wonder if I can stop practicing...
Message_StartTextbox(play, 0x353D, NULL);
} else {
+ // Where did that Deku Scrub go?
Message_StartTextbox(play, 0x627, NULL);
}
}
-void func_80989E18(EnDg* this, PlayState* play) {
- RacetrackDogInfo* temp;
-
- if ((D_8098C2A0 != 0) && !(this->unk_280 & 1)) {
+/**
+ * Checks to see if the player picked up the dog and sets the appropriate state if they did.
+ */
+void EnDg_TryPickUp(EnDg* this, PlayState* play) {
+ if (sIsAnyDogHeld && !(this->dogFlags & DOG_FLAG_HELD)) {
this->actor.flags |= ACTOR_FLAG_8000000;
- this->unk_280 |= 1;
- } else if ((D_8098C2A0 == 0) && (this->unk_280 & 1)) {
+ this->dogFlags |= DOG_FLAG_HELD;
+ } else if (!sIsAnyDogHeld && (this->dogFlags & DOG_FLAG_HELD)) {
this->actor.flags &= ~ACTOR_FLAG_8000000;
- this->unk_280 &= ~1;
+ this->dogFlags &= ~DOG_FLAG_HELD;
}
if (Actor_HasParent(&this->actor, play)) {
Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_SMALL_DOG_BARK);
- this->unk_290 = 1;
+ this->grabState = DOG_GRAB_STATE_HELD;
sSelectedRacetrackDogInfo = sRacetrackDogInfo[this->index];
- if (D_8098C2A0 == 0) {
+ if (!sIsAnyDogHeld) {
this->actor.flags |= ACTOR_FLAG_8000000;
- D_8098C2A0 = 1;
- this->unk_280 |= 1;
+ sIsAnyDogHeld = true;
+ this->dogFlags |= DOG_FLAG_HELD;
}
- func_80989140(&this->skelAnime, sAnimations, 5);
+ EnDg_ChangeAnimation(&this->skelAnime, sAnimations, DOG_ANIMATION_SIT_DOWN);
this->actor.flags &= ~ACTOR_FLAG_1;
this->actor.speedXZ = 0.0f;
if (Player_GetMask(play) == PLAYER_MASK_TRUTH) {
this->actor.flags |= ACTOR_FLAG_10000;
func_800B8614(&this->actor, play, 100.0f);
- this->actionFunc = func_8098BBEC;
+ this->actionFunc = EnDg_SetupTalk;
} else {
- this->actionFunc = func_8098BA64;
+ this->actionFunc = EnDg_Held;
}
} else {
Actor_LiftActor(&this->actor, play);
}
}
-s32 func_80989FC8(PlayState* play) {
- EnDg* enemy = (EnDg*)play->actorCtx.actorLists[ACTORCAT_ENEMY].first;
+/**
+ * Returns true if it finds a dog to follow the player around while they're marching with
+ * the Bremen Mask. The index of the dog it finds is stored in sBremenMaskFollowerIndex.
+ */
+s32 EnDg_FindFollowerForBremenMask(PlayState* play) {
+ Actor* enemy = play->actorCtx.actorLists[ACTORCAT_ENEMY].first;
f32 minDist = 9999.0f;
f32 dist;
while (enemy != NULL) {
- if (enemy->actor.id == ACTOR_EN_DG) {
- if (enemy->actor.isTargeted) {
- D_8098C2A4.unk_00 = enemy->index;
+ if (enemy->id == ACTOR_EN_DG) {
+ if (enemy->isTargeted) {
+ sBremenMaskFollowerIndex = ((EnDg*)enemy)->index;
return true;
}
- dist = enemy->actor.xzDistToPlayer;
+ dist = enemy->xzDistToPlayer;
if (dist < minDist) {
- D_8098C2A4.unk_00 = enemy->index;
+ sBremenMaskFollowerIndex = ((EnDg*)enemy)->index;
minDist = dist;
}
}
- enemy = (EnDg*)enemy->actor.next;
+
+ enemy = enemy->next;
}
- if (D_8098C2A4.unk_00 != 99) {
+ if (sBremenMaskFollowerIndex != ENDG_INDEX_NO_BREMEN_MASK_FOLLOWER) {
return true;
}
return false;
}
-void func_8098A064(EnDg* this, PlayState* play) {
+/**
+ * This checks for two conditions:
+ * - If the player has started marching with the Bremen Mask, then it makes the dog
+ * start following the player around (assuming it's the best candidate found in
+ * EnDg_FindFollowerForBremenMask above).
+ * - If the player has stopped marching with the Bremen Mask, and this dog was
+ * following them around, then it returns the dog to its idle state.
+ */
+void EnDg_CheckForBremenMaskMarch(EnDg* this, PlayState* play) {
Player* player = GET_PLAYER(play);
- if (player->stateFlags3 & 0x20000000) {
- if (D_8098C2A4.unk_00 == 99) {
- func_80989FC8(play);
+ if (player->stateFlags3 & 0x20000000) { // bremen mask march
+ if (sBremenMaskFollowerIndex == ENDG_INDEX_NO_BREMEN_MASK_FOLLOWER) {
+ EnDg_FindFollowerForBremenMask(play);
}
- if (this->index == D_8098C2A4.unk_00) {
- if (!(this->unk_280 & 0x20)) {
- this->unk_280 |= 0x20;
- func_80989140(&this->skelAnime, sAnimations, 1);
- this->actionFunc = func_8098AF44;
- } else if ((this->actionFunc == func_8098B004) || (this->actionFunc == func_8098AB48)) {
- if (DECR(this->unk_292) == 0) {
- this->unk_292 = 10;
+ if (this->index == sBremenMaskFollowerIndex) {
+ if (!(this->dogFlags & DOG_FLAG_FOLLOWING_BREMEN_MASK)) {
+ this->dogFlags |= DOG_FLAG_FOLLOWING_BREMEN_MASK;
+ EnDg_ChangeAnimation(&this->skelAnime, sAnimations, DOG_ANIMATION_WALK);
+ this->actionFunc = EnDg_SetupBremenMaskApproachPlayer;
+ } else if ((this->actionFunc == EnDg_ApproachPlayer) || (this->actionFunc == EnDg_SitNextToPlayer)) {
+ if (DECR(this->bremenBarkTimer) == 0) {
+ this->bremenBarkTimer = 10;
Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_SMALL_DOG_BARK);
}
}
}
- } else if (this->index == D_8098C2A4.unk_00) {
- this->unk_280 &= ~0x20;
- D_8098C2A4.unk_00 = 99;
- func_80989ADC(this, play);
- this->actionFunc = func_8098A468;
+ } else if (this->index == sBremenMaskFollowerIndex) {
+ this->dogFlags &= ~DOG_FLAG_FOLLOWING_BREMEN_MASK;
+ sBremenMaskFollowerIndex = ENDG_INDEX_NO_BREMEN_MASK_FOLLOWER;
+ EnDg_SetupIdleMove(this, play);
+ this->actionFunc = EnDg_IdleMove;
}
}
-s32 func_8098A1B4(EnDg* this, PlayState* play) {
+/**
+ * Returns true if the player is not human and the dog is close enough to start
+ * reacting to their current form.
+ */
+s32 EnDg_ShouldReactToNonHumanPlayer(EnDg* this, PlayState* play) {
Player* player = GET_PLAYER(play);
switch (player->transformation) {
@@ -496,7 +585,7 @@ s32 func_8098A1B4(EnDg* this, PlayState* play) {
if (this->actor.xzDistToPlayer < 300.0f) {
return true;
}
-
+ // fallthrough
case PLAYER_FORM_DEKU:
if (this->actor.xzDistToPlayer < 250.0f) {
return true;
@@ -507,144 +596,167 @@ s32 func_8098A1B4(EnDg* this, PlayState* play) {
return false;
}
-void func_8098A234(EnDg* this, PlayState* play) {
+/**
+ * Sets the appropriate actionFunc given the player's current form and the dog's current behavior.
+ * Specifically, it makes sure that the dog doesn't start reacting to the player's form until the
+ * player starts moving a bit. This was presumably done so the player could more easily react to
+ * the dog changing its behavior; it would be strange if the dog attacked the player the instant
+ * they put on the Deku Mask, for example.
+ */
+void EnDg_ChooseActionForForm(EnDg* this, PlayState* play) {
Player* player = GET_PLAYER(play);
if (!(this->actor.bgCheckFlags & 0x20)) {
switch (player->transformation) {
case PLAYER_FORM_HUMAN:
- if (this->unk_28C != 1) {
- this->unk_28C = 1;
- this->unk_280 &= ~2;
- func_80989ADC(this, play);
+ if (this->behavior != DOG_BEHAVIOR_HUMAN) {
+ this->behavior = DOG_BEHAVIOR_HUMAN;
+ this->dogFlags &= ~DOG_FLAG_JUMP_ATTACKING;
+ EnDg_SetupIdleMove(this, play);
}
break;
case PLAYER_FORM_ZORA:
- this->unk_280 &= ~2;
- if ((this->unk_28C != 4) && (player->actor.speedXZ > 1.0f)) {
- this->unk_28C = 4;
- func_80989140(&this->skelAnime, sAnimations, 2);
- this->actionFunc = func_8098B004;
+ this->dogFlags &= ~DOG_FLAG_JUMP_ATTACKING;
+ if ((this->behavior != DOG_BEHAVIOR_ZORA) && (player->actor.speedXZ > 1.0f)) {
+ this->behavior = DOG_BEHAVIOR_ZORA;
+ EnDg_ChangeAnimation(&this->skelAnime, sAnimations, DOG_ANIMATION_RUN);
+ this->actionFunc = EnDg_ApproachPlayer;
}
- if ((this->unk_28C != 5) && (this->unk_28C != 4)) {
- this->unk_28C = 5;
- func_80989ADC(this, play);
+ if ((this->behavior != DOG_BEHAVIOR_ZORA_WAIT) && (this->behavior != DOG_BEHAVIOR_ZORA)) {
+ this->behavior = DOG_BEHAVIOR_ZORA_WAIT;
+ EnDg_SetupIdleMove(this, play);
}
break;
case PLAYER_FORM_GORON:
- this->unk_280 &= ~2;
- if ((this->unk_28C != 2) && (player->actor.speedXZ > 1.0f)) {
- this->unk_28C = 2;
- func_80989140(&this->skelAnime, sAnimations, 11);
- this->unk_282 = 50;
- this->actionFunc = func_8098A618;
+ this->dogFlags &= ~DOG_FLAG_JUMP_ATTACKING;
+ if ((this->behavior != DOG_BEHAVIOR_GORON) && (player->actor.speedXZ > 1.0f)) {
+ this->behavior = DOG_BEHAVIOR_GORON;
+ EnDg_ChangeAnimation(&this->skelAnime, sAnimations, DOG_ANIMATION_WALK_BACKWARDS);
+ this->timer = 50;
+ this->actionFunc = EnDg_BackAwayFromGoron;
}
- if ((this->unk_28C != 3) && (this->unk_28C != 2)) {
- this->unk_28C = 3;
- func_80989ADC(this, play);
+ if ((this->behavior != DOG_BEHAVIOR_GORON_WAIT) && (this->behavior != DOG_BEHAVIOR_GORON)) {
+ this->behavior = DOG_BEHAVIOR_GORON_WAIT;
+ EnDg_SetupIdleMove(this, play);
}
break;
case PLAYER_FORM_DEKU:
- this->unk_280 &= ~2;
- if ((this->unk_28C != 6) && (player->actor.speedXZ > 1.0f)) {
- this->unk_28C = 6;
- func_80989140(&this->skelAnime, sAnimations, 2);
- this->actionFunc = func_8098A938;
+ this->dogFlags &= ~DOG_FLAG_JUMP_ATTACKING;
+ if ((this->behavior != DOG_BEHAVIOR_DEKU) && (player->actor.speedXZ > 1.0f)) {
+ this->behavior = DOG_BEHAVIOR_DEKU;
+ EnDg_ChangeAnimation(&this->skelAnime, sAnimations, DOG_ANIMATION_RUN);
+ this->actionFunc = EnDg_ApproachPlayerToAttack;
}
- if ((this->unk_28C != 7) && (this->unk_28C != 6)) {
- this->unk_28C = 7;
- func_80989ADC(this, play);
+ if ((this->behavior != DOG_BEHAVIOR_DEKU_WAIT) && (this->behavior != DOG_BEHAVIOR_DEKU)) {
+ this->behavior = DOG_BEHAVIOR_DEKU_WAIT;
+ EnDg_SetupIdleMove(this, play);
}
break;
}
}
}
-void func_8098A468(EnDg* this, PlayState* play) {
+/**
+ * Moves the dog along its path, stopping to bark at random intervals.
+ */
+void EnDg_IdleMove(EnDg* this, PlayState* play) {
Player* player = GET_PLAYER(play);
this->actor.velocity.y = 0.0f;
this->actor.gravity = -3.0f;
- func_80989674(this, play);
+ EnDg_MoveAlongPath(this, play);
Actor_MoveWithGravity(&this->actor);
if (player->transformation == PLAYER_FORM_HUMAN) {
- func_80989E18(this, play);
+ EnDg_TryPickUp(this, play);
}
- func_8098A064(this, play);
- func_80989974(this);
+ EnDg_CheckForBremenMaskMarch(this, play);
+ EnDg_PlaySfxWalk(this);
if (!(this->actor.bgCheckFlags & 1)) {
- this->actionFunc = func_8098AF98;
+ this->actionFunc = EnDg_Fall;
}
- if (DECR(this->unk_282) == 0) {
- this->unk_282 = Rand_S16Offset(20, 20);
- func_80989140(&this->skelAnime, sAnimations, 3);
- this->actionFunc = func_8098A55C;
+ if (DECR(this->timer) == 0) {
+ this->timer = Rand_S16Offset(20, 20);
+ EnDg_ChangeAnimation(&this->skelAnime, sAnimations, DOG_ANIMATION_BARK);
+ this->actionFunc = EnDg_IdleBark;
}
}
-void func_8098A55C(EnDg* this, PlayState* play) {
+/**
+ * Stops and barks, before returning to moving along its path.
+ */
+void EnDg_IdleBark(EnDg* this, PlayState* play) {
Player* player = GET_PLAYER(play);
if (player->transformation == PLAYER_FORM_HUMAN) {
- func_80989E18(this, play);
+ EnDg_TryPickUp(this, play);
}
- func_809899C8(this, 13.0f);
- func_809899C8(this, 19.0f);
+ EnDg_PlaySfxBark(this, 13.0f);
+ EnDg_PlaySfxBark(this, 19.0f);
+
if (!(this->actor.bgCheckFlags & 1)) {
- this->actionFunc = func_8098AF98;
+ this->actionFunc = EnDg_Fall;
}
- if (DECR(this->unk_282) == 0) {
- this->unk_282 = Rand_S16Offset(60, 60);
- func_80989ADC(this, play);
+ if (DECR(this->timer) == 0) {
+ this->timer = Rand_S16Offset(60, 60);
+ EnDg_SetupIdleMove(this, play);
}
}
-void func_8098A618(EnDg* this, PlayState* play) {
+/**
+ * Slowly back away from the player while growling. After a short time backing away,
+ * this function will make the dog away from the player.
+ */
+void EnDg_BackAwayFromGoron(EnDg* this, PlayState* play) {
this->actor.velocity.y = 0.0f;
this->actor.gravity = -3.0f;
- if (DECR(this->unk_282) == 0) {
- this->unk_282 = 50;
- func_80989140(&this->skelAnime, sAnimations, 2);
- this->actionFunc = func_8098A70C;
+ if (DECR(this->timer) == 0) {
+ this->timer = 50;
+ EnDg_ChangeAnimation(&this->skelAnime, sAnimations, DOG_ANIMATION_RUN);
+ this->actionFunc = EnDg_RunAwayFromGoron;
} else {
Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 4, 0x3E8, 1);
if (this->actor.bgCheckFlags & 8) {
this->actor.shape.rot.y = this->actor.wallYaw;
}
+
this->actor.world.rot.y = this->actor.shape.rot.y;
Math_ApproachF(&this->actor.speedXZ, -1.5f, 0.2f, 1.0f);
Actor_MoveWithGravity(&this->actor);
}
- func_80989974(this);
- func_80989A9C(this, 0);
+ EnDg_PlaySfxWalk(this);
+ EnDg_PlaySfxGrowl(this, 0);
}
-void func_8098A70C(EnDg* this, PlayState* play) {
+/**
+ * Quickly run away from the player. Once the dog is far enough from the player,
+ * this function will make them start barking at them.
+ */
+void EnDg_RunAwayFromGoron(EnDg* this, PlayState* play) {
Player* player = GET_PLAYER(play);
- s16 phi_a1;
+ s16 yRotation;
if (this->actor.xzDistToPlayer < 250.0f) {
Math_ApproachS(&this->actor.shape.rot.y, -this->actor.yawTowardsPlayer, 4, 0xC00);
if (this->actor.bgCheckFlags & 8) {
- phi_a1 = this->actor.wallYaw;
+ yRotation = this->actor.wallYaw;
} else {
- phi_a1 = 0;
+ yRotation = 0;
}
- Math_SmoothStepToS(&this->actor.world.rot.y, phi_a1, 4, 0x3E8, 1);
+ Math_SmoothStepToS(&this->actor.world.rot.y, yRotation, 4, 0x3E8, 1);
this->actor.world.rot.y = this->actor.shape.rot.y;
if (player->actor.speedXZ != 0.0f) {
Math_ApproachF(&this->actor.speedXZ, player->actor.speedXZ, 0.2f, 1.0f);
@@ -652,8 +764,8 @@ void func_8098A70C(EnDg* this, PlayState* play) {
Math_ApproachF(&this->actor.speedXZ, 3.5f, 0.2f, 1.0f);
}
} else {
- func_80989140(&this->skelAnime, sAnimations, 3);
- this->actionFunc = func_8098A89C;
+ EnDg_ChangeAnimation(&this->skelAnime, sAnimations, DOG_ANIMATION_BARK);
+ this->actionFunc = EnDg_BarkAtGoron;
}
if (this->actor.speedXZ > 7.0f) {
@@ -661,7 +773,8 @@ void func_8098A70C(EnDg* this, PlayState* play) {
}
Actor_MoveWithGravity(&this->actor);
- func_80989974(this);
+ EnDg_PlaySfxWalk(this);
+
if (Animation_OnFrame(&this->skelAnime, 3.0f)) {
Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_SMALL_DOG_CRY);
} else if (Animation_OnFrame(&this->skelAnime, 6.0f)) {
@@ -669,20 +782,23 @@ void func_8098A70C(EnDg* this, PlayState* play) {
}
}
-void func_8098A89C(EnDg* this, PlayState* play) {
+/**
+ * Bark at the player until they get close enough, at which point the dog starts backing away.
+ */
+void EnDg_BarkAtGoron(EnDg* this, PlayState* play) {
Math_ApproachS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 4, 0xC00);
this->actor.world.rot.y = this->actor.shape.rot.y;
if (this->actor.xzDistToPlayer < 250.0f) {
- func_80989140(&this->skelAnime, sAnimations, 11);
- this->unk_282 = 50;
- this->actionFunc = func_8098A618;
+ EnDg_ChangeAnimation(&this->skelAnime, sAnimations, DOG_ANIMATION_WALK_BACKWARDS);
+ this->timer = 50;
+ this->actionFunc = EnDg_BackAwayFromGoron;
}
- func_80989A08(this, 13.0f);
- func_80989A08(this, 19.0f);
+ EnDg_PlaySfxAngryBark(this, 13.0f);
+ EnDg_PlaySfxAngryBark(this, 19.0f);
}
-void func_8098A938(EnDg* this, PlayState* play) {
+void EnDg_ApproachPlayerToAttack(EnDg* this, PlayState* play) {
Player* player = GET_PLAYER(play);
this->actor.velocity.y = 0.0f;
@@ -695,16 +811,16 @@ void func_8098A938(EnDg* this, PlayState* play) {
if (this->actor.xzDistToPlayer < 70.0f) {
Math_ApproachZeroF(&this->actor.speedXZ, 0.2f, 1.0f);
if (Animation_OnFrame(&this->skelAnime, 7.0f)) {
- s16 y = ABS_ALT(player->actor.shape.rot.y - this->actor.shape.rot.y);
+ s16 yawDiff = ABS_ALT(player->actor.shape.rot.y - this->actor.shape.rot.y);
- this->unk_28E = 20;
- if (y < 0x4000) {
- func_80989140(&this->skelAnime, sAnimations, 14);
- this->actionFunc = func_8098AC34;
+ this->attackTimer = 20;
+ if (yawDiff < 0x4000) {
+ EnDg_ChangeAnimation(&this->skelAnime, sAnimations, DOG_ANIMATION_JUMP_ATTACK);
+ this->actionFunc = EnDg_JumpAttack;
} else {
- func_80989140(&this->skelAnime, sAnimations, 11);
- sAnimations[11].playSpeed = -1.0f;
- this->actionFunc = func_8098B198;
+ EnDg_ChangeAnimation(&this->skelAnime, sAnimations, DOG_ANIMATION_WALK_BACKWARDS);
+ sAnimations[DOG_ANIMATION_WALK_BACKWARDS].playSpeed = -1.0f;
+ this->actionFunc = EnDg_SlowlyBackUpBeforeAttacking;
}
}
} else {
@@ -713,102 +829,121 @@ void func_8098A938(EnDg* this, PlayState* play) {
}
Actor_MoveWithGravity(&this->actor);
- func_80989974(this);
- func_80989A08(this, 5.0f);
+ EnDg_PlaySfxWalk(this);
+ EnDg_PlaySfxAngryBark(this, 5.0f);
}
-void func_8098AAAC(EnDg* this, PlayState* play) {
- this->unk_280 &= ~8;
+/**
+ * Makes the dog run around for a bit after attacking before it
+ * starts to approach the player for another attack.
+ */
+void EnDg_RunAfterAttacking(EnDg* this, PlayState* play) {
+ this->dogFlags &= ~DOG_FLAG_BOUNCED;
Math_ApproachF(&this->actor.speedXZ, 3.5f, 0.1f, 0.5f);
Actor_MoveWithGravity(&this->actor);
- if (DECR(this->unk_28E) == 0) {
- this->unk_28E = 20;
- this->actionFunc = func_8098A938;
+ if (DECR(this->attackTimer) == 0) {
+ this->attackTimer = 20;
+ this->actionFunc = EnDg_ApproachPlayerToAttack;
}
- func_80989974(this);
- func_80989A08(this, 3.0f);
+ EnDg_PlaySfxWalk(this);
+ EnDg_PlaySfxAngryBark(this, 3.0f);
}
-void func_8098AB48(EnDg* this, PlayState* play) {
+/**
+ * Makes the dog sit next to the player until they get too far away, at which point
+ * it will attempt to approach them again.
+ */
+void EnDg_SitNextToPlayer(EnDg* this, PlayState* play) {
Player* player = GET_PLAYER(play);
if (!(this->actor.bgCheckFlags & 1)) {
- this->actionFunc = func_8098AF98;
+ this->actionFunc = EnDg_Fall;
}
if (this->actor.xzDistToPlayer < 50.0f) {
Math_ApproachS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 4, 0xC00);
this->actor.world.rot.y = this->actor.shape.rot.y;
} else {
- if (player->stateFlags3 & 0x20000000) {
- func_80989140(&this->skelAnime, sAnimations, 1);
+ if (player->stateFlags3 & 0x20000000) { // bremen mask march
+ EnDg_ChangeAnimation(&this->skelAnime, sAnimations, DOG_ANIMATION_WALK);
} else {
- func_80989140(&this->skelAnime, sAnimations, 2);
+ EnDg_ChangeAnimation(&this->skelAnime, sAnimations, DOG_ANIMATION_RUN);
}
- this->actionFunc = func_8098B004;
+
+ this->actionFunc = EnDg_ApproachPlayer;
}
- func_8098A064(this, play);
- if (!(this->unk_280 & 0x20)) {
- func_80989A48(this);
+ EnDg_CheckForBremenMaskMarch(this, play);
+
+ // If we're in this function, the player is either marching with the Bremen Mask, or
+ // they're a Zora. The below code will make the dog repeatedly whine in the latter case.
+ if (!(this->dogFlags & DOG_FLAG_FOLLOWING_BREMEN_MASK)) {
+ EnDg_PlaySfxWhine(this);
}
}
-void func_8098AC34(EnDg* this, PlayState* play) {
- s16 sp26 = this->skelAnime.curFrame;
+void EnDg_JumpAttack(EnDg* this, PlayState* play) {
+ s16 curFrame = this->skelAnime.curFrame;
if ((this->actor.xyzDistToPlayerSq < 800.0f) && (this->collider.base.atFlags & AT_BOUNCED)) {
- this->unk_28E = 60;
- this->unk_280 &= ~2;
- this->unk_280 |= 8;
+ this->attackTimer = 60;
+ this->dogFlags &= ~DOG_FLAG_JUMP_ATTACKING;
+ this->dogFlags |= DOG_FLAG_BOUNCED;
this->collider.base.atFlags &= ~AT_BOUNCED;
this->actor.speedXZ *= -1.0f;
- func_80989140(&this->skelAnime, sAnimations, 2);
- this->actionFunc = func_8098AAAC;
+ EnDg_ChangeAnimation(&this->skelAnime, sAnimations, DOG_ANIMATION_RUN);
+ this->actionFunc = EnDg_RunAfterAttacking;
return;
}
- if (DECR(this->unk_28E) == 0) {
- this->unk_28E = 60;
- this->unk_280 &= ~2;
- func_80989140(&this->skelAnime, sAnimations, 2);
- this->actionFunc = func_8098AAAC;
+ if (DECR(this->attackTimer) == 0) {
+ this->attackTimer = 60;
+ this->dogFlags &= ~DOG_FLAG_JUMP_ATTACKING;
+ EnDg_ChangeAnimation(&this->skelAnime, sAnimations, DOG_ANIMATION_RUN);
+ this->actionFunc = EnDg_RunAfterAttacking;
}
- if (sp26 < 9) {
+ if (curFrame < 9) {
if (Animation_OnFrame(&this->skelAnime, 0.0f)) {
- sAnimations[14].playSpeed = randPlusMinusPoint5Scaled(1.0f) + 3.0f;
+ sAnimations[DOG_ANIMATION_JUMP_ATTACK].playSpeed = randPlusMinusPoint5Scaled(1.0f) + 3.0f;
}
- func_80989864(this, play);
+
+ EnDg_SpawnFloorDustRing(this, play);
} else {
- this->unk_280 |= 2;
+ this->dogFlags |= DOG_FLAG_JUMP_ATTACKING;
if (Animation_OnFrame(&this->skelAnime, 9.0f)) {
f32 rand = randPlusMinusPoint5Scaled(1.5f);
- sAnimations[14].playSpeed = 1.2f;
+ sAnimations[DOG_ANIMATION_JUMP_ATTACK].playSpeed = 1.2f;
this->actor.velocity.y = 2.0f * rand + 3.0f;
this->actor.speedXZ = 8.0f + rand;
- } else if (sp26 >= 0x15) {
+ } else if (curFrame > 20) {
Math_ApproachF(&this->actor.speedXZ, 2.5f, 0.2f, 1.0f);
}
- if (sp26 >= 0x18) {
- func_80989864(this, play);
+
+ if (curFrame > 23) {
+ EnDg_SpawnFloorDustRing(this, play);
}
+
Actor_MoveWithGravity(&this->actor);
}
- func_80989A9C(this, 10.0f);
+ EnDg_PlaySfxGrowl(this, 10.0f);
}
-// Unused?
-void func_8098AE58(EnDg* this, PlayState* play) {
+/**
+ * An unused function that will make the dog walk slowly towards the player until they're
+ * in a specific range, at which point they will bark at them. This might be part of an
+ * unused or early variation of how dogs react to Goron Link.
+ */
+void EnDg_WalkToPlayer(EnDg* this, PlayState* play) {
if (this->actor.xzDistToPlayer < 150.0f) {
- func_80989140(&this->skelAnime, sAnimations, 11);
- this->actionFunc = func_8098B28C;
+ EnDg_ChangeAnimation(&this->skelAnime, sAnimations, DOG_ANIMATION_WALK_BACKWARDS);
+ this->actionFunc = EnDg_BackAwayFromPlayer;
} else if (this->actor.xzDistToPlayer < 200.0f) {
- func_80989140(&this->skelAnime, sAnimations, 3);
- this->actionFunc = func_8098B390;
+ EnDg_ChangeAnimation(&this->skelAnime, sAnimations, DOG_ANIMATION_BARK);
+ this->actionFunc = EnDg_BarkAtPlayer;
} else {
Math_ApproachS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 4, 0xC00);
this->actor.world.rot.y = this->actor.shape.rot.y;
@@ -816,29 +951,33 @@ void func_8098AE58(EnDg* this, PlayState* play) {
Actor_MoveWithGravity(&this->actor);
}
- func_80989974(this);
- func_809899C8(this, 5.0f);
+ EnDg_PlaySfxWalk(this);
+ EnDg_PlaySfxBark(this, 5.0f);
}
-void func_8098AF44(EnDg* this, PlayState* play) {
+void EnDg_SetupBremenMaskApproachPlayer(EnDg* this, PlayState* play) {
if (func_801A46F8() == 1) {
- this->unk_292 = 10;
+ this->bremenBarkTimer = 10;
Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_SMALL_DOG_BARK);
- this->actionFunc = func_8098B004;
+ this->actionFunc = EnDg_ApproachPlayer;
}
}
-void func_8098AF98(EnDg* this, PlayState* play) {
+void EnDg_Fall(EnDg* this, PlayState* play) {
if (this->actor.bgCheckFlags & 1) {
- func_80989140(&this->skelAnime, sAnimations, 2);
- this->actionFunc = func_8098A468;
+ EnDg_ChangeAnimation(&this->skelAnime, sAnimations, DOG_ANIMATION_RUN);
+ this->actionFunc = EnDg_IdleMove;
}
Actor_MoveWithGravity(&this->actor);
- func_809899C8(this, 3.0f);
+ EnDg_PlaySfxBark(this, 3.0f);
}
-void func_8098B004(EnDg* this, PlayState* play) {
+/**
+ * Approach the player non-aggressively. If the player stops moving, then
+ * eventually the dog will sit down next to them.
+ */
+void EnDg_ApproachPlayer(EnDg* this, PlayState* play) {
Player* player = GET_PLAYER(play);
this->actor.velocity.y = 0.0f;
@@ -851,9 +990,9 @@ void func_8098B004(EnDg* this, PlayState* play) {
this->actor.world.rot.y = this->actor.shape.rot.y;
if (this->actor.xzDistToPlayer < 40.0f) {
- func_80989140(&this->skelAnime, sAnimations, 5);
- this->actionFunc = func_8098AB48;
- } else if (player->stateFlags3 & 0x20000000) {
+ EnDg_ChangeAnimation(&this->skelAnime, sAnimations, DOG_ANIMATION_SIT_DOWN);
+ this->actionFunc = EnDg_SitNextToPlayer;
+ } else if (player->stateFlags3 & 0x20000000) { // bremen mask march
if ((this->actor.xzDistToPlayer > 40.0f) && (player->linearVelocity == 0.0f)) {
Math_ApproachF(&this->actor.speedXZ, 1.5f, 0.2f, 1.0f);
} else {
@@ -863,41 +1002,54 @@ void func_8098B004(EnDg* this, PlayState* play) {
Math_ApproachF(&this->actor.speedXZ, 3.5f, 0.2f, 1.0f);
}
- func_8098A064(this, play);
+ EnDg_CheckForBremenMaskMarch(this, play);
Actor_MoveWithGravity(&this->actor);
- func_80989974(this);
- if (!(this->unk_280 & 0x20)) {
- func_809899C8(this, 3.0f);
+ EnDg_PlaySfxWalk(this);
+
+ // If we're in this function, the player is either marching with the Bremen Mask, or
+ // they're a Zora. The below code will make the dog repeatedly bark in the latter case.
+ if (!(this->dogFlags & DOG_FLAG_FOLLOWING_BREMEN_MASK)) {
+ EnDg_PlaySfxBark(this, 3.0f);
}
}
-void func_8098B198(EnDg* this, PlayState* play) {
+/**
+ * Makes the dog slowly back up and face the player before performing a jump attack. Used to
+ * give the dog a bit of time to correct its angle if they were unlikely to hit the player.
+ */
+void EnDg_SlowlyBackUpBeforeAttacking(EnDg* this, PlayState* play) {
if (this->actor.xzDistToPlayer > 72.0f) {
- func_80989140(&this->skelAnime, sAnimations, 14);
- this->actionFunc = func_8098AC34;
+ EnDg_ChangeAnimation(&this->skelAnime, sAnimations, DOG_ANIMATION_JUMP_ATTACK);
+ this->actionFunc = EnDg_JumpAttack;
}
Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 4, 0x3E8, 1);
if (this->actor.bgCheckFlags & 8) {
this->actor.shape.rot.y = this->actor.wallYaw;
- func_80989140(&this->skelAnime, sAnimations, 14);
- this->actionFunc = func_8098AC34;
+ EnDg_ChangeAnimation(&this->skelAnime, sAnimations, DOG_ANIMATION_JUMP_ATTACK);
+ this->actionFunc = EnDg_JumpAttack;
}
this->actor.world.rot.y = this->actor.shape.rot.y;
Math_ApproachF(&this->actor.speedXZ, -1.0f, 0.2f, 1.0f);
Actor_MoveWithGravity(&this->actor);
- func_80989974(this);
- func_80989A9C(this, 4.0f);
+ EnDg_PlaySfxWalk(this);
+ EnDg_PlaySfxGrowl(this, 4.0f);
}
-void func_8098B28C(EnDg* this, PlayState* play) {
+/**
+ * An unused function that will make the dog back away from the player while growling.
+ * It is quite similar to EnDg_BackAwayFromGoron; perhaps this is an earlier version of it?
+ * Unlike that function, this will make the dog approach the player if they move too far away.
+ * It also lacks the behavior where the dog runs away in a panic after a short time.
+ */
+void EnDg_BackAwayFromPlayer(EnDg* this, PlayState* play) {
if (this->actor.xzDistToPlayer > 200.0f) {
- func_80989140(&this->skelAnime, sAnimations, 1);
- this->actionFunc = func_8098AE58;
+ EnDg_ChangeAnimation(&this->skelAnime, sAnimations, DOG_ANIMATION_WALK);
+ this->actionFunc = EnDg_WalkToPlayer;
} else if (this->actor.xzDistToPlayer > 150.0f) {
- func_80989140(&this->skelAnime, sAnimations, 3);
- this->actionFunc = func_8098B390;
+ EnDg_ChangeAnimation(&this->skelAnime, sAnimations, DOG_ANIMATION_BARK);
+ this->actionFunc = EnDg_BarkAtPlayer;
} else {
Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 4, 0x3E8, 1);
if (this->actor.bgCheckFlags & 8) {
@@ -909,69 +1061,86 @@ void func_8098B28C(EnDg* this, PlayState* play) {
Actor_MoveWithGravity(&this->actor);
}
- func_80989974(this);
+ EnDg_PlaySfxWalk(this);
Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_SMALL_DOG_GROAN);
}
-void func_8098B390(EnDg* this, PlayState* play) {
+/**
+ * An unused function that will make the dog bark at the player endlessly.
+ * It is quite similar to EnDg_BarkAtGoron; perhaps this is an earlier version of it?
+ * Unlike that function, this will make the dog approach the player if they move too far away.
+ * It also mixes in multiple growls into the bark.
+ */
+void EnDg_BarkAtPlayer(EnDg* this, PlayState* play) {
if (this->actor.xzDistToPlayer < 150.0f) {
- func_80989140(&this->skelAnime, sAnimations, 11);
- this->actionFunc = func_8098B28C;
+ EnDg_ChangeAnimation(&this->skelAnime, sAnimations, DOG_ANIMATION_WALK_BACKWARDS);
+ this->actionFunc = EnDg_BackAwayFromPlayer;
} else if (this->actor.xzDistToPlayer > 200.0f) {
- func_80989140(&this->skelAnime, sAnimations, 1);
- this->actionFunc = func_8098AE58;
+ EnDg_ChangeAnimation(&this->skelAnime, sAnimations, DOG_ANIMATION_WALK);
+ this->actionFunc = EnDg_WalkToPlayer;
}
- func_80989A9C(this, 0.0f);
- func_80989A9C(this, 1.0f);
- func_80989A9C(this, 2.0f);
- func_80989A9C(this, 3.0f);
- func_809899C8(this, 5.0f);
+ EnDg_PlaySfxGrowl(this, 0.0f);
+ EnDg_PlaySfxGrowl(this, 1.0f);
+ EnDg_PlaySfxGrowl(this, 2.0f);
+ EnDg_PlaySfxGrowl(this, 3.0f);
+ EnDg_PlaySfxBark(this, 5.0f);
}
-void func_8098B464(EnDg* this, PlayState* play) {
- Vec3f sp2C;
+/**
+ * Makes a splash effect and plays the splash sfx when the dog enters the water, then
+ * makes them start swimming.
+ */
+void EnDg_SetupSwim(EnDg* this, PlayState* play) {
+ Vec3f pos;
+
+ pos.x = this->actor.world.pos.x;
+ pos.y = this->actor.world.pos.y + this->actor.depthInWater;
+ pos.z = this->actor.world.pos.z + 20.0f;
+ EffectSsGSplash_Spawn(play, &pos, NULL, NULL, 0, 800);
+ EffectSsGRipple_Spawn(play, &pos, 100, 500, 30);
- sp2C.x = this->actor.world.pos.x;
- sp2C.y = this->actor.world.pos.y + this->actor.depthInWater;
- sp2C.z = this->actor.world.pos.z + 20.0f;
- EffectSsGSplash_Spawn(play, &sp2C, NULL, NULL, 0, 800);
- EffectSsGRipple_Spawn(play, &sp2C, 100, 500, 30);
if (this->actor.depthInWater > 0.0f) {
this->actor.gravity = 0.0f;
this->actor.velocity.y = -3.0f;
- this->unk_284 = 10;
+ this->swimTimer = 10;
Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BOMB_DROP_WATER);
- this->actionFunc = func_8098B560;
+ this->actionFunc = EnDg_Swim;
}
Math_ApproachF(&this->actor.speedXZ, 1.0f, 0.2f, 1.0f);
Actor_MoveWithGravity(&this->actor);
}
-void func_8098B560(EnDg* this, PlayState* play) {
- Vec3f sp54;
+/**
+ * Makes the dog swim until it either:
+ * - Touches land, at which point it will just resume its idle movement.
+ * - Touches a wall, at which point it will attempt to jump out of the water.
+ */
+void EnDg_Swim(EnDg* this, PlayState* play) {
+ Vec3f ripplePos;
Vec3f pos;
- s16 sp46 = 0;
+ s16 yRotation = 0;
WaterBox* waterBox;
f32 waterSurface;
CollisionPoly* poly;
- f32 sp34;
+ f32 floorHeight;
- sp54.x = this->actor.world.pos.x;
- sp54.y = this->actor.world.pos.y + this->actor.depthInWater;
- sp54.z = this->actor.world.pos.z + 20.0f;
+ ripplePos.x = this->actor.world.pos.x;
+ ripplePos.y = this->actor.world.pos.y + this->actor.depthInWater;
+ ripplePos.z = this->actor.world.pos.z + 20.0f;
pos.x = (Math_SinS(this->actor.world.rot.y) * 50.0f) + this->actor.world.pos.x;
pos.y = this->actor.home.pos.y + 100.0f;
pos.z = (Math_CosS(this->actor.world.rot.y) * 50.0f) + this->actor.world.pos.z;
- if (DECR(this->unk_284) == 0) {
- if (!(this->unk_280 & 4)) {
- this->unk_280 |= 4;
+ if (DECR(this->swimTimer) == 0) {
+ if (!(this->dogFlags & DOG_FLAG_SWIMMING)) {
+ this->dogFlags |= DOG_FLAG_SWIMMING;
Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_OUT_OF_WATER);
}
- this->unk_284 = 5;
- EffectSsGRipple_Spawn(play, &sp54, 100, 500, 30);
+
+ this->swimTimer = 5;
+ EffectSsGRipple_Spawn(play, &ripplePos, 100, 500, 30);
}
if (this->actor.depthInWater > 15.0f) {
@@ -980,52 +1149,63 @@ void func_8098B560(EnDg* this, PlayState* play) {
this->actor.velocity.y = -0.5f;
}
- sp34 = BgCheck_EntityRaycastFloor2(play, &play->colCtx, &poly, &pos);
+ floorHeight = BgCheck_EntityRaycastFloor2(play, &play->colCtx, &poly, &pos);
+
+ // The below code checks *only* that the dog is touching a wall, which can result in
+ // some strange behavior if the dog is touching a wall that is too tall for it to jump
+ // over. For example, if the player throws the dog at a tall wall next to some water,
+ // this code will make the dog "skip" along the water's surface, assuming the floor
+ // height is low enough to make it try to jump out.
if (this->actor.bgCheckFlags & 8) {
if (!WaterBox_GetSurface1(play, &play->colCtx, pos.x, pos.z, &waterSurface, &waterBox)) {
- if (sp34 > -100.0f) {
- this->unk_280 &= ~4;
- this->actionFunc = func_8098B88C;
+ if (floorHeight > -100.0f) {
+ this->dogFlags &= ~DOG_FLAG_SWIMMING;
+ this->actionFunc = EnDg_JumpOutOfWater;
} else {
- sp46 = this->actor.wallYaw;
+ yRotation = this->actor.wallYaw;
}
- } else if (sp34 > -100.0f) {
- if (waterSurface < sp34) {
- this->unk_280 &= ~4;
- this->actionFunc = func_8098B88C;
+ } else if (floorHeight > -100.0f) {
+ if (waterSurface < floorHeight) {
+ this->dogFlags &= ~DOG_FLAG_SWIMMING;
+ this->actionFunc = EnDg_JumpOutOfWater;
} else {
- sp46 = this->actor.wallYaw;
+ yRotation = this->actor.wallYaw;
}
} else {
- sp46 = this->actor.wallYaw;
+ yRotation = this->actor.wallYaw;
}
} else if ((this->actor.bgCheckFlags & 1) && !(this->actor.bgCheckFlags & 0x20)) {
this->actor.gravity = -3.0f;
- this->unk_280 &= ~4;
- this->unk_28C = 8;
- this->unk_282 = Rand_S16Offset(60, 60);
+ this->dogFlags &= ~DOG_FLAG_SWIMMING;
+ this->behavior = DOG_BEHAVIOR_DEFAULT;
+ this->timer = Rand_S16Offset(60, 60);
Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_OUT_OF_WATER);
- func_80989140(&this->skelAnime, sAnimations, 2);
+ EnDg_ChangeAnimation(&this->skelAnime, sAnimations, DOG_ANIMATION_RUN);
Math_ApproachF(&this->actor.speedXZ, 3.5f, 0.2f, 1.0f);
- this->actionFunc = func_8098A468;
+ this->actionFunc = EnDg_IdleMove;
}
- Math_SmoothStepToS(&this->actor.world.rot.y, sp46, 4, 0x3E8, 1);
+ Math_SmoothStepToS(&this->actor.world.rot.y, yRotation, 4, 0x3E8, 1);
this->actor.shape.rot.y = this->actor.world.rot.y;
Math_ApproachF(&this->actor.speedXZ, 0.5f, 0.2f, 1.0f);
Actor_MoveWithGravity(&this->actor);
}
-void func_8098B88C(EnDg* this, PlayState* play) {
- Vec3f sp34;
+/**
+ * This function attempts to get the dog out of water by making it jump near walls.
+ * The point of this is seemingly to let the dog escape the shallow water pools in
+ * South Clock Town.
+ */
+void EnDg_JumpOutOfWater(EnDg* this, PlayState* play) {
+ Vec3f pos;
- sp34.x = this->actor.world.pos.x;
- sp34.y = this->actor.world.pos.y + this->actor.depthInWater;
- sp34.z = this->actor.world.pos.z + 20.0f;
+ pos.x = this->actor.world.pos.x;
+ pos.y = this->actor.world.pos.y + this->actor.depthInWater;
+ pos.z = this->actor.world.pos.z + 20.0f;
- if (DECR(this->unk_284) == 0) {
- this->unk_284 = 5;
- EffectSsGRipple_Spawn(play, &sp34, 100, 500, 30);
+ if (DECR(this->swimTimer) == 0) {
+ this->swimTimer = 5;
+ EffectSsGRipple_Spawn(play, &pos, 100, 500, 30);
}
if (this->actor.depthInWater > 15.0f) {
@@ -1035,19 +1215,19 @@ void func_8098B88C(EnDg* this, PlayState* play) {
}
if (this->actor.bgCheckFlags & 8) {
- this->actor.world.pos.y = sp34.y;
+ this->actor.world.pos.y = pos.y;
this->actor.velocity.y = 10.0f;
- EffectSsGSplash_Spawn(play, &sp34, NULL, NULL, 0, 800);
+ EffectSsGSplash_Spawn(play, &pos, NULL, NULL, 0, 800);
}
if (!(this->actor.bgCheckFlags & 0x20)) {
- this->unk_28C = 8;
+ this->behavior = DOG_BEHAVIOR_DEFAULT;
this->actor.velocity.y = 10.0f;
this->actor.gravity = -3.0f;
- this->unk_282 = Rand_S16Offset(60, 60);
+ this->timer = Rand_S16Offset(60, 60);
Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_OUT_OF_WATER);
- func_80989140(&this->skelAnime, sAnimations, 2);
- this->actionFunc = func_8098A468;
+ EnDg_ChangeAnimation(&this->skelAnime, sAnimations, DOG_ANIMATION_RUN);
+ this->actionFunc = EnDg_IdleMove;
Math_ApproachF(&this->actor.speedXZ, 3.5f, 0.2f, 1.0f);
} else {
Math_ApproachF(&this->actor.speedXZ, 0.5f, 0.2f, 1.0f);
@@ -1056,63 +1236,64 @@ void func_8098B88C(EnDg* this, PlayState* play) {
Actor_MoveWithGravity(&this->actor);
}
-void func_8098BA64(EnDg* this, PlayState* play) {
+void EnDg_Held(EnDg* this, PlayState* play) {
if (Actor_HasNoParent(&this->actor, play)) {
- this->unk_290 = 2;
+ this->grabState = DOG_GRAB_STATE_THROWN_OR_SITTING_AFTER_THROW;
this->actor.flags |= ACTOR_FLAG_1;
- if (D_8098C2A0 != 0) {
+ if (sIsAnyDogHeld) {
this->actor.flags &= ~ACTOR_FLAG_8000000;
- D_8098C2A0 = 0;
- this->unk_280 &= ~1;
+ sIsAnyDogHeld = false;
+ this->dogFlags &= ~DOG_FLAG_HELD;
}
+
this->selectedDogIndex = -1;
sSelectedRacetrackDogInfo.index = this->selectedDogIndex;
- this->unk_28A = 100;
+ this->sitAfterThrowTimer = 100;
Actor_MoveWithGravity(&this->actor);
- this->unk_280 |= 0x10;
- this->actionFunc = func_8098BB10;
+ this->dogFlags |= DOG_FLAG_THROWN;
+ this->actionFunc = EnDg_Thrown;
}
}
-void func_8098BB10(EnDg* this, PlayState* play) {
+void EnDg_Thrown(EnDg* this, PlayState* play) {
Player* player = GET_PLAYER(play);
if (this->actor.bgCheckFlags & 1) {
- if (this->unk_280 & 0x10) {
- this->unk_280 &= ~0x10;
+ if (this->dogFlags & DOG_FLAG_THROWN) {
+ this->dogFlags &= ~DOG_FLAG_THROWN;
Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_MONKEY_WALK);
}
this->actor.speedXZ = 0.0f;
this->actor.gravity = -3.0f;
if (player->transformation == PLAYER_FORM_HUMAN) {
- func_80989E18(this, play);
+ EnDg_TryPickUp(this, play);
}
}
- if (DECR(this->unk_28A) == 0) {
- this->unk_290 = 0;
- func_80989ADC(this, play);
- this->actionFunc = func_8098A468;
+ if (DECR(this->sitAfterThrowTimer) == 0) {
+ this->grabState = DOG_GRAB_STATE_NONE;
+ EnDg_SetupIdleMove(this, play);
+ this->actionFunc = EnDg_IdleMove;
}
Actor_MoveWithGravity(&this->actor);
}
-void func_8098BBEC(EnDg* this, PlayState* play) {
+void EnDg_SetupTalk(EnDg* this, PlayState* play) {
if (Actor_ProcessTalkRequest(&this->actor, &play->state)) {
this->actor.flags &= ~ACTOR_FLAG_10000;
- func_80989D38(this, play);
- this->actionFunc = func_8098BC54;
+ EnDg_StartTextBox(this, play);
+ this->actionFunc = EnDg_Talk;
} else {
func_800B8614(&this->actor, play, 100.0f);
}
}
-void func_8098BC54(EnDg* this, PlayState* play) {
+void EnDg_Talk(EnDg* this, PlayState* play) {
if (Message_GetState(&play->msgCtx) == 2) {
- func_80989140(&this->skelAnime, sAnimations, 0);
- this->actionFunc = func_8098BA64;
+ EnDg_ChangeAnimation(&this->skelAnime, sAnimations, DOG_ANIMATION_WALK_AFTER_TALKING);
+ this->actionFunc = EnDg_Held;
}
}
@@ -1126,22 +1307,24 @@ void EnDg_Init(Actor* thisx, PlayState* play) {
Collider_SetCylinder(play, &this->collider, &this->actor, &sCylinderInit);
CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit);
Actor_ProcessInitChain(&this->actor, sInitChain);
+
this->path = SubS_GetPathByIndex(play, ENDG_GET_PATH(&this->actor), 0x3F);
Actor_SetScale(&this->actor, 0.0075f);
this->actor.targetMode = 1;
this->actor.gravity = -3.0f;
- this->unk_282 = Rand_S16Offset(60, 60);
- this->unk_280 = 0;
- this->unk_28E = 20;
- this->unk_284 = 10;
+ this->timer = Rand_S16Offset(60, 60);
+ this->dogFlags = DOG_FLAG_NONE;
+ this->attackTimer = 20;
+ this->swimTimer = 10;
this->index = ENDG_GET_INDEX(&this->actor);
- this->unk_28C = 0;
- this->unk_290 = 0;
+ this->behavior = DOG_BEHAVIOR_INITIAL;
+ this->grabState = DOG_GRAB_STATE_NONE;
if (play->sceneNum == SCENE_F01_B) {
- this->unk_28A = 100;
- func_80989BF8(this);
+ this->sitAfterThrowTimer = 100;
+ EnDg_UpdateTextId(this);
}
- func_80989ADC(this, play);
+
+ EnDg_SetupIdleMove(this, play);
}
void EnDg_Destroy(Actor* thisx, PlayState* play) {
@@ -1154,27 +1337,27 @@ void EnDg_Update(Actor* thisx, PlayState* play) {
EnDg* this = THIS;
Player* player = GET_PLAYER(play);
s32 pad;
- Vec3f sp28 = { 0.0f, 0.0f, 0.0f };
+ Vec3f floorRot = { 0.0f, 0.0f, 0.0f };
this->selectedDogIndex = sSelectedRacetrackDogInfo.index;
if (!(player->stateFlags1 & 0x20) || (play->sceneNum != SCENE_CLOCKTOWER)) {
- if (func_8098A1B4(this, play)) {
- func_8098A234(this, play);
- } else if (this->unk_28C != 8) {
- this->unk_28C = 8;
- func_80989ADC(this, play);
+ if (EnDg_ShouldReactToNonHumanPlayer(this, play)) {
+ EnDg_ChooseActionForForm(this, play);
+ } else if (this->behavior != DOG_BEHAVIOR_DEFAULT) {
+ this->behavior = DOG_BEHAVIOR_DEFAULT;
+ EnDg_SetupIdleMove(this, play);
}
if ((this->actor.bgCheckFlags & 0x40) && Actor_HasNoParent(&this->actor, play)) {
- func_80989140(&this->skelAnime, sAnimations, 15);
- this->actionFunc = func_8098B464;
+ EnDg_ChangeAnimation(&this->skelAnime, sAnimations, DOG_ANIMATION_SWIM);
+ this->actionFunc = EnDg_SetupSwim;
}
this->actionFunc(this, play);
- func_80989204(this, play);
- func_8098933C(this, &sp28);
- Math_ApproachF(&this->unk_294.x, sp28.x, 0.2f, 0.1f);
- Math_ApproachF(&this->unk_294.z, sp28.z, 0.2f, 0.1f);
+ EnDg_UpdateCollision(this, play);
+ EnDg_GetFloorRot(this, &floorRot);
+ Math_ApproachF(&this->curRot.x, floorRot.x, 0.2f, 0.1f);
+ Math_ApproachF(&this->curRot.z, floorRot.z, 0.2f, 0.1f);
SkelAnime_Update(&this->skelAnime);
}
}
@@ -1185,14 +1368,14 @@ s32 EnDg_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* po
void EnDg_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) {
EnDg* this = THIS;
- Vec3f sp20 = { 0.0f, 20.0f, 0.0f };
+ Vec3f sFocusOffset = { 0.0f, 20.0f, 0.0f };
if (limbIndex == DOG_LIMB_HEAD) {
- if (this->actionFunc == func_8098BBEC) {
- sp20.x = 5000.0f;
- Matrix_MultVec3f(&sp20, &this->actor.focus.pos);
- } else if (this->actionFunc != func_8098BC54) {
- Matrix_MultVec3f(&sp20, &this->actor.focus.pos);
+ if (this->actionFunc == EnDg_SetupTalk) {
+ sFocusOffset.x = 5000.0f;
+ Matrix_MultVec3f(&sFocusOffset, &this->actor.focus.pos);
+ } else if (this->actionFunc != EnDg_Talk) {
+ Matrix_MultVec3f(&sFocusOffset, &this->actor.focus.pos);
}
}
}
@@ -1237,8 +1420,8 @@ void EnDg_Draw(Actor* thisx, PlayState* play) {
}
Matrix_Translate(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW);
- Matrix_RotateXFApply(this->unk_294.x);
- Matrix_RotateZF(this->unk_294.z, MTXMODE_APPLY);
+ Matrix_RotateXFApply(this->curRot.x);
+ Matrix_RotateZF(this->curRot.z, MTXMODE_APPLY);
Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_APPLY);
Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY);
SkelAnime_DrawFlexOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount,
diff --git a/src/overlays/actors/ovl_En_Dg/z_en_dg.h b/src/overlays/actors/ovl_En_Dg/z_en_dg.h
index 43e65b5f87..2b2bdd7cb4 100644
--- a/src/overlays/actors/ovl_En_Dg/z_en_dg.h
+++ b/src/overlays/actors/ovl_En_Dg/z_en_dg.h
@@ -19,7 +19,28 @@ struct EnDg;
typedef void (*EnDgActionFunc)(struct EnDg*, PlayState*);
#define ENDG_GET_INDEX(thisx) (((thisx)->params & 0x3E0) >> 5)
-#define ENDG_GET_PATH(thisx) (((thisx)->params & 0xFC00) >> 0xA)
+#define ENDG_GET_PATH(thisx) (((thisx)->params & 0xFC00) >> 10)
+#define ENDG_PARAMS(path, index) ((path << 10) | (index << 5))
+
+typedef enum {
+ /* 0 */ ENDG_INDEX_RACETRACK_0,
+ /* 1 */ ENDG_INDEX_RACETRACK_1,
+ /* 2 */ ENDG_INDEX_RACETRACK_2,
+ /* 3 */ ENDG_INDEX_RACETRACK_3,
+ /* 4 */ ENDG_INDEX_RACETRACK_4,
+ /* 5 */ ENDG_INDEX_RACETRACK_5,
+ /* 6 */ ENDG_INDEX_RACETRACK_6,
+ /* 7 */ ENDG_INDEX_RACETRACK_7,
+ /* 8 */ ENDG_INDEX_RACETRACK_8,
+ /* 9 */ ENDG_INDEX_RACETRACK_9,
+ /* 10 */ ENDG_INDEX_RACETRACK_10,
+ /* 11 */ ENDG_INDEX_RACETRACK_11,
+ /* 12 */ ENDG_INDEX_RACETRACK_12,
+ /* 13 */ ENDG_INDEX_RACETRACK_13,
+ /* 20 */ ENDG_INDEX_ROMANI_RANCH = 20,
+ /* 21 */ ENDG_INDEX_SWAMP_SPIDER_HOUSE,
+ /* 31 */ ENDG_INDEX_SOUTH_CLOCK_TOWN = 31
+} EnDgIndex;
typedef struct EnDg {
/* 0x000 */ Actor actor;
@@ -28,20 +49,20 @@ typedef struct EnDg {
/* 0x14C */ SkelAnime skelAnime;
/* 0x190 */ ColliderCylinder collider;
/* 0x1DC */ Path* path;
- /* 0x1E0 */ s32 unk_1E0;
+ /* 0x1E0 */ s32 currentPoint;
/* 0x1E4 */ Vec3s jointTable[DOG_LIMB_MAX];
/* 0x232 */ Vec3s morphTable[DOG_LIMB_MAX];
- /* 0x280 */ u16 unk_280;
- /* 0x282 */ s16 unk_282;
- /* 0x284 */ s16 unk_284;
+ /* 0x280 */ u16 dogFlags;
+ /* 0x282 */ s16 timer;
+ /* 0x284 */ s16 swimTimer;
/* 0x286 */ s16 index;
/* 0x288 */ s16 selectedDogIndex;
- /* 0x28A */ s16 unk_28A;
- /* 0x28C */ s16 unk_28C;
- /* 0x28E */ s16 unk_28E;
- /* 0x290 */ s16 unk_290;
- /* 0x292 */ s16 unk_292;
- /* 0x294 */ Vec3f unk_294;
+ /* 0x28A */ s16 sitAfterThrowTimer;
+ /* 0x28C */ s16 behavior;
+ /* 0x28E */ s16 attackTimer;
+ /* 0x290 */ s16 grabState;
+ /* 0x292 */ s16 bremenBarkTimer;
+ /* 0x294 */ Vec3f curRot;
} EnDg; // size = 0x2A0
extern const ActorInit En_Dg_InitVars;
diff --git a/src/overlays/actors/ovl_En_Racedog/z_en_racedog.c b/src/overlays/actors/ovl_En_Racedog/z_en_racedog.c
index 7b7d7a76bb..529ac9f4e3 100644
--- a/src/overlays/actors/ovl_En_Racedog/z_en_racedog.c
+++ b/src/overlays/actors/ovl_En_Racedog/z_en_racedog.c
@@ -30,11 +30,11 @@ void EnRacedog_CheckForFinish(EnRacedog* this);
void EnRacedog_UpdateRunAnimationPlaySpeed(EnRacedog* this);
s32 EnRacedog_IsOverFinishLine(EnRacedog* this, Vec2f* arg1);
void EnRacedog_SpawnFloorDustRing(EnRacedog* this, PlayState* play);
-void EnRacedog_PlayWalkSfx(EnRacedog* this);
+void EnRacedog_PlaySfxWalk(EnRacedog* this);
/**
- * Dogs can be in three conditions, which is indicated by the message it says when
- * you pick it up prior to entering the race.
+ * Dogs can be in three conditions, which is, for the most part, indicated by the
+ * message it says when you pick it up prior to entering the race.
* If it starts with "Ruff!", it's in good condition.
* If it starts with "Rrr-Ruff!", it's in normal condition.
* If it starts with "Hoo-whine", it's in bad condition.
@@ -42,30 +42,21 @@ void EnRacedog_PlayWalkSfx(EnRacedog* this);
* - 0x3538 - 0x353D: Good condition
* - 0x353E - 0x3541: Normal condition
* - 0x3542 - 0x3546: Bad condition
+ *
+ * There are two caveats, though, that are useful to keep in mind:
+ * - Because of differences between how EnDg computes the text ID and how EnRacedog
+ * computes it, there are two dogs whose text upon picking them up does not
+ * accurately reflect their condition during the race. Check the comment above
+ * EnRacedog_UpdateTextId for more information on this phenomenon.
+ * - Note that text ID 0x353D is actually used for the Romani Ranch dog; its text
+ * just so happens to be in the middle of the race dog text block. In EnDg, the
+ * dog that gets this text ID will instead use text ID 0x3538 when the player
+ * picks it up. Since EnRacedog cannot be picked up, however, it can use 0x353D
+ * as an additional good condition text ID.
*/
#define DOG_IS_IN_GOOD_CONDITION(this) (sDogInfo[this->index].textId < 0x353E)
#define DOG_IS_IN_BAD_CONDITION(this) (sDogInfo[this->index].textId >= 0x3542)
-typedef enum {
- /* 0 */ RACEDOG_ANIMATION_IDLE,
- /* 1 */ RACEDOG_ANIMATION_WALK_1,
- /* 2 */ RACEDOG_ANIMATION_RUN,
- /* 3 */ RACEDOG_ANIMATION_BARK,
- /* 4 */ RACEDOG_ANIMATION_SIT_DOWN_1,
- /* 5 */ RACEDOG_ANIMATION_SIT_DOWN_2,
- /* 6 */ RACEDOG_ANIMATION_LYING_DOWN_START_1,
- /* 7 */ RACEDOG_ANIMATION_LYING_DOWN_LOOP,
- /* 8 */ RACEDOG_ANIMATION_LYING_DOWN_START_2,
- /* 9 */ RACEDOG_ANIMATION_LYING_DOWN_START_3,
- /* 10 */ RACEDOG_ANIMATION_LYING_DOWN_START_4,
- /* 11 */ RACEDOG_ANIMATION_WALK_2,
- /* 12 */ RACEDOG_ANIMATION_JUMP,
- /* 13 */ RACEDOG_ANIMATION_LONG_JUMP,
- /* 14 */ RACEDOG_ANIMATION_JUMP_2,
- /* 15 */ RACEDOG_ANIMATION_WALK_3,
- /* 16 */ RACEDOG_ANIMATION_MAX
-} RacedogAnimationIndex;
-
/**
* Stores various information for each dog in the race, mostly related to speed.
*/
@@ -212,6 +203,26 @@ static DamageTable sDamageTable = {
/* Powder Keg */ DMG_ENTRY(0, 0x0),
};
+typedef enum {
+ /* 0 */ RACEDOG_ANIMATION_IDLE,
+ /* 1 */ RACEDOG_ANIMATION_WALK_1, // unused
+ /* 2 */ RACEDOG_ANIMATION_RUN,
+ /* 3 */ RACEDOG_ANIMATION_BARK, // unused
+ /* 4 */ RACEDOG_ANIMATION_SIT_DOWN_ONCE, // unused
+ /* 5 */ RACEDOG_ANIMATION_SIT_DOWN, // unused
+ /* 6 */ RACEDOG_ANIMATION_LYING_DOWN_START_1, // unused
+ /* 7 */ RACEDOG_ANIMATION_LYING_DOWN_LOOP, // unused
+ /* 8 */ RACEDOG_ANIMATION_LYING_DOWN_START_2, // unused
+ /* 9 */ RACEDOG_ANIMATION_LYING_DOWN_START_3, // unused
+ /* 10 */ RACEDOG_ANIMATION_LYING_DOWN_START_4, // unused
+ /* 11 */ RACEDOG_ANIMATION_WALK_BACKWARDS, // unused
+ /* 12 */ RACEDOG_ANIMATION_JUMP,
+ /* 13 */ RACEDOG_ANIMATION_LONG_JUMP, // unused
+ /* 14 */ RACEDOG_ANIMATION_JUMP_ATTACK, // unused
+ /* 15 */ RACEDOG_ANIMATION_SWIM, // unused
+ /* 16 */ RACEDOG_ANIMATION_MAX
+} RacedogAnimationIndex;
+
static AnimationInfoS sAnimations[] = {
{ &gDogWalkAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, { &gDogWalkAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -6 },
{ &gDogRunAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, { &gDogBarkAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -6 },
@@ -220,7 +231,7 @@ static AnimationInfoS sAnimations[] = {
{ &gDogLyingDownAnim, 1.0f, 0, 27, ANIMMODE_ONCE, -6 }, { &gDogLyingDownAnim, 1.0f, 28, -1, ANIMMODE_ONCE, -6 },
{ &gDogLyingDownAnim, 1.0f, 54, 54, ANIMMODE_ONCE, -6 }, { &gDogWalkAnim, -1.5f, -1, 0, ANIMMODE_LOOP, -6 },
{ &gDogJumpAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, { &gDogLongJumpAnim, 1.2f, 0, -1, ANIMMODE_ONCE, 0 },
- { &gDogJump2Anim, 1.2f, 0, -1, ANIMMODE_ONCE, 0 }, { &gDogWalkAnim, 0.5f, 0, -1, ANIMMODE_LOOP, 0 },
+ { &gDogJumpAttackAnim, 1.2f, 0, -1, ANIMMODE_ONCE, 0 }, { &gDogWalkAnim, 0.5f, 0, -1, ANIMMODE_LOOP, 0 },
};
static InitChainEntry sInitChain[] = {
@@ -255,27 +266,27 @@ void EnRacedog_UpdateCollision(EnRacedog* this, PlayState* play) {
*/
s16 EnRacedog_GetYRotation(Path* path, s32 pointIndex, Vec3f* pos, f32* distSQ) {
Vec3s* point;
- f32 xDiffRand;
- f32 zDiffRand;
- f32 xDiff;
- f32 zDiff;
+ f32 diffXRand;
+ f32 diffZRand;
+ f32 diffX;
+ f32 diffZ;
if (path != NULL) {
point = Lib_SegmentedToVirtual(path->points);
point = &point[pointIndex];
- xDiffRand = (randPlusMinusPoint5Scaled(100.0f) + point->x) - pos->x;
- zDiffRand = (randPlusMinusPoint5Scaled(100.0f) + point->z) - pos->z;
- xDiff = point->x - pos->x;
- zDiff = point->z - pos->z;
+ diffXRand = (randPlusMinusPoint5Scaled(100.0f) + point->x) - pos->x;
+ diffZRand = (randPlusMinusPoint5Scaled(100.0f) + point->z) - pos->z;
+ diffX = point->x - pos->x;
+ diffZ = point->z - pos->z;
} else {
- xDiffRand = 0.0f;
- zDiffRand = 0.0f;
- xDiff = 0.0f;
- zDiff = 0.0f;
+ diffXRand = 0.0f;
+ diffZRand = 0.0f;
+ diffX = 0.0f;
+ diffZ = 0.0f;
}
- *distSQ = SQ(xDiff) + SQ(zDiff);
- return RADF_TO_BINANG(Math_Acot2F(zDiffRand, xDiffRand));
+ *distSQ = SQ(diffX) + SQ(diffZ);
+ return RADF_TO_BINANG(Math_Acot2F(diffZRand, diffXRand));
}
void EnRacedog_GetFloorRot(EnRacedog* this, Vec3f* floorRot) {
@@ -409,7 +420,7 @@ void EnRacedog_Race(EnRacedog* this, PlayState* play) {
}
EnRacedog_UpdateRunAnimationPlaySpeed(this);
- EnRacedog_PlayWalkSfx(this);
+ EnRacedog_PlaySfxWalk(this);
EnRacedog_SpawnFloorDustRing(this, play);
}
@@ -417,18 +428,26 @@ void EnRacedog_Race(EnRacedog* this, PlayState* play) {
* Updates the text ID in sDogInfo based on what was set in the weekEventRegs by
* En_Aob_01. This makes it so sDogInfo can be used in other functions to determine
* the condition of the dog.
+ *
+ * Note that the text IDs generated by this function are off-by-one compared to the
+ * similar function in EnDg. The end result of this is that one of the dogs that says
+ * it's in good condition when you pick it up is actually in normal condition once the
+ * race starts, and one of the dogs that says it's in normal condition when you pick
+ * it up is actually in bad condition. It's unknown whether this is a simple oversight
+ * or an intentional choice to introduce a bit of extra variance to the race.
*/
void EnRacedog_UpdateTextId(EnRacedog* this) {
+ // Assuming that the weekEventRegs haven't been tampered with, then this will produce a text ID in the
+ // range of 0x3539 to 0x3546.
if (this->index % 2) {
sDogInfo[this->index].textId =
- (((gSaveContext.save.weekEventReg[42 + (this->index / 2)]) & (0x10 | 0x20 | 0x40 | 0x80)) >> 4) + 0x3539;
+ (((gSaveContext.save.weekEventReg[42 + (this->index / 2)]) & 0xF0) >> 4) + 0x3539;
} else {
- sDogInfo[this->index].textId =
- ((gSaveContext.save.weekEventReg[42 + (this->index / 2)]) & (1 | 2 | 4 | 8)) + 0x3539;
+ sDogInfo[this->index].textId = ((gSaveContext.save.weekEventReg[42 + (this->index / 2)]) & 0x0F) + 0x3539;
}
- // This makes sure the text ID is something in the range of 0x3539 to 0x3547.
- if ((sDogInfo[this->index].textId >= 0x3547) || (sDogInfo[this->index].textId < 0x3539)) {
+ // As a sanity check, this makes sure the text ID is something in the expected range of 0x3539 to 0x3546.
+ if ((sDogInfo[this->index].textId > 0x3546) || (sDogInfo[this->index].textId < 0x3539)) {
sDogInfo[this->index].textId = 0x353E;
}
@@ -650,7 +669,7 @@ void EnRacedog_SpawnFloorDustRing(EnRacedog* this, PlayState* play) {
}
}
-void EnRacedog_PlayWalkSfx(EnRacedog* this) {
+void EnRacedog_PlaySfxWalk(EnRacedog* this) {
s16 curFrame = this->skelAnime.curFrame;
if ((curFrame == 1) || (curFrame == 7)) {
diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt
index 844f4b7073..b6e95426c9 100644
--- a/tools/disasm/functions.txt
+++ b/tools/disasm/functions.txt
@@ -8305,49 +8305,49 @@
0x80987A3C:("OceffWipe3_Destroy",),
0x80987A70:("OceffWipe3_Update",),
0x80987AD0:("OceffWipe3_Draw",),
- 0x80989140:("func_80989140",),
- 0x80989204:("func_80989204",),
- 0x8098933C:("func_8098933C",),
- 0x80989418:("func_80989418",),
- 0x809895B4:("func_809895B4",),
- 0x80989674:("func_80989674",),
- 0x80989864:("func_80989864",),
- 0x80989974:("func_80989974",),
- 0x809899C8:("func_809899C8",),
- 0x80989A08:("func_80989A08",),
- 0x80989A48:("func_80989A48",),
- 0x80989A9C:("func_80989A9C",),
- 0x80989ADC:("func_80989ADC",),
- 0x80989BF8:("func_80989BF8",),
- 0x80989D38:("func_80989D38",),
- 0x80989E18:("func_80989E18",),
- 0x80989FC8:("func_80989FC8",),
- 0x8098A064:("func_8098A064",),
- 0x8098A1B4:("func_8098A1B4",),
- 0x8098A234:("func_8098A234",),
- 0x8098A468:("func_8098A468",),
- 0x8098A55C:("func_8098A55C",),
- 0x8098A618:("func_8098A618",),
- 0x8098A70C:("func_8098A70C",),
- 0x8098A89C:("func_8098A89C",),
- 0x8098A938:("func_8098A938",),
- 0x8098AAAC:("func_8098AAAC",),
- 0x8098AB48:("func_8098AB48",),
- 0x8098AC34:("func_8098AC34",),
- 0x8098AE58:("func_8098AE58",),
- 0x8098AF44:("func_8098AF44",),
- 0x8098AF98:("func_8098AF98",),
- 0x8098B004:("func_8098B004",),
- 0x8098B198:("func_8098B198",),
- 0x8098B28C:("func_8098B28C",),
- 0x8098B390:("func_8098B390",),
- 0x8098B464:("func_8098B464",),
- 0x8098B560:("func_8098B560",),
- 0x8098B88C:("func_8098B88C",),
- 0x8098BA64:("func_8098BA64",),
- 0x8098BB10:("func_8098BB10",),
- 0x8098BBEC:("func_8098BBEC",),
- 0x8098BC54:("func_8098BC54",),
+ 0x80989140:("EnDg_ChangeAnimation",),
+ 0x80989204:("EnDg_UpdateCollision",),
+ 0x8098933C:("EnDg_GetFloorRot",),
+ 0x80989418:("EnDg_HasReachedPoint",),
+ 0x809895B4:("EnDg_GetYRotation",),
+ 0x80989674:("EnDg_MoveAlongPath",),
+ 0x80989864:("EnDg_SpawnFloorDustRing",),
+ 0x80989974:("EnDg_PlaySfxWalk",),
+ 0x809899C8:("EnDg_PlaySfxBark",),
+ 0x80989A08:("EnDg_PlaySfxAngryBark",),
+ 0x80989A48:("EnDg_PlaySfxWhine",),
+ 0x80989A9C:("EnDg_PlaySfxGrowl",),
+ 0x80989ADC:("EnDg_SetupIdleMove",),
+ 0x80989BF8:("EnDg_UpdateTextId",),
+ 0x80989D38:("EnDg_StartTextBox",),
+ 0x80989E18:("EnDg_TryPickUp",),
+ 0x80989FC8:("EnDg_FindFollowerForBremenMask",),
+ 0x8098A064:("EnDg_CheckForBremenMaskMarch",),
+ 0x8098A1B4:("EnDg_ShouldReactToNonHumanPlayer",),
+ 0x8098A234:("EnDg_ChooseActionForForm",),
+ 0x8098A468:("EnDg_IdleMove",),
+ 0x8098A55C:("EnDg_IdleBark",),
+ 0x8098A618:("EnDg_BackAwayFromGoron",),
+ 0x8098A70C:("EnDg_RunAwayFromGoron",),
+ 0x8098A89C:("EnDg_BarkAtGoron",),
+ 0x8098A938:("EnDg_ApproachPlayerToAttack",),
+ 0x8098AAAC:("EnDg_RunAfterAttacking",),
+ 0x8098AB48:("EnDg_SitNextToPlayer",),
+ 0x8098AC34:("EnDg_JumpAttack",),
+ 0x8098AE58:("EnDg_WalkToPlayer",),
+ 0x8098AF44:("EnDg_SetupBremenMaskApproachPlayer",),
+ 0x8098AF98:("EnDg_Fall",),
+ 0x8098B004:("EnDg_ApproachPlayer",),
+ 0x8098B198:("EnDg_SlowlyBackUpBeforeAttacking",),
+ 0x8098B28C:("EnDg_BackAwayFromPlayer",),
+ 0x8098B390:("EnDg_BarkAtPlayer",),
+ 0x8098B464:("EnDg_SetupSwim",),
+ 0x8098B560:("EnDg_Swim",),
+ 0x8098B88C:("EnDg_JumpOutOfWater",),
+ 0x8098BA64:("EnDg_Held",),
+ 0x8098BB10:("EnDg_Thrown",),
+ 0x8098BBEC:("EnDg_SetupTalk",),
+ 0x8098BC54:("EnDg_Talk",),
0x8098BCA8:("EnDg_Init",),
0x8098BE18:("EnDg_Destroy",),
0x8098BE44:("EnDg_Update",),
@@ -13293,7 +13293,7 @@
0x80B25448:("EnRacedog_UpdateRunAnimationPlaySpeed",),
0x80B25490:("EnRacedog_IsOverFinishLine",),
0x80B255AC:("EnRacedog_SpawnFloorDustRing",),
- 0x80B256BC:("EnRacedog_PlayWalkSfx",),
+ 0x80B256BC:("EnRacedog_PlaySfxWalk",),
0x80B25708:("EnRacedog_Update",),
0x80B2583C:("EnRacedog_UpdateSelectionArrow",),
0x80B258D8:("EnRacedog_DrawSelectionArrow",),
diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt
index 280ca73650..3c97d3de0f 100644
--- a/tools/disasm/variables.txt
+++ b/tools/disasm/variables.txt
@@ -9176,8 +9176,8 @@
0x80989064:("D_80989064","f32","",0x4),
0x80989068:("D_80989068","f32","",0x4),
0x8098C280:("En_Dg_InitVars","UNK_TYPE1","",0x1),
- 0x8098C2A0:("D_8098C2A0","UNK_TYPE1","",0x1),
- 0x8098C2A4:("D_8098C2A4","UNK_TYPE2","",0x2),
+ 0x8098C2A0:("sIsAnyDogHeld","UNK_TYPE1","",0x1),
+ 0x8098C2A4:("sBremenMaskFollower","UNK_TYPE2","",0x2),
0x8098C2A8:("D_8098C2A8","UNK_TYPE2","",0x2),
0x8098C2AC:("D_8098C2AC","UNK_TYPE2","",0x2),
0x8098C2FC:("D_8098C2FC","UNK_TYPE1","",0x1),