diff --git a/assets/xml/objects/object_oF1d_map.xml b/assets/xml/objects/object_oF1d_map.xml index 09a35dbd1c2..501a89dc993 100644 --- a/assets/xml/objects/object_oF1d_map.xml +++ b/assets/xml/objects/object_oF1d_map.xml @@ -1,37 +1,78 @@ + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + - + diff --git a/src/overlays/actors/ovl_Demo_Go/z_demo_go.c b/src/overlays/actors/ovl_Demo_Go/z_demo_go.c index 01c173dcc48..8d373a13f8c 100644 --- a/src/overlays/actors/ovl_Demo_Go/z_demo_go.c +++ b/src/overlays/actors/ovl_Demo_Go/z_demo_go.c @@ -254,7 +254,7 @@ void func_8097CEEC(DemoGo* this, PlayState* play) { } void func_8097CF20(DemoGo* this, PlayState* play, s32 arg2) { - AnimationHeader* animation = &gGoronAnim_0029A8; + AnimationHeader* animation = &gGoronWalkingAnim; if (arg2 != 0) { Animation_Change(&this->skelAnime, animation, 1.0f, 0.0f, Animation_GetLastFrame(animation), ANIMMODE_LOOP, -8.0f); @@ -328,7 +328,7 @@ void DemoGo_Update(Actor* thisx, PlayState* play) { void DemoGo_Init(Actor* thisx, PlayState* play) { DemoGo* this = (DemoGo*)thisx; - AnimationHeader* animation = &gGoronAnim_004930; + AnimationHeader* animation = &gGoronUncurlSitStandAnim; ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 30.0f); SkelAnime_InitFlex(play, &this->skelAnime, &gGoronSkel, NULL, NULL, NULL, 0); diff --git a/src/overlays/actors/ovl_En_Go/z_en_go.c b/src/overlays/actors/ovl_En_Go/z_en_go.c index e4f9a39ff7f..1de9faa7fb1 100644 --- a/src/overlays/actors/ovl_En_Go/z_en_go.c +++ b/src/overlays/actors/ovl_En_Go/z_en_go.c @@ -1,3 +1,7 @@ +/* @unused: unlike `ACTOR_EN_GO2`, this one doesn't participate in any scene whatsoever + * and nothing spawns this type of entities as well; see `z_en_go2.c` instead + */ + #include "z_en_go.h" #include "overlays/actors/ovl_En_Bom/z_en_bom.h" #include "assets/objects/gameplay_keep/gameplay_keep.h" @@ -12,24 +16,24 @@ void EnGo_Destroy(Actor* thisx, PlayState* play); void EnGo_Update(Actor* thisx, PlayState* play); void EnGo_Draw(Actor* thisx, PlayState* play); -void func_80A3FEB4(EnGo* this, PlayState* play); -void EnGo_StopRolling(EnGo* this, PlayState* play); -void func_80A4008C(EnGo* this, PlayState* play); -void EnGo_GoronLinkRolling(EnGo* this, PlayState* play); -void EnGo_FireGenericActionFunc(EnGo* this, PlayState* play); +void EnGo_RollingFar(EnGo* this, PlayState* play); +void EnGo_RollingNear(EnGo* this, PlayState* play); +void EnGo_RollingToCurledUp(EnGo* this, PlayState* play); +void EnGo_RollingLink(EnGo* this, PlayState* play); +void EnGo_GoronFireGeneric(EnGo* this, PlayState* play); void EnGo_CurledUp(EnGo* this, PlayState* play); -void EnGo_WakeUp(EnGo* this, PlayState* play); +void EnGo_AttentionDrawn(EnGo* this, PlayState* play); -void func_80A40494(EnGo* this, PlayState* play); -void func_80A405CC(EnGo* this, PlayState* play); -void EnGo_BiggoronActionFunc(EnGo* this, PlayState* play); -void func_80A408D8(EnGo* this, PlayState* play); +void EnGo_CurlUp(EnGo* this, PlayState* play); +void EnGo_Sitting(EnGo* this, PlayState* play); +void EnGo_Standing(EnGo* this, PlayState* play); +void EnGo_AttentionLost(EnGo* this, PlayState* play); -void func_80A40B1C(EnGo* this, PlayState* play); +void EnGo_GoronDmtBombFlower(EnGo* this, PlayState* play); +void EnGo_Interact(EnGo* this, PlayState* play); void EnGo_GetItem(EnGo* this, PlayState* play); -void func_80A40C78(EnGo* this, PlayState* play); -void EnGo_Eyedrops(EnGo* this, PlayState* play); -void func_80A40DCC(EnGo* this, PlayState* play); +void EnGo_TakingEyedrops(EnGo* this, PlayState* play); +void EnGo_EyedropsTaken(EnGo* this, PlayState* play); void EnGo_SpawnEffectDust(EnGo* this, Vec3f* pos, Vec3f* velocity, Vec3f* accel, u8 initialTimer, f32 scale, f32 scaleStep); @@ -71,17 +75,17 @@ static ColliderCylinderInit sCylinderInit = { static CollisionCheckInfoInit2 sColChkInfoInit = { 0, 0, 0, 0, MASS_IMMOVABLE }; typedef enum EnGoAnimation { - /* 0 */ ENGO_ANIM_0, - /* 1 */ ENGO_ANIM_1, - /* 2 */ ENGO_ANIM_2, - /* 3 */ ENGO_ANIM_3 + /* 0 */ ENGO_ANIM_UNCURL_SIT_STAND_DEFAULT, + /* 1 */ ENGO_ANIM_UNCURL_SIT_STAND_NORMAL, + /* 2 */ ENGO_ANIM_WALKING, + /* 3 */ ENGO_ANIM_SIDESTEP } EnGoAnimation; static AnimationSpeedInfo sAnimationInfo[] = { - { &gGoronAnim_004930, 0.0f, ANIMMODE_LOOP_INTERP, 0.0f }, - { &gGoronAnim_004930, 0.0f, ANIMMODE_LOOP_INTERP, -10.0f }, - { &gGoronAnim_0029A8, 1.0f, ANIMMODE_LOOP_INTERP, -10.0f }, - { &gGoronAnim_010590, 1.0f, ANIMMODE_LOOP_INTERP, -10.0f }, + { &gGoronUncurlSitStandAnim, 0.0f, ANIMMODE_LOOP_INTERP, 0.0f }, + { &gGoronUncurlSitStandAnim, 0.0f, ANIMMODE_LOOP_INTERP, -10.0f }, + { &gGoronWalkingAnim, 1.0f, ANIMMODE_LOOP_INTERP, -10.0f }, + { &gGoronSidestepAnim, 1.0f, ANIMMODE_LOOP_INTERP, -10.0f }, }; void EnGo_SetupAction(EnGo* this, EnGoActionFunc actionFunc) { @@ -91,8 +95,8 @@ void EnGo_SetupAction(EnGo* this, EnGoActionFunc actionFunc) { u16 EnGo_GetTextID(PlayState* play, Actor* thisx) { Player* player = GET_PLAYER(play); - switch (PARAMS_GET_NOSHIFT(thisx->params, 4, 4)) { - case 0x90: + switch (ENGO_GET_TYPE((EnGo*)thisx)) { + case ENGO_TYPE_DMT_BIGGORON: if (gSaveContext.save.info.playerData.bgsFlag) { return 0x305E; } else if (INV_CONTENT(ITEM_TRADE_ADULT) >= ITEM_CLAIM_CHECK) { @@ -110,7 +114,7 @@ u16 EnGo_GetTextID(PlayState* play, Actor* thisx) { player->exchangeItemId = EXCH_ITEM_BROKEN_GORONS_SWORD; return 0x3053; } - case 0x00: + case ENGO_TYPE_CITY_LINK: if (CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)) { if (GET_INFTABLE(INFTABLE_10F)) { return 0x3042; @@ -134,13 +138,13 @@ u16 EnGo_GetTextID(PlayState* play, Actor* thisx) { return 0x3030; } } - case 0x10: - if (Flags_GetSwitch(play, PARAMS_GET_NOMASK(thisx->params, 8))) { + case ENGO_TYPE_FIRE_GENERIC: + if (ENGO_IS_CAGE_OPEN((EnGo*)thisx, play)) { return 0x3052; } else { return 0x3051; } - case 0x20: + case ENGO_TYPE_DMT_DC_ENTRANCE: if (CHECK_QUEST_ITEM(QUEST_GORON_RUBY)) { return 0x3027; } else if (GET_EVENTCHKINF(EVENTCHKINF_23)) { @@ -150,7 +154,7 @@ u16 EnGo_GetTextID(PlayState* play, Actor* thisx) { } else { return 0x3008; } - case 0x30: + case ENGO_TYPE_DMT_ROLLING_SMALL: if (CHECK_QUEST_ITEM(QUEST_GORON_RUBY)) { return 0x3027; } else if (GET_EVENTCHKINF(EVENTCHKINF_23)) { @@ -158,7 +162,7 @@ u16 EnGo_GetTextID(PlayState* play, Actor* thisx) { } else { return 0x3009; } - case 0x40: + case ENGO_TYPE_DMT_BOMB_FLOWER: if (CHECK_QUEST_ITEM(QUEST_GORON_RUBY)) { return 0x3027; } else if (GET_EVENTCHKINF(EVENTCHKINF_23)) { @@ -166,7 +170,7 @@ u16 EnGo_GetTextID(PlayState* play, Actor* thisx) { } else { return 0x300A; } - case 0x50: + case ENGO_TYPE_CITY_ENTRANCE: if (CHECK_QUEST_ITEM(QUEST_GORON_RUBY)) { return 0x3027; } else if (GET_INFTABLE(INFTABLE_F0)) { @@ -174,7 +178,7 @@ u16 EnGo_GetTextID(PlayState* play, Actor* thisx) { } else { return 0x3014; } - case 0x60: + case ENGO_TYPE_CITY_ISLAND: if (CHECK_QUEST_ITEM(QUEST_GORON_RUBY)) { return 0x3027; } else if (GET_INFTABLE(INFTABLE_F4)) { @@ -182,7 +186,7 @@ u16 EnGo_GetTextID(PlayState* play, Actor* thisx) { } else { return 0x3016; } - case 0x70: + case ENGO_TYPE_CITY_LOST_WOODS: if (CHECK_QUEST_ITEM(QUEST_GORON_RUBY)) { return 0x3027; } else if (GET_INFTABLE(INFTABLE_F8)) { @@ -351,30 +355,27 @@ s32 EnGo_UpdateTalking(PlayState* play, Actor* thisx, s16* talkState, f32 intera void EnGo_ChangeAnim(EnGo* this, s32 index) { Animation_Change(&this->skelAnime, sAnimationInfo[index].animation, - sAnimationInfo[index].playSpeed * - (PARAMS_GET_NOSHIFT(this->actor.params, 4, 4) == 0x90 ? 0.5f : 1.0f), - 0.0f, Animation_GetLastFrame(sAnimationInfo[index].animation), sAnimationInfo[index].mode, + sAnimationInfo[index].playSpeed * ENGO_GET_SPEED_SCALE(this), 0.0f, + Animation_GetLastFrame(sAnimationInfo[index].animation), sAnimationInfo[index].mode, sAnimationInfo[index].morphFrames); } s32 EnGo_IsActorSpawned(EnGo* this, PlayState* play) { - if (((this->actor.params) & 0xF0) == 0x90) { + if (ENGO_GET_TYPE(this) == ENGO_TYPE_DMT_BIGGORON) { return true; - } else if (play->sceneId == SCENE_FIRE_TEMPLE && !Flags_GetSwitch(play, PARAMS_GET_NOMASK(this->actor.params, 8)) && - LINK_IS_ADULT && PARAMS_GET_NOSHIFT(this->actor.params, 4, 4) == 0x10) { + } else if (play->sceneId == SCENE_FIRE_TEMPLE && !ENGO_IS_CAGE_OPEN(this, play) && LINK_IS_ADULT && + ENGO_GET_TYPE(this) == ENGO_TYPE_FIRE_GENERIC) { return true; - } else if (play->sceneId == SCENE_GORON_CITY && LINK_IS_ADULT && - PARAMS_GET_NOSHIFT(this->actor.params, 4, 4) == 0x00) { + } else if (play->sceneId == SCENE_GORON_CITY && LINK_IS_ADULT && ENGO_GET_TYPE(this) == ENGO_TYPE_CITY_LINK) { return true; } else if (play->sceneId == SCENE_DEATH_MOUNTAIN_TRAIL && LINK_IS_CHILD && - (PARAMS_GET_NOSHIFT(this->actor.params, 4, 4) == 0x20 || - PARAMS_GET_NOSHIFT(this->actor.params, 4, 4) == 0x30 || - PARAMS_GET_NOSHIFT(this->actor.params, 4, 4) == 0x40)) { + (ENGO_GET_TYPE(this) == ENGO_TYPE_DMT_DC_ENTRANCE || + ENGO_GET_TYPE(this) == ENGO_TYPE_DMT_ROLLING_SMALL || + ENGO_GET_TYPE(this) == ENGO_TYPE_DMT_BOMB_FLOWER)) { return true; } else if (play->sceneId == SCENE_GORON_CITY && LINK_IS_CHILD && - (PARAMS_GET_NOSHIFT(this->actor.params, 4, 4) == 0x50 || - PARAMS_GET_NOSHIFT(this->actor.params, 4, 4) == 0x60 || - PARAMS_GET_NOSHIFT(this->actor.params, 4, 4) == 0x70)) { + (ENGO_GET_TYPE(this) == ENGO_TYPE_CITY_ENTRANCE || ENGO_GET_TYPE(this) == ENGO_TYPE_CITY_ISLAND || + ENGO_GET_TYPE(this) == ENGO_TYPE_CITY_LOST_WOODS)) { return true; } else { return false; @@ -382,28 +383,28 @@ s32 EnGo_IsActorSpawned(EnGo* this, PlayState* play) { } f32 EnGo_GetPlayerTrackingYOffset(EnGo* this) { - switch (PARAMS_GET_NOSHIFT(this->actor.params, 4, 4)) { - case 0x00: + switch (ENGO_GET_TYPE(this)) { + case ENGO_TYPE_CITY_LINK: return 10.0f; - case 0x20: - case 0x30: - case 0x50: - case 0x60: - case 0x70: + case ENGO_TYPE_DMT_DC_ENTRANCE: + case ENGO_TYPE_DMT_ROLLING_SMALL: + case ENGO_TYPE_CITY_ENTRANCE: + case ENGO_TYPE_CITY_ISLAND: + case ENGO_TYPE_CITY_LOST_WOODS: return 20.0f; - case 0x40: + case ENGO_TYPE_DMT_BOMB_FLOWER: return 60.0f; default: return 20.0f; } } -void func_80A3F060(EnGo* this, PlayState* play) { +void EnGo_TrackPlayer(EnGo* this, PlayState* play) { Player* player = GET_PLAYER(play); s16 trackingMode; - if (this->actionFunc != EnGo_BiggoronActionFunc && this->actionFunc != EnGo_FireGenericActionFunc && - this->actionFunc != func_80A40B1C) { + if (this->actionFunc != EnGo_Standing && this->actionFunc != EnGo_GoronFireGeneric && + this->actionFunc != EnGo_GoronDmtBombFlower) { trackingMode = NPC_TRACKING_NONE; } @@ -412,17 +413,20 @@ void func_80A3F060(EnGo* this, PlayState* play) { Npc_TrackPoint(&this->actor, &this->interactInfo, 4, trackingMode); } -void func_80A3F0E4(EnGo* this) { - if (DECR(this->unk_214) == 0) { - this->unk_216++; - if (this->unk_216 >= 3) { - this->unk_214 = Rand_S16Offset(30, 30); - this->unk_216 = 0; +void EnGo_UpdateBlinking(EnGo* this) { + // @unused + // although this function runs a similar logic as `EnGo2_EyeMouthTexState` + // its results are never used: this Goron always sets `gGoronCsEyeOpenTex` + if (DECR(this->blinkTimer) == 0) { + this->eyeTexIndex++; + if (this->eyeTexIndex >= 3) { + this->blinkTimer = Rand_S16Offset(30, 30); + this->eyeTexIndex = 0; } } } -s32 EnGo_IsCameraModified(EnGo* this, PlayState* play) { +s32 EnGo_IsInRange(EnGo* this, PlayState* play) { f32 xyzDistSq; s16 yawDiff = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; Camera* mainCam = play->cameraPtrs[CAM_ID_MAIN]; @@ -432,7 +436,7 @@ s32 EnGo_IsCameraModified(EnGo* this, PlayState* play) { } xyzDistSq = (this->actor.scale.x / 0.01f) * SQ(100.0f); - if (PARAMS_GET_NOSHIFT(this->actor.params, 4, 4) == 0x90) { + if (ENGO_GET_TYPE(this) == ENGO_TYPE_DMT_BIGGORON) { Camera_RequestSetting(mainCam, CAM_SET_DIRECTED_YAW); xyzDistSq *= 4.8f; } @@ -442,9 +446,9 @@ s32 EnGo_IsCameraModified(EnGo* this, PlayState* play) { Camera_RequestSetting(mainCam, CAM_SET_NORMAL0); } return 0; - } else { - return 1; } + + return 1; } void EnGo_ReverseAnimation(EnGo* this) { @@ -457,8 +461,8 @@ void EnGo_ReverseAnimation(EnGo* this) { void EnGo_UpdateShadow(EnGo* this) { s16 shadowAlpha; f32 currentFrame = this->skelAnime.curFrame; - s16 shadowAlphaTarget = (this->skelAnime.animation == &gGoronAnim_004930 && currentFrame > 32.0f) || - this->skelAnime.animation != &gGoronAnim_004930 + s16 shadowAlphaTarget = (this->skelAnime.animation == &gGoronUncurlSitStandAnim && currentFrame > 32.0f) || + this->skelAnime.animation != &gGoronUncurlSitStandAnim ? 255 : 0; @@ -473,29 +477,29 @@ s32 EnGo_FollowPath(EnGo* this, PlayState* play) { f32 xDist; f32 zDist; - if (PARAMS_GET_U(this->actor.params, 0, 4) == 15) { + if (ENGO_GET_PATH_INDEX(this) == ENGO_PATH_NONE) { return false; } - path = &play->pathList[PARAMS_GET_U(this->actor.params, 0, 4)]; + path = &play->pathList[ENGO_GET_PATH_INDEX(this)]; pointPos = SEGMENTED_TO_VIRTUAL(path->points); - pointPos += this->unk_218; + pointPos += this->waypoint; xDist = pointPos->x - this->actor.world.pos.x; zDist = pointPos->z - this->actor.world.pos.z; Math_SmoothStepToS(&this->actor.world.rot.y, RAD_TO_BINANG(Math_FAtan2F(xDist, zDist)), 10, 1000, 1); if ((SQ(xDist) + SQ(zDist)) < 600.0f) { - this->unk_218++; - if (this->unk_218 >= path->count) { - this->unk_218 = 0; + this->waypoint++; + if (this->waypoint >= path->count) { + this->waypoint = 0; } - if (PARAMS_GET_NOSHIFT(this->actor.params, 4, 4) != 0x00) { + if (ENGO_GET_TYPE(this) != ENGO_TYPE_CITY_LINK) { return true; - } else if (Flags_GetSwitch(play, PARAMS_GET_NOMASK(this->actor.params, 8))) { + } else if (ENGO_IS_CAGE_OPEN(this, play)) { return true; - } else if (this->unk_218 >= this->actor.shape.rot.z) { - this->unk_218 = 0; + } else if (this->waypoint >= this->actor.shape.rot.z) { + this->waypoint = 0; } return true; @@ -508,10 +512,10 @@ s32 EnGo_SetMovedPos(EnGo* this, PlayState* play) { Path* path; Vec3s* pointPos; - if (PARAMS_GET_U(this->actor.params, 0, 4) == 0xF) { + if (ENGO_GET_PATH_INDEX(this) == ENGO_PATH_NONE) { return false; } else { - path = &play->pathList[PARAMS_GET_U(this->actor.params, 0, 4)]; + path = &play->pathList[ENGO_GET_PATH_INDEX(this)]; pointPos = SEGMENTED_TO_VIRTUAL(path->points); pointPos += (path->count - 1); this->actor.world.pos.x = pointPos->x; @@ -545,51 +549,59 @@ s32 EnGo_SpawnDust(EnGo* this, u8 initialTimer, f32 scale, f32 scaleStep, s32 nu return 0; } -s32 EnGo_IsRollingOnGround(EnGo* this, s16 unkArg1, f32 unkArg2) { +s32 EnGo_IsRollingOnGround(EnGo* this, s16 bounceCount, f32 boundSpeed) { if (!(this->actor.bgCheckFlags & BGCHECKFLAG_GROUND) || this->actor.velocity.y > 0.0f) { return false; - } else if (this->interactInfo.talkState != NPC_TALK_STATE_IDLE) { + } + + if (this->interactInfo.talkState != NPC_TALK_STATE_IDLE) { return true; - } else if (DECR(this->unk_21C)) { - if (this->unk_21C & 1) { + } + + // rumble on odds and evens + if (DECR(this->bounceTimer)) { + if (this->bounceTimer & 1) { this->actor.world.pos.y += 1.5f; } else { this->actor.world.pos.y -= 1.5f; } return true; - } else { - this->unk_21A--; - if (this->unk_21A <= 0) { - if (this->unk_21A == 0) { - this->unk_21C = Rand_S16Offset(60, 30); - this->unk_21A = 0; + } + + // bounce! + { + this->bounceCounter--; + if (this->bounceCounter <= 0) { + if (this->bounceCounter == 0) { + this->bounceTimer = Rand_S16Offset(60, 30); + this->bounceCounter = 0; this->actor.velocity.y = 0.0f; return true; } - this->unk_21A = unkArg1; + this->bounceCounter = bounceCount; } - this->actor.velocity.y = ((f32)this->unk_21A / (f32)unkArg1) * unkArg2; + this->actor.velocity.y = ((f32)this->bounceCounter / (f32)bounceCount) * boundSpeed; return true; } } -void func_80A3F908(EnGo* this, PlayState* play) { +void EnGo_UpdateInteraction(EnGo* this, PlayState* play) { Player* player = GET_PLAYER(play); f32 interactRange; s32 dialogStarted; - if (this->actionFunc == EnGo_BiggoronActionFunc || this->actionFunc == EnGo_GoronLinkRolling || - this->actionFunc == EnGo_FireGenericActionFunc || this->actionFunc == EnGo_Eyedrops || - this->actionFunc == func_80A40DCC || this->actionFunc == EnGo_GetItem || this->actionFunc == func_80A40C78 || - this->actionFunc == func_80A40B1C) { + if (this->actionFunc == EnGo_Standing || this->actionFunc == EnGo_RollingLink || + this->actionFunc == EnGo_GoronFireGeneric || this->actionFunc == EnGo_TakingEyedrops || + this->actionFunc == EnGo_EyedropsTaken || this->actionFunc == EnGo_Interact || + this->actionFunc == EnGo_GetItem || this->actionFunc == EnGo_GoronDmtBombFlower) { interactRange = (this->collider.dim.radius + 30.0f); interactRange *= (this->actor.scale.x / 0.01f); - if (PARAMS_GET_NOSHIFT(this->actor.params, 4, 4) == 0x90) { + if (ENGO_GET_TYPE(this) == ENGO_TYPE_DMT_BIGGORON) { interactRange *= 4.8f; } - if (PARAMS_GET_NOSHIFT(this->actor.params, 4, 4) == 0x90) { + if (ENGO_GET_TYPE(this) == ENGO_TYPE_DMT_BIGGORON) { dialogStarted = EnGo_UpdateTalking(play, &this->actor, &this->interactInfo.talkState, interactRange, EnGo_GetTextID, EnGo_UpdateTalkState); } else { @@ -597,7 +609,7 @@ void func_80A3F908(EnGo* this, PlayState* play) { EnGo_GetTextID, EnGo_UpdateTalkState); } - if ((PARAMS_GET_NOSHIFT(this->actor.params, 4, 4) == 0x90) && (dialogStarted == true)) { + if ((ENGO_GET_TYPE(this) == ENGO_TYPE_DMT_BIGGORON) && (dialogStarted == true)) { if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_BROKEN_GORONS_SWORD) { if (func_8002F368(play) == EXCH_ITEM_BROKEN_GORONS_SWORD) { if (GET_INFTABLE(INFTABLE_B4)) { @@ -640,18 +652,18 @@ void EnGo_Init(Actor* thisx, PlayState* play) { return; } - if (PARAMS_GET_NOSHIFT(this->actor.params, 4, 4) && (PARAMS_GET_NOSHIFT(this->actor.params, 4, 4) != 0x90)) { + if (ENGO_GET_TYPE(this) && (ENGO_GET_TYPE(this) != ENGO_TYPE_DMT_BIGGORON)) { this->actor.flags &= ~ACTOR_FLAG_UPDATE_CULLING_DISABLED; this->actor.flags &= ~ACTOR_FLAG_DRAW_CULLING_DISABLED; } - EnGo_ChangeAnim(this, ENGO_ANIM_0); + EnGo_ChangeAnim(this, ENGO_ANIM_UNCURL_SIT_STAND_DEFAULT); this->actor.attentionRangeType = ATTENTION_RANGE_6; this->interactInfo.talkState = NPC_TALK_STATE_IDLE; this->actor.gravity = -1.0f; - switch (PARAMS_GET_NOSHIFT(this->actor.params, 4, 4)) { - case 0x00: + switch (ENGO_GET_TYPE(this)) { + case ENGO_TYPE_CITY_LINK: Actor_SetScale(&this->actor, 0.008f); if (CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_GORON)) { EnGo_SetMovedPos(this, play); @@ -659,35 +671,35 @@ void EnGo_Init(Actor* thisx, PlayState* play) { } else { this->actor.shape.yOffset = 1400.0f; this->actor.speed = 3.0f; - EnGo_SetupAction(this, EnGo_GoronLinkRolling); + EnGo_SetupAction(this, EnGo_RollingLink); } break; - case 0x10: - this->skelAnime.curFrame = Animation_GetLastFrame(&gGoronAnim_004930); + case ENGO_TYPE_FIRE_GENERIC: + this->skelAnime.curFrame = Animation_GetLastFrame(&gGoronUncurlSitStandAnim); Actor_SetScale(&this->actor, 0.01f); - EnGo_SetupAction(this, EnGo_FireGenericActionFunc); + EnGo_SetupAction(this, EnGo_GoronFireGeneric); break; - case 0x40: + case ENGO_TYPE_DMT_BOMB_FLOWER: if (GET_INFTABLE(INFTABLE_EB)) { EnGo_SetMovedPos(this, play); } Actor_SetScale(&this->actor, 0.015f); EnGo_SetupAction(this, EnGo_CurledUp); break; - case 0x30: + case ENGO_TYPE_DMT_ROLLING_SMALL: this->actor.shape.yOffset = 1400.0f; Actor_SetScale(&this->actor, 0.01f); - EnGo_SetupAction(this, func_80A3FEB4); + EnGo_SetupAction(this, EnGo_RollingFar); break; - case 0x90: + case ENGO_TYPE_DMT_BIGGORON: this->actor.attentionRangeType = ATTENTION_RANGE_5; Actor_SetScale(&this->actor, 0.16f); EnGo_SetupAction(this, EnGo_CurledUp); break; - case 0x20: - case 0x50: - case 0x60: - case 0x70: + case ENGO_TYPE_DMT_DC_ENTRANCE: + case ENGO_TYPE_CITY_ENTRANCE: + case ENGO_TYPE_CITY_ISLAND: + case ENGO_TYPE_CITY_LOST_WOODS: Actor_SetScale(&this->actor, 0.01f); EnGo_SetupAction(this, EnGo_CurledUp); break; @@ -703,26 +715,26 @@ void EnGo_Destroy(Actor* thisx, PlayState* play) { Collider_DestroyCylinder(play, &this->collider); } -void func_80A3FEB4(EnGo* this, PlayState* play) { +void EnGo_RollingFar(EnGo* this, PlayState* play) { if (!(this->actor.xyzDistToPlayerSq > SQ(1200.0f))) { - EnGo_SetupAction(this, EnGo_StopRolling); + EnGo_SetupAction(this, EnGo_RollingNear); } } -void EnGo_StopRolling(EnGo* this, PlayState* play) { +void EnGo_RollingNear(EnGo* this, PlayState* play) { EnBom* bomb; - if (DECR(this->unk_20E) == 0) { + if (DECR(this->knockbackCooldown) == 0) { if (this->collider.base.ocFlags2 & OC2_HIT_PLAYER) { this->collider.base.ocFlags2 &= ~OC2_HIT_PLAYER; play->damagePlayer(play, -4); Actor_SetPlayerKnockbackLargeNoDamage(play, &this->actor, 4.0f, this->actor.yawTowardsPlayer, 6.0f); - this->unk_20E = 0x10; + this->knockbackCooldown = 0x10; } } this->actor.speed = 3.0f; - if ((EnGo_FollowPath(this, play) == true) && (this->unk_218 == 0)) { + if ((EnGo_FollowPath(this, play) == true) && (this->waypoint == 0)) { bomb = (EnBom*)Actor_Spawn(&play->actorCtx, play, ACTOR_EN_BOM, this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, 0); if (bomb != NULL) { @@ -730,7 +742,7 @@ void EnGo_StopRolling(EnGo* this, PlayState* play) { } this->actor.speed = 0.0f; - EnGo_SetupAction(this, func_80A4008C); + EnGo_SetupAction(this, EnGo_RollingToCurledUp); } this->actor.shape.rot = this->actor.world.rot; @@ -740,9 +752,9 @@ void EnGo_StopRolling(EnGo* this, PlayState* play) { } } -void func_80A4008C(EnGo* this, PlayState* play) { +void EnGo_RollingToCurledUp(EnGo* this, PlayState* play) { if (EnGo_IsRollingOnGround(this, 3, 6.0f)) { - if (this->unk_21A == 0) { + if (this->bounceCounter == 0) { this->actor.shape.yOffset = 0.0f; EnGo_SetupAction(this, EnGo_CurledUp); } else { @@ -751,11 +763,10 @@ void func_80A4008C(EnGo* this, PlayState* play) { } } -void EnGo_GoronLinkRolling(EnGo* this, PlayState* play) { - if ((EnGo_FollowPath(this, play) == true) && Flags_GetSwitch(play, PARAMS_GET_NOMASK(this->actor.params, 8)) && - (this->unk_218 == 0)) { +void EnGo_RollingLink(EnGo* this, PlayState* play) { + if ((EnGo_FollowPath(this, play) == true) && ENGO_IS_CAGE_OPEN(this, play) && (this->waypoint == 0)) { this->actor.speed = 0.0f; - EnGo_SetupAction(this, func_80A4008C); + EnGo_SetupAction(this, EnGo_RollingToCurledUp); SET_INFTABLE(INFTABLE_109); } @@ -766,31 +777,29 @@ void EnGo_GoronLinkRolling(EnGo* this, PlayState* play) { } } -void EnGo_FireGenericActionFunc(EnGo* this, PlayState* play) { +void EnGo_GoronFireGeneric(EnGo* this, PlayState* play) { } void EnGo_CurledUp(EnGo* this, PlayState* play) { - if ((DECR(this->unk_210) == 0) && EnGo_IsCameraModified(this, play)) { + if ((DECR(this->curledTimer) == 0) && EnGo_IsInRange(this, play)) { Audio_PlaySfxGeneral(NA_SE_EN_GOLON_WAKE_UP, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->skelAnime.playSpeed = 0.1f; - this->skelAnime.playSpeed *= PARAMS_GET_NOSHIFT(this->actor.params, 4, 4) == 0x90 ? 0.5f : 1.0f; + this->skelAnime.playSpeed *= ENGO_GET_SPEED_SCALE(this); - EnGo_SetupAction(this, EnGo_WakeUp); - if (PARAMS_GET_NOSHIFT(this->actor.params, 4, 4) == 0x90) { + EnGo_SetupAction(this, EnGo_AttentionDrawn); + if (ENGO_GET_TYPE(this) == ENGO_TYPE_DMT_BIGGORON) { OnePointCutscene_Init(play, 4200, -99, &this->actor, CAM_ID_MAIN); } } } -void EnGo_WakeUp(EnGo* this, PlayState* play) { +void EnGo_AttentionDrawn(EnGo* this, PlayState* play) { f32 frame; if (this->skelAnime.playSpeed != 0.0f) { - Math_SmoothStepToF(&this->skelAnime.playSpeed, - (PARAMS_GET_NOSHIFT(this->actor.params, 4, 4) == 0x90 ? 0.5f : 1.0f) * 0.5f, 0.1f, 1000.0f, - 0.1f); + Math_SmoothStepToF(&this->skelAnime.playSpeed, ENGO_GET_SPEED_SCALE(this) * 0.5f, 0.1f, 1000.0f, 0.1f); frame = this->skelAnime.curFrame; frame += this->skelAnime.playSpeed; @@ -799,30 +808,28 @@ void EnGo_WakeUp(EnGo* this, PlayState* play) { } else { this->skelAnime.curFrame = 12.0f; this->skelAnime.playSpeed = 0.0f; - if (PARAMS_GET_NOSHIFT(this->actor.params, 4, 4) != 0x90) { - this->unk_212 = 30; + if (ENGO_GET_TYPE(this) != ENGO_TYPE_DMT_BIGGORON) { + this->attentionCooldown = 30; return; } } } - if (DECR(this->unk_212) == 0) { + if (DECR(this->attentionCooldown) == 0) { Audio_PlaySfxGeneral(NA_SE_EN_GOLON_SIT_DOWN, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); - EnGo_SetupAction(this, func_80A405CC); - } else if (!EnGo_IsCameraModified(this, play)) { + EnGo_SetupAction(this, EnGo_Sitting); + } else if (!EnGo_IsInRange(this, play)) { EnGo_ReverseAnimation(this); this->skelAnime.playSpeed = 0.0f; - EnGo_SetupAction(this, func_80A40494); + EnGo_SetupAction(this, EnGo_CurlUp); } } -void func_80A40494(EnGo* this, PlayState* play) { +void EnGo_CurlUp(EnGo* this, PlayState* play) { f32 frame; - Math_SmoothStepToF(&this->skelAnime.playSpeed, - (PARAMS_GET_NOSHIFT(this->actor.params, 4, 4) == 0x90 ? 0.5f : 1.0f) * -0.5f, 0.1f, 1000.0f, - 0.1f); + Math_SmoothStepToF(&this->skelAnime.playSpeed, ENGO_GET_SPEED_SCALE(this) * -0.5f, 0.1f, 1000.0f, 0.1f); frame = this->skelAnime.curFrame; frame += this->skelAnime.playSpeed; @@ -833,18 +840,17 @@ void func_80A40494(EnGo* this, PlayState* play) { EnGo_ReverseAnimation(this); this->skelAnime.playSpeed = 0.0f; this->skelAnime.curFrame = 0.0f; - this->unk_210 = Rand_S16Offset(30, 30); + this->curledTimer = Rand_S16Offset(30, 30); EnGo_SetupAction(this, EnGo_CurledUp); } } -void func_80A405CC(EnGo* this, PlayState* play) { +void EnGo_Sitting(EnGo* this, PlayState* play) { f32 lastFrame; f32 frame; - lastFrame = Animation_GetLastFrame(&gGoronAnim_004930); - Math_SmoothStepToF(&this->skelAnime.playSpeed, PARAMS_GET_NOSHIFT(this->actor.params, 4, 4) == 0x90 ? 0.5f : 1.0f, - 0.1f, 1000.0f, 0.1f); + lastFrame = Animation_GetLastFrame(&gGoronUncurlSitStandAnim); + Math_SmoothStepToF(&this->skelAnime.playSpeed, ENGO_GET_SPEED_SCALE(this), 0.1f, 1000.0f, 0.1f); frame = this->skelAnime.curFrame; frame += this->skelAnime.playSpeed; @@ -852,58 +858,56 @@ void func_80A405CC(EnGo* this, PlayState* play) { if (!(frame < lastFrame)) { this->skelAnime.curFrame = lastFrame; this->skelAnime.playSpeed = 0.0f; - this->unk_212 = Rand_S16Offset(30, 30); - if ((PARAMS_GET_NOSHIFT(this->actor.params, 4, 4) == 0x40) && !GET_INFTABLE(INFTABLE_EB)) { - EnGo_SetupAction(this, func_80A40B1C); + this->attentionCooldown = Rand_S16Offset(30, 30); + if ((ENGO_GET_TYPE(this) == ENGO_TYPE_DMT_BOMB_FLOWER) && !GET_INFTABLE(INFTABLE_EB)) { + EnGo_SetupAction(this, EnGo_GoronDmtBombFlower); } else { - EnGo_SetupAction(this, EnGo_BiggoronActionFunc); + EnGo_SetupAction(this, EnGo_Standing); } } } -void EnGo_BiggoronActionFunc(EnGo* this, PlayState* play) { - if ((PARAMS_GET_NOSHIFT(this->actor.params, 4, 4) == 0x90) && - (this->interactInfo.talkState == NPC_TALK_STATE_ACTION)) { +void EnGo_Standing(EnGo* this, PlayState* play) { + if ((ENGO_GET_TYPE(this) == ENGO_TYPE_DMT_BIGGORON) && (this->interactInfo.talkState == NPC_TALK_STATE_ACTION)) { if (gSaveContext.save.info.playerData.bgsFlag) { this->interactInfo.talkState = NPC_TALK_STATE_IDLE; } else { if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_EYE_DROPS) { - EnGo_ChangeAnim(this, ENGO_ANIM_2); - this->unk_21E = 100; + //! @bug: `gGoronEyedropsAnim` is not applied; see `z_en_go2.c` for the correct behaviour + EnGo_ChangeAnim(this, ENGO_ANIM_WALKING); + this->eyedropsTimer = 100; this->interactInfo.talkState = NPC_TALK_STATE_IDLE; - EnGo_SetupAction(this, EnGo_Eyedrops); + EnGo_SetupAction(this, EnGo_TakingEyedrops); play->msgCtx.msgMode = MSGMODE_PAUSED; gSaveContext.subTimerState = SUBTIMER_STATE_OFF; OnePointCutscene_Init(play, 4190, -99, &this->actor, CAM_ID_MAIN); } else { this->interactInfo.talkState = NPC_TALK_STATE_IDLE; - EnGo_SetupAction(this, EnGo_GetItem); + EnGo_SetupAction(this, EnGo_Interact); Message_CloseTextbox(play); - EnGo_GetItem(this, play); + EnGo_Interact(this, play); } } - } else if ((PARAMS_GET_NOSHIFT(this->actor.params, 4, 4) == 0) && + } else if ((ENGO_GET_TYPE(this) == ENGO_TYPE_CITY_LINK) && (this->interactInfo.talkState == NPC_TALK_STATE_ACTION)) { - EnGo_SetupAction(this, EnGo_GetItem); + EnGo_SetupAction(this, EnGo_Interact); play->msgCtx.stateTimer = 4; play->msgCtx.msgMode = MSGMODE_TEXT_CLOSING; } else { - if ((DECR(this->unk_212) == 0) && !EnGo_IsCameraModified(this, play)) { + if ((DECR(this->attentionCooldown) == 0) && !EnGo_IsInRange(this, play)) { EnGo_ReverseAnimation(this); this->skelAnime.playSpeed = -0.1f; - this->skelAnime.playSpeed *= PARAMS_GET_NOSHIFT(this->actor.params, 4, 4) == 0x90 ? 0.5f : 1.0f; - EnGo_SetupAction(this, func_80A408D8); + this->skelAnime.playSpeed *= ENGO_GET_SPEED_SCALE(this); + EnGo_SetupAction(this, EnGo_AttentionLost); } } } -void func_80A408D8(EnGo* this, PlayState* play) { +void EnGo_AttentionLost(EnGo* this, PlayState* play) { f32 frame; if (this->skelAnime.playSpeed != 0.0f) { - Math_SmoothStepToF(&this->skelAnime.playSpeed, - (PARAMS_GET_NOSHIFT(this->actor.params, 4, 4) == 0x90 ? 0.5f : 1.0f) * -1.0f, 0.1f, 1000.0f, - 0.1f); + Math_SmoothStepToF(&this->skelAnime.playSpeed, ENGO_GET_SPEED_SCALE(this) * -1.0f, 0.1f, 1000.0f, 0.1f); frame = this->skelAnime.curFrame; frame += this->skelAnime.playSpeed; if (frame >= 12.0f) { @@ -911,47 +915,47 @@ void func_80A408D8(EnGo* this, PlayState* play) { } else { this->skelAnime.curFrame = 12.0f; this->skelAnime.playSpeed = 0.0f; - if (PARAMS_GET_NOSHIFT(this->actor.params, 4, 4) != 0x90) { - this->unk_212 = 30; + if (ENGO_GET_TYPE(this) != ENGO_TYPE_DMT_BIGGORON) { + this->attentionCooldown = 30; return; } } } - if (DECR(this->unk_212) == 0) { - EnGo_SetupAction(this, func_80A40494); - } else if (EnGo_IsCameraModified(this, play)) { + if (DECR(this->attentionCooldown) == 0) { + EnGo_SetupAction(this, EnGo_CurlUp); + } else if (EnGo_IsInRange(this, play)) { EnGo_ReverseAnimation(this); Audio_PlaySfxGeneral(NA_SE_EN_GOLON_SIT_DOWN, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->skelAnime.playSpeed = 0.0f; - EnGo_SetupAction(this, func_80A405CC); + EnGo_SetupAction(this, EnGo_Sitting); } } -void func_80A40A54(EnGo* this, PlayState* play) { - f32 float1 = ((f32)0x8000 / Animation_GetLastFrame(&gGoronAnim_010590)); +void EnGo_Sidestep(EnGo* this, PlayState* play) { + f32 float1 = ((f32)0x8000 / Animation_GetLastFrame(&gGoronSidestepAnim)); f32 float2 = this->skelAnime.curFrame * float1; this->actor.speed = Math_SinS((s16)float2); - if (EnGo_FollowPath(this, play) && this->unk_218 == 0) { - EnGo_ChangeAnim(this, ENGO_ANIM_1); - this->skelAnime.curFrame = Animation_GetLastFrame(&gGoronAnim_004930); + if (EnGo_FollowPath(this, play) && this->waypoint == 0) { + EnGo_ChangeAnim(this, ENGO_ANIM_UNCURL_SIT_STAND_NORMAL); + this->skelAnime.curFrame = Animation_GetLastFrame(&gGoronUncurlSitStandAnim); this->actor.speed = 0.0f; - EnGo_SetupAction(this, EnGo_BiggoronActionFunc); + EnGo_SetupAction(this, EnGo_Standing); } } -void func_80A40B1C(EnGo* this, PlayState* play) { +void EnGo_GoronDmtBombFlower(EnGo* this, PlayState* play) { if (GET_INFTABLE(INFTABLE_EB)) { - EnGo_ChangeAnim(this, ENGO_ANIM_3); - EnGo_SetupAction(this, func_80A40A54); + EnGo_ChangeAnim(this, ENGO_ANIM_SIDESTEP); + EnGo_SetupAction(this, EnGo_Sidestep); } else { - EnGo_BiggoronActionFunc(this, play); + EnGo_Standing(this, play); } } -void EnGo_GetItem(EnGo* this, PlayState* play) { +void EnGo_Interact(EnGo* this, PlayState* play) { f32 xzDist; f32 yDist; s32 getItemId; @@ -959,13 +963,13 @@ void EnGo_GetItem(EnGo* this, PlayState* play) { if (Actor_HasParent(&this->actor, play)) { this->interactInfo.talkState = NPC_TALK_STATE_ACTION; this->actor.parent = NULL; - EnGo_SetupAction(this, func_80A40C78); + EnGo_SetupAction(this, EnGo_GetItem); } else { - this->unk_20C = 0; - if (PARAMS_GET_NOSHIFT(this->actor.params, 4, 4) == 0x90) { + this->gaveSword = 0; + if (ENGO_GET_TYPE(this) == ENGO_TYPE_DMT_BIGGORON) { if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_CLAIM_CHECK) { getItemId = GI_SWORD_BIGGORON; - this->unk_20C = 1; + this->gaveSword = 1; } if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_EYE_DROPS) { getItemId = GI_CLAIM_CHECK; @@ -975,7 +979,7 @@ void EnGo_GetItem(EnGo* this, PlayState* play) { } } - if (PARAMS_GET_NOSHIFT(this->actor.params, 4, 4) == 0) { + if (ENGO_GET_TYPE(this) == ENGO_TYPE_CITY_LINK) { getItemId = GI_TUNIC_GORON; } @@ -985,12 +989,12 @@ void EnGo_GetItem(EnGo* this, PlayState* play) { } } -void func_80A40C78(EnGo* this, PlayState* play) { +void EnGo_GetItem(EnGo* this, PlayState* play) { if (this->interactInfo.talkState == NPC_TALK_STATE_ITEM_GIVEN) { - EnGo_SetupAction(this, EnGo_BiggoronActionFunc); - if (PARAMS_GET_NOSHIFT(this->actor.params, 4, 4) != 0x90) { + EnGo_SetupAction(this, EnGo_Standing); + if (ENGO_GET_TYPE(this) != ENGO_TYPE_DMT_BIGGORON) { this->interactInfo.talkState = NPC_TALK_STATE_IDLE; - } else if (this->unk_20C) { + } else if (this->gaveSword) { this->interactInfo.talkState = NPC_TALK_STATE_IDLE; gSaveContext.save.info.playerData.bgsFlag = true; } else if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_PRESCRIPTION) { @@ -1006,22 +1010,23 @@ void func_80A40C78(EnGo* this, PlayState* play) { } } -void EnGo_Eyedrops(EnGo* this, PlayState* play) { - if (DECR(this->unk_21E) == 0) { +void EnGo_TakingEyedrops(EnGo* this, PlayState* play) { + if (DECR(this->eyedropsTimer) == 0) { + //! @bug: `gGoronEyedropsTakenAnim` is not applied; see `z_en_go2.c` for the correct behaviour this->actor.textId = 0x305A; Message_ContinueTextbox(play, this->actor.textId); this->interactInfo.talkState = NPC_TALK_STATE_TALKING; - EnGo_SetupAction(this, func_80A40DCC); + EnGo_SetupAction(this, EnGo_EyedropsTaken); } } -void func_80A40DCC(EnGo* this, PlayState* play) { +void EnGo_EyedropsTaken(EnGo* this, PlayState* play) { if (this->interactInfo.talkState == NPC_TALK_STATE_ACTION) { - EnGo_ChangeAnim(this, ENGO_ANIM_1); - this->skelAnime.curFrame = Animation_GetLastFrame(&gGoronAnim_004930); + EnGo_ChangeAnim(this, ENGO_ANIM_UNCURL_SIT_STAND_NORMAL); + this->skelAnime.curFrame = Animation_GetLastFrame(&gGoronUncurlSitStandAnim); Message_CloseTextbox(play); - EnGo_SetupAction(this, EnGo_GetItem); - EnGo_GetItem(this, play); + EnGo_SetupAction(this, EnGo_Interact); + EnGo_Interact(this, play); } } @@ -1033,9 +1038,9 @@ void EnGo_Update(Actor* thisx, PlayState* play) { CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base); SkelAnime_Update(&this->skelAnime); - if (this->actionFunc == EnGo_BiggoronActionFunc || this->actionFunc == EnGo_FireGenericActionFunc || - this->actionFunc == func_80A40B1C) { - Actor_UpdateFidgetTables(play, this->fidgetTableY, this->fidgetTableZ, 18); + if (this->actionFunc == EnGo_Standing || this->actionFunc == EnGo_GoronFireGeneric || + this->actionFunc == EnGo_GoronDmtBombFlower) { + Actor_UpdateFidgetTables(play, this->fidgetTableY, this->fidgetTableZ, GORON_LIMB_MAX); } EnGo_UpdateShadow(this); @@ -1045,14 +1050,14 @@ void EnGo_Update(Actor* thisx, PlayState* play) { } Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 0.0f, 0.0f, UPDBGCHECKINFO_FLAG_2); - func_80A3F0E4(this); - func_80A3F908(this, play); + EnGo_UpdateBlinking(this); + EnGo_UpdateInteraction(this, play); this->actionFunc(this, play); - func_80A3F060(this, play); + EnGo_TrackPlayer(this, play); } void EnGo_DrawCurledUp(EnGo* this, PlayState* play) { - Vec3f D_80A41BB4 = { 0.0f, 0.0f, 0.0f }; + Vec3f focusOffset = { 0.0f, 0.0f, 0.0f }; OPEN_DISPS(play->state.gfxCtx, "../z_en_go.c", 2320); @@ -1061,16 +1066,16 @@ void EnGo_DrawCurledUp(EnGo* this, PlayState* play) { MATRIX_FINALIZE_AND_LOAD(POLY_OPA_DISP++, play->state.gfxCtx, "../z_en_go.c", 2326); - gSPDisplayList(POLY_OPA_DISP++, gGoronDL_00BD80); + gSPDisplayList(POLY_OPA_DISP++, gGoronCurledUpDL); - Matrix_MultVec3f(&D_80A41BB4, &this->actor.focus.pos); + Matrix_MultVec3f(&focusOffset, &this->actor.focus.pos); Matrix_Pop(); CLOSE_DISPS(play->state.gfxCtx, "../z_en_go.c", 2341); } void EnGo_DrawRolling(EnGo* this, PlayState* play) { - Vec3f D_80A41BC0 = { 0.0f, 0.0f, 0.0f }; + Vec3f focusOffset = { 0.0f, 0.0f, 0.0f }; OPEN_DISPS(play->state.gfxCtx, "../z_en_go.c", 2355); @@ -1079,8 +1084,8 @@ void EnGo_DrawRolling(EnGo* this, PlayState* play) { Matrix_RotateZYX((s16)(play->state.frames * ((s16)this->actor.speed * 1400)), 0, this->actor.shape.rot.z, MTXMODE_APPLY); MATRIX_FINALIZE_AND_LOAD(POLY_OPA_DISP++, play->state.gfxCtx, "../z_en_go.c", 2368); - gSPDisplayList(POLY_OPA_DISP++, gGoronDL_00C140); - Matrix_MultVec3f(&D_80A41BC0, &this->actor.focus.pos); + gSPDisplayList(POLY_OPA_DISP++, gGoronRollingDL); + Matrix_MultVec3f(&focusOffset, &this->actor.focus.pos); Matrix_Pop(); CLOSE_DISPS(play->state.gfxCtx, "../z_en_go.c", 2383); @@ -1090,7 +1095,7 @@ s32 EnGo_OverrideLimbDraw(PlayState* play, s32 limb, Gfx** dList, Vec3f* pos, Ve EnGo* this = (EnGo*)thisx; Vec3s limbRot; - if (limb == 17) { + if (limb == GORON_LIMB_HEAD) { Matrix_Translate(2800.0f, 0.0f, 0.0f, MTXMODE_APPLY); limbRot = this->interactInfo.headRot; Matrix_RotateX(BINANG_TO_RAD_ALT(limbRot.y), MTXMODE_APPLY); @@ -1098,13 +1103,13 @@ s32 EnGo_OverrideLimbDraw(PlayState* play, s32 limb, Gfx** dList, Vec3f* pos, Ve Matrix_Translate(-2800.0f, 0.0f, 0.0f, MTXMODE_APPLY); } - if (limb == 10) { + if (limb == GORON_LIMB_TORSO) { limbRot = this->interactInfo.torsoRot; Matrix_RotateY(BINANG_TO_RAD_ALT(limbRot.y), MTXMODE_APPLY); Matrix_RotateX(BINANG_TO_RAD_ALT(limbRot.x), MTXMODE_APPLY); } - if ((limb == 10) || (limb == 11) || (limb == 14)) { + if ((limb == GORON_LIMB_TORSO) || (limb == GORON_LIMB_LEFT_ARM) || (limb == GORON_LIMB_RIGHT_ARM)) { rot->y += Math_SinS(this->fidgetTableY[limb]) * FIDGET_AMPLITUDE; rot->z += Math_CosS(this->fidgetTableZ[limb]) * FIDGET_AMPLITUDE; } @@ -1114,10 +1119,10 @@ s32 EnGo_OverrideLimbDraw(PlayState* play, s32 limb, Gfx** dList, Vec3f* pos, Ve void EnGo_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx) { EnGo* this = (EnGo*)thisx; - Vec3f D_80A41BCC = { 600.0f, 0.0f, 0.0f }; + Vec3f focusOffset = { 600.0f, 0.0f, 0.0f }; // ahead, this distance - if (limbIndex == 17) { - Matrix_MultVec3f(&D_80A41BCC, &this->actor.focus.pos); + if (limbIndex == GORON_LIMB_HEAD) { + Matrix_MultVec3f(&focusOffset, &this->actor.focus.pos); } } @@ -1133,22 +1138,27 @@ void EnGo_Draw(Actor* thisx, PlayState* play) { if (this->actionFunc == EnGo_CurledUp) { EnGo_DrawCurledUp(this, play); - return; // needed for match? - } else if (this->actionFunc == EnGo_GoronLinkRolling || this->actionFunc == func_80A3FEB4 || - this->actionFunc == EnGo_StopRolling || this->actionFunc == func_80A3FEB4) { + return; + } + + //! @bug? should've been `EnGo_RollingToCurledUp` instead of the second `EnGo_RollingFar` + //! in that state bouncing Goron will be drawn normally, rather than as a boulder + if (this->actionFunc == EnGo_RollingLink || this->actionFunc == EnGo_RollingFar || + this->actionFunc == EnGo_RollingNear || this->actionFunc == EnGo_RollingFar) { EnGo_DrawRolling(this, play); - return; // needed for match? - } else { - Gfx_SetupDL_37Opa(play->state.gfxCtx); + return; + } - gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(gGoronCsEyeOpenTex)); - gSPSegment(POLY_OPA_DISP++, 0x09, SEGMENTED_TO_VIRTUAL(gGoronCsMouthNeutralTex)); + // draw skeleton normally + Gfx_SetupDL_37Opa(play->state.gfxCtx); - SkelAnime_DrawFlexOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - EnGo_OverrideLimbDraw, EnGo_PostLimbDraw, &this->actor); - CLOSE_DISPS(play->state.gfxCtx, "../z_en_go.c", 2525); - EnGo_DrawEffects(this, play); - } + gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(gGoronCsEyeOpenTex)); + gSPSegment(POLY_OPA_DISP++, 0x09, SEGMENTED_TO_VIRTUAL(gGoronCsMouthNeutralTex)); + + SkelAnime_DrawFlexOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnGo_OverrideLimbDraw, EnGo_PostLimbDraw, &this->actor); + CLOSE_DISPS(play->state.gfxCtx, "../z_en_go.c", 2525); + EnGo_DrawEffects(this, play); } void EnGo_SpawnEffectDust(EnGo* this, Vec3f* pos, Vec3f* velocity, Vec3f* accel, u8 initialTimer, f32 scale, @@ -1215,7 +1225,7 @@ void EnGo_DrawEffects(EnGo* this, PlayState* play) { if (!materialFlag) { POLY_XLU_DISP = Gfx_SetupDL(POLY_XLU_DISP, SETUPDL_0); - gSPDisplayList(POLY_XLU_DISP++, gGoronDL_00FD40); + gSPDisplayList(POLY_XLU_DISP++, gGoronParticleMaterialDL); gDPSetEnvColor(POLY_XLU_DISP++, 100, 60, 20, 0); materialFlag = true; } @@ -1230,7 +1240,7 @@ void EnGo_DrawEffects(EnGo* this, PlayState* play) { index = dustEffect->timer * (8.0f / dustEffect->initialTimer); gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(dustTex[index])); - gSPDisplayList(POLY_XLU_DISP++, gGoronDL_00FD50); + gSPDisplayList(POLY_XLU_DISP++, gGoronParticleDL); } CLOSE_DISPS(play->state.gfxCtx, "../z_en_go.c", 2678); diff --git a/src/overlays/actors/ovl_En_Go/z_en_go.h b/src/overlays/actors/ovl_En_Go/z_en_go.h index bd673c95216..6400cfc42d1 100644 --- a/src/overlays/actors/ovl_En_Go/z_en_go.h +++ b/src/overlays/actors/ovl_En_Go/z_en_go.h @@ -7,20 +7,48 @@ struct EnGo; typedef void (*EnGoActionFunc)(struct EnGo*, PlayState*); -typedef u16 (*callback1_80A3ED24)(PlayState*, struct EnGo*); -typedef s16 (*callback2_80A3ED24)(PlayState*, struct EnGo*); - -// WIP type docs -// /* 0x00 */ GORON1_CITY_LINK, -// /* 0x10 */ GORON1_FIRE_GENERIC, -// /* 0x20 */ GORON1_DMT_DC_ENTRANCE, -// /* 0x30 */ GORON1_DMT_ROLLING_SMALL, -// /* 0x40 */ GORON1_DMT_BOMB_FLOWER, -// /* 0x50 */ GORON1_CITY_ENTRANCE, -// /* 0x60 */ GORON1_CITY_ISLAND, -// /* 0x70 */ GORON1_CITY_LOST_WOODS, -// /* 0x80 */ // Not Used -// /* 0x90 */ GORON1_DMT_BIGGORON, + +typedef enum GoronLimb { + /* 0 */ GORON_LIMB_NONE, // skeleton itself + /* 1 */ GORON_LIMB_ROOT, + /* 2 */ GORON_LIMB_WAIST, // drives bottom submesh + /* 3 */ GORON_LIMB_LEGS, + /* 4 */ GORON_LIMB_LEFT_THIGH, + /* 5 */ GORON_LIMB_LEFT_SHIN, + /* 6 */ GORON_LIMB_LEFT_FOOT, + /* 7 */ GORON_LIMB_RIGHT_THIGH, + /* 8 */ GORON_LIMB_RIGHT_SHIN, + /* 9 */ GORON_LIMB_RIGHT_FOOT, + /* 10 */ GORON_LIMB_TORSO, // drives top submesh + /* 11 */ GORON_LIMB_LEFT_ARM, + /* 12 */ GORON_LIMB_LEFT_FOREARM, + /* 13 */ GORON_LIMB_LEFT_HAND, + /* 14 */ GORON_LIMB_RIGHT_ARM, + /* 15 */ GORON_LIMB_RIGHT_FOREARM, + /* 16 */ GORON_LIMB_RIGHT_HAND, + /* 17 */ GORON_LIMB_HEAD, + /* 18 */ GORON_LIMB_MAX +} GoronLimb; + +typedef enum EnGoType { + ENGO_TYPE_CITY_LINK = (0 << 4), + ENGO_TYPE_FIRE_GENERIC = (1 << 4), + ENGO_TYPE_DMT_DC_ENTRANCE = (2 << 4), + ENGO_TYPE_DMT_ROLLING_SMALL = (3 << 4), + ENGO_TYPE_DMT_BOMB_FLOWER = (4 << 4), + ENGO_TYPE_CITY_ENTRANCE = (5 << 4), + ENGO_TYPE_CITY_ISLAND = (6 << 4), + ENGO_TYPE_CITY_LOST_WOODS = (7 << 4), + ENGO_TYPE_DMT_BIGGORON = (9 << 4) +} EnGoType; + +#define ENGO_GET_PATH_INDEX(this) PARAMS_GET_U((this)->actor.params, 0, 4) +#define ENGO_GET_TYPE(this) PARAMS_GET_NOSHIFT((this)->actor.params, 4, 4) +#define ENGO_CAGED_SWITCH_FLAG(this) PARAMS_GET_NOMASK((this)->actor.params, 8) + +#define ENGO_PATH_NONE NBITS_TO_MASK(4) +#define ENGO_IS_CAGE_OPEN(this, play) Flags_GetSwitch(play, ENGO_CAGED_SWITCH_FLAG(this)) +#define ENGO_GET_SPEED_SCALE(this) (ENGO_GET_TYPE(this) == ENGO_TYPE_DMT_BIGGORON ? 0.5f : 1.0f) #define EN_GO_EFFECT_COUNT 20 @@ -44,18 +72,18 @@ typedef struct EnGo { /* 0x0194 */ ColliderCylinder collider; /* 0x01E0 */ NpcInteractInfo interactInfo; /* 0x0208 */ char unk_208[0x4]; - /* 0x020C */ s16 unk_20C; - /* 0x020E */ s16 unk_20E; - /* 0x0210 */ s16 unk_210; - /* 0x0212 */ s16 unk_212; - /* 0x0214 */ s16 unk_214; - /* 0x0216 */ s16 unk_216; - /* 0x0218 */ s16 unk_218; - /* 0x021A */ s16 unk_21A; - /* 0x021C */ s16 unk_21C; - /* 0x021E */ s16 unk_21E; - /* 0x0220 */ s16 fidgetTableY[18]; - /* 0x0244 */ s16 fidgetTableZ[18]; + /* 0x020C */ s16 gaveSword; + /* 0x020E */ s16 knockbackCooldown; + /* 0x0210 */ s16 curledTimer; + /* 0x0212 */ s16 attentionCooldown; + /* 0x0214 */ s16 blinkTimer; // unused + /* 0x0216 */ s16 eyeTexIndex; // unused + /* 0x0218 */ s16 waypoint; + /* 0x021A */ s16 bounceCounter; + /* 0x021C */ s16 bounceTimer; + /* 0x021E */ s16 eyedropsTimer; + /* 0x0220 */ s16 fidgetTableY[GORON_LIMB_MAX]; + /* 0x0244 */ s16 fidgetTableZ[GORON_LIMB_MAX]; /* 0x0268 */ EnGoEffect effects[EN_GO_EFFECT_COUNT]; } EnGo; // size = 0x06C8 diff --git a/src/overlays/actors/ovl_En_Go2/z_en_go2.c b/src/overlays/actors/ovl_En_Go2/z_en_go2.c index 3fb5067976b..0fdac25abbb 100644 --- a/src/overlays/actors/ovl_En_Go2/z_en_go2.c +++ b/src/overlays/actors/ovl_En_Go2/z_en_go2.c @@ -46,19 +46,19 @@ void EnGo2_Draw(Actor* thisx, PlayState* play); void EnGo2_StopRolling(EnGo2* this, PlayState* play); void EnGo2_CurledUp(EnGo2* this, PlayState* play); -void func_80A46B40(EnGo2* this, PlayState* play); -void EnGo2_GoronDmtBombFlowerAnimation(EnGo2* this, PlayState* play); -void EnGo2_GoronRollingBigContinueRolling(EnGo2* this, PlayState* play); -void EnGo2_ContinueRolling(EnGo2* this, PlayState* play); -void EnGo2_SlowRolling(EnGo2* this, PlayState* play); +void EnGo2_Standing(EnGo2* this, PlayState* play); +void EnGo2_GoronDmtBombFlower(EnGo2* this, PlayState* play); +void EnGo2_GoronHotRodder(EnGo2* this, PlayState* play); +void EnGo2_RollingStart(EnGo2* this, PlayState* play); +void EnGo2_RollingSlow(EnGo2* this, PlayState* play); void EnGo2_GroundRolling(EnGo2* this, PlayState* play); -void EnGo2_ReverseRolling(EnGo2* this, PlayState* play); -void EnGo2_SetupGetItem(EnGo2* this, PlayState* play); -void EnGo2_SetGetItem(EnGo2* this, PlayState* play); +void EnGo2_RollingReverse(EnGo2* this, PlayState* play); +void EnGo2_HandleOffer(EnGo2* this, PlayState* play); +void EnGo2_HandleOfferParented(EnGo2* this, PlayState* play); void EnGo2_BiggoronEyedrops(EnGo2* this, PlayState* play); -void EnGo2_GoronLinkStopRolling(EnGo2* this, PlayState* play); -void EnGo2_GoronFireGenericAction(EnGo2* this, PlayState* play); +void EnGo2_GoronLink(EnGo2* this, PlayState* play); +void EnGo2_GoronFireGeneric(EnGo2* this, PlayState* play); static void* sDustTex[] = { gDust8Tex, gDust7Tex, gDust6Tex, gDust5Tex, gDust4Tex, gDust3Tex, gDust2Tex, gDust1Tex }; @@ -100,13 +100,13 @@ ActorProfile En_Go2_Profile = { /**/ EnGo2_Draw, }; -static EnGo2DataStruct1 D_80A4816C[14] = { +static EnGo2ColliderData sColliderData[14] = { { 0, 0, 0, 68, 148 }, { 0, 0, 0, 24, 52 }, { 0, 320, 380, 400, 120 }, { 0, 0, 0, 30, 68 }, { 0, 0, 0, 46, 90 }, { 0, 0, 0, 30, 68 }, { 0, 0, 0, 30, 68 }, { 0, 0, 0, 30, 68 }, { 0, 0, 0, 30, 68 }, { 0, 0, 0, 30, 68 }, { 0, 0, 0, 30, 68 }, { 0, 0, 0, 30, 68 }, { 0, 0, 0, 30, 68 }, { 0, 0, 0, 30, 68 }, }; -static EnGo2DataStruct2 D_80A481F8[14] = { +static EnGo2ShapeData sShapeData[14] = { { 30.0f, 0.026f, 6, 60.0f }, { 24.0f, 0.008f, 6, 30.0f }, { 28.0f, 0.16f, 5, 380.0f }, { 28.0f, 0.01f, 7, 40.0f }, { 30.0f, 0.015f, 6, 30.0f }, { 28.0f, 0.01f, 6, 30.0f }, { 28.0f, 0.01f, 6, 30.0f }, { 28.0f, 0.01f, 6, 30.0f }, { 28.0f, 0.01f, 6, 30.0f }, { 28.0f, 0.01f, 6, 30.0f }, { 28.0f, 0.01f, 6, 30.0f }, { 28.0f, 0.01f, 6, 30.0f }, @@ -114,45 +114,54 @@ static EnGo2DataStruct2 D_80A481F8[14] = { }; static f32 sPlayerTrackingYOffsets[14][2] = { + // { adult, child } { 80.0f, 80.0f }, { -10.0f, -10.0f }, { 800.0f, 800.0f }, { 0.0f, 0.0f }, { 20.0f, 40.0f }, { 20.0f, 20.0f }, { 20.0f, 20.0f }, { 20.0f, 20.0f }, { 20.0f, 20.0f }, { 20.0f, 20.0f }, { 20.0f, 20.0f }, { 20.0f, 20.0f }, { 20.0f, 20.0f }, { 20.0f, 20.0f }, }; typedef enum EnGo2Animation { - /* 0 */ ENGO2_ANIM_0, - /* 1 */ ENGO2_ANIM_1, - /* 2 */ ENGO2_ANIM_2, - /* 3 */ ENGO2_ANIM_3, - /* 4 */ ENGO2_ANIM_4, - /* 5 */ ENGO2_ANIM_5, - /* 6 */ ENGO2_ANIM_6, - /* 7 */ ENGO2_ANIM_7, - /* 8 */ ENGO2_ANIM_8, - /* 9 */ ENGO2_ANIM_9, - /* 10 */ ENGO2_ANIM_10, - /* 11 */ ENGO2_ANIM_11, - /* 12 */ ENGO2_ANIM_12 + /* 0 */ ENGO2_ANIM_UNCURL_SIT_STAND_DEFAULT, + /* 1 */ ENGO2_ANIM_UNCURL_SIT_STAND_NORMAL, + /* 2 */ ENGO2_ANIM_WALKING, + /* 3 */ ENGO2_ANIM_SIDESTEP, + /* 4 */ ENGO2_ANIM_CRYING, + /* 5 */ ENGO2_ANIM_EYEDROPS, + /* 6 */ ENGO2_ANIM_EYEDROPS_TAKEN, + /* 7 */ ENGO2_ANIM_UNCURL_PRONE_UNUSED, + /* 8 */ ENGO2_ANIM_PRONE_UNUSED, + /* 9 */ ENGO2_ANIM_SCRATCHING, + /* 10 */ ENGO2_ANIM_UNCURL_SIT_STAND_BIG, + /* 11 */ ENGO2_ANIM_SOBBING, + /* 12 */ ENGO2_ANIM_SHAKING } EnGo2Animation; static AnimationInfo sAnimationInfo[] = { - { &gGoronAnim_004930, 0.0f, 0.0f, -1.0f, 0x00, 0.0f }, { &gGoronAnim_004930, 0.0f, 0.0f, -1.0f, 0x00, -8.0f }, - { &gGoronAnim_0029A8, 1.0f, 0.0f, -1.0f, 0x00, -8.0f }, { &gGoronAnim_010590, 1.0f, 0.0f, -1.0f, 0x00, -8.0f }, - { &gGoronAnim_003768, 1.0f, 0.0f, -1.0f, 0x00, -8.0f }, { &gGoronAnim_0038E4, 1.0f, 0.0f, -1.0f, 0x02, -8.0f }, - { &gGoronAnim_002D80, 1.0f, 0.0f, -1.0f, 0x02, -8.0f }, { &gGoronAnim_00161C, 1.0f, 0.0f, -1.0f, 0x00, -8.0f }, - { &gGoronAnim_001A00, 1.0f, 0.0f, -1.0f, 0x00, -8.0f }, { &gGoronAnim_0021D0, 1.0f, 0.0f, -1.0f, 0x00, -8.0f }, - { &gGoronAnim_004930, 0.0f, 0.0f, -1.0f, 0x01, -8.0f }, { &gGoronAnim_000750, 1.0f, 0.0f, -1.0f, 0x00, -8.0f }, - { &gGoronAnim_000D5C, 1.0f, 0.0f, -1.0f, 0x00, -8.0f }, + { &gGoronUncurlSitStandAnim, 0.0f, 0.0f, -1.0f, 0x00, 0.0f }, + { &gGoronUncurlSitStandAnim, 0.0f, 0.0f, -1.0f, 0x00, -8.0f }, + { &gGoronWalkingAnim, 1.0f, 0.0f, -1.0f, 0x00, -8.0f }, + { &gGoronSidestepAnim, 1.0f, 0.0f, -1.0f, 0x00, -8.0f }, + { &gGoronCryingAnim, 1.0f, 0.0f, -1.0f, 0x00, -8.0f }, + { &gGoronEyeropsAnim, 1.0f, 0.0f, -1.0f, 0x02, -8.0f }, + { &gGoronEyedropsTakenAnim, 1.0f, 0.0f, -1.0f, 0x02, -8.0f }, + { &gGoronUncurlToProneAnim, 1.0f, 0.0f, -1.0f, 0x00, -8.0f }, + { &gGoronProneAnim, 1.0f, 0.0f, -1.0f, 0x00, -8.0f }, + { &gGoronScratchingAnim, 1.0f, 0.0f, -1.0f, 0x00, -8.0f }, + { &gGoronUncurlSitStandAnim, 0.0f, 0.0f, -1.0f, 0x01, -8.0f }, + { &gGoronSobbingAnim, 1.0f, 0.0f, -1.0f, 0x00, -8.0f }, + { &gGoronShakingAnim, 1.0f, 0.0f, -1.0f, 0x00, -8.0f }, }; static EnGo2DustEffectData sDustEffectData[2][4] = { { + // default { 12, 0.2f, 0.2f, 1, 18.0f, 0.0f }, { 12, 0.1f, 0.2f, 12, 26.0f, 0.0f }, { 12, 0.1f, 0.3f, 4, 10.0f, 0.0f }, { 12, 0.2f, 0.2f, 1, 18.0f, 0.0f }, }, { + // GORON_CITY_HOT_RODDER { 12, 0.5f, 0.4f, 3, 42.0f, 0.0f }, { 12, 0.5f, 0.4f, 3, 42.0f, 0.0f }, { 12, 0.5f, 0.4f, 3, 42.0f, 0.0f }, @@ -225,7 +234,7 @@ void EnGo2_DrawEffects(EnGo2* this, PlayState* play) { if (!materialFlag) { POLY_XLU_DISP = Gfx_SetupDL(POLY_XLU_DISP, SETUPDL_0); - gSPDisplayList(POLY_XLU_DISP++, gGoronDL_00FD40); + gSPDisplayList(POLY_XLU_DISP++, gGoronParticleMaterialDL); gDPSetEnvColor(POLY_XLU_DISP++, 100, 60, 20, 0); materialFlag = true; } @@ -239,14 +248,14 @@ void EnGo2_DrawEffects(EnGo2* this, PlayState* play) { MATRIX_FINALIZE_AND_LOAD(POLY_XLU_DISP++, play->state.gfxCtx, "../z_en_go2_eff.c", 137); index = dustEffect->timer * (8.0f / dustEffect->initialTimer); gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sDustTex[index])); - gSPDisplayList(POLY_XLU_DISP++, gGoronDL_00FD50); + gSPDisplayList(POLY_XLU_DISP++, gGoronParticleDL); } CLOSE_DISPS(play->state.gfxCtx, "../z_en_go2_eff.c", 151); } -s32 EnGo2_SpawnDust(EnGo2* this, u8 initialTimer, f32 scale, f32 scaleStep, s32 numDustEffects, f32 radius, - f32 yAccel) { +s32 EnGo2_SpawnDustExplicitly(EnGo2* this, u8 initialTimer, f32 scale, f32 scaleStep, s32 numDustEffects, f32 radius, + f32 yAccel) { Vec3f pos = sPos; Vec3f velocity = sVelocity; Vec3f accel = sAccel; @@ -255,41 +264,41 @@ s32 EnGo2_SpawnDust(EnGo2* this, u8 initialTimer, f32 scale, f32 scaleStep, s32 pos = this->actor.world.pos; // overwrites sPos data pos.y = this->actor.floorHeight; - angle = (Rand_ZeroOne() - 0.5f) * 0x10000; + angle = (Rand_ZeroOne() - 0.5f) * 0x10000; // `[-180 .. 180]` degrees i = numDustEffects; while (i >= 0) { accel.y += Rand_ZeroOne() * yAccel; pos.x = (Math_SinS(angle) * radius) + this->actor.world.pos.x; pos.z = (Math_CosS(angle) * radius) + this->actor.world.pos.z; EnGo2_SpawnEffectDust(this, &pos, &velocity, &accel, initialTimer, scale, scaleStep); - angle += (s16)(0x10000 / numDustEffects); + angle += (s16)(0x10000 / numDustEffects); // `360 / N` degrees i--; } return 0; } -void EnGo2_GetItem(EnGo2* this, PlayState* play, s32 getItemId) { +void EnGo2_OfferItem(EnGo2* this, PlayState* play, s32 getItemId) { this->getItemId = getItemId; Actor_OfferGetItem(&this->actor, play, getItemId, this->actor.xzDistToPlayer + 1.0f, fabsf(this->actor.yDistToPlayer) + 1.0f); } s32 EnGo2_GetDialogState(EnGo2* this, PlayState* play) { - s16 dialogState = Message_GetState(&play->msgCtx); + s16 messageState = Message_GetState(&play->msgCtx); - if ((this->dialogState == TEXT_STATE_AWAITING_NEXT) || (this->dialogState == TEXT_STATE_EVENT) || - (this->dialogState == TEXT_STATE_CLOSING) || (this->dialogState == TEXT_STATE_DONE_HAS_NEXT)) { - if (dialogState != this->dialogState) { - this->unk_20C++; + if ((this->messageState == TEXT_STATE_AWAITING_NEXT) || (this->messageState == TEXT_STATE_EVENT) || + (this->messageState == TEXT_STATE_CLOSING) || (this->messageState == TEXT_STATE_DONE_HAS_NEXT)) { + if (messageState != this->messageState) { + this->messageEntry++; } } - this->dialogState = dialogState; - return dialogState; + this->messageState = messageState; + return messageState; } u16 EnGo2_GoronFireGenericGetTextId(EnGo2* this) { - switch (PARAMS_GET_S(this->actor.params, 10, 6)) { + switch (ENGO2_CAGED_SWITCH_FLAG(this)) { case 3: return 0x3069; case 5: @@ -311,7 +320,7 @@ u16 EnGo2_GoronFireGenericGetTextId(EnGo2* this) { } } -u16 EnGo2_GetTextIdGoronCityRollingBig(PlayState* play, EnGo2* this) { +u16 EnGo2_GetTextIdGoronCityHotRodder(PlayState* play, EnGo2* this) { if (GET_INFTABLE(INFTABLE_11E)) { return 0x3013; } else if (CUR_CAPACITY(UPG_BOMB_BAG) >= 20 && this->waypoint > 7 && this->waypoint < 12) { @@ -321,7 +330,7 @@ u16 EnGo2_GetTextIdGoronCityRollingBig(PlayState* play, EnGo2* this) { } } -s16 EnGo2_UpdateTalkStateGoronCityRollingBig(PlayState* play, EnGo2* this) { +s16 EnGo2_UpdateTalkStateGoronCityHotRodder(PlayState* play, EnGo2* this) { s32 bombBagUpgrade; switch (Message_GetState(&play->msgCtx)) { @@ -330,9 +339,9 @@ s16 EnGo2_UpdateTalkStateGoronCityRollingBig(PlayState* play, EnGo2* this) { case TEXT_STATE_EVENT: if (Message_ShouldAdvance(play)) { if (this->actor.textId == 0x3012) { - this->actionFunc = EnGo2_SetupGetItem; + this->actionFunc = EnGo2_HandleOffer; bombBagUpgrade = CUR_CAPACITY(UPG_BOMB_BAG) == 30 ? GI_BOMB_BAG_40 : GI_BOMB_BAG_30; - EnGo2_GetItem(this, play, bombBagUpgrade); + EnGo2_OfferItem(this, play, bombBagUpgrade); Message_CloseTextbox(play); SET_INFTABLE(INFTABLE_11E); return NPC_TALK_STATE_ACTION; @@ -488,8 +497,8 @@ u16 EnGo2_GetTextIdGoronCityLink(PlayState* play, EnGo2* this) { } else if (CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_GORON)) { return GET_INFTABLE(INFTABLE_10E) ? 0x3038 : 0x3037; } else if (GET_INFTABLE(INFTABLE_10C)) { - this->unk_20C = 0; - this->dialogState = TEXT_STATE_NONE; + this->messageEntry = 0; + this->messageState = TEXT_STATE_NONE; return GET_INFTABLE(INFTABLE_10A) ? 0x3033 : 0x3032; } else { return 0x3030; @@ -501,8 +510,8 @@ s16 EnGo2_UpdateTalkStateGoronCityLink(PlayState* play, EnGo2* this) { case TEXT_STATE_CLOSING: switch (this->actor.textId) { case 0x3036: - EnGo2_GetItem(this, play, GI_TUNIC_GORON); - this->actionFunc = EnGo2_SetupGetItem; + EnGo2_OfferItem(this, play, GI_TUNIC_GORON); + this->actionFunc = EnGo2_HandleOffer; return NPC_TALK_STATE_ACTION; case 0x3037: SET_INFTABLE(INFTABLE_10E); @@ -525,7 +534,7 @@ s16 EnGo2_UpdateTalkStateGoronCityLink(PlayState* play, EnGo2* this) { } } Message_ContinueTextbox(play, this->actor.textId); - this->unk_20C = 0; + this->messageEntry = 0; } } else { break; @@ -571,7 +580,7 @@ u16 EnGo2_GetTextIdGoronDmtBiggoron(PlayState* play, EnGo2* this) { s16 EnGo2_UpdateTalkStateGoronDmtBiggoron(PlayState* play, EnGo2* this) { s32 unusedPad; - u8 dialogState = this->dialogState; + u8 dialogState = this->messageState; switch (EnGo2_GetDialogState(this, play)) { #if OOT_VERSION < PAL_1_0 @@ -581,8 +590,8 @@ s16 EnGo2_UpdateTalkStateGoronDmtBiggoron(PlayState* play, EnGo2* this) { #endif if (this->actor.textId == 0x305E) { if (!gSaveContext.save.info.playerData.bgsFlag) { - EnGo2_GetItem(this, play, GI_SWORD_BIGGORON); - this->actionFunc = EnGo2_SetupGetItem; + EnGo2_OfferItem(this, play, GI_SWORD_BIGGORON); + this->actionFunc = EnGo2_HandleOffer; return NPC_TALK_STATE_ACTION; } else { return NPC_TALK_STATE_IDLE; @@ -614,8 +623,8 @@ s16 EnGo2_UpdateTalkStateGoronDmtBiggoron(PlayState* play, EnGo2* this) { if (Message_ShouldAdvance(play)) { if ((this->actor.textId == 0x3054) || (this->actor.textId == 0x3055)) { if (play->msgCtx.choiceIndex == 0) { - EnGo2_GetItem(this, play, GI_PRESCRIPTION); - this->actionFunc = EnGo2_SetupGetItem; + EnGo2_OfferItem(this, play, GI_PRESCRIPTION); + this->actionFunc = EnGo2_HandleOffer; return NPC_TALK_STATE_ACTION; } this->actor.textId = 0x3056; @@ -638,7 +647,7 @@ s16 EnGo2_UpdateTalkStateGoronDmtBiggoron(PlayState* play, EnGo2* this) { } u16 EnGo2_GetTextIdGoronFireGeneric(PlayState* play, EnGo2* this) { - if (Flags_GetSwitch(play, PARAMS_GET_S(this->actor.params, 10, 6))) { + if (ENGO2_IS_CAGE_OPEN(play, this)) { return 0x3071; } else { return 0x3051; @@ -738,9 +747,9 @@ u16 EnGo2_GetTextId(PlayState* play, Actor* thisx) { if (textId != 0) { return textId; } else { - switch (PARAMS_GET_S(this->actor.params, 0, 5)) { - case GORON_CITY_ROLLING_BIG: - return EnGo2_GetTextIdGoronCityRollingBig(play, this); + switch (ENGO2_GET_TYPE(this)) { + case GORON_CITY_HOT_RODDER: + return EnGo2_GetTextIdGoronCityHotRodder(play, this); case GORON_CITY_LINK: return EnGo2_GetTextIdGoronCityLink(play, this); case GORON_DMT_BIGGORON: @@ -776,9 +785,9 @@ u16 EnGo2_GetTextId(PlayState* play, Actor* thisx) { s16 EnGo2_UpdateTalkState(PlayState* play, Actor* thisx) { EnGo2* this = (EnGo2*)thisx; - switch (PARAMS_GET_S(this->actor.params, 0, 5)) { - case GORON_CITY_ROLLING_BIG: - return EnGo2_UpdateTalkStateGoronCityRollingBig(play, this); + switch (ENGO2_GET_TYPE(this)) { + case GORON_CITY_HOT_RODDER: + return EnGo2_UpdateTalkStateGoronCityHotRodder(play, this); case GORON_CITY_LINK: return EnGo2_UpdateTalkStateGoronCityLink(play, this); case GORON_DMT_BIGGORON: @@ -813,15 +822,19 @@ s16 EnGo2_UpdateTalkState(PlayState* play, Actor* thisx) { #endif } -s32 func_80A44790(EnGo2* this, PlayState* play) { - if (PARAMS_GET_S(this->actor.params, 0, 5) != GORON_DMT_BIGGORON && - PARAMS_GET_S(this->actor.params, 0, 5) != GORON_CITY_ROLLING_BIG) { +s32 EnGo2_UpdateTalking(EnGo2* this, PlayState* play) { + if (ENGO2_GET_TYPE(this) != GORON_DMT_BIGGORON && ENGO2_GET_TYPE(this) != GORON_CITY_HOT_RODDER) { return Npc_UpdateTalking(play, &this->actor, &this->interactInfo.talkState, this->interactRange, EnGo2_GetTextId, EnGo2_UpdateTalkState); - } else if ((PARAMS_GET_S(this->actor.params, 0, 5) == GORON_DMT_BIGGORON) && - !(this->collider.base.ocFlags2 & OC2_HIT_PLAYER)) { + } + + // Biggoron is close enough; see `EnGo2_IsWithinInteactionRange` + if (ENGO2_GET_TYPE(this) == GORON_DMT_BIGGORON && !(this->collider.base.ocFlags2 & OC2_HIT_PLAYER)) { return false; - } else { + } + + // dialog with Biggoron or Hot Rodder + { if (Actor_TalkOfferAccepted(&this->actor, play)) { this->interactInfo.talkState = NPC_TALK_STATE_TALKING; return true; @@ -836,19 +849,19 @@ s32 func_80A44790(EnGo2* this, PlayState* play) { } void EnGo2_SetColliderDim(EnGo2* this) { - u8 index = PARAMS_GET_S(this->actor.params, 0, 5); + u8 index = ENGO2_GET_TYPE(this); - this->collider.dim.radius = D_80A4816C[index].radius; - this->collider.dim.height = D_80A4816C[index].height; + this->collider.dim.radius = sColliderData[index].radius; + this->collider.dim.height = sColliderData[index].height; } void EnGo2_SetShape(EnGo2* this) { - u8 index = PARAMS_GET_S(this->actor.params, 0, 5); + u8 index = ENGO2_GET_TYPE(this); - this->actor.shape.shadowScale = D_80A481F8[index].shape_unk_10; - Actor_SetScale(&this->actor, D_80A481F8[index].scale); - this->actor.attentionRangeType = D_80A481F8[index].actor_unk_1F; - this->interactRange = D_80A481F8[index].interactRange; + this->actor.shape.shadowScale = sShapeData[index].shadowScale; + Actor_SetScale(&this->actor, sShapeData[index].scale); + this->actor.attentionRangeType = sShapeData[index].attentionRangeType; + this->interactRange = sShapeData[index].interactRange; this->interactRange += this->collider.dim.radius; } @@ -859,16 +872,16 @@ void EnGo2_CheckCollision(EnGo2* this, PlayState* play) { pos.x = this->actor.world.pos.x; pos.y = this->actor.world.pos.y; pos.z = this->actor.world.pos.z; - xzDist = D_80A4816C[PARAMS_GET_S(this->actor.params, 0, 5)].xzDist; + xzDist = sColliderData[ENGO2_GET_TYPE(this)].xzDist; pos.x += (s16)(xzDist * Math_SinS(this->actor.shape.rot.y)); pos.z += (s16)(xzDist * Math_CosS(this->actor.shape.rot.y)); - pos.y += D_80A4816C[PARAMS_GET_S(this->actor.params, 0, 5)].yDist; + pos.y += sColliderData[ENGO2_GET_TYPE(this)].yDist; this->collider.dim.pos = pos; CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base); CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider.base); } -void EnGo2_SwapInitialFrameAnimFrameCount(EnGo2* this) { +void EnGo2_ReverseAnimation(EnGo2* this) { f32 initialFrame; initialFrame = this->skelAnime.startFrame; @@ -876,42 +889,45 @@ void EnGo2_SwapInitialFrameAnimFrameCount(EnGo2* this) { this->skelAnime.endFrame = initialFrame; } -s32 func_80A44AB0(EnGo2* this, PlayState* play) { +s32 EnGo2_UpdateRollingKnockback(EnGo2* this, PlayState* play) { Player* player = GET_PLAYER(play); - f32 arg2; + f32 knockbackSpeed; - if (PARAMS_GET_S(this->actor.params, 0, 5) == GORON_DMT_BIGGORON) { + if (ENGO2_GET_TYPE(this) == GORON_DMT_BIGGORON) { return false; + } + + if ((this->actionFunc != EnGo2_RollingSlow) && (this->actionFunc != EnGo2_RollingReverse) && + (this->actionFunc != EnGo2_RollingStart)) { + return false; + } + + if (this->collider.base.acFlags & AC_HIT) { + Audio_PlaySfxGeneral(NA_SE_SY_CORRECT_CHIME, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + this->actor.flags &= ~ACTOR_FLAG_SFX_FOR_PLAYER_BODY_HIT; + this->collider.base.acFlags &= ~AC_HIT; + EnGo2_StopRolling(this, play); + return true; + } + + if (player->invincibilityTimer <= 0) { + this->collider.base.ocFlags1 |= OC1_TYPE_PLAYER; } else { - if ((this->actionFunc != EnGo2_SlowRolling) && (this->actionFunc != EnGo2_ReverseRolling) && - (this->actionFunc != EnGo2_ContinueRolling)) { - return false; - } else { - if (this->collider.base.acFlags & AC_HIT) { - Audio_PlaySfxGeneral(NA_SE_SY_CORRECT_CHIME, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, - &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); - this->actor.flags &= ~ACTOR_FLAG_SFX_FOR_PLAYER_BODY_HIT; - this->collider.base.acFlags &= ~AC_HIT; - EnGo2_StopRolling(this, play); - return true; - } - if (player->invincibilityTimer <= 0) { - this->collider.base.ocFlags1 |= OC1_TYPE_PLAYER; - } else { - return false; - } - if (this->collider.base.ocFlags2 & OC2_HIT_PLAYER) { - this->collider.base.ocFlags2 &= ~OC2_HIT_PLAYER; + return false; + } - arg2 = this->actionFunc == EnGo2_ContinueRolling ? 1.5f : this->actor.speed * 1.5f; + if (this->collider.base.ocFlags2 & OC2_HIT_PLAYER) { + this->collider.base.ocFlags2 &= ~OC2_HIT_PLAYER; - play->damagePlayer(play, -4); - Actor_SetPlayerKnockbackLargeNoDamage(play, &this->actor, arg2, this->actor.yawTowardsPlayer, 6.0f); - Actor_PlaySfx(&player->actor, NA_SE_PL_BODY_HIT); - this->collider.base.ocFlags1 &= ~OC1_TYPE_PLAYER; - } - } + knockbackSpeed = this->actionFunc == EnGo2_RollingStart ? 1.5f : this->actor.speed * 1.5f; + + play->damagePlayer(play, -4); + Actor_SetPlayerKnockbackLargeNoDamage(play, &this->actor, knockbackSpeed, this->actor.yawTowardsPlayer, 6.0f); + Actor_PlaySfx(&player->actor, NA_SE_PL_BODY_HIT); + this->collider.base.ocFlags1 &= ~OC1_TYPE_PLAYER; } + return false; } @@ -938,7 +954,7 @@ s32 EnGo2_UpdateWaypoint(EnGo2* this, PlayState* play) { return 1; } -s32 EnGo2_Orient(EnGo2* this, PlayState* play) { +s32 EnGo2_FollowPath(EnGo2* this, PlayState* play) { s16 targetYaw; f32 waypointDistSq = Path_OrientAndGetDistSq(&this->actor, this->path, this->waypoint, &targetYaw); @@ -950,7 +966,7 @@ s32 EnGo2_Orient(EnGo2* this, PlayState* play) { } } -s32 func_80A44D84(EnGo2* this) { +s32 EnGo2_OrientInstant(EnGo2* this) { s16 targetYaw; Path_OrientAndGetDistSq(&this->actor, this->path, this->waypoint, &targetYaw); @@ -958,13 +974,13 @@ s32 func_80A44D84(EnGo2* this) { return 1; } -s32 EnGo2_IsWakingUp(EnGo2* this) { +s32 EnGo2_IsWithinInteactionRange(EnGo2* this) { s16 yawDiff; - f32 xyzDist = PARAMS_GET_S(this->actor.params, 0, 5) == GORON_DMT_BIGGORON ? 800.0f : 200.0f; - f32 yDist = PARAMS_GET_S(this->actor.params, 0, 5) == GORON_DMT_BIGGORON ? 400.0f : 60.0f; + f32 xyzDist = (ENGO2_GET_TYPE(this) == GORON_DMT_BIGGORON) ? 800.0f : 200.0f; + f32 yDist = (ENGO2_GET_TYPE(this) == GORON_DMT_BIGGORON) ? 400.0f : 60.0f; s16 yawDiffAbs; - if (PARAMS_GET_S(this->actor.params, 0, 5) == GORON_DMT_BIGGORON) { + if (ENGO2_GET_TYPE(this) == GORON_DMT_BIGGORON) { if (!(this->collider.base.ocFlags2 & OC2_HIT_PLAYER)) { this->actor.flags &= ~ACTOR_FLAG_ATTENTION_ENABLED; return false; @@ -977,55 +993,59 @@ s32 EnGo2_IsWakingUp(EnGo2* this) { xyzDist = SQ(xyzDist); yawDiff = (f32)this->actor.yawTowardsPlayer - (f32)this->actor.shape.rot.y; yawDiffAbs = ABS(yawDiff); - if (this->actor.xyzDistToPlayerSq <= xyzDist && fabsf(this->actor.yDistToPlayer) < yDist && yawDiffAbs < 0x2AA8) { + if (this->actor.xyzDistToPlayerSq <= xyzDist && fabsf(this->actor.yDistToPlayer) < yDist && + yawDiffAbs < DEG_TO_BINANG(59.99)) { return true; } else { return false; } } -s32 EnGo2_IsRollingOnGround(EnGo2* this, s16 arg1, f32 arg2, s16 arg3) { +s32 EnGo2_IsRollingOnGround(EnGo2* this, s16 bounceCount, f32 boundSpeed, s16 rumble) { if (!(this->actor.bgCheckFlags & BGCHECKFLAG_GROUND) || this->actor.velocity.y > 0.0f) { return false; } - if (DECR(this->unk_590)) { - if (!arg3) { + // rumble on odds and evens + if (DECR(this->bounceTimer)) { + if (!rumble) { return true; } else { this->actor.world.pos.y = - (this->unk_590 & 1) ? this->actor.world.pos.y + 1.5f : this->actor.world.pos.y - 1.5f; + (this->bounceTimer & 1) ? this->actor.world.pos.y + 1.5f : this->actor.world.pos.y - 1.5f; Actor_PlaySfx(&this->actor, NA_SE_EV_BIGBALL_ROLL - SFX_FLAG); return true; } } - if (this->unk_59C >= 2) { - Actor_PlaySfx(&this->actor, (PARAMS_GET_S(this->actor.params, 0, 5) == GORON_CITY_ROLLING_BIG) - ? NA_SE_EN_GOLON_LAND_BIG - : NA_SE_EN_DODO_M_GND); - } + // bounce! + { + if (this->bounceCounter >= 2) { + Actor_PlaySfx(&this->actor, (ENGO2_GET_TYPE(this) == GORON_CITY_HOT_RODDER) ? NA_SE_EN_GOLON_LAND_BIG + : NA_SE_EN_DODO_M_GND); + } - this->unk_59C--; - if (this->unk_59C <= 0) { - if (this->unk_59C == 0) { - this->unk_590 = Rand_S16Offset(60, 30); - this->unk_59C = 0; - this->actor.velocity.y = 0.0f; - return true; - } else { - this->unk_59C = arg1; + this->bounceCounter--; + if (this->bounceCounter <= 0) { + if (this->bounceCounter == 0) { + this->bounceTimer = Rand_S16Offset(60, 30); + this->bounceCounter = 0; + this->actor.velocity.y = 0.0f; + return true; + } else { + this->bounceCounter = bounceCount; + } } - } - this->actor.velocity.y = ((f32)this->unk_59C / (f32)arg1) * arg2; - return true; + this->actor.velocity.y = ((f32)this->bounceCounter / (f32)bounceCount) * boundSpeed; + return true; + } } void EnGo2_BiggoronSetTextId(EnGo2* this, PlayState* play, Player* player) { u16 textId; - if (PARAMS_GET_S(this->actor.params, 0, 5) == GORON_DMT_BIGGORON) { + if (ENGO2_GET_TYPE(this) == GORON_DMT_BIGGORON) { if (gSaveContext.save.info.playerData.bgsFlag) { if (func_8002F368(play) == EXCH_ITEM_CLAIM_CHECK) { this->actor.textId = 0x3003; @@ -1083,25 +1103,25 @@ void EnGo2_BiggoronSetTextId(EnGo2* this, PlayState* play, Player* player) { } } -void func_80A45288(EnGo2* this, PlayState* play) { +void EnGo2_TrackPlayer(EnGo2* this, PlayState* play) { Player* player = GET_PLAYER(play); - if (this->actionFunc != EnGo2_GoronFireGenericAction) { + if (this->actionFunc != EnGo2_GoronFireGeneric) { this->interactInfo.trackPos = player->actor.world.pos; this->interactInfo.yOffset = - sPlayerTrackingYOffsets[PARAMS_GET_S(this->actor.params, 0, 5)][((void)0, gSaveContext.save.linkAge)]; + sPlayerTrackingYOffsets[ENGO2_GET_TYPE(this)][((void)0, gSaveContext.save.linkAge)]; Npc_TrackPoint(&this->actor, &this->interactInfo, 4, this->trackingMode); } - if ((this->actionFunc != EnGo2_SetGetItem) && (this->isAwake == true)) { - if (func_80A44790(this, play)) { + if ((this->actionFunc != EnGo2_HandleOfferParented) && (this->isTalkative == true)) { + if (EnGo2_UpdateTalking(this, play)) { EnGo2_BiggoronSetTextId(this, play, player); } } } -void func_80A45360(EnGo2* this, f32* alpha) { +void EnGo2_UpdateShadowAlpha(EnGo2* this, f32* alpha) { f32 alphaTarget = - (this->skelAnime.animation == &gGoronAnim_004930) && (this->skelAnime.curFrame <= 32.0f) ? 0.0f : 255.0f; + (this->skelAnime.animation == &gGoronUncurlSitStandAnim) && (this->skelAnime.curFrame <= 32.0f) ? 0.0f : 255.0f; Math_ApproachF(alpha, alphaTarget, 0.4f, 100.0f); this->actor.shape.shadowAlpha = (u8)(u32)*alpha; @@ -1114,26 +1134,26 @@ void EnGo2_RollForward(EnGo2* this) { this->actor.speed = 0.0f; } - if (this->actionFunc != EnGo2_ContinueRolling) { + if (this->actionFunc != EnGo2_RollingStart) { Actor_MoveXZGravity(&this->actor); } this->actor.speed = speedXZ; } -void func_80A454CC(EnGo2* this) { - switch (PARAMS_GET_S(this->actor.params, 0, 5)) { - case GORON_CITY_ROLLING_BIG: +void EnGo2_ChooseIdleAnimation(EnGo2* this) { + switch (ENGO2_GET_TYPE(this)) { + case GORON_CITY_HOT_RODDER: case GORON_DMT_DC_ENTRANCE: case GORON_CITY_ENTRANCE: case GORON_CITY_STAIRWELL: case GORON_DMT_FAIRY_HINT: - Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_9); + Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_SCRATCHING); break; case GORON_DMT_BIGGORON: if (INV_CONTENT(ITEM_TRADE_ADULT) >= ITEM_BROKEN_GORONS_SWORD && INV_CONTENT(ITEM_TRADE_ADULT) <= ITEM_EYE_DROPS) { - Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_4); + Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_CRYING); break; } FALLTHROUGH; @@ -1144,59 +1164,56 @@ void func_80A454CC(EnGo2* this) { } f32 EnGo2_GetTargetXZSpeed(EnGo2* this) { - f32 yDist = PARAMS_GET_S(this->actor.params, 0, 5) == GORON_DMT_BIGGORON ? 400.0f : 60.0f; - s32 index = PARAMS_GET_S(this->actor.params, 0, 5); + f32 yDist = (ENGO2_GET_TYPE(this) == GORON_DMT_BIGGORON) ? 400.0f : 60.0f; + s32 index = ENGO2_GET_TYPE(this); if (index == GORON_CITY_LINK && (fabsf(this->actor.yDistToPlayer) < yDist) && (this->actor.xzDistToPlayer < 400.0f)) { return 9.0f; } else { - return index == GORON_CITY_ROLLING_BIG ? 3.6000001f : 6.0f; + return index == GORON_CITY_HOT_RODDER ? 3.6000001f : 6.0f; } } -s32 EnGo2_IsCameraModified(EnGo2* this, PlayState* play) { +s32 EnGo2_ShouldStay(EnGo2* this, PlayState* play) { Camera* mainCam = play->cameraPtrs[CAM_ID_MAIN]; - if (PARAMS_GET_S(this->actor.params, 0, 5) == GORON_DMT_BIGGORON) { - if (EnGo2_IsWakingUp(this)) { + if (ENGO2_GET_TYPE(this) == GORON_DMT_BIGGORON) { + if (EnGo2_IsWithinInteactionRange(this)) { Camera_RequestSetting(mainCam, CAM_SET_DIRECTED_YAW); Camera_UnsetStateFlag(mainCam, CAM_STATE_CHECK_BG); - } else if (!EnGo2_IsWakingUp(this) && (mainCam->setting == CAM_SET_DIRECTED_YAW)) { + } else if (!EnGo2_IsWithinInteactionRange(this) && (mainCam->setting == CAM_SET_DIRECTED_YAW)) { Camera_RequestSetting(mainCam, CAM_SET_DUNGEON1); Camera_SetStateFlag(mainCam, CAM_STATE_CHECK_BG); } } - if (PARAMS_GET_S(this->actor.params, 0, 5) == GORON_FIRE_GENERIC || - PARAMS_GET_S(this->actor.params, 0, 5) == GORON_CITY_ROLLING_BIG || - PARAMS_GET_S(this->actor.params, 0, 5) == GORON_CITY_STAIRWELL || - PARAMS_GET_S(this->actor.params, 0, 5) == GORON_DMT_BIGGORON || - PARAMS_GET_S(this->actor.params, 0, 5) == GORON_MARKET_BAZAAR) { + if (ENGO2_GET_TYPE(this) == GORON_FIRE_GENERIC || ENGO2_GET_TYPE(this) == GORON_CITY_HOT_RODDER || + ENGO2_GET_TYPE(this) == GORON_CITY_STAIRWELL || (ENGO2_GET_TYPE(this) == GORON_DMT_BIGGORON) || + ENGO2_GET_TYPE(this) == GORON_MARKET_BAZAAR) { return true; - } else if (!CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE) && CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_GORON)) { + } + + if (!CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE) && CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_GORON)) { return true; - } else { - return false; } + + return false; } -void EnGo2_DefaultWakingUp(EnGo2* this) { - if (EnGo2_IsWakingUp(this)) { - this->trackingMode = NPC_TRACKING_HEAD_AND_TORSO; - } else { - this->trackingMode = NPC_TRACKING_NONE; - } +void EnGo2_SetupUncurledFlags_Default(EnGo2* this) { + this->trackingMode = EnGo2_IsWithinInteactionRange(this) ? NPC_TRACKING_HEAD_AND_TORSO : NPC_TRACKING_NONE; if (this->interactInfo.talkState != NPC_TALK_STATE_IDLE) { this->trackingMode = NPC_TRACKING_FULL_BODY; } - this->isAwake = true; + this->isTalkative = true; } -void EnGo2_WakingUp(EnGo2* this) { - f32 xyzDist = PARAMS_GET_S(this->actor.params, 0, 5) == GORON_DMT_BIGGORON ? 800.0f : 200.0f; +void EnGo2_SetupUncurledFlags_NearTracking(EnGo2* this) { + // always false, he wakes up with `EnGo2_SetupUncurledFlags_Biggoron` + f32 xyzDist = (ENGO2_GET_TYPE(this) == GORON_DMT_BIGGORON) ? 800.0f : 200.0f; s32 isTrue = true; xyzDist = SQ(xyzDist); @@ -1205,39 +1222,39 @@ void EnGo2_WakingUp(EnGo2* this) { this->trackingMode = NPC_TRACKING_FULL_BODY; } - this->isAwake = isTrue; + this->isTalkative = isTrue; } -void EnGo2_BiggoronWakingUp(EnGo2* this) { - if (EnGo2_IsWakingUp(this) || this->interactInfo.talkState != NPC_TALK_STATE_IDLE) { +void EnGo2_SetupUncurledFlags_Biggoron(EnGo2* this) { + if (EnGo2_IsWithinInteactionRange(this) || this->interactInfo.talkState != NPC_TALK_STATE_IDLE) { this->trackingMode = NPC_TRACKING_HEAD_AND_TORSO; - this->isAwake = true; + this->isTalkative = true; } else { this->trackingMode = NPC_TRACKING_NONE; - this->isAwake = false; + this->isTalkative = false; } } -void EnGo2_SelectGoronWakingUp(EnGo2* this) { - switch (PARAMS_GET_S(this->actor.params, 0, 5)) { +void EnGo2_SetupUncurledFlags(EnGo2* this) { + switch (ENGO2_GET_TYPE(this)) { case GORON_DMT_BOMB_FLOWER: - this->isAwake = true; - this->trackingMode = EnGo2_IsWakingUp(this) ? NPC_TRACKING_HEAD_AND_TORSO : NPC_TRACKING_NONE; + this->isTalkative = true; + this->trackingMode = EnGo2_IsWithinInteactionRange(this) ? NPC_TRACKING_HEAD_AND_TORSO : NPC_TRACKING_NONE; break; case GORON_FIRE_GENERIC: - EnGo2_WakingUp(this); + EnGo2_SetupUncurledFlags_NearTracking(this); break; case GORON_DMT_BIGGORON: - EnGo2_BiggoronWakingUp(this); + EnGo2_SetupUncurledFlags_Biggoron(this); break; case GORON_CITY_LINK: if (!CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE) && CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_GORON)) { - EnGo2_WakingUp(this); + EnGo2_SetupUncurledFlags_NearTracking(this); break; } FALLTHROUGH; default: - EnGo2_DefaultWakingUp(this); + EnGo2_SetupUncurledFlags_Default(this); break; } } @@ -1271,10 +1288,10 @@ void EnGo2_EyeMouthTexState(EnGo2* this) { } } -void EnGo2_SitDownAnimation(EnGo2* this) { - if ((this->skelAnime.playSpeed != 0.0f) && (this->skelAnime.animation == &gGoronAnim_004930)) { +void EnGo2_PlayStandingChangeSfx(EnGo2* this) { + if ((this->skelAnime.playSpeed != 0.0f) && (this->skelAnime.animation == &gGoronUncurlSitStandAnim)) { if (this->skelAnime.playSpeed > 0.0f && this->skelAnime.curFrame == 14.0f) { - if (PARAMS_GET_S(this->actor.params, 0, 5) != GORON_DMT_BIGGORON) { + if (ENGO2_GET_TYPE(this) != GORON_DMT_BIGGORON) { Actor_PlaySfx(&this->actor, NA_SE_EN_GOLON_SIT_DOWN); } else { func_800F4524(&gSfxDefaultPos, NA_SE_EN_GOLON_SIT_DOWN, 60); @@ -1291,61 +1308,60 @@ void EnGo2_SitDownAnimation(EnGo2* this) { } } -void EnGo2_GetDustData(EnGo2* this, s32 index2) { - s32 index1 = PARAMS_GET_S(this->actor.params, 0, 5) == GORON_CITY_ROLLING_BIG ? 1 : 0; +void EnGo2_SpawnDust(EnGo2* this, s32 index2) { + s32 index1 = ENGO2_GET_TYPE(this) == GORON_CITY_HOT_RODDER ? 1 : 0; EnGo2DustEffectData* dustEffectData = &sDustEffectData[index1][index2]; - EnGo2_SpawnDust(this, dustEffectData->initialTimer, dustEffectData->scale, dustEffectData->scaleStep, - dustEffectData->numDustEffects, dustEffectData->radius, dustEffectData->yAccel); + EnGo2_SpawnDustExplicitly(this, dustEffectData->initialTimer, dustEffectData->scale, dustEffectData->scaleStep, + dustEffectData->numDustEffects, dustEffectData->radius, dustEffectData->yAccel); } -void EnGo2_RollingAnimation(EnGo2* this, PlayState* play) { - if (PARAMS_GET_S(this->actor.params, 0, 5) == GORON_DMT_BIGGORON) { +void EnGo2_SetupCurledUp(EnGo2* this, PlayState* play) { + if (ENGO2_GET_TYPE(this) == GORON_DMT_BIGGORON) { this->actor.flags &= ~ACTOR_FLAG_ATTENTION_ENABLED; - Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_10); + Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_UNCURL_SIT_STAND_BIG); this->skelAnime.playSpeed = -0.5f; } else { - Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_1); + Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_UNCURL_SIT_STAND_NORMAL); this->skelAnime.playSpeed = -1.0f; } - EnGo2_SwapInitialFrameAnimFrameCount(this); + EnGo2_ReverseAnimation(this); this->trackingMode = NPC_TRACKING_NONE; - this->unk_211 = false; - this->isAwake = false; + this->isUncurled = false; + this->isTalkative = false; this->actionFunc = EnGo2_CurledUp; } -void EnGo2_WakeUp(EnGo2* this, PlayState* play) { +void EnGo2_WakeUpAnimated(EnGo2* this, PlayState* play) { if (this->skelAnime.playSpeed == 0.0f) { - if (PARAMS_GET_S(this->actor.params, 0, 5) != GORON_DMT_BIGGORON) { + if (ENGO2_GET_TYPE(this) != GORON_DMT_BIGGORON) { Actor_PlaySfx(&this->actor, NA_SE_EN_GOLON_WAKE_UP); } else { func_800F4524(&gSfxDefaultPos, NA_SE_EN_GOLON_WAKE_UP, 60); } } - if (PARAMS_GET_S(this->actor.params, 0, 5) == GORON_DMT_BIGGORON) { + if (ENGO2_GET_TYPE(this) == GORON_DMT_BIGGORON) { OnePointCutscene_Init(play, 4200, -99, &this->actor, CAM_ID_MAIN); - Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_10); + Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_UNCURL_SIT_STAND_BIG); this->skelAnime.playSpeed = 0.5f; } else { - Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_1); + Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_UNCURL_SIT_STAND_NORMAL); this->skelAnime.playSpeed = 1.0f; } - this->actionFunc = func_80A46B40; + this->actionFunc = EnGo2_Standing; } -void EnGo2_GetItemAnimation(EnGo2* this, PlayState* play) { - Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_1); - this->unk_211 = true; - this->actionFunc = func_80A46B40; +void EnGo2_WakeUpInstant(EnGo2* this, PlayState* play) { + Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_UNCURL_SIT_STAND_NORMAL); + this->isUncurled = true; + this->actionFunc = EnGo2_Standing; this->skelAnime.playSpeed = 0.0f; this->actor.speed = 0.0f; this->skelAnime.curFrame = this->skelAnime.endFrame; } -void EnGo2_SetupRolling(EnGo2* this, PlayState* play) { - if (PARAMS_GET_S(this->actor.params, 0, 5) == GORON_CITY_ROLLING_BIG || - PARAMS_GET_S(this->actor.params, 0, 5) == GORON_CITY_LINK) { +void EnGo2_StartRolling(EnGo2* this, PlayState* play) { + if (ENGO2_GET_TYPE(this) == GORON_CITY_HOT_RODDER || ENGO2_GET_TYPE(this) == GORON_CITY_LINK) { this->collider.elem.acElemFlags = ACELEM_ON; this->actor.speed = GET_INFTABLE(INFTABLE_11E) ? 6.0f : 3.6000001f; } else { @@ -1355,122 +1371,121 @@ void EnGo2_SetupRolling(EnGo2* this, PlayState* play) { this->animTimer = 10; this->actor.shape.yOffset = 1800.0f; this->actor.speed *= 2.0f; // Speeding up - this->actionFunc = EnGo2_ContinueRolling; + this->actionFunc = EnGo2_RollingStart; } void EnGo2_StopRolling(EnGo2* this, PlayState* play) { EnBom* bomb; - if ((PARAMS_GET_S(this->actor.params, 0, 5) != GORON_CITY_ROLLING_BIG) && - (PARAMS_GET_S(this->actor.params, 0, 5) != GORON_CITY_LINK)) { - if (PARAMS_GET_S(this->actor.params, 0, 5) == GORON_DMT_ROLLING_SMALL) { + switch (ENGO2_GET_TYPE(this)) { + case GORON_DMT_ROLLING_SMALL: bomb = (EnBom*)Actor_Spawn(&play->actorCtx, play, ACTOR_EN_BOM, this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, 0); if (bomb != NULL) { bomb->timer = 0; } - } - } else { - this->collider.elem.acElemFlags = ACELEM_NONE; + break; + + case GORON_CITY_LINK: + case GORON_CITY_HOT_RODDER: + this->collider.elem.acElemFlags = ACELEM_NONE; + break; } this->actor.shape.rot = this->actor.world.rot; - this->unk_59C = 0; - this->unk_590 = 0; + this->bounceCounter = 0; + this->bounceTimer = 0; this->actionFunc = EnGo2_GroundRolling; this->actor.shape.yOffset = 0.0f; this->actor.speed = 0.0f; } -s32 EnGo2_IsFreeingGoronInFire(EnGo2* this, PlayState* play) { - if (PARAMS_GET_S(this->actor.params, 0, 5) != GORON_FIRE_GENERIC) { +s32 EnGo2_IsGoronFireGenericFreed(EnGo2* this, PlayState* play) { + if (ENGO2_GET_TYPE(this) != GORON_FIRE_GENERIC) { return false; } // shaking curled up this->actor.world.pos.x += (play->state.frames & 1) ? 1.0f : -1.0f; - if (Flags_GetSwitch(play, PARAMS_GET_S(this->actor.params, 10, 6))) { + if (ENGO2_IS_CAGE_OPEN(play, this)) { return true; } return false; } s32 EnGo2_IsGoronDmtBombFlower(EnGo2* this) { - if (PARAMS_GET_S(this->actor.params, 0, 5) != GORON_DMT_BOMB_FLOWER || - this->interactInfo.talkState != NPC_TALK_STATE_ACTION) { + if (ENGO2_GET_TYPE(this) != GORON_DMT_BOMB_FLOWER || this->interactInfo.talkState != NPC_TALK_STATE_ACTION) { return false; } - Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_3); + Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_SIDESTEP); this->interactInfo.talkState = NPC_TALK_STATE_IDLE; - this->isAwake = false; + this->isTalkative = false; this->trackingMode = NPC_TRACKING_NONE; - this->actionFunc = EnGo2_GoronDmtBombFlowerAnimation; + this->actionFunc = EnGo2_GoronDmtBombFlower; return true; } -s32 EnGo2_IsGoronRollingBig(EnGo2* this, PlayState* play) { - if (PARAMS_GET_S(this->actor.params, 0, 5) != GORON_CITY_ROLLING_BIG || - (this->interactInfo.talkState != NPC_TALK_STATE_ACTION)) { +s32 EnGo2_IsGoronHotRodder(EnGo2* this, PlayState* play) { + if (ENGO2_GET_TYPE(this) != GORON_CITY_HOT_RODDER || (this->interactInfo.talkState != NPC_TALK_STATE_ACTION)) { return false; } this->interactInfo.talkState = NPC_TALK_STATE_IDLE; - EnGo2_RollingAnimation(this, play); - this->actionFunc = EnGo2_GoronRollingBigContinueRolling; + EnGo2_SetupCurledUp(this, play); + this->actionFunc = EnGo2_GoronHotRodder; return true; } s32 EnGo2_IsGoronFireGeneric(EnGo2* this) { - if (PARAMS_GET_S(this->actor.params, 0, 5) != GORON_FIRE_GENERIC || - this->interactInfo.talkState == NPC_TALK_STATE_IDLE) { + if (ENGO2_GET_TYPE(this) != GORON_FIRE_GENERIC || this->interactInfo.talkState == NPC_TALK_STATE_IDLE) { return false; } - this->actionFunc = EnGo2_GoronFireGenericAction; + this->actionFunc = EnGo2_GoronFireGeneric; return true; } s32 EnGo2_IsGoronLinkReversing(EnGo2* this) { - if (PARAMS_GET_S(this->actor.params, 0, 5) != GORON_CITY_LINK || (this->waypoint >= this->unk_216) || - !EnGo2_IsWakingUp(this)) { + if (ENGO2_GET_TYPE(this) != GORON_CITY_LINK || (this->waypoint >= this->reverseWaypoint) || + !EnGo2_IsWithinInteactionRange(this)) { return false; } return true; } -s32 EnGo2_IsRolling(EnGo2* this) { +s32 EnGo2_IsTalkingAndFast(EnGo2* this) { if (this->interactInfo.talkState == NPC_TALK_STATE_IDLE || this->actor.speed < 1.0f) { return false; } - if (EnGo2_IsRollingOnGround(this, 2, 20.0 / 3.0f, 0)) { - if ((this->unk_590 >= 9) && (this->unk_59C == 0)) { - this->unk_590 = 8; + if (EnGo2_IsRollingOnGround(this, 2, 20.0 / 3.0f, false)) { + if ((this->bounceTimer >= 9) && (this->bounceCounter == 0)) { + this->bounceTimer = 8; } - EnGo2_GetDustData(this, 0); + EnGo2_SpawnDust(this, 0); } return true; } -void EnGo2_GoronLinkAnimation(EnGo2* this, PlayState* play) { +void EnGo2_AnimateGoronLinkAndDoSfx(EnGo2* this, PlayState* play) { s32 animation = ARRAY_COUNT(sAnimationInfo); - if (PARAMS_GET_S(this->actor.params, 0, 5) == GORON_CITY_LINK) { - if ((this->actor.textId == 0x3035 && this->unk_20C == 0) || - (this->actor.textId == 0x3036 && this->unk_20C == 0)) { - if (this->skelAnime.animation != &gGoronAnim_000D5C) { - animation = ENGO2_ANIM_12; + if (ENGO2_GET_TYPE(this) == GORON_CITY_LINK) { + if ((this->actor.textId == 0x3035 && this->messageEntry == 0) || + (this->actor.textId == 0x3036 && this->messageEntry == 0)) { + if (this->skelAnime.animation != &gGoronShakingAnim) { + animation = ENGO2_ANIM_SHAKING; this->eyeMouthTexState = 0; } } - if ((this->actor.textId == 0x3032 && this->unk_20C == 12) || (this->actor.textId == 0x3033) || - (this->actor.textId == 0x3035 && this->unk_20C == 6)) { - if (this->skelAnime.animation != &gGoronAnim_000750) { - animation = ENGO2_ANIM_11; + if ((this->actor.textId == 0x3032 && this->messageEntry == 12) || (this->actor.textId == 0x3033) || + (this->actor.textId == 0x3035 && this->messageEntry == 6)) { + if (this->skelAnime.animation != &gGoronSobbingAnim) { + animation = ENGO2_ANIM_SOBBING; this->eyeMouthTexState = 1; } } - if (this->skelAnime.animation == &gGoronAnim_000750) { + if (this->skelAnime.animation == &gGoronSobbingAnim) { if (this->skelAnime.curFrame == 20.0f) { Actor_PlaySfx(&this->actor, NA_SE_EN_GOLON_CRY); } @@ -1482,14 +1497,14 @@ void EnGo2_GoronLinkAnimation(EnGo2* this, PlayState* play) { } } -void EnGo2_GoronFireCamera(EnGo2* this, PlayState* play) { +void EnGo2_GoronFireGeneric_CreateSubcamera(EnGo2* this, PlayState* play) { s16 yaw; this->subCamId = Play_CreateSubCamera(play); Play_ChangeCameraStatus(play, CAM_ID_MAIN, CAM_STAT_WAIT); Play_ChangeCameraStatus(play, this->subCamId, CAM_STAT_ACTIVE); Path_CopyLastPoint(this->path, &this->subCamAt); - yaw = Math_Vec3f_Yaw(&this->actor.world.pos, &this->subCamAt) + 0xE38; + yaw = Math_Vec3f_Yaw(&this->actor.world.pos, &this->subCamAt) + DEG_TO_BINANG(20); this->subCamEye.x = Math_SinS(yaw) * 100.0f + this->actor.world.pos.x; this->subCamEye.z = Math_CosS(yaw) * 100.0f + this->actor.world.pos.z; this->subCamEye.y = this->actor.world.pos.y + 20.0f; @@ -1499,15 +1514,14 @@ void EnGo2_GoronFireCamera(EnGo2* this, PlayState* play) { Play_SetCameraAtEye(play, this->subCamId, &this->subCamAt, &this->subCamEye); } -void EnGo2_GoronFireClearCamera(EnGo2* this, PlayState* play) { +void EnGo2_GoronFireGeneric_ClearSubcamera(EnGo2* this, PlayState* play) { Play_ChangeCameraStatus(play, CAM_ID_MAIN, CAM_STAT_ACTIVE); Play_ClearCamera(play, this->subCamId); } -void EnGo2_BiggoronAnimation(EnGo2* this) { +void EnGo2_AnimateBiggoronAndDoSfx(EnGo2* this) { if (INV_CONTENT(ITEM_TRADE_ADULT) >= ITEM_BROKEN_GORONS_SWORD && INV_CONTENT(ITEM_TRADE_ADULT) <= ITEM_EYE_DROPS && - PARAMS_GET_S(this->actor.params, 0, 5) == GORON_DMT_BIGGORON && - this->interactInfo.talkState == NPC_TALK_STATE_IDLE) { + (ENGO2_GET_TYPE(this) == GORON_DMT_BIGGORON) && this->interactInfo.talkState == NPC_TALK_STATE_IDLE) { if (DECR(this->animTimer) == 0) { this->animTimer = Rand_S16Offset(30, 30); func_800F4524(&gSfxDefaultPos, NA_SE_EN_GOLON_EYE_BIG, 60); @@ -1520,13 +1534,13 @@ void EnGo2_Init(Actor* thisx, PlayState* play) { s32 pad; ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 28.0f); - SkelAnime_InitFlex(play, &this->skelAnime, &gGoronSkel, NULL, this->jointTable, this->morphTable, 18); + SkelAnime_InitFlex(play, &this->skelAnime, &gGoronSkel, NULL, this->jointTable, this->morphTable, GORON_LIMB_MAX); Collider_InitCylinder(play, &this->collider); Collider_SetCylinder(play, &this->collider, &this->actor, &sCylinderInit); CollisionCheck_SetInfo2(&this->actor.colChkInfo, NULL, &sColChkInfoInit); - // Not GORON_CITY_ROLLING_BIG, GORON_CITY_LINK, GORON_DMT_BIGGORON - switch (PARAMS_GET_S(this->actor.params, 0, 5)) { + // Not GORON_CITY_HOT_RODDER, GORON_CITY_LINK, GORON_DMT_BIGGORON + switch (ENGO2_GET_TYPE(this)) { case GORON_FIRE_GENERIC: case GORON_DMT_BOMB_FLOWER: case GORON_DMT_ROLLING_SMALL: @@ -1544,18 +1558,18 @@ void EnGo2_Init(Actor* thisx, PlayState* play) { EnGo2_SetColliderDim(this); EnGo2_SetShape(this); - Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_0); + Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_UNCURL_SIT_STAND_DEFAULT); this->actor.gravity = -1.0f; - this->alpha = this->actor.shape.shadowAlpha = 0; + this->shadownAlpha = this->actor.shape.shadowAlpha = 0; this->reverse = 0; - this->isAwake = false; - this->unk_211 = false; + this->isTalkative = false; + this->isUncurled = false; this->goronState = 0; this->waypoint = 0; - this->unk_216 = this->actor.shape.rot.z; + this->reverseWaypoint = this->actor.shape.rot.z; this->trackingMode = NPC_TRACKING_NONE; - this->path = Path_GetByIndex(play, PARAMS_GET_S(this->actor.params, 5, 5), 0x1F); - switch (PARAMS_GET_S(this->actor.params, 0, 5)) { + this->path = Path_GetByIndex(play, ENGO2_GET_PATH_INDEX(this), ENGO2_PATH_INDEX_MAX); + switch (ENGO2_GET_TYPE(this)) { case GORON_CITY_ENTRANCE: case GORON_CITY_ISLAND: case GORON_CITY_LOWEST_FLOOR: @@ -1570,7 +1584,7 @@ void EnGo2_Init(Actor* thisx, PlayState* play) { if ((LINK_IS_ADULT) || !CHECK_QUEST_ITEM(QUEST_GORON_RUBY)) { Actor_Kill(&this->actor); } - EnGo2_GetItemAnimation(this, play); + EnGo2_WakeUpInstant(this, play); break; case GORON_CITY_LINK: if (GET_INFTABLE(INFTABLE_109)) { @@ -1578,7 +1592,7 @@ void EnGo2_Init(Actor* thisx, PlayState* play) { this->actor.home.pos = this->actor.world.pos; if (!CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE) && CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_GORON)) { - EnGo2_GetItemAnimation(this, play); + EnGo2_WakeUpInstant(this, play); } else { this->actionFunc = EnGo2_CurledUp; } @@ -1586,21 +1600,21 @@ void EnGo2_Init(Actor* thisx, PlayState* play) { #if OOT_VERSION >= PAL_1_1 CLEAR_INFTABLE(INFTABLE_10C); #endif - this->collider.dim.height = (D_80A4816C[PARAMS_GET_S(this->actor.params, 0, 5)].height * 0.6f); - EnGo2_SetupRolling(this, play); - this->isAwake = true; + this->collider.dim.height = (sColliderData[ENGO2_GET_TYPE(this)].height * 0.6f); + EnGo2_StartRolling(this, play); + this->isTalkative = true; } break; - case GORON_CITY_ROLLING_BIG: + case GORON_CITY_HOT_RODDER: case GORON_DMT_ROLLING_SMALL: - this->collider.dim.height = (D_80A4816C[PARAMS_GET_S(this->actor.params, 0, 5)].height * 0.6f); - EnGo2_SetupRolling(this, play); + this->collider.dim.height = (sColliderData[ENGO2_GET_TYPE(this)].height * 0.6f); + EnGo2_StartRolling(this, play); break; case GORON_FIRE_GENERIC: - if (Flags_GetSwitch(play, PARAMS_GET_S(this->actor.params, 10, 6))) { + if (ENGO2_IS_CAGE_OPEN(play, this)) { Actor_Kill(&this->actor); } else { - this->isAwake = true; + this->isTalkative = true; this->actionFunc = EnGo2_CurledUp; } break; @@ -1633,49 +1647,49 @@ void EnGo2_Destroy(Actor* thisx, PlayState* play) { } void EnGo2_CurledUp(EnGo2* this, PlayState* play) { - u8 index = PARAMS_GET_S(this->actor.params, 0, 5); + u8 index = ENGO2_GET_TYPE(this); s16 height; s32 quakeIndex; if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { - if (PARAMS_GET_S(this->actor.params, 0, 5) == GORON_DMT_BIGGORON) { + if (ENGO2_GET_TYPE(this) == GORON_DMT_BIGGORON) { quakeIndex = Quake_Request(GET_ACTIVE_CAM(play), QUAKE_TYPE_3); Quake_SetSpeed(quakeIndex, -0x3CB0); Quake_SetPerturbations(quakeIndex, 8, 0, 0, 0); Quake_SetDuration(quakeIndex, 16); } else { - EnGo2_GetDustData(this, 1); + EnGo2_SpawnDust(this, 1); } this->skelAnime.playSpeed = 0.0f; } if ((s32)this->skelAnime.curFrame == 0) { - this->collider.dim.height = (D_80A4816C[index].height * 0.6f); + this->collider.dim.height = (sColliderData[index].height * 0.6f); } else { - height = D_80A4816C[index].height; + height = sColliderData[index].height; this->collider.dim.height = - ((D_80A4816C[index].height * 0.4f * (this->skelAnime.curFrame / this->skelAnime.startFrame)) + + ((sColliderData[index].height * 0.4f * (this->skelAnime.curFrame / this->skelAnime.startFrame)) + (height * 0.6f)); } - if (EnGo2_IsFreeingGoronInFire(this, play)) { - this->isAwake = false; - EnGo2_WakeUp(this, play); + if (EnGo2_IsGoronFireGenericFreed(this, play)) { + this->isTalkative = false; + EnGo2_WakeUpAnimated(this, play); } - if ((PARAMS_GET_S(this->actor.params, 0, 5) != GORON_FIRE_GENERIC) && EnGo2_IsWakingUp(this)) { - EnGo2_WakeUp(this, play); + if ((ENGO2_GET_TYPE(this) != GORON_FIRE_GENERIC) && EnGo2_IsWithinInteactionRange(this)) { + EnGo2_WakeUpAnimated(this, play); } } -void func_80A46B40(EnGo2* this, PlayState* play) { - u8 index = PARAMS_GET_S(this->actor.params, 0, 5); +void EnGo2_Standing(EnGo2* this, PlayState* play) { + u8 index = ENGO2_GET_TYPE(this); f32 height; - if (this->unk_211 == true) { - EnGo2_BiggoronAnimation(this); - EnGo2_GoronLinkAnimation(this, play); - EnGo2_SelectGoronWakingUp(this); + if (this->isUncurled == true) { + EnGo2_AnimateBiggoronAndDoSfx(this); + EnGo2_AnimateGoronLinkAndDoSfx(this, play); + EnGo2_SetupUncurledFlags(this); - if (!EnGo2_IsGoronRollingBig(this, play) && !EnGo2_IsGoronFireGeneric(this)) { + if (!EnGo2_IsGoronHotRodder(this, play) && !EnGo2_IsGoronFireGeneric(this)) { if (EnGo2_IsGoronDmtBombFlower(this)) { return; } @@ -1684,75 +1698,78 @@ void func_80A46B40(EnGo2* this, PlayState* play) { } } else { if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { - if (PARAMS_GET_S(this->actor.params, 0, 5) == GORON_DMT_BIGGORON) { + if (ENGO2_GET_TYPE(this) == GORON_DMT_BIGGORON) { this->actor.flags |= ACTOR_FLAG_ATTENTION_ENABLED; } - func_80A454CC(this); - this->unk_211 = true; - this->collider.dim.height = D_80A4816C[index].height; + EnGo2_ChooseIdleAnimation(this); + this->isUncurled = true; + this->collider.dim.height = sColliderData[index].height; } else { - height = D_80A4816C[index].height; + height = sColliderData[index].height; this->collider.dim.height = (s16)((height * 0.4f * (this->skelAnime.curFrame / this->skelAnime.endFrame)) + (height * 0.6f)); } } - if ((!EnGo2_IsCameraModified(this, play)) && (!EnGo2_IsWakingUp(this))) { - EnGo2_RollingAnimation(this, play); + if ((!EnGo2_ShouldStay(this, play)) && (!EnGo2_IsWithinInteactionRange(this))) { + EnGo2_SetupCurledUp(this, play); } } -void EnGo2_GoronDmtBombFlowerAnimation(EnGo2* this, PlayState* play) { +void EnGo2_GoronDmtBombFlower(EnGo2* this, PlayState* play) { f32 float1 = this->skelAnime.endFrame; f32 float2 = this->skelAnime.curFrame * ((f32)0x8000 / float1); this->actor.speed = Math_SinS(float2); - if ((EnGo2_Orient(this, play)) && (this->waypoint == 0)) { - EnGo2_GetItemAnimation(this, play); + if ((EnGo2_FollowPath(this, play)) && (this->waypoint == 0)) { + EnGo2_WakeUpInstant(this, play); } } -void EnGo2_GoronRollingBigContinueRolling(EnGo2* this, PlayState* play) { +void EnGo2_GoronHotRodder(EnGo2* this, PlayState* play) { if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { - EnGo2_GetDustData(this, 1); + EnGo2_SpawnDust(this, 1); this->skelAnime.playSpeed = 0.0f; - EnGo2_SetupRolling(this, play); + EnGo2_StartRolling(this, play); } } -void EnGo2_ContinueRolling(EnGo2* this, PlayState* play) { - f32 float1 = 1000.0f; +void EnGo2_RollingStart(EnGo2* this, PlayState* play) { + f32 slowdownRadius = 1000.0f; - if ((PARAMS_GET_S(this->actor.params, 0, 5) != GORON_DMT_ROLLING_SMALL || - !(this->actor.xyzDistToPlayerSq > SQ(float1))) && + if ((ENGO2_GET_TYPE(this) != GORON_DMT_ROLLING_SMALL || !(this->actor.xyzDistToPlayerSq > SQ(slowdownRadius))) && DECR(this->animTimer) == 0) { - this->actionFunc = EnGo2_SlowRolling; + this->actionFunc = EnGo2_RollingSlow; this->actor.speed *= 0.5f; // slowdown } - EnGo2_GetDustData(this, 2); + EnGo2_SpawnDust(this, 2); } -void EnGo2_SlowRolling(EnGo2* this, PlayState* play) { - s32 orientation; - s32 index; +void EnGo2_RollingSlow(EnGo2* this, PlayState* play) { + s32 updatedWaypoint; - if (!EnGo2_IsRolling(this)) { - if (EnGo2_IsRollingOnGround(this, 4, 8.0f, 1) == true) { + if (!EnGo2_IsTalkingAndFast(this)) { + if (EnGo2_IsRollingOnGround(this, 4, 8.0f, true) == true) { if (EnGo2_IsGoronLinkReversing(this)) { - this->actionFunc = EnGo2_ReverseRolling; + this->actionFunc = EnGo2_RollingReverse; return; } - EnGo2_GetDustData(this, 3); + EnGo2_SpawnDust(this, 3); } - orientation = EnGo2_Orient(this, play); - index = PARAMS_GET_S(this->actor.params, 0, 5); - if (index != GORON_CITY_LINK) { - if ((index == GORON_DMT_ROLLING_SMALL) && (orientation == 1) && (this->waypoint == 0)) { - EnGo2_StopRolling(this, play); - return; - } - } else if ((orientation == 2) && (this->waypoint == 1)) { - EnGo2_StopRolling(this, play); - return; + updatedWaypoint = EnGo2_FollowPath(this, play); + switch (ENGO2_GET_TYPE(this)) { + case GORON_DMT_ROLLING_SMALL: + if ((updatedWaypoint == 1) && (this->waypoint == 0)) { + EnGo2_StopRolling(this, play); + return; + } + break; + case GORON_CITY_LINK: + if ((updatedWaypoint == 2) && (this->waypoint == 1)) { + // @unreachable: `EnGo2_FollowPath` returns `0` or `1` + EnGo2_StopRolling(this, play); + return; + } + break; } Math_ApproachF(&this->actor.speed, EnGo2_GetTargetXZSpeed(this), 0.4f, 0.6f); this->actor.shape.rot = this->actor.world.rot; @@ -1760,16 +1777,16 @@ void EnGo2_SlowRolling(EnGo2* this, PlayState* play) { } void EnGo2_GroundRolling(EnGo2* this, PlayState* play) { - if (EnGo2_IsRollingOnGround(this, 4, 8.0f, 0)) { - EnGo2_GetDustData(this, 0); - if (this->unk_59C == 0) { - switch (PARAMS_GET_S(this->actor.params, 0, 5)) { + if (EnGo2_IsRollingOnGround(this, 4, 8.0f, false)) { + EnGo2_SpawnDust(this, 0); + if (this->bounceCounter == 0) { + switch (ENGO2_GET_TYPE(this)) { case GORON_CITY_LINK: this->goronState = 0; - this->actionFunc = EnGo2_GoronLinkStopRolling; + this->actionFunc = EnGo2_GoronLink; break; - case GORON_CITY_ROLLING_BIG: - EnGo2_WakeUp(this, play); + case GORON_CITY_HOT_RODDER: + EnGo2_WakeUpAnimated(this, play); break; default: this->actionFunc = EnGo2_CurledUp; @@ -1778,74 +1795,75 @@ void EnGo2_GroundRolling(EnGo2* this, PlayState* play) { } } -void EnGo2_ReverseRolling(EnGo2* this, PlayState* play) { - if (!EnGo2_IsRolling(this)) { +void EnGo2_RollingReverse(EnGo2* this, PlayState* play) { + if (!EnGo2_IsTalkingAndFast(this)) { Math_ApproachF(&this->actor.speed, 0.0f, 0.6f, 0.8f); if (this->actor.speed >= 1.0f) { - EnGo2_GetDustData(this, 3); + EnGo2_SpawnDust(this, 3); } if ((s32)this->actor.speed == 0) { - this->actor.world.rot.y ^= 0x8000; + this->actor.world.rot.y ^= 0x8000; // turn around 180 degrees this->actor.shape.rot.y = this->actor.world.rot.y; this->reverse ^= 1; EnGo2_UpdateWaypoint(this, play); - EnGo2_SetupRolling(this, play); + EnGo2_StartRolling(this, play); } } } -void EnGo2_SetupGetItem(EnGo2* this, PlayState* play) { +void EnGo2_HandleOffer(EnGo2* this, PlayState* play) { if (Actor_HasParent(&this->actor, play)) { #if OOT_VERSION >= PAL_1_0 this->actor.parent = NULL; #endif - this->actionFunc = EnGo2_SetGetItem; + this->actionFunc = EnGo2_HandleOfferParented; } else { + // @redundant: this action is always paired with `EnGo2_OfferItem`, which itself calls `Actor_OfferGetItem` Actor_OfferGetItem(&this->actor, play, this->getItemId, this->actor.xzDistToPlayer + 1.0f, fabsf(this->actor.yDistToPlayer) + 1.0f); } } -void EnGo2_SetGetItem(EnGo2* this, PlayState* play) { +void EnGo2_HandleOfferParented(EnGo2* this, PlayState* play) { if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play)) { this->interactInfo.talkState = NPC_TALK_STATE_IDLE; switch (this->getItemId) { case GI_CLAIM_CHECK: Environment_ClearBgsDayCount(); - EnGo2_GetItemAnimation(this, play); + EnGo2_WakeUpInstant(this, play); return; case GI_TUNIC_GORON: SET_INFTABLE(INFTABLE_109); - EnGo2_GetItemAnimation(this, play); + EnGo2_WakeUpInstant(this, play); return; case GI_SWORD_BIGGORON: gSaveContext.save.info.playerData.bgsFlag = true; break; case GI_BOMB_BAG_30: case GI_BOMB_BAG_40: - EnGo2_RollingAnimation(this, play); - this->actionFunc = EnGo2_GoronRollingBigContinueRolling; + EnGo2_SetupCurledUp(this, play); + this->actionFunc = EnGo2_GoronHotRodder; return; } - this->actionFunc = func_80A46B40; + this->actionFunc = EnGo2_Standing; } } void EnGo2_BiggoronEyedrops(EnGo2* this, PlayState* play) { switch (this->goronState) { - case 0: - Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_5); + case 0: // give eyedrops + Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_EYEDROPS); this->actor.flags &= ~ACTOR_FLAG_ATTENTION_ENABLED; - this->actor.shape.rot.y += 0x5B0; + this->actor.shape.rot.y += DEG_TO_BINANG(8); this->trackingMode = NPC_TRACKING_NONE; this->animTimer = this->skelAnime.endFrame + 60.0f + 60.0f; // eyeDrops animation timer this->eyeMouthTexState = 2; - this->unk_20C = 0; + this->messageEntry = 0; this->goronState++; Audio_SetMainBgmVolume(0x28, 5); OnePointCutscene_Init(play, 4190, -99, &this->actor, CAM_ID_MAIN); break; - case 1: + case 1: // applying eyedrops if (DECR(this->animTimer)) { if (this->animTimer == 60 || this->animTimer == 120) { Camera_SetFinishedFlag(GET_ACTIVE_CAM(play)); @@ -1853,36 +1871,36 @@ void EnGo2_BiggoronEyedrops(EnGo2* this, PlayState* play) { } } else { func_800F4524(&gSfxDefaultPos, NA_SE_EN_GOLON_GOOD_BIG, 60); - Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_6); + Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_EYEDROPS_TAKEN); Message_ContinueTextbox(play, 0x305A); this->eyeMouthTexState = 3; this->goronState++; Audio_SetMainBgmVolume(0x7F, 5); } break; - case 2: + case 2: // getting claimcheck if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { this->eyeMouthTexState = 0; } if (Message_GetState(&play->msgCtx) == TEXT_STATE_CLOSING) { - Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_1); + Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_UNCURL_SIT_STAND_NORMAL); this->actor.flags |= ACTOR_FLAG_ATTENTION_ENABLED; this->trackingMode = NPC_TRACKING_HEAD_AND_TORSO; this->skelAnime.playSpeed = 0.0f; this->skelAnime.curFrame = this->skelAnime.endFrame; - EnGo2_GetItem(this, play, GI_CLAIM_CHECK); - this->actionFunc = EnGo2_SetupGetItem; + EnGo2_OfferItem(this, play, GI_CLAIM_CHECK); + this->actionFunc = EnGo2_HandleOffer; this->goronState = 0; } break; } } -void EnGo2_GoronLinkStopRolling(EnGo2* this, PlayState* play) { +void EnGo2_GoronLink(EnGo2* this, PlayState* play) { Player* player = GET_PLAYER(play); switch (this->goronState) { - case 0: + case 0: // rolling if (Message_GetState(&play->msgCtx) != TEXT_STATE_NONE) { return; } else { @@ -1890,7 +1908,7 @@ void EnGo2_GoronLinkStopRolling(EnGo2* this, PlayState* play) { player->actor.freezeTimer = 10; this->goronState++; } - case 1: + case 1: // stunned break; default: return; @@ -1901,25 +1919,25 @@ void EnGo2_GoronLinkStopRolling(EnGo2* this, PlayState* play) { } else { SET_INFTABLE(INFTABLE_10C); this->trackingMode = NPC_TRACKING_NONE; - this->unk_211 = false; - this->isAwake = false; + this->isUncurled = false; + this->isTalkative = false; this->actionFunc = EnGo2_CurledUp; } } -void EnGo2_GoronFireGenericAction(EnGo2* this, PlayState* play) { +void EnGo2_GoronFireGeneric(EnGo2* this, PlayState* play) { Player* player = GET_PLAYER(play); Vec3s zeroVec = { 0x00, 0x00, 0x00 }; switch (this->goronState) { case 0: // Wake up if (Message_GetState(&play->msgCtx) == TEXT_STATE_CLOSING) { - EnGo2_GoronFireCamera(this, play); + EnGo2_GoronFireGeneric_CreateSubcamera(this, play); play->msgCtx.msgMode = MSGMODE_PAUSED; - Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_2); + Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_WALKING); this->waypoint = 1; this->skelAnime.playSpeed = 2.0f; - func_80A44D84(this); + EnGo2_OrientInstant(this); this->actor.shape.rot = this->actor.world.rot; this->animTimer = 60; this->actor.gravity = 0.0f; @@ -1947,9 +1965,9 @@ void EnGo2_GoronFireGenericAction(EnGo2* this, PlayState* play) { } else { this->animTimer = 0; this->actor.speed = 0.0f; - if ((PARAMS_GET_S(this->actor.params, 10, 6) != 1) && (PARAMS_GET_S(this->actor.params, 10, 6) != 2) && - (PARAMS_GET_S(this->actor.params, 10, 6) != 4) && (PARAMS_GET_S(this->actor.params, 10, 6) != 5) && - (PARAMS_GET_S(this->actor.params, 10, 6) != 9) && (PARAMS_GET_S(this->actor.params, 10, 6) != 11)) { + if ((ENGO2_CAGED_SWITCH_FLAG(this) != 1) && (ENGO2_CAGED_SWITCH_FLAG(this) != 2) && + (ENGO2_CAGED_SWITCH_FLAG(this) != 4) && (ENGO2_CAGED_SWITCH_FLAG(this) != 5) && + (ENGO2_CAGED_SWITCH_FLAG(this) != 9) && (ENGO2_CAGED_SWITCH_FLAG(this) != 11)) { this->goronState++; } this->goronState++; @@ -1970,7 +1988,7 @@ void EnGo2_GoronFireGenericAction(EnGo2* this, PlayState* play) { } case 4: // Finalize walking away Message_CloseTextbox(play); - EnGo2_GoronFireClearCamera(this, play); + EnGo2_GoronFireGeneric_ClearSubcamera(this, play); Player_SetCsActionWithHaltedActors(play, &this->actor, PLAYER_CSACTION_7); Actor_Kill(&this->actor); break; @@ -1982,54 +2000,54 @@ void EnGo2_GoronFireGenericAction(EnGo2* this, PlayState* play) { void EnGo2_Update(Actor* thisx, PlayState* play) { EnGo2* this = (EnGo2*)thisx; - func_80A45360(this, &this->alpha); - EnGo2_SitDownAnimation(this); + EnGo2_UpdateShadowAlpha(this, &this->shadownAlpha); + EnGo2_PlayStandingChangeSfx(this); SkelAnime_Update(&this->skelAnime); EnGo2_RollForward(this); Actor_UpdateBgCheckInfo(play, &this->actor, this->collider.dim.height * 0.5f, this->collider.dim.radius * 0.6f, 0.0f, UPDBGCHECKINFO_FLAG_0 | UPDBGCHECKINFO_FLAG_2); #if OOT_VERSION < PAL_1_0 - func_80A44AB0(this, play); + EnGo2_UpdateRollingKnockback(this, play); #else if (this->interactInfo.talkState == NPC_TALK_STATE_IDLE) { - func_80A44AB0(this, play); + EnGo2_UpdateRollingKnockback(this, play); } #endif this->actionFunc(this, play); - if (this->unk_211 == true) { - Actor_UpdateFidgetTables(play, this->fidgetTableY, this->fidgetTableZ, 18); + if (this->isUncurled == true) { + Actor_UpdateFidgetTables(play, this->fidgetTableY, this->fidgetTableZ, GORON_LIMB_MAX); } - func_80A45288(this, play); + EnGo2_TrackPlayer(this, play); EnGo2_EyeMouthTexState(this); EnGo2_CheckCollision(this, play); } s32 EnGo2_DrawCurledUp(EnGo2* this, PlayState* play) { - Vec3f D_80A48554 = { 0.0f, 0.0f, 0.0f }; + Vec3f focusOffset = { 0.0f, 0.0f, 0.0f }; OPEN_DISPS(play->state.gfxCtx, "../z_en_go2.c", 2881); Gfx_SetupDL_25Opa(play->state.gfxCtx); MATRIX_FINALIZE_AND_LOAD(POLY_OPA_DISP++, play->state.gfxCtx, "../z_en_go2.c", 2884); - gSPDisplayList(POLY_OPA_DISP++, gGoronDL_00BD80); + gSPDisplayList(POLY_OPA_DISP++, gGoronCurledUpDL); CLOSE_DISPS(play->state.gfxCtx, "../z_en_go2.c", 2889); - Matrix_MultVec3f(&D_80A48554, &this->actor.focus.pos); + Matrix_MultVec3f(&focusOffset, &this->actor.focus.pos); return 1; } s32 EnGo2_DrawRolling(EnGo2* this, PlayState* play) { s32 pad; - Vec3f D_80A48560 = { 0.0f, 0.0f, 0.0f }; + Vec3f focusOffset = { 0.0f, 0.0f, 0.0f }; f32 speedXZ; OPEN_DISPS(play->state.gfxCtx, "../z_en_go2.c", 2914); Gfx_SetupDL_25Opa(play->state.gfxCtx); - speedXZ = this->actionFunc == EnGo2_ReverseRolling ? 0.0f : this->actor.speed; + speedXZ = this->actionFunc == EnGo2_RollingReverse ? 0.0f : this->actor.speed; Matrix_RotateZYX((play->state.frames * ((s16)speedXZ * 1400)), 0, this->actor.shape.rot.z, MTXMODE_APPLY); MATRIX_FINALIZE_AND_LOAD(POLY_OPA_DISP++, play->state.gfxCtx, "../z_en_go2.c", 2926); - gSPDisplayList(POLY_OPA_DISP++, gGoronDL_00C140); + gSPDisplayList(POLY_OPA_DISP++, gGoronRollingDL); CLOSE_DISPS(play->state.gfxCtx, "../z_en_go2.c", 2930); - Matrix_MultVec3f(&D_80A48560, &this->actor.focus.pos); + Matrix_MultVec3f(&focusOffset, &this->actor.focus.pos); return 1; } @@ -2037,19 +2055,19 @@ s32 EnGo2_OverrideLimbDraw(PlayState* play, s32 limb, Gfx** dList, Vec3f* pos, V EnGo2* this = (EnGo2*)thisx; Vec3s limbRot; - if (limb == 17) { + if (limb == GORON_LIMB_HEAD) { Matrix_Translate(2800.0f, 0.0f, 0.0f, MTXMODE_APPLY); limbRot = this->interactInfo.headRot; Matrix_RotateX(BINANG_TO_RAD_ALT(limbRot.y), MTXMODE_APPLY); Matrix_RotateZ(BINANG_TO_RAD_ALT(limbRot.x), MTXMODE_APPLY); Matrix_Translate(-2800.0f, 0.0f, 0.0f, MTXMODE_APPLY); } - if (limb == 10) { + if (limb == GORON_LIMB_TORSO) { limbRot = this->interactInfo.torsoRot; Matrix_RotateY(BINANG_TO_RAD_ALT(limbRot.y), MTXMODE_APPLY); Matrix_RotateX(BINANG_TO_RAD_ALT(limbRot.x), MTXMODE_APPLY); } - if ((limb == 10) || (limb == 11) || (limb == 14)) { + if ((limb == GORON_LIMB_TORSO) || (limb == GORON_LIMB_LEFT_ARM) || (limb == GORON_LIMB_RIGHT_ARM)) { rot->y += Math_SinS(this->fidgetTableY[limb]) * FIDGET_AMPLITUDE; rot->z += Math_CosS(this->fidgetTableZ[limb]) * FIDGET_AMPLITUDE; } @@ -2058,10 +2076,10 @@ s32 EnGo2_OverrideLimbDraw(PlayState* play, s32 limb, Gfx** dList, Vec3f* pos, V void EnGo2_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx) { EnGo2* this = (EnGo2*)thisx; - Vec3f D_80A4856C = { 600.0f, 0.0f, 0.0f }; + Vec3f focusOffset = { 600.0f, 0.0f, 0.0f }; // ahead, this distance - if (limbIndex == 17) { - Matrix_MultVec3f(&D_80A4856C, &this->actor.focus.pos); + if (limbIndex == GORON_LIMB_HEAD) { + Matrix_MultVec3f(&focusOffset, &this->actor.focus.pos); } } @@ -2079,18 +2097,23 @@ void EnGo2_Draw(Actor* thisx, PlayState* play) { (this->skelAnime.curFrame == 0.0f)) { if (1) {} EnGo2_DrawCurledUp(this, play); - } else if (this->actionFunc == EnGo2_SlowRolling || this->actionFunc == EnGo2_ReverseRolling || - this->actionFunc == EnGo2_ContinueRolling) { + return; + } + + if (this->actionFunc == EnGo2_RollingSlow || this->actionFunc == EnGo2_RollingReverse || + this->actionFunc == EnGo2_RollingStart) { EnGo2_DrawRolling(this, play); - } else { - OPEN_DISPS(play->state.gfxCtx, "../z_en_go2.c", 3063); - Gfx_SetupDL_25Opa(play->state.gfxCtx); + return; + } + + // draw skeleton normally + OPEN_DISPS(play->state.gfxCtx, "../z_en_go2.c", 3063); + Gfx_SetupDL_25Opa(play->state.gfxCtx); - gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(eyeTextures[this->eyeTexIndex])); - gSPSegment(POLY_OPA_DISP++, 0x09, SEGMENTED_TO_VIRTUAL(mouthTextures[this->mouthTexIndex])); + gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(eyeTextures[this->eyeTexIndex])); + gSPSegment(POLY_OPA_DISP++, 0x09, SEGMENTED_TO_VIRTUAL(mouthTextures[this->mouthTexIndex])); - SkelAnime_DrawFlexOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - EnGo2_OverrideLimbDraw, EnGo2_PostLimbDraw, this); - CLOSE_DISPS(play->state.gfxCtx, "../z_en_go2.c", 3081); - } + SkelAnime_DrawFlexOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnGo2_OverrideLimbDraw, EnGo2_PostLimbDraw, this); + CLOSE_DISPS(play->state.gfxCtx, "../z_en_go2.c", 3081); } diff --git a/src/overlays/actors/ovl_En_Go2/z_en_go2.h b/src/overlays/actors/ovl_En_Go2/z_en_go2.h index 6fb62293551..59238f1556b 100644 --- a/src/overlays/actors/ovl_En_Go2/z_en_go2.h +++ b/src/overlays/actors/ovl_En_Go2/z_en_go2.h @@ -9,23 +9,6 @@ struct EnGo2; typedef void (*EnGo2ActionFunc)(struct EnGo2*, PlayState*); -typedef enum GoronType { - /* 0x00 */ GORON_CITY_ROLLING_BIG, - /* 0x01 */ GORON_CITY_LINK, - /* 0x02 */ GORON_DMT_BIGGORON, - /* 0x03 */ GORON_FIRE_GENERIC, - /* 0x04 */ GORON_DMT_BOMB_FLOWER, - /* 0x05 */ GORON_DMT_ROLLING_SMALL, - /* 0x06 */ GORON_DMT_DC_ENTRANCE, - /* 0x07 */ GORON_CITY_ENTRANCE, - /* 0x08 */ GORON_CITY_ISLAND, - /* 0x09 */ GORON_CITY_LOWEST_FLOOR, - /* 0x0A */ GORON_CITY_STAIRWELL, - /* 0x0B */ GORON_CITY_LOST_WOODS, - /* 0x0C */ GORON_DMT_FAIRY_HINT, - /* 0x0D */ GORON_MARKET_BAZAAR -} GoronType; - // WIP fire temple type docs // /* 0x00 */ UNUSED // /* 0x01 */ GORON_FIRE_LAVA_ROOM_OPEN @@ -40,21 +23,20 @@ typedef enum GoronType { // /* 0x0A */ GORON_FIRE_MAZE_UPPER, // /* 0x0B */ GORON_FIRE_HIGHEST - -typedef struct EnGo2DataStruct1 { +typedef struct EnGo2ColliderData { s16 unused; s16 yDist; s16 xzDist; s16 radius; s16 height; -} EnGo2DataStruct1; // size = 0xA +} EnGo2ColliderData; // size = 0xA -typedef struct EnGo2DataStruct2 { - f32 shape_unk_10; +typedef struct EnGo2ShapeData { + f32 shadowScale; f32 scale; - s8 actor_unk_1F; + s8 attentionRangeType; f32 interactRange; -} EnGo2DataStruct2; // size = 0x10 +} EnGo2ShapeData; // size = 0x10 typedef struct EnGo2DustEffectData { u8 initialTimer; @@ -65,6 +47,30 @@ typedef struct EnGo2DustEffectData { f32 yAccel; } EnGo2DustEffectData; // size = 0x18 +typedef enum GoronType { + /* 0x0 */ GORON_CITY_HOT_RODDER, + /* 0x1 */ GORON_CITY_LINK, + /* 0x2 */ GORON_DMT_BIGGORON, + /* 0x3 */ GORON_FIRE_GENERIC, + /* 0x4 */ GORON_DMT_BOMB_FLOWER, + /* 0x5 */ GORON_DMT_ROLLING_SMALL, + /* 0x6 */ GORON_DMT_DC_ENTRANCE, + /* 0x7 */ GORON_CITY_ENTRANCE, + /* 0x8 */ GORON_CITY_ISLAND, + /* 0x9 */ GORON_CITY_LOWEST_FLOOR, + /* 0xA */ GORON_CITY_STAIRWELL, + /* 0xB */ GORON_CITY_LOST_WOODS, + /* 0xC */ GORON_DMT_FAIRY_HINT, + /* 0xD */ GORON_MARKET_BAZAAR +} GoronType; + +#define ENGO2_GET_TYPE(this) PARAMS_GET_S((this)->actor.params, 0, 5) +#define ENGO2_GET_PATH_INDEX(this) PARAMS_GET_S((this)->actor.params, 5, 5) +#define ENGO2_CAGED_SWITCH_FLAG(this) PARAMS_GET_S((this)->actor.params, 10, 6) + +#define ENGO2_PATH_INDEX_MAX NBITS_TO_MASK(5) +#define ENGO2_IS_CAGE_OPEN(play, this) Flags_GetSwitch(play, ENGO2_CAGED_SWITCH_FLAG(this)) + #define EN_GO2_EFFECT_COUNT 10 typedef struct EnGo2 { @@ -74,38 +80,35 @@ typedef struct EnGo2 { /* 0x0194 */ NpcInteractInfo interactInfo; /* 0x01BC */ ColliderCylinder collider; /* 0x0208 */ Path* path; - /* 0x020C */ u8 unk_20C; // counter for GORON_CITY_LINK animation - /* 0x020D */ u8 dialogState; + /* 0x020C */ u8 messageEntry; // tracks message state changes, like with `BOX_BREAK` or `TEXTID` + /* 0x020D */ u8 messageState; // last known result of `Message_GetState` /* 0x020E */ u8 reverse; - /* 0x020F */ u8 isAwake; // Conditional + /* 0x020F */ u8 isTalkative; /* 0x0210 */ s8 waypoint; - /* 0x0211 */ u8 unk_211; // Conditional - // goron link: 0 - rolling, 1 - frozen - // biggoron: 0 - give eyedrops, 1 - applying eyedrops, 2 - getting claimcheck - // generic fire: 0 - + /* 0x0211 */ u8 isUncurled; /* 0x0212 */ u8 goronState; - /* 0x0213 */ u8 eyeMouthTexState; // 0, 1, 2, 3 + /* 0x0213 */ u8 eyeMouthTexState; /* 0x0214 */ u8 eyeTexIndex; /* 0x0215 */ u8 mouthTexIndex; - /* 0x0216 */ u8 unk_216; // Set to z rotation, checked by waypoint + /* 0x0216 */ u8 reverseWaypoint; // Set to z rotation, checked by waypoint /* 0x0218 */ f32 interactRange; /* 0x021C */ char unk_21C[0x04]; - /* 0x0220 */ f32 alpha; // Set to 0, used by func_80A45360, smoothed to this->actor.shape.shadowAlpha from either 0 or 255.0f + /* 0x0220 */ f32 shadownAlpha; /* 0x0224 */ s16 blinkTimer; - /* 0x0226 */ s16 fidgetTableY[18]; - /* 0x024A */ s16 fidgetTableZ[18]; + /* 0x0226 */ s16 fidgetTableY[GORON_LIMB_MAX]; + /* 0x024A */ s16 fidgetTableZ[GORON_LIMB_MAX]; /* 0x026E */ u16 trackingMode; /* 0x0270 */ EnGoEffect effects[EN_GO2_EFFECT_COUNT]; /* 0x04A0 */ Vec3f subCamEye; /* 0x04AC */ Vec3f subCamAt; - /* 0x04B8 */ Vec3s jointTable[18]; - /* 0x0524 */ Vec3s morphTable[18]; - /* 0x0590 */ s16 unk_590; // timer - /* 0x0592 */ s16 animTimer; // animTimer. Plays NA_SE_EN_MORIBLIN_WALK, NA_SE_EV_IRON_DOOR_OPEN, NA_SE_EV_IRON_DOOR_CLOSE + /* 0x04B8 */ Vec3s jointTable[GORON_LIMB_MAX]; + /* 0x0524 */ Vec3s morphTable[GORON_LIMB_MAX]; + /* 0x0590 */ s16 bounceTimer; + /* 0x0592 */ s16 animTimer; /* 0x0594 */ s32 getItemId; /* 0x0598 */ char unk_598[0x02]; /* 0x059A */ s16 subCamId; - /* 0x059C */ s16 unk_59C; + /* 0x059C */ s16 bounceCounter; } EnGo2; // size = 0x05A0 #endif