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
This commit is contained in:
Tom Overton 2022-07-21 21:48:55 -07:00 committed by GitHub
parent d1d1bf8ec6
commit 905c089beb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 756 additions and 533 deletions

View File

@ -17,7 +17,7 @@
<Animation Name="gDogLyingDownAnim" Offset="0x1048" /> <!-- Original name is "dog_fuse" ("lying on the ground") -->
<Animation Name="gDogLyingDownLoopAnim" Offset="0x1348" /> <!-- Original name is "dog_fusetamama" ("lying on the ground continues") -->
<Animation Name="gDogJumpAnim" Offset="0x1560" /> <!-- Original name is "dog_jump" -->
<Animation Name="gDogJump2Anim" Offset="0x17C0" /> <!-- Original name is "dog_jump2" -->
<Animation Name="gDogJumpAttackAnim" Offset="0x17C0" /> <!-- Original name is "dog_jump2" -->
<Animation Name="gDogLongJumpAnim" Offset="0x1A84" /> <!-- Original name is "dog_longjump" -->
<Animation Name="gDogRunAnim" Offset="0x1BD8" /> <!-- Original name is "dog_run" -->
<Animation Name="gDogSitAnim" Offset="0x1FB0" /> <!-- Original name is "dog_sit" -->

View File

@ -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);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -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;

View File

@ -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)) {

View File

@ -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",),

View File

@ -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),