From 905c089bebdbee64ccb2e3106bac752b3b28a43f Mon Sep 17 00:00:00 2001 From: Tom Overton Date: Thu, 21 Jul 2022 21:48:55 -0700 Subject: [PATCH] Document En_Dg (dog) and do some light cleanup on En_Racedog (#926) * Document some low-hanging fruit in EnDg * Animation and type documentation * Document a bunch of stuff * Name more functions * Params macro * Defines for dog flags * Name all struct variables * Give all animations better names * Better name for Swim2 * Document/name a bunch of stuff * Make index enum * Respond to engineer's review * Respond to mzx's review * Fix up comment (again) * Respond to hensldm's review --- assets/xml/objects/object_dog.xml | 2 +- .../actors/ovl_En_Aob_01/z_en_aob_01.c | 6 +- src/overlays/actors/ovl_En_Dg/z_en_dg.c | 1037 ++++++++++------- src/overlays/actors/ovl_En_Dg/z_en_dg.h | 43 +- .../actors/ovl_En_Racedog/z_en_racedog.c | 109 +- tools/disasm/functions.txt | 88 +- tools/disasm/variables.txt | 4 +- 7 files changed, 756 insertions(+), 533 deletions(-) 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),