From a5f7478b99a94947d27cf152217aa4a53b38352a Mon Sep 17 00:00:00 2001 From: aMannus Date: Wed, 18 Jan 2023 16:56:32 +0100 Subject: [PATCH 01/22] Fix CC connection bugs (#2367) --- soh/soh/Enhancements/crowd-control/CrowdControl.cpp | 8 +++++--- soh/soh/OTRGlobals.cpp | 5 +++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/soh/soh/Enhancements/crowd-control/CrowdControl.cpp b/soh/soh/Enhancements/crowd-control/CrowdControl.cpp index 2f5b1a3accc..3fbd24a90ff 100644 --- a/soh/soh/Enhancements/crowd-control/CrowdControl.cpp +++ b/soh/soh/Enhancements/crowd-control/CrowdControl.cpp @@ -101,7 +101,7 @@ void CrowdControl::Disable() { void CrowdControl::ListenToServer() { while (isEnabled) { - while (!connected) { + while (!connected && isEnabled) { SPDLOG_TRACE("[CrowdControl] Attempting to make connection to server..."); tcpsock = SDLNet_TCP_Open(&ip); @@ -112,8 +112,10 @@ void CrowdControl::ListenToServer() { } } - auto socketSet = SDLNet_AllocSocketSet(1); - SDLNet_TCP_AddSocket(socketSet, tcpsock); + SDLNet_SocketSet socketSet = SDLNet_AllocSocketSet(1); + if (tcpsock) { + SDLNet_TCP_AddSocket(socketSet, tcpsock); + } // Listen to socket messages while (connected && tcpsock && isEnabled) { diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index a5b3908708d..9011fcc7931 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -461,6 +461,11 @@ extern "C" void InitOTR() { #ifdef ENABLE_CROWD_CONTROL CrowdControl::Instance = new CrowdControl(); CrowdControl::Instance->Init(); + if (CVar_GetS32("gCrowdControl", 0)) { + CrowdControl::Instance->Enable(); + } else { + CrowdControl::Instance->Disable(); + } #endif } From 32ad0ab4b8f6fcd7a22c78d3176d4eebcee7950e Mon Sep 17 00:00:00 2001 From: David Chavez Date: Wed, 18 Jan 2023 19:21:38 +0100 Subject: [PATCH 02/22] Bump version --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 84da81a1220..0f0f6b8df6e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,8 +7,8 @@ set(CMAKE_CXX_STANDARD 20 CACHE STRING "The C++ standard to use") set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment version" FORCE) project(Ship LANGUAGES C CXX - VERSION 5.1.3) -set(PROJECT_BUILD_NAME "BRADLEY DELTA" CACHE STRING "") + VERSION 5.1.4) +set(PROJECT_BUILD_NAME "BRADLEY ECHO" CACHE STRING "") set(PROJECT_TEAM "github.com/harbourmasters" CACHE STRING "") set_property(DIRECTORY ${CMAKE_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT soh) From 7c8be2153c7ad94155b90b6e5d42b1cc6b28f972 Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Thu, 19 Jan 2023 02:38:04 -0500 Subject: [PATCH 03/22] documentation: use `NpcInteractInfo` from zret (#2370) --- soh/include/functions.h | 8 +- soh/include/z64.h | 12 - soh/include/z64actor.h | 31 +- soh/src/code/z_actor.c | 323 +++++++++++------- .../overlays/actors/ovl_Demo_Im/z_demo_im.c | 46 +-- .../overlays/actors/ovl_Demo_Im/z_demo_im.h | 2 +- soh/src/overlays/actors/ovl_En_Cs/z_en_cs.c | 16 +- soh/src/overlays/actors/ovl_En_Cs/z_en_cs.h | 2 +- .../overlays/actors/ovl_En_Daiku/z_en_daiku.c | 18 +- .../overlays/actors/ovl_En_Daiku/z_en_daiku.h | 2 +- .../z_en_daiku_kakariko.c | 14 +- .../z_en_daiku_kakariko.h | 2 +- .../ovl_En_Diving_Game/z_en_diving_game.c | 10 +- .../ovl_En_Diving_Game/z_en_diving_game.h | 2 +- soh/src/overlays/actors/ovl_En_Du/z_en_du.c | 46 +-- soh/src/overlays/actors/ovl_En_Du/z_en_du.h | 2 +- soh/src/overlays/actors/ovl_En_Go/z_en_go.c | 104 +++--- soh/src/overlays/actors/ovl_En_Go/z_en_go.h | 2 +- soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c | 227 ++++++------ soh/src/overlays/actors/ovl_En_Go2/z_en_go2.h | 4 +- .../overlays/actors/ovl_En_Guest/z_en_guest.c | 12 +- .../overlays/actors/ovl_En_Guest/z_en_guest.h | 2 +- .../actors/ovl_En_Heishi4/z_en_heishi4.c | 10 +- .../actors/ovl_En_Heishi4/z_en_heishi4.h | 2 +- soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c | 50 +-- soh/src/overlays/actors/ovl_En_Hy/z_en_hy.h | 2 +- soh/src/overlays/actors/ovl_En_In/z_en_in.c | 98 +++--- soh/src/overlays/actors/ovl_En_In/z_en_in.h | 2 +- soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c | 108 +++--- soh/src/overlays/actors/ovl_En_Ko/z_en_ko.h | 2 +- soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c | 38 +-- soh/src/overlays/actors/ovl_En_Kz/z_en_kz.h | 2 +- soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c | 64 ++-- soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.h | 2 +- soh/src/overlays/actors/ovl_En_Ma2/z_en_ma2.c | 42 +-- soh/src/overlays/actors/ovl_En_Ma2/z_en_ma2.h | 2 +- soh/src/overlays/actors/ovl_En_Ma3/z_en_ma3.c | 42 +-- soh/src/overlays/actors/ovl_En_Ma3/z_en_ma3.h | 2 +- soh/src/overlays/actors/ovl_En_Md/z_en_md.c | 57 ++-- soh/src/overlays/actors/ovl_En_Md/z_en_md.h | 2 +- soh/src/overlays/actors/ovl_En_Mu/z_en_mu.c | 14 +- soh/src/overlays/actors/ovl_En_Mu/z_en_mu.h | 2 +- soh/src/overlays/actors/ovl_En_Nb/z_en_nb.c | 26 +- soh/src/overlays/actors/ovl_En_Nb/z_en_nb.h | 2 +- .../actors/ovl_En_Niw_Girl/z_en_niw_girl.c | 10 +- .../actors/ovl_En_Niw_Girl/z_en_niw_girl.h | 2 +- .../actors/ovl_En_Niw_Lady/z_en_niw_lady.c | 10 +- .../actors/ovl_En_Niw_Lady/z_en_niw_lady.h | 2 +- soh/src/overlays/actors/ovl_En_Ru1/z_en_ru1.c | 22 +- soh/src/overlays/actors/ovl_En_Ru1/z_en_ru1.h | 2 +- soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c | 46 +-- soh/src/overlays/actors/ovl_En_Sa/z_en_sa.h | 2 +- soh/src/overlays/actors/ovl_En_Tg/z_en_tg.c | 6 +- soh/src/overlays/actors/ovl_En_Tg/z_en_tg.h | 3 +- soh/src/overlays/actors/ovl_En_Tk/z_en_tk.c | 28 +- soh/src/overlays/actors/ovl_En_Tk/z_en_tk.h | 4 +- .../overlays/actors/ovl_En_Toryo/z_en_toryo.c | 20 +- .../overlays/actors/ovl_En_Toryo/z_en_toryo.h | 2 +- soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c | 14 +- soh/src/overlays/actors/ovl_En_Xc/z_en_xc.h | 2 +- soh/src/overlays/actors/ovl_En_Zl3/z_en_zl3.c | 28 +- soh/src/overlays/actors/ovl_En_Zl3/z_en_zl3.h | 2 +- soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c | 22 +- soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.h | 2 +- soh/src/overlays/actors/ovl_En_Zo/z_en_zo.c | 56 +-- soh/src/overlays/actors/ovl_En_Zo/z_en_zo.h | 4 +- 66 files changed, 933 insertions(+), 814 deletions(-) diff --git a/soh/include/functions.h b/soh/include/functions.h index 7bf9028c600..70def4ac2d6 100644 --- a/soh/include/functions.h +++ b/soh/include/functions.h @@ -531,10 +531,10 @@ void func_8003424C(PlayState* play, Vec3f* arg1); void Actor_SetColorFilter(Actor* actor, s16 colorFlag, s16 colorIntensityMax, s16 xluFlag, s16 duration); Hilite* func_800342EC(Vec3f* object, PlayState* play); Hilite* func_8003435C(Vec3f* object, PlayState* play); -s32 func_800343CC(PlayState* play, Actor* actor, s16* arg2, f32 interactRange, - u16 (*unkFunc1)(PlayState*, Actor*), s16 (*unkFunc2)(PlayState*, Actor*)); -s16 func_800347E8(s16 arg0); -void func_80034A14(Actor* actor, struct_80034A14_arg1* arg1, s16 arg2, s16 arg3); +s32 Npc_UpdateTalking(PlayState* play, Actor* actor, s16* talkState, f32 interactRange, + NpcGetTextIdFunc getTextId, NpcUpdateTalkStateFunc updateTalkState); +s16 Npc_GetTrackingPresetMaxPlayerYaw(s16 presetIndex); +void Npc_TrackPoint(Actor* actor, NpcInteractInfo* interactInfo, s16 presetIndex, s16 trackingMode); void func_80034BA0(PlayState* play, SkelAnime* skelAnime, OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, Actor* actor, s16 alpha); void func_80034CC4(PlayState* play, SkelAnime* skelAnime, OverrideLimbDraw overrideLimbDraw, diff --git a/soh/include/z64.h b/soh/include/z64.h index 7d548d69ec5..4edcd1fcdc6 100644 --- a/soh/include/z64.h +++ b/soh/include/z64.h @@ -1506,18 +1506,6 @@ typedef struct { /* 0x08 */ f32 morphFrames; } AnimationMinimalInfo; // size = 0xC -typedef struct { - /* 0x00 */ s16 unk_00; - /* 0x02 */ s16 unk_02; - /* 0x04 */ s16 unk_04; - /* 0x06 */ s16 unk_06; - /* 0x08 */ Vec3s unk_08; - /* 0x0E */ Vec3s unk_0E; - /* 0x14 */ f32 unk_14; - /* 0x18 */ Vec3f unk_18; - /* 0x24 */ s16 unk_24; -} struct_80034A14_arg1; // size = 0x28 - typedef struct { /* 0x00 */ s8 scene; /* 0x01 */ s8 spawn; diff --git a/soh/include/z64actor.h b/soh/include/z64actor.h index 11cf861386c..abcc1f2e19d 100644 --- a/soh/include/z64actor.h +++ b/soh/include/z64actor.h @@ -20,8 +20,8 @@ struct Lights; typedef void (*ActorFunc)(struct Actor*, struct PlayState*); typedef void (*ActorResetFunc)(void); typedef void (*ActorShadowFunc)(struct Actor*, struct Lights*, struct PlayState*); -typedef u16 (*callback1_800343CC)(struct PlayState*, struct Actor*); -typedef s16 (*callback2_800343CC)(struct PlayState*, struct Actor*); +typedef u16 (*NpcGetTextIdFunc)(struct PlayState*, struct Actor*); +typedef s16 (*NpcUpdateTalkStateFunc)(struct PlayState*, struct Actor*); typedef struct { Vec3f pos; @@ -369,4 +369,31 @@ typedef enum { DOORLOCK_NORMAL_SPIRIT } DoorLockType; +typedef enum { + /* 0x0 */ NPC_TALK_STATE_IDLE, // NPC not currently talking to player + /* 0x1 */ NPC_TALK_STATE_TALKING, // NPC is currently talking to player + /* 0x2 */ NPC_TALK_STATE_ACTION, // An NPC-defined action triggered in the conversation + /* 0x3 */ NPC_TALK_STATE_ITEM_GIVEN // NPC finished giving an item and text box is done +} NpcTalkState; + +typedef enum { + /* 0x0 */ NPC_TRACKING_PLAYER_AUTO_TURN, // Determine tracking mode based on player position, see Npc_UpdateAutoTurn + /* 0x1 */ NPC_TRACKING_NONE, // Don't track the target (usually the player) + /* 0x2 */ NPC_TRACKING_HEAD_AND_TORSO, // Track target by turning the head and the torso + /* 0x3 */ NPC_TRACKING_HEAD, // Track target by turning the head + /* 0x4 */ NPC_TRACKING_FULL_BODY // Track target by turning the body, torso and head +} NpcTrackingMode; + +typedef struct { + /* 0x00 */ s16 talkState; + /* 0x02 */ s16 trackingMode; + /* 0x04 */ s16 autoTurnTimer; + /* 0x06 */ s16 autoTurnState; + /* 0x08 */ Vec3s headRot; + /* 0x0E */ Vec3s torsoRot; + /* 0x14 */ f32 yOffset; // Y position offset to add to actor position when calculating angle to target + /* 0x18 */ Vec3f trackPos; + /* 0x24 */ char unk_24[0x4]; +} NpcInteractInfo; // size = 0x28 + #endif diff --git a/soh/src/code/z_actor.c b/soh/src/code/z_actor.c index 97494de44bf..a86ad33f76b 100644 --- a/soh/src/code/z_actor.c +++ b/soh/src/code/z_actor.c @@ -4172,24 +4172,41 @@ Hilite* func_8003435C(Vec3f* object, PlayState* play) { return func_8002EB44(object, &play->view.eye, &lightDir, play->state.gfxCtx); } -s32 func_800343CC(PlayState* play, Actor* actor, s16* arg2, f32 interactRange, callback1_800343CC unkFunc1, - callback2_800343CC unkFunc2) { +/** + * Updates NPC talking state. Checks for a talk request and updates + * the talkState parameter when a dialog is ongoing. Otherwise checks if + * the actor is onscreen, advertises the interaction in a range and sets + * the current text id if necessary. + * + * The talk state values are defined in the NpcTalkState enum. + * + * @see NpcTalkState + * + * @param[in,out] talkState Talk state + * @param interactRange The interact (talking) range for the actor + * @param getTextId Callback for getting the next text id + * @param updateTalkState Callback for getting the next talkState value + * @return True if a new dialog was started (player talked to the actor). False otherwise. + */ +s32 Npc_UpdateTalking(PlayState* play, Actor* actor, s16* talkState, f32 interactRange, NpcGetTextIdFunc getTextId, + NpcUpdateTalkStateFunc updateTalkState) { s16 x; s16 y; if (Actor_ProcessTalkRequest(actor, play)) { - *arg2 = 1; + *talkState = NPC_TALK_STATE_TALKING; return true; } - if (*arg2 != 0) { - *arg2 = unkFunc2(play, actor); + if (*talkState != NPC_TALK_STATE_IDLE) { + *talkState = updateTalkState(play, actor); return false; } Actor_GetScreenPos(play, actor, &x, &y); if ((x < 0) || (x > SCREEN_WIDTH) || (y < 0) || (y > SCREEN_HEIGHT)) { + // Actor is offscreen return false; } @@ -4197,159 +4214,237 @@ s32 func_800343CC(PlayState* play, Actor* actor, s16* arg2, f32 interactRange, c return false; } - actor->textId = unkFunc1(play, actor); + actor->textId = getTextId(play, actor); return false; } typedef struct { - /* 0x00 */ s16 unk_00; - /* 0x02 */ s16 unk_02; - /* 0x04 */ s16 unk_04; - /* 0x06 */ s16 unk_06; - /* 0x08 */ s16 unk_08; - /* 0x0A */ s16 unk_0A; - /* 0x0C */ u8 unk_0C; -} struct_80116130_0; // size = 0x10 + /* 0x00 */ s16 maxHeadYaw; + /* 0x02 */ s16 minHeadPitch; + /* 0x04 */ s16 maxHeadPitch; + /* 0x06 */ s16 maxTorsoYaw; + /* 0x08 */ s16 minTorsoPitch; + /* 0x0A */ s16 maxTorsoPitch; + /* 0x0C */ u8 rotateYaw; +} NpcTrackingRotLimits; // size = 0x10 typedef struct { - /* 0x00 */ struct_80116130_0 sub_00; - /* 0x10 */ f32 unk_10; - /* 0x14 */ s16 unk_14; -} struct_80116130; // size = 0x18 - -static struct_80116130 D_80116130[] = { - { { 0x2AA8, 0xF1C8, 0x18E2, 0x1554, 0x0000, 0x0000, 1 }, 170.0f, 0x3FFC }, - { { 0x2AA8, 0xEAAC, 0x1554, 0x1554, 0xF8E4, 0x0E38, 1 }, 170.0f, 0x3FFC }, - { { 0x31C4, 0xE390, 0x0E38, 0x0E38, 0xF1C8, 0x071C, 1 }, 170.0f, 0x3FFC }, - { { 0x1554, 0xF1C8, 0x0000, 0x071C, 0xF8E4, 0x0000, 1 }, 170.0f, 0x3FFC }, - { { 0x2AA8, 0xF8E4, 0x071C, 0x0E38, 0xD558, 0x2AA8, 1 }, 170.0f, 0x3FFC }, - { { 0x0000, 0xE390, 0x2AA8, 0x3FFC, 0xF1C8, 0x0E38, 1 }, 170.0f, 0x3FFC }, - { { 0x2AA8, 0xF1C8, 0x0E38, 0x0E38, 0x0000, 0x0000, 1 }, 0.0f, 0x0000 }, - { { 0x2AA8, 0xF1C8, 0x0000, 0x0E38, 0x0000, 0x1C70, 1 }, 0.0f, 0x0000 }, - { { 0x2AA8, 0xF1C8, 0xF1C8, 0x0000, 0x0000, 0x0000, 1 }, 0.0f, 0x0000 }, - { { 0x071C, 0xF1C8, 0x0E38, 0x1C70, 0x0000, 0x0000, 1 }, 0.0f, 0x0000 }, - { { 0x0E38, 0xF1C8, 0x0000, 0x1C70, 0x0000, 0x0E38, 1 }, 0.0f, 0x0000 }, - { { 0x2AA8, 0xE390, 0x1C70, 0x0E38, 0xF1C8, 0x0E38, 1 }, 0.0f, 0x0000 }, - { { 0x18E2, 0xF1C8, 0x0E38, 0x0E38, 0x0000, 0x0000, 1 }, 0.0f, 0x0000 }, + /* 0x00 */ NpcTrackingRotLimits rotLimits; + // Fields specific to NPC_TRACKING_PLAYER_AUTO_TURN mode + /* 0x10 */ f32 autoTurnDistanceRange; // Max distance to player to enable tracking and auto-turn + /* 0x14 */ s16 maxYawForPlayerTracking; // Player is tracked if within this yaw +} NpcTrackingParams; // size = 0x18 + +/** + * Npc tracking angle limit presets to use with Npc_TrackPoint. + * + * @see Npc_TrackPoint + */ +static NpcTrackingParams sNpcTrackingPresets[] = { + { { 0x2AA8, -0x0E38, 0x18E2, 0x1554, 0x0000, 0x0000, true }, 170.0f, 0x3FFC }, + { { 0x2AA8, -0x1554, 0x1554, 0x1554, -0x071C, 0x0E38, true }, 170.0f, 0x3FFC }, + { { 0x31C4, -0x1C70, 0x0E38, 0x0E38, -0x0E38, 0x071C, true }, 170.0f, 0x3FFC }, + { { 0x1554, -0x0E38, 0x0000, 0x071C, -0x071C, 0x0000, true }, 170.0f, 0x3FFC }, + { { 0x2AA8, -0x071C, 0x071C, 0x0E38, -0x2AA8, 0x2AA8, true }, 170.0f, 0x3FFC }, + { { 0x0000, -0x1C70, 0x2AA8, 0x3FFC, -0x0E38, 0x0E38, true }, 170.0f, 0x3FFC }, + { { 0x2AA8, -0x0E38, 0x0E38, 0x0E38, 0x0000, 0x0000, true }, 0.0f, 0x0000 }, + { { 0x2AA8, -0x0E38, 0x0000, 0x0E38, 0x0000, 0x1C70, true }, 0.0f, 0x0000 }, + { { 0x2AA8, -0x0E38, -0x0E38, 0x0000, 0x0000, 0x0000, true }, 0.0f, 0x0000 }, + { { 0x071C, -0x0E38, 0x0E38, 0x1C70, 0x0000, 0x0000, true }, 0.0f, 0x0000 }, + { { 0x0E38, -0x0E38, 0x0000, 0x1C70, 0x0000, 0x0E38, true }, 0.0f, 0x0000 }, + { { 0x2AA8, -0x1C70, 0x1C70, 0x0E38, -0x0E38, 0x0E38, true }, 0.0f, 0x0000 }, + { { 0x18E2, -0x0E38, 0x0E38, 0x0E38, 0x0000, 0x0000, true }, 0.0f, 0x0000 }, }; -void func_800344BC(Actor* actor, struct_80034A14_arg1* arg1, s16 arg2, s16 arg3, s16 arg4, s16 arg5, s16 arg6, s16 arg7, - u8 arg8) { - s16 sp46; - s16 sp44; - s16 temp2; - s16 sp40; - s16 temp1; - Vec3f sp30; +/** + * Smoothly turns the actor's whole body and updates torso and head rotations in + * NpcInteractInfo so that the actor tracks the point specified in NpcInteractInfo.trackPos. + * Rotations are limited to specified angles. + * + * Head and torso rotation angles are determined by calculating the pitch and yaw + * from the actor position to the given target position. + * + * The y position of the actor is offset by NpcInteractInfo.yOffset + * before calculating the angles. It can be used to configure the height difference + * between the actor and the target. + * + * @param maxHeadYaw maximum head yaw difference from neutral position + * @param maxHeadPitch maximum head pitch angle + * @param minHeadPitch minimum head pitch angle + * @param maxTorsoYaw maximum torso yaw difference from neutral position + * @param maxTorsoPitch maximum torso pitch angle + * @param minTorsoPitch minimum torso pitch angle + * @param rotateYaw if true, the actor's yaw (shape.rot.y) is updated to turn the actor's whole body + */ +void Npc_TrackPointWithLimits(Actor* actor, NpcInteractInfo* interactInfo, s16 maxHeadYaw, s16 maxHeadPitch, + s16 minHeadPitch, s16 maxTorsoYaw, s16 maxTorsoPitch, s16 minTorsoPitch, u8 rotateYaw) { + s16 pitchTowardsTarget; + s16 yawTowardsTarget; + s16 torsoPitch; + s16 bodyYawDiff; + s16 temp; + Vec3f offsetActorPos; - sp30.x = actor->world.pos.x; - sp30.y = actor->world.pos.y + arg1->unk_14; - sp30.z = actor->world.pos.z; + offsetActorPos.x = actor->world.pos.x; + offsetActorPos.y = actor->world.pos.y + interactInfo->yOffset; + offsetActorPos.z = actor->world.pos.z; - sp46 = Math_Vec3f_Pitch(&sp30, &arg1->unk_18); - sp44 = Math_Vec3f_Yaw(&sp30, &arg1->unk_18); - sp40 = Math_Vec3f_Yaw(&actor->world.pos, &arg1->unk_18) - actor->shape.rot.y; + pitchTowardsTarget = Math_Vec3f_Pitch(&offsetActorPos, &interactInfo->trackPos); + yawTowardsTarget = Math_Vec3f_Yaw(&offsetActorPos, &interactInfo->trackPos); + bodyYawDiff = Math_Vec3f_Yaw(&actor->world.pos, &interactInfo->trackPos) - actor->shape.rot.y; - temp1 = CLAMP(sp40, -arg2, arg2); - Math_SmoothStepToS(&arg1->unk_08.y, temp1, 6, 2000, 1); + temp = CLAMP(bodyYawDiff, -maxHeadYaw, maxHeadYaw); + Math_SmoothStepToS(&interactInfo->headRot.y, temp, 6, 2000, 1); - temp1 = (ABS(sp40) >= 0x8000) ? 0 : ABS(sp40); - arg1->unk_08.y = CLAMP(arg1->unk_08.y, -temp1, temp1); + temp = (ABS(bodyYawDiff) >= 0x8000) ? 0 : ABS(bodyYawDiff); + interactInfo->headRot.y = CLAMP(interactInfo->headRot.y, -temp, temp); - sp40 -= arg1->unk_08.y; + bodyYawDiff -= interactInfo->headRot.y; - temp1 = CLAMP(sp40, -arg5, arg5); - Math_SmoothStepToS(&arg1->unk_0E.y, temp1, 6, 2000, 1); + temp = CLAMP(bodyYawDiff, -maxTorsoYaw, maxTorsoYaw); + Math_SmoothStepToS(&interactInfo->torsoRot.y, temp, 6, 2000, 1); - temp1 = (ABS(sp40) >= 0x8000) ? 0 : ABS(sp40); - arg1->unk_0E.y = CLAMP(arg1->unk_0E.y, -temp1, temp1); + temp = (ABS(bodyYawDiff) >= 0x8000) ? 0 : ABS(bodyYawDiff); + interactInfo->torsoRot.y = CLAMP(interactInfo->torsoRot.y, -temp, temp); - if (arg8) { - Math_SmoothStepToS(&actor->shape.rot.y, sp44, 6, 2000, 1); + if (rotateYaw) { + Math_SmoothStepToS(&actor->shape.rot.y, yawTowardsTarget, 6, 2000, 1); } - temp1 = CLAMP(sp46, arg4, (s16)(u16)arg3); - Math_SmoothStepToS(&arg1->unk_08.x, temp1, 6, 2000, 1); + temp = CLAMP(pitchTowardsTarget, minHeadPitch, (s16)(u16)maxHeadPitch); + Math_SmoothStepToS(&interactInfo->headRot.x, temp, 6, 2000, 1); - temp2 = sp46 - arg1->unk_08.x; + torsoPitch = pitchTowardsTarget - interactInfo->headRot.x; - temp1 = CLAMP(temp2, arg7, arg6); - Math_SmoothStepToS(&arg1->unk_0E.x, temp1, 6, 2000, 1); + temp = CLAMP(torsoPitch, minTorsoPitch, maxTorsoPitch); + Math_SmoothStepToS(&interactInfo->torsoRot.x, temp, 6, 2000, 1); } -s16 func_800347E8(s16 arg0) { - return D_80116130[arg0].unk_14; +s16 Npc_GetTrackingPresetMaxPlayerYaw(s16 presetIndex) { + return sNpcTrackingPresets[presetIndex].maxYawForPlayerTracking; } -s16 func_80034810(Actor* actor, struct_80034A14_arg1* arg1, f32 arg2, s16 arg3, s16 arg4) { +/** + * Handles NPC tracking modes and auto-turning towards the player when + * NPC_TRACKING_PLAYER_AUTO_TURN tracking mode is used. + * + * Returns a tracking mode that will determine which actor limbs + * will be rotated towards the target. + * + * When the player is behind the actor (i.e. not in the yaw range in front of the actor + * defined by maxYawForPlayerTracking), the actor will start an auto-turn sequence: + * - look forward for 30-60 frames + * - turn head to look at the player for 10-20 frames + * - look forward for 30-60 frames + * - turn the entire body to face the player + * + * @param distanceRange Max distance to player that tracking and auto-turning will be active for + * @param maxYawForPlayerTracking Maximum angle for tracking the player. + * @param trackingMode The tracking mode selected by the actor. If this is not + * NPC_TRACKING_PLAYER_AUTO_TURN this function does nothing + * + * @return The tracking mode (NpcTrackingMode) to use for the current frame. + */ +s16 Npc_UpdateAutoTurn(Actor* actor, NpcInteractInfo* interactInfo, f32 distanceRange, s16 maxYawForPlayerTracking, + s16 trackingMode) { s32 pad; - s16 var; - s16 abs_var; + s16 yaw; + s16 yawDiff; - if (arg4 != 0) { - return arg4; + if (trackingMode != NPC_TRACKING_PLAYER_AUTO_TURN) { + return trackingMode; } - if (arg1->unk_00 != 0) { - return 4; + if (interactInfo->talkState != NPC_TALK_STATE_IDLE) { + // When talking, always fully turn to face the player + return NPC_TRACKING_FULL_BODY; } - if (arg2 < Math_Vec3f_DistXYZ(&actor->world.pos, &arg1->unk_18)) { - arg1->unk_04 = 0; - arg1->unk_06 = 0; - return 1; + if (distanceRange < Math_Vec3f_DistXYZ(&actor->world.pos, &interactInfo->trackPos)) { + // Player is too far away, do not track + interactInfo->autoTurnTimer = 0; + interactInfo->autoTurnState = 0; + return NPC_TRACKING_NONE; } - var = Math_Vec3f_Yaw(&actor->world.pos, &arg1->unk_18); - abs_var = ABS((s16)((f32)var - actor->shape.rot.y)); - if (arg3 >= abs_var) { - arg1->unk_04 = 0; - arg1->unk_06 = 0; - return 2; + yaw = Math_Vec3f_Yaw(&actor->world.pos, &interactInfo->trackPos); + yawDiff = ABS((s16)((f32)yaw - actor->shape.rot.y)); + if (maxYawForPlayerTracking >= yawDiff) { + // Player is in front of the actor, track with the head and the torso + interactInfo->autoTurnTimer = 0; + interactInfo->autoTurnState = 0; + return NPC_TRACKING_HEAD_AND_TORSO; } - if (DECR(arg1->unk_04) != 0) { - return arg1->unk_02; + // Player is behind the actor, run the auto-turn sequence. + if (DECR(interactInfo->autoTurnTimer) != 0) { + // While the timer is still running, return the previous tracking mode + return interactInfo->trackingMode; } - switch (arg1->unk_06) { + switch (interactInfo->autoTurnState) { case 0: case 2: - arg1->unk_04 = Rand_S16Offset(30, 30); - arg1->unk_06++; - return 1; + // Just stand still, not tracking the player + interactInfo->autoTurnTimer = Rand_S16Offset(30, 30); + interactInfo->autoTurnState++; + return NPC_TRACKING_NONE; case 1: - arg1->unk_04 = Rand_S16Offset(10, 10); - arg1->unk_06++; - return 3; + // Glance at the player by only turning the head + interactInfo->autoTurnTimer = Rand_S16Offset(10, 10); + interactInfo->autoTurnState++; + return NPC_TRACKING_HEAD; } - return 4; + // Auto-turn sequence complete, turn towards the player + return NPC_TRACKING_FULL_BODY; } -void func_80034A14(Actor* actor, struct_80034A14_arg1* arg1, s16 arg2, s16 arg3) { - struct_80116130_0 sp38; - - arg1->unk_02 = func_80034810(actor, arg1, D_80116130[arg2].unk_10, D_80116130[arg2].unk_14, arg3); - - sp38 = D_80116130[arg2].sub_00; - - switch (arg1->unk_02) { - case 1: - sp38.unk_00 = 0; - sp38.unk_04 = 0; - sp38.unk_02 = 0; - case 3: - sp38.unk_06 = 0; - sp38.unk_0A = 0; - sp38.unk_08 = 0; - case 2: - sp38.unk_0C = 0; - } - - func_800344BC(actor, arg1, sp38.unk_00, sp38.unk_04, sp38.unk_02, sp38.unk_06, sp38.unk_0A, sp38.unk_08, - sp38.unk_0C); +/** + * Rotates the actor's whole body, torso and head tracking the point specified in NpcInteractInfo.trackPos. + * Uses angle limits from a preset selected from from sNpcTrackingPresets. + * + * The trackingMode parameter controls whether the head and torso are turned towards the target. + * If not, they are smoothly turned towards zero. Setting the parameter to NPC_TRACKING_FULL_BODY + * causes the actor's whole body to be rotated to face the target. + * + * If NPC_TRACKING_PLAYER_AUTO_TURN is used, the actor will track the player with its head and torso as long + * as the player is in front of the actor (within a yaw angle specified in the option preset). + * If the player is outside of this angle, the actor will turn to face the player after a while. + * + * @see Npc_UpdateAutoTurn + * @see sNpcTrackingPresets + * @see NpcTrackingMode + * + * @param presetIndex The index to a preset in sNpcTrackingPresets + * @param trackingMode A value from NpcTrackingMode enum + */ +void Npc_TrackPoint(Actor* actor, NpcInteractInfo* interactInfo, s16 presetIndex, s16 trackingMode) { + NpcTrackingRotLimits rotLimits; + + interactInfo->trackingMode = + Npc_UpdateAutoTurn(actor, interactInfo, sNpcTrackingPresets[presetIndex].autoTurnDistanceRange, + sNpcTrackingPresets[presetIndex].maxYawForPlayerTracking, trackingMode); + + rotLimits = sNpcTrackingPresets[presetIndex].rotLimits; + + switch (interactInfo->trackingMode) { + case NPC_TRACKING_NONE: + rotLimits.maxHeadYaw = 0; + rotLimits.maxHeadPitch = 0; + rotLimits.minHeadPitch = 0; + case NPC_TRACKING_HEAD: + rotLimits.maxTorsoYaw = 0; + rotLimits.maxTorsoPitch = 0; + rotLimits.minTorsoPitch = 0; + case NPC_TRACKING_HEAD_AND_TORSO: + rotLimits.rotateYaw = false; + } + + Npc_TrackPointWithLimits(actor, interactInfo, rotLimits.maxHeadYaw, rotLimits.maxHeadPitch, rotLimits.minHeadPitch, + rotLimits.maxTorsoYaw, rotLimits.maxTorsoPitch, rotLimits.minTorsoPitch, + rotLimits.rotateYaw); } Gfx* func_80034B28(GraphicsContext* gfxCtx) { diff --git a/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.c b/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.c index c36403f394e..5ea59cef7db 100644 --- a/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.c +++ b/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.c @@ -166,44 +166,44 @@ void DemoIm_UpdateCollider(DemoIm* this, PlayState* play) { void func_80984DB8(DemoIm* this) { s32 pad[2]; - Vec3s* vec1 = &this->unk_2D4.unk_08; - Vec3s* vec2 = &this->unk_2D4.unk_0E; + Vec3s* headRot = &this->interactInfo.headRot; + Vec3s* torsoRot = &this->interactInfo.torsoRot; - Math_SmoothStepToS(&vec1->x, 0, 20, 6200, 100); - Math_SmoothStepToS(&vec1->y, 0, 20, 6200, 100); + Math_SmoothStepToS(&headRot->x, 0, 20, 6200, 100); + Math_SmoothStepToS(&headRot->y, 0, 20, 6200, 100); - Math_SmoothStepToS(&vec2->x, 0, 20, 6200, 100); - Math_SmoothStepToS(&vec2->y, 0, 20, 6200, 100); + Math_SmoothStepToS(&torsoRot->x, 0, 20, 6200, 100); + Math_SmoothStepToS(&torsoRot->y, 0, 20, 6200, 100); } void func_80984E58(DemoIm* this, PlayState* play) { Player* player = GET_PLAYER(play); s16 yawDiff; - s16 phi_a3; + s16 npcTrackingMode; - this->unk_2D4.unk_18 = player->actor.world.pos; - this->unk_2D4.unk_14 = kREG(16) + 4.0f; + this->interactInfo.trackPos = player->actor.world.pos; + this->interactInfo.yOffset = kREG(16) + 4.0f; yawDiff = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; - phi_a3 = (ABS(yawDiff) < 0x18E3) ? 2 : 1; - func_80034A14(&this->actor, &this->unk_2D4, kREG(17) + 0xC, phi_a3); + npcTrackingMode = (ABS(yawDiff) < 0x18E3) ? NPC_TRACKING_HEAD_AND_TORSO : NPC_TRACKING_NONE; + Npc_TrackPoint(&this->actor, &this->interactInfo, kREG(17) + 0xC, npcTrackingMode); } void func_80984F10(DemoIm* this, PlayState* play) { Player* player = GET_PLAYER(play); - this->unk_2D4.unk_18 = player->actor.world.pos; - this->unk_2D4.unk_14 = kREG(16) + 12.0f; + this->interactInfo.trackPos = player->actor.world.pos; + this->interactInfo.yOffset = kREG(16) + 12.0f; - func_80034A14(&this->actor, &this->unk_2D4, kREG(17) + 0xC, 2); + Npc_TrackPoint(&this->actor, &this->interactInfo, kREG(17) + 0xC, NPC_TRACKING_HEAD_AND_TORSO); } void func_80984F94(DemoIm* this, PlayState* play) { Player* player = GET_PLAYER(play); - this->unk_2D4.unk_18 = player->actor.world.pos; - this->unk_2D4.unk_14 = kREG(16) + 4.0f; - func_80034A14(&this->actor, &this->unk_2D4, kREG(17) + 0xC, 4); + this->interactInfo.trackPos = player->actor.world.pos; + this->interactInfo.yOffset = kREG(16) + 4.0f; + Npc_TrackPoint(&this->actor, &this->interactInfo, kREG(17) + 0xC, NPC_TRACKING_FULL_BODY); } void DemoIm_UpdateBgCheckInfo(DemoIm* this, PlayState* play) { @@ -1171,17 +1171,17 @@ s32 DemoIm_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* s32* unk_2D0 = &this->unk_2D0; if (this->unk_280 != 0) { - Vec3s* unk_2D4_unk_0E = &this->unk_2D4.unk_0E; - Vec3s* unk_2D4_unk_08 = &this->unk_2D4.unk_08; + Vec3s* torsoRot = &this->interactInfo.torsoRot; + Vec3s* headRot = &this->interactInfo.headRot; switch (limbIndex) { case IMPA_LIMB_CHEST: - rot->x += unk_2D4_unk_0E->y; - rot->y -= unk_2D4_unk_0E->x; + rot->x += torsoRot->y; + rot->y -= torsoRot->x; break; case IMPA_LIMB_HEAD: - rot->x += unk_2D4_unk_08->y; - rot->z += unk_2D4_unk_08->x; + rot->x += headRot->y; + rot->z += headRot->x; break; } } diff --git a/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.h b/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.h index 810909fab77..3697733e166 100644 --- a/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.h +++ b/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.h @@ -48,7 +48,7 @@ typedef struct DemoIm { /* 0x0280 */ s32 unk_280; /* 0x0284 */ ColliderCylinder collider; /* 0x02D0 */ s32 unk_2D0; - /* 0x02D4 */ struct_80034A14_arg1 unk_2D4; + /* 0x02D4 */ NpcInteractInfo interactInfo; } DemoIm; // size = 0x02FC #endif diff --git a/soh/src/overlays/actors/ovl_En_Cs/z_en_cs.c b/soh/src/overlays/actors/ovl_En_Cs/z_en_cs.c index fca4d24fedc..497a6d52724 100644 --- a/soh/src/overlays/actors/ovl_En_Cs/z_en_cs.c +++ b/soh/src/overlays/actors/ovl_En_Cs/z_en_cs.c @@ -404,10 +404,10 @@ void EnCs_Talk(EnCs* this, PlayState* play) { } this->flag |= 1; - this->npcInfo.unk_18.x = player->actor.focus.pos.x; - this->npcInfo.unk_18.y = player->actor.focus.pos.y; - this->npcInfo.unk_18.z = player->actor.focus.pos.z; - func_80034A14(&this->actor, &this->npcInfo, 0, 4); + this->interactInfo.trackPos.x = player->actor.focus.pos.x; + this->interactInfo.trackPos.y = player->actor.focus.pos.y; + this->interactInfo.trackPos.z = player->actor.focus.pos.z; + Npc_TrackPoint(&this->actor, &this->interactInfo, 0, NPC_TRACKING_FULL_BODY); if (this->talkState == 0) { EnCs_ChangeAnim(this, ENCS_ANIM_0, &this->currentAnimIndex); @@ -495,12 +495,12 @@ s32 EnCs_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* po if (this->flag & 1) { switch (limbIndex) { case 8: - rot->x += this->npcInfo.unk_0E.y; - rot->y -= this->npcInfo.unk_0E.x; + rot->x += this->interactInfo.torsoRot.y; + rot->y -= this->interactInfo.torsoRot.x; break; case 15: - rot->x += this->npcInfo.unk_08.y; - rot->z += this->npcInfo.unk_08.x; + rot->x += this->interactInfo.headRot.y; + rot->z += this->interactInfo.headRot.x; break; } } diff --git a/soh/src/overlays/actors/ovl_En_Cs/z_en_cs.h b/soh/src/overlays/actors/ovl_En_Cs/z_en_cs.h index 26f19a0a901..71de6b28dda 100644 --- a/soh/src/overlays/actors/ovl_En_Cs/z_en_cs.h +++ b/soh/src/overlays/actors/ovl_En_Cs/z_en_cs.h @@ -28,7 +28,7 @@ typedef struct EnCs { /* 0x0210 */ s32 currentAnimIndex; /* 0x0214 */ char unk_214[4]; /* 0x0218 */ MtxF spookyMaskMtx; - /* 0x0258 */ struct_80034A14_arg1 npcInfo; + /* 0x0258 */ NpcInteractInfo interactInfo; /* 0x0280 */ s32 flag; /* 0x0284 */ Vec3s jointTable[16]; /* 0x02E4 */ Vec3s morphTable[16]; diff --git a/soh/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c b/soh/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c index 4a1f6dde9b1..57d2b9055d0 100644 --- a/soh/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c +++ b/soh/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c @@ -571,14 +571,14 @@ void EnDaiku_Update(Actor* thisx, PlayState* play) { this->actionFunc(this, play); if (this->stateFlags & ENDAIKU_STATEFLAG_1) { - this->unk_244.unk_18.x = player->actor.focus.pos.x; - this->unk_244.unk_18.y = player->actor.focus.pos.y; - this->unk_244.unk_18.z = player->actor.focus.pos.z; + this->interactInfo.trackPos.x = player->actor.focus.pos.x; + this->interactInfo.trackPos.y = player->actor.focus.pos.y; + this->interactInfo.trackPos.z = player->actor.focus.pos.z; if (this->stateFlags & ENDAIKU_STATEFLAG_2) { - func_80034A14(&this->actor, &this->unk_244, 0, 4); + Npc_TrackPoint(&this->actor, &this->interactInfo, 0, NPC_TRACKING_FULL_BODY); } else { - func_80034A14(&this->actor, &this->unk_244, 0, 2); + Npc_TrackPoint(&this->actor, &this->interactInfo, 0, NPC_TRACKING_HEAD_AND_TORSO); } } } @@ -611,12 +611,12 @@ s32 EnDaiku_OverrideLimbDraw(PlayState* play, s32 limb, Gfx** dList, Vec3f* pos, switch (limb) { case 8: // torso - rot->x += this->unk_244.unk_0E.y; - rot->y -= this->unk_244.unk_0E.x; + rot->x += this->interactInfo.torsoRot.y; + rot->y -= this->interactInfo.torsoRot.x; break; case 15: // head - rot->x += this->unk_244.unk_08.y; - rot->z += this->unk_244.unk_08.x; + rot->x += this->interactInfo.headRot.y; + rot->z += this->interactInfo.headRot.x; break; } diff --git a/soh/src/overlays/actors/ovl_En_Daiku/z_en_daiku.h b/soh/src/overlays/actors/ovl_En_Daiku/z_en_daiku.h index 479eb1b348e..b3f36c6a524 100644 --- a/soh/src/overlays/actors/ovl_En_Daiku/z_en_daiku.h +++ b/soh/src/overlays/actors/ovl_En_Daiku/z_en_daiku.h @@ -30,7 +30,7 @@ typedef struct EnDaiku { /* 0x0230 */ Vec3f subCamAt; /* 0x023C */ s32 stateFlags; /* 0x0240 */ s32 startFightSwitchFlag; - /* 0x0244 */ struct_80034A14_arg1 unk_244; // probably related to animating torso and head towards the player + /* 0x0244 */ NpcInteractInfo interactInfo; /* 0x026C */ Vec3s jointTable[17]; /* 0x02D2 */ Vec3s morphTable[17]; /* 0x0338 */ Vec3s initRot; diff --git a/soh/src/overlays/actors/ovl_En_Daiku_Kakariko/z_en_daiku_kakariko.c b/soh/src/overlays/actors/ovl_En_Daiku_Kakariko/z_en_daiku_kakariko.c index ecd64c9253e..a7a107d3a44 100644 --- a/soh/src/overlays/actors/ovl_En_Daiku_Kakariko/z_en_daiku_kakariko.c +++ b/soh/src/overlays/actors/ovl_En_Daiku_Kakariko/z_en_daiku_kakariko.c @@ -476,18 +476,18 @@ void EnDaikuKakariko_Update(Actor* thisx, PlayState* play) { this->actionFunc(this, play); - this->npcInfo.unk_18.x = player->actor.focus.pos.x; - this->npcInfo.unk_18.y = player->actor.focus.pos.y; - this->npcInfo.unk_18.z = player->actor.focus.pos.z; + this->interactInfo.trackPos.x = player->actor.focus.pos.x; + this->interactInfo.trackPos.y = player->actor.focus.pos.y; + this->interactInfo.trackPos.z = player->actor.focus.pos.z; if (this->flags & 0x100) { this->neckAngleTarget.x = 5900; this->flags |= 0x1000; - func_80034A14(&this->actor, &this->npcInfo, 0, 2); + Npc_TrackPoint(&this->actor, &this->interactInfo, 0, NPC_TRACKING_HEAD_AND_TORSO); } else if (this->flags & 0x200) { this->neckAngleTarget.x = 5900; this->flags |= 0x1000; - func_80034A14(&this->actor, &this->npcInfo, 0, 4); + Npc_TrackPoint(&this->actor, &this->interactInfo, 0, NPC_TRACKING_FULL_BODY); } Math_SmoothStepToS(&this->neckAngle.x, this->neckAngleTarget.x, 1, 1820, 0); @@ -500,13 +500,13 @@ s32 EnDaikuKakariko_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList switch (limbIndex) { case 8: - angle = this->npcInfo.unk_0E; + angle = this->interactInfo.torsoRot; Matrix_RotateX(-(angle.y * (M_PI / 32768.0f)), MTXMODE_APPLY); Matrix_RotateZ(-(angle.x * (M_PI / 32768.0f)), MTXMODE_APPLY); break; case 15: Matrix_Translate(1400.0f, 0.0f, 0.0f, MTXMODE_APPLY); - angle = this->npcInfo.unk_08; + angle = this->interactInfo.headRot; if (this->flags & 0x1000) { osSyncPrintf("<%d>\n", this->neckAngle.x); diff --git a/soh/src/overlays/actors/ovl_En_Daiku_Kakariko/z_en_daiku_kakariko.h b/soh/src/overlays/actors/ovl_En_Daiku_Kakariko/z_en_daiku_kakariko.h index 36bae49deaf..59c13383a85 100644 --- a/soh/src/overlays/actors/ovl_En_Daiku_Kakariko/z_en_daiku_kakariko.h +++ b/soh/src/overlays/actors/ovl_En_Daiku_Kakariko/z_en_daiku_kakariko.h @@ -22,7 +22,7 @@ typedef struct EnDaikuKakariko { /* 0x01FC */ s32 run; // If true the carpenter will run /* 0x0200 */ u16 flags; /* 0x0202 */ u16 runFlag; - /* 0x0204 */ struct_80034A14_arg1 npcInfo; // Info related to NPCs and turning their head towards the player + /* 0x0204 */ NpcInteractInfo interactInfo; /* 0x022C */ Vec3s jointTable[17]; /* 0x0292 */ Vec3s morphTable[17]; /* 0x02F8 */ s32 timer; diff --git a/soh/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.c b/soh/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.c index 904b143b806..cbd6cee2bd3 100644 --- a/soh/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.c +++ b/soh/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.c @@ -521,11 +521,11 @@ void EnDivingGame_Update(Actor* thisx, PlayState* play2) { } this->actionFunc(this, play); Actor_SetFocus(&this->actor, 80.0f); - this->unk_324.unk_18 = player->actor.world.pos; - this->unk_324.unk_18.y = player->actor.world.pos.y; - func_80034A14(&this->actor, &this->unk_324, 2, 4); - this->vec_284 = this->unk_324.unk_08; - this->vec_28A = this->unk_324.unk_0E; + this->interactInfo.trackPos = player->actor.world.pos; + this->interactInfo.trackPos.y = player->actor.world.pos.y; + Npc_TrackPoint(&this->actor, &this->interactInfo, 2, NPC_TRACKING_FULL_BODY); + this->vec_284 = this->interactInfo.headRot; + this->vec_28A = this->interactInfo.torsoRot; if ((play->gameplayFrames % 16) == 0) { pos = this->actor.world.pos; pos.y += 20.0f; diff --git a/soh/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.h b/soh/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.h index ff49a1f6d4b..57acaafb469 100644 --- a/soh/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.h +++ b/soh/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.h @@ -45,7 +45,7 @@ typedef struct EnDivingGame { /* 0x031E */ u8 allRupeesThrown; // flag /* 0x031F */ u8 unk_31F; // flag /* 0x0320 */ char unk_320[0x4]; // unused - /* 0x0324 */ struct_80034A14_arg1 unk_324; + /* 0x0324 */ NpcInteractInfo interactInfo; /* 0x034C */ ColliderCylinder collider; } EnDivingGame; // size = 0x0398 diff --git a/soh/src/overlays/actors/ovl_En_Du/z_en_du.c b/soh/src/overlays/actors/ovl_En_Du/z_en_du.c index 8f8ff7f361d..235f9b896eb 100644 --- a/soh/src/overlays/actors/ovl_En_Du/z_en_du.c +++ b/soh/src/overlays/actors/ovl_En_Du/z_en_du.c @@ -131,7 +131,7 @@ s16 func_809FDCDC(PlayState* play, Actor* actor) { break; case 0x301C: case 0x301F: - return 2; + return NPC_TALK_STATE_ACTION; case 0x3020: gSaveContext.eventChkInf[0x2] |= 4; break; @@ -143,7 +143,7 @@ s16 func_809FDCDC(PlayState* play, Actor* actor) { break; case TEXT_STATE_DONE: if (Message_ShouldAdvance(play)) { - return 3; + return NPC_TALK_STATE_ITEM_GIVEN; } break; case TEXT_STATE_SONG_DEMO_DONE: @@ -151,7 +151,7 @@ s16 func_809FDCDC(PlayState* play, Actor* actor) { case TEXT_STATE_9: break; } - return 1; + return NPC_TALK_STATE_TALKING; } s32 func_809FDDB4(EnDu* this, PlayState* play) { @@ -165,17 +165,17 @@ s32 func_809FDDB4(EnDu* this, PlayState* play) { void func_809FDE24(EnDu* this, PlayState* play) { Player* player = GET_PLAYER(play); - s16 phi_a3 = 0; + s16 trackingMode = NPC_TRACKING_PLAYER_AUTO_TURN; - if (this->unk_1F4.unk_00 == 0) { - phi_a3 = 1; + if (this->interactInfo.talkState == NPC_TALK_STATE_IDLE) { + trackingMode = NPC_TRACKING_NONE; } if (this->actionFunc == func_809FE890) { - phi_a3 = 1; + trackingMode = NPC_TRACKING_NONE; } - this->unk_1F4.unk_18 = player->actor.world.pos; - this->unk_1F4.unk_14 = 10.0f; - func_80034A14(&this->actor, &this->unk_1F4, 3, phi_a3); + this->interactInfo.trackPos = player->actor.world.pos; + this->interactInfo.yOffset = 10.0f; + Npc_TrackPoint(&this->actor, &this->interactInfo, 3, trackingMode); } void func_809FDE9C(EnDu* this) { @@ -293,7 +293,7 @@ void EnDu_Init(Actor* thisx, PlayState* play) { Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENDU_ANIM_0); Actor_SetScale(&this->actor, 0.01f); this->actor.targetMode = 1; - this->unk_1F4.unk_00 = 0; + this->interactInfo.talkState = NPC_TALK_STATE_IDLE; if (gSaveContext.cutsceneIndex >= 0xFFF0) { play->csCtx.segment = SEGMENTED_TO_VIRTUAL(gGoronCityDarunia01Cs); @@ -328,9 +328,9 @@ void func_809FE3C0(EnDu* this, PlayState* play) { EnDu_SetupAction(this, func_809FE4A4); return; } - if (this->unk_1F4.unk_00 == 2) { + if (this->interactInfo.talkState == NPC_TALK_STATE_ACTION) { func_8002DF54(play, &this->actor, 7); - this->unk_1F4.unk_00 = 0; + this->interactInfo.talkState = NPC_TALK_STATE_IDLE; } if (this->actor.xzDistToPlayer < 116.0f + this->collider.dim.radius) { player->stateFlags2 |= 0x800000; @@ -389,13 +389,13 @@ void func_809FE6CC(EnDu* this, PlayState* play) { if (phi_v1 == 0) { this->actor.textId = 0x3039; Message_StartTextbox(play, this->actor.textId, NULL); - this->unk_1F4.unk_00 = 1; + this->interactInfo.talkState = NPC_TALK_STATE_TALKING; EnDu_SetupAction(this, func_809FE740); } } void func_809FE740(EnDu* this, PlayState* play) { - if (this->unk_1F4.unk_00 == 0) { + if (this->interactInfo.talkState == NPC_TALK_STATE_IDLE) { func_8005B1A4(GET_ACTIVE_CAM(play)); this->unk_1E2 = 0x5A; EnDu_SetupAction(this, func_809FE798); @@ -531,11 +531,11 @@ void func_809FEB08(EnDu* this, PlayState* play) { } Message_StartTextbox(play, this->actor.textId, NULL); Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENDU_ANIM_14); - this->unk_1F4.unk_00 = 1; + this->interactInfo.talkState = NPC_TALK_STATE_TALKING; } void func_809FEC14(EnDu* this, PlayState* play) { - if (this->unk_1F4.unk_00 == 2) { + if (this->interactInfo.talkState == NPC_TALK_STATE_ACTION) { func_8002DF54(play, &this->actor, 7); EnDu_SetupAction(this, func_809FEC70); func_809FEC70(this, play); @@ -558,8 +558,8 @@ void func_809FEC70(EnDu* this, PlayState* play) { } void func_809FECE4(EnDu* this, PlayState* play) { - if (this->unk_1F4.unk_00 == 3) { - this->unk_1F4.unk_00 = 0; + if (this->interactInfo.talkState == NPC_TALK_STATE_ITEM_GIVEN) { + this->interactInfo.talkState = NPC_TALK_STATE_IDLE; EnDu_SetupAction(this, func_809FE3C0); } } @@ -591,8 +591,8 @@ void EnDu_Update(Actor* thisx, PlayState* play) { Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 0.0f, 0.0f, 4); if (this->actionFunc != func_809FE4A4) { - func_800343CC(play, &this->actor, &this->unk_1F4.unk_00, this->collider.dim.radius + 116.0f, func_809FDC38, - func_809FDCDC); + Npc_UpdateTalking(play, &this->actor, &this->interactInfo.talkState, this->collider.dim.radius + 116.0f, + func_809FDC38, func_809FDCDC); } this->actionFunc(this, play); } @@ -604,13 +604,13 @@ s32 EnDu_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* po if (limbIndex == 16) { Matrix_Translate(2400.0f, 0.0f, 0.0f, MTXMODE_APPLY); - sp1C = this->unk_1F4.unk_08; + sp1C = this->interactInfo.headRot; Matrix_RotateX(BINANG_TO_RAD(sp1C.y), MTXMODE_APPLY); Matrix_RotateZ(BINANG_TO_RAD(sp1C.x), MTXMODE_APPLY); Matrix_Translate(-2400.0f, 0.0f, 0.0f, MTXMODE_APPLY); } if (limbIndex == 8) { - sp1C = this->unk_1F4.unk_0E; + sp1C = this->interactInfo.torsoRot; Matrix_RotateY(BINANG_TO_RAD(sp1C.y), MTXMODE_APPLY); Matrix_RotateX(BINANG_TO_RAD(sp1C.x), MTXMODE_APPLY); } diff --git a/soh/src/overlays/actors/ovl_En_Du/z_en_du.h b/soh/src/overlays/actors/ovl_En_Du/z_en_du.h index 141bc634bce..a3a8188d2fa 100644 --- a/soh/src/overlays/actors/ovl_En_Du/z_en_du.h +++ b/soh/src/overlays/actors/ovl_En_Du/z_en_du.h @@ -26,7 +26,7 @@ typedef struct EnDu { /* 0x01F0 */ u8 mouthTexIndex; /* 0x01F1 */ u8 noseTexIndex; /* 0x01F2 */ s16 blinkTimer; - /* 0x01F4 */ struct_80034A14_arg1 unk_1F4; + /* 0x01F4 */ NpcInteractInfo interactInfo; } EnDu; // size = 0x021C #endif diff --git a/soh/src/overlays/actors/ovl_En_Go/z_en_go.c b/soh/src/overlays/actors/ovl_En_Go/z_en_go.c index 127a844dcf0..3231fb31aa7 100644 --- a/soh/src/overlays/actors/ovl_En_Go/z_en_go.c +++ b/soh/src/overlays/actors/ovl_En_Go/z_en_go.c @@ -198,8 +198,8 @@ u16 EnGo_GetTextID(PlayState* play, Actor* thisx) { } } -s16 EnGo_SetFlagsGetStates(PlayState* play, Actor* thisx) { - s16 unkState = 1; +s16 EnGo_UpdateTalkState(PlayState* play, Actor* thisx) { + s16 unkState = NPC_TALK_STATE_TALKING; f32 xzRange; f32 yRange = fabsf(thisx->yDistToPlayer) + 1.0f; @@ -210,51 +210,51 @@ s16 EnGo_SetFlagsGetStates(PlayState* play, Actor* thisx) { switch (thisx->textId) { case 0x3008: gSaveContext.infTable[14] |= 1; - unkState = 0; + unkState = NPC_TALK_STATE_IDLE; break; case 0x300B: gSaveContext.infTable[14] |= 0x800; - unkState = 0; + unkState = NPC_TALK_STATE_IDLE; break; case 0x3014: gSaveContext.infTable[15] |= 1; - unkState = 0; + unkState = NPC_TALK_STATE_IDLE; break; case 0x3016: gSaveContext.infTable[15] |= 0x10; - unkState = 0; + unkState = NPC_TALK_STATE_IDLE; break; case 0x3018: gSaveContext.infTable[15] |= 0x100; - unkState = 0; + unkState = NPC_TALK_STATE_IDLE; break; case 0x3036: func_8002F434(thisx, play, GI_TUNIC_GORON, xzRange, yRange); gSaveContext.infTable[16] |= 0x2000; // EnGo exclusive flag - unkState = 2; + unkState = NPC_TALK_STATE_ACTION; break; case 0x3037: gSaveContext.infTable[16] |= 0x4000; - unkState = 0; + unkState = NPC_TALK_STATE_IDLE; break; case 0x3041: gSaveContext.infTable[16] |= 0x8000; - unkState = 0; + unkState = NPC_TALK_STATE_IDLE; break; case 0x3059: - unkState = 2; + unkState = NPC_TALK_STATE_ACTION; break; case 0x3052: case 0x3054: case 0x3055: case 0x305A: - unkState = 2; + unkState = NPC_TALK_STATE_ACTION; break; case 0x305E: - unkState = 2; + unkState = NPC_TALK_STATE_ACTION; break; default: - unkState = 0; + unkState = NPC_TALK_STATE_IDLE; break; } break; @@ -272,7 +272,7 @@ s16 EnGo_SetFlagsGetStates(PlayState* play, Actor* thisx) { thisx->textId = 0x300D; } Message_ContinueTextbox(play, thisx->textId); - unkState = 1; + unkState = NPC_TALK_STATE_TALKING; break; case 0x3034: if (play->msgCtx.choiceIndex == 0) { @@ -287,16 +287,16 @@ s16 EnGo_SetFlagsGetStates(PlayState* play, Actor* thisx) { thisx->textId = 0x3033; } Message_ContinueTextbox(play, thisx->textId); - unkState = 1; + unkState = NPC_TALK_STATE_TALKING; break; case 0x3054: case 0x3055: if (play->msgCtx.choiceIndex == 0) { - unkState = 2; + unkState = NPC_TALK_STATE_ACTION; } else { thisx->textId = 0x3056; Message_ContinueTextbox(play, thisx->textId); - unkState = 1; + unkState = NPC_TALK_STATE_TALKING; } gSaveContext.infTable[11] |= 0x10; break; @@ -312,17 +312,17 @@ s16 EnGo_SetFlagsGetStates(PlayState* play, Actor* thisx) { case 0x3033: thisx->textId = 0x3034; Message_ContinueTextbox(play, thisx->textId); - unkState = 1; + unkState = NPC_TALK_STATE_TALKING; break; default: - unkState = 2; + unkState = NPC_TALK_STATE_ACTION; break; } } break; case TEXT_STATE_DONE: if (Message_ShouldAdvance(play)) { - unkState = 3; + unkState = NPC_TALK_STATE_ITEM_GIVEN; } break; case TEXT_STATE_NONE: @@ -335,13 +335,13 @@ s16 EnGo_SetFlagsGetStates(PlayState* play, Actor* thisx) { return unkState; } -s32 func_80A3ED24(PlayState* play, EnGo* this, struct_80034A14_arg1* arg2, f32 arg3, - u16 (*getTextId)(PlayState*, Actor*), s16 (*unkFunc2)(PlayState*, Actor*)) { - if (arg2->unk_00) { - arg2->unk_00 = unkFunc2(play, &this->actor); +s32 func_80A3ED24(PlayState* play, EnGo* this, NpcInteractInfo* interactInfo, f32 arg3, NpcGetTextIdFunc getTextId, + NpcUpdateTalkStateFunc updateTalkState) { + if (interactInfo->talkState != NPC_TALK_STATE_IDLE) { + interactInfo->talkState = updateTalkState(play, &this->actor); return false; } else if (Actor_ProcessTalkRequest(&this->actor, play)) { - arg2->unk_00 = 1; + interactInfo->talkState = NPC_TALK_STATE_TALKING; return true; } else if (!func_8002F2CC(&this->actor, play, arg3)) { return false; @@ -398,16 +398,16 @@ f32 EnGo_GetGoronSize(EnGo* this) { void func_80A3F060(EnGo* this, PlayState* play) { Player* player = GET_PLAYER(play); - s16 unkVal; + s16 npcTrackingMode; if (this->actionFunc != EnGo_BiggoronActionFunc && this->actionFunc != EnGo_FireGenericActionFunc && this->actionFunc != func_80A40B1C) { - unkVal = 1; + npcTrackingMode = NPC_TRACKING_NONE; } - this->unk_1E0.unk_18 = player->actor.world.pos; - this->unk_1E0.unk_14 = EnGo_GetGoronSize(this); - func_80034A14(&this->actor, &this->unk_1E0, 4, unkVal); + this->interactInfo.trackPos = player->actor.world.pos; + this->interactInfo.yOffset = EnGo_GetGoronSize(this); + Npc_TrackPoint(&this->actor, &this->interactInfo, 4, npcTrackingMode); } void func_80A3F0E4(EnGo* this) { @@ -546,7 +546,7 @@ s32 EnGo_SpawnDust(EnGo* this, u8 initialTimer, f32 scale, f32 scaleStep, s32 nu s32 EnGo_IsRollingOnGround(EnGo* this, s16 unkArg1, f32 unkArg2) { if ((this->actor.bgCheckFlags & 1) == 0 || this->actor.velocity.y > 0.0f) { return false; - } else if (this->unk_1E0.unk_00 != 0) { + } else if (this->interactInfo.talkState != NPC_TALK_STATE_IDLE) { return true; } else if (DECR(this->unk_21C)) { if ((this->unk_21C & 1)) { @@ -589,10 +589,10 @@ void func_80A3F908(EnGo* this, PlayState* play) { if ((this->actor.params & 0xF0) == 0x90) { isUnkCondition = - func_80A3ED24(play, this, &this->unk_1E0, float1, EnGo_GetTextID, EnGo_SetFlagsGetStates); + func_80A3ED24(play, this, &this->interactInfo, float1, EnGo_GetTextID, EnGo_UpdateTalkState); } else { - isUnkCondition = func_800343CC(play, &this->actor, &this->unk_1E0.unk_00, float1, EnGo_GetTextID, - EnGo_SetFlagsGetStates); + isUnkCondition = Npc_UpdateTalking(play, &this->actor, &this->interactInfo.talkState, float1, + EnGo_GetTextID, EnGo_UpdateTalkState); } if (((this->actor.params & 0xF0) == 0x90) && (isUnkCondition == true)) { @@ -645,7 +645,7 @@ void EnGo_Init(Actor* thisx, PlayState* play) { EnGo_ChangeAnim(this, ENGO_ANIM_0); this->actor.targetMode = 6; - this->unk_1E0.unk_00 = 0; + this->interactInfo.talkState = NPC_TALK_STATE_IDLE; this->actor.gravity = -1.0f; switch (this->actor.params & 0xF0) { @@ -858,26 +858,26 @@ void func_80A405CC(EnGo* this, PlayState* play) { } void EnGo_BiggoronActionFunc(EnGo* this, PlayState* play) { - if (((this->actor.params & 0xF0) == 0x90) && (this->unk_1E0.unk_00 == 2)) { + if (((this->actor.params & 0xF0) == 0x90) && (this->interactInfo.talkState == NPC_TALK_STATE_ACTION)) { if (!gSaveContext.n64ddFlag && gSaveContext.bgsFlag) { - this->unk_1E0.unk_00 = 0; + this->interactInfo.talkState = NPC_TALK_STATE_IDLE; } else { if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_EYEDROPS) { EnGo_ChangeAnim(this, ENGO_ANIM_2); this->unk_21E = 100; - this->unk_1E0.unk_00 = 0; + this->interactInfo.talkState = NPC_TALK_STATE_IDLE; EnGo_SetupAction(this, EnGo_Eyedrops); play->msgCtx.msgMode = MSGMODE_PAUSED; gSaveContext.timer2State = 0; OnePointCutscene_Init(play, 4190, -99, &this->actor, MAIN_CAM); } else { - this->unk_1E0.unk_00 = 0; + this->interactInfo.talkState = NPC_TALK_STATE_IDLE; EnGo_SetupAction(this, EnGo_GetItem); Message_CloseTextbox(play); EnGo_GetItem(this, play); } } - } else if (((this->actor.params & 0xF0) == 0) && (this->unk_1E0.unk_00 == 2)) { + } else if (((this->actor.params & 0xF0) == 0) && (this->interactInfo.talkState == NPC_TALK_STATE_ACTION)) { EnGo_SetupAction(this, EnGo_GetItem); play->msgCtx.stateTimer = 4; play->msgCtx.msgMode = MSGMODE_TEXT_CLOSING; @@ -951,7 +951,7 @@ void EnGo_GetItem(EnGo* this, PlayState* play) { s32 getItemId; if (Actor_HasParent(&this->actor, play)) { - this->unk_1E0.unk_00 = 2; + this->interactInfo.talkState = NPC_TALK_STATE_ACTION; this->actor.parent = NULL; EnGo_SetupAction(this, func_80A40C78); } else { @@ -1001,21 +1001,21 @@ void EnGo_GetItem(EnGo* this, PlayState* play) { } void func_80A40C78(EnGo* this, PlayState* play) { - if (this->unk_1E0.unk_00 == 3) { + if (this->interactInfo.talkState == NPC_TALK_STATE_ITEM_GIVEN) { EnGo_SetupAction(this, EnGo_BiggoronActionFunc); if ((this->actor.params & 0xF0) != 0x90) { - this->unk_1E0.unk_00 = 0; + this->interactInfo.talkState = NPC_TALK_STATE_IDLE; } else if (this->unk_20C) { - this->unk_1E0.unk_00 = 0; + this->interactInfo.talkState = NPC_TALK_STATE_IDLE; gSaveContext.bgsFlag = true; } else if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_PRESCRIPTION) { this->actor.textId = 0x3058; Message_ContinueTextbox(play, this->actor.textId); - this->unk_1E0.unk_00 = 1; + this->interactInfo.talkState = NPC_TALK_STATE_TALKING; } else if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_CLAIM_CHECK) { this->actor.textId = 0x305C; Message_ContinueTextbox(play, this->actor.textId); - this->unk_1E0.unk_00 = 1; + this->interactInfo.talkState = NPC_TALK_STATE_TALKING; Environment_ClearBgsDayCount(); } } @@ -1025,13 +1025,13 @@ void EnGo_Eyedrops(EnGo* this, PlayState* play) { if (DECR(this->unk_21E) == 0) { this->actor.textId = 0x305A; Message_ContinueTextbox(play, this->actor.textId); - this->unk_1E0.unk_00 = 1; + this->interactInfo.talkState = NPC_TALK_STATE_TALKING; EnGo_SetupAction(this, func_80A40DCC); } } void func_80A40DCC(EnGo* this, PlayState* play) { - if (this->unk_1E0.unk_00 == 2) { + if (this->interactInfo.talkState == NPC_TALK_STATE_ACTION) { EnGo_ChangeAnim(this, ENGO_ANIM_1); this->skelAnime.curFrame = Animation_GetLastFrame(&gGoronAnim_004930); Message_CloseTextbox(play); @@ -1055,7 +1055,7 @@ void EnGo_Update(Actor* thisx, PlayState* play) { EnGo_UpdateShadow(this); - if (this->unk_1E0.unk_00 == 0) { + if (this->interactInfo.talkState == NPC_TALK_STATE_IDLE) { Actor_MoveForward(&this->actor); } @@ -1110,7 +1110,7 @@ s32 EnGo_OverrideLimbDraw(PlayState* play, s32 limb, Gfx** dList, Vec3f* pos, Ve if (limb == 17) { Matrix_Translate(2800.0f, 0.0f, 0.0f, MTXMODE_APPLY); - vec1 = this->unk_1E0.unk_08; + vec1 = this->interactInfo.headRot; float1 = (vec1.y / (f32)0x8000) * M_PI; Matrix_RotateX(float1, MTXMODE_APPLY); float1 = (vec1.x / (f32)0x8000) * M_PI; @@ -1119,7 +1119,7 @@ s32 EnGo_OverrideLimbDraw(PlayState* play, s32 limb, Gfx** dList, Vec3f* pos, Ve } if (limb == 10) { - vec1 = this->unk_1E0.unk_0E; + vec1 = this->interactInfo.torsoRot; float1 = (vec1.y / (f32)0x8000) * M_PI; Matrix_RotateY(float1, MTXMODE_APPLY); float1 = (vec1.x / (f32)0x8000) * M_PI; diff --git a/soh/src/overlays/actors/ovl_En_Go/z_en_go.h b/soh/src/overlays/actors/ovl_En_Go/z_en_go.h index 5100522eb64..7b3224aecda 100644 --- a/soh/src/overlays/actors/ovl_En_Go/z_en_go.h +++ b/soh/src/overlays/actors/ovl_En_Go/z_en_go.h @@ -42,7 +42,7 @@ typedef struct EnGo { /* 0x014C */ SkelAnime skelAnime; /* 0x0190 */ EnGoActionFunc actionFunc; /* 0x0194 */ ColliderCylinder collider; - /* 0x01E0 */ struct_80034A14_arg1 unk_1E0; + /* 0x01E0 */ NpcInteractInfo interactInfo; /* 0x0208 */ char unk_208[0x4]; /* 0x020C */ s16 unk_20C; /* 0x020E */ s16 unk_20E; diff --git a/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c b/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c index 08ffeda936f..640b04cfa16 100644 --- a/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c +++ b/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c @@ -41,7 +41,7 @@ EnGo2 (this->actor.params & 0xFC00) >> 0xA - Gorons in Fire Temple this->actor.params & 0x1F -Gorons only move when this->unk_194.unk_00 == 0 +Gorons only move when this->interactInfo.talkState == NPC_TALK_STATE_IDLE */ void EnGo2_Init(Actor* thisx, PlayState* play); @@ -342,10 +342,10 @@ u16 EnGo2_GetTextIdGoronCityRollingBig(PlayState* play, EnGo2* this) { } } -s16 EnGo2_GetStateGoronCityRollingBig(PlayState* play, EnGo2* this) { +s16 EnGo2_UpdateTalkStateGoronCityRollingBig(PlayState* play, EnGo2* this) { switch (Message_GetState(&play->msgCtx)) { case TEXT_STATE_CLOSING: - return 2; + return NPC_TALK_STATE_ACTION; case TEXT_STATE_EVENT: if (Message_ShouldAdvance(play)) { if (this->actor.textId == 0x3012) { @@ -357,13 +357,13 @@ s16 EnGo2_GetStateGoronCityRollingBig(PlayState* play, EnGo2* this) { } Message_CloseTextbox(play); gSaveContext.infTable[17] |= 0x4000; - return 2; + return NPC_TALK_STATE_ACTION; } else { - return 2; + return NPC_TALK_STATE_ACTION; } } default: - return 1; + return NPC_TALK_STATE_TALKING; } } @@ -372,14 +372,14 @@ u16 EnGo2_GetTextIdGoronDmtBombFlower(PlayState* play, EnGo2* this) { } // DMT Goron by Bomb Flower Choice -s16 EnGo2_GetStateGoronDmtBombFlower(PlayState* play, EnGo2* this) { +s16 EnGo2_UpdateTalkStateGoronDmtBombFlower(PlayState* play, EnGo2* this) { switch (Message_GetState(&play->msgCtx)) { case TEXT_STATE_CLOSING: if ((this->actor.textId == 0x300B) && (gSaveContext.infTable[14] & 0x800) == 0) { gSaveContext.infTable[14] |= 0x800; - return 2; + return NPC_TALK_STATE_ACTION; } else { - return 0; + return NPC_TALK_STATE_IDLE; } case TEXT_STATE_CHOICE: if (Message_ShouldAdvance(play)) { @@ -392,10 +392,10 @@ s16 EnGo2_GetStateGoronDmtBombFlower(PlayState* play, EnGo2* this) { } Message_ContinueTextbox(play, this->actor.textId); } - return 1; + return NPC_TALK_STATE_TALKING; } default: - return 1; + return NPC_TALK_STATE_TALKING; } } @@ -407,11 +407,11 @@ u16 EnGo2_GetTextIdGoronDmtRollingSmall(PlayState* play, EnGo2* this) { } } -s16 EnGo2_GetStateGoronDmtRollingSmall(PlayState* play, EnGo2* this) { +s16 EnGo2_UpdateTalkStateGoronDmtRollingSmall(PlayState* play, EnGo2* this) { if (Message_GetState(&play->msgCtx) == TEXT_STATE_CLOSING) { - return 0; + return NPC_TALK_STATE_IDLE; } else { - return 1; + return NPC_TALK_STATE_TALKING; } } @@ -427,14 +427,14 @@ u16 EnGo2_GetTextIdGoronDmtDcEntrance(PlayState* play, EnGo2* this) { } } -s16 EnGo2_GetStateGoronDmtDcEntrance(PlayState* play, EnGo2* this) { +s16 EnGo2_UpdateTalkStateGoronDmtDcEntrance(PlayState* play, EnGo2* this) { if (Message_GetState(&play->msgCtx) == TEXT_STATE_CLOSING) { if (this->actor.textId == 0x3008) { gSaveContext.infTable[14] |= 0x1; } - return 0; + return NPC_TALK_STATE_IDLE; } else { - return 1; + return NPC_TALK_STATE_TALKING; } } @@ -450,14 +450,14 @@ u16 EnGo2_GetTextIdGoronCityEntrance(PlayState* play, EnGo2* this) { } } -s16 EnGo2_GetStateGoronCityEntrance(PlayState* play, EnGo2* this) { +s16 EnGo2_UpdateTalkStateGoronCityEntrance(PlayState* play, EnGo2* this) { if (Message_GetState(&play->msgCtx) == TEXT_STATE_CLOSING) { if (this->actor.textId == 0x3014) { gSaveContext.infTable[15] |= 0x1; } - return 0; + return NPC_TALK_STATE_IDLE; } else { - return 1; + return NPC_TALK_STATE_TALKING; } } @@ -473,14 +473,14 @@ u16 EnGo2_GetTextIdGoronCityIsland(PlayState* play, EnGo2* this) { } } -s16 EnGo2_GetStateGoronCityIsland(PlayState* play, EnGo2* this) { +s16 EnGo2_UpdateTalkStateGoronCityIsland(PlayState* play, EnGo2* this) { if (Message_GetState(&play->msgCtx) == TEXT_STATE_CLOSING) { if (this->actor.textId == 0x3016) { gSaveContext.infTable[15] |= 0x10; } - return 0; + return NPC_TALK_STATE_IDLE; } else { - return 1; + return NPC_TALK_STATE_TALKING; } } @@ -499,14 +499,14 @@ u16 EnGo2_GetTextIdGoronCityLowestFloor(PlayState* play, EnGo2* this) { } } -s16 EnGo2_GetStateGoronCityLowestFloor(PlayState* play, EnGo2* this) { +s16 EnGo2_UpdateTalkStateGoronCityLowestFloor(PlayState* play, EnGo2* this) { if (Message_GetState(&play->msgCtx) == TEXT_STATE_CLOSING) { if (this->actor.textId == 0x3018) { gSaveContext.infTable[15] |= 0x100; } - return 0; + return NPC_TALK_STATE_IDLE; } else { - return 1; + return NPC_TALK_STATE_TALKING; } } @@ -528,7 +528,7 @@ u16 EnGo2_GetTextIdGoronCityLink(PlayState* play, EnGo2* this) { } } -s16 EnGo2_GetStateGoronCityLink(PlayState* play, EnGo2* this) { +s16 EnGo2_UpdateTalkStateGoronCityLink(PlayState* play, EnGo2* this) { switch (EnGo2_GetDialogState(this, play)) { case TEXT_STATE_CLOSING: if(!gSaveContext.n64ddFlag) { @@ -536,22 +536,22 @@ s16 EnGo2_GetStateGoronCityLink(PlayState* play, EnGo2* this) { case 0x3036: EnGo2_GetItem(this, play, GI_TUNIC_GORON); this->actionFunc = EnGo2_SetupGetItem; - return 2; + return NPC_TALK_STATE_ACTION; case 0x3037: gSaveContext.infTable[16] |= 0x4000; default: - return 0; + return NPC_TALK_STATE_IDLE; } } else { if (Flags_GetTreasure(play, 0x1F)) { - return 0; + return NPC_TALK_STATE_IDLE; } gSaveContext.infTable[16] |= 0x200; EnGo2_GetItemEntry(this, play, Randomizer_GetItemFromKnownCheck(RC_GC_ROLLING_GORON_AS_ADULT, GI_TUNIC_GORON)); this->actionFunc = EnGo2_SetupGetItem; Flags_SetTreasure(play, 0x1F); - return 2; + return NPC_TALK_STATE_ACTION; } case TEXT_STATE_CHOICE: @@ -574,7 +574,7 @@ s16 EnGo2_GetStateGoronCityLink(PlayState* play, EnGo2* this) { } else { break; } - return 1; + return NPC_TALK_STATE_TALKING; case TEXT_STATE_EVENT: if (Message_ShouldAdvance(play)) { switch (this->actor.textId) { @@ -584,13 +584,13 @@ s16 EnGo2_GetStateGoronCityLink(PlayState* play, EnGo2* this) { case 0x3033: this->actor.textId = 0x3034; Message_ContinueTextbox(play, this->actor.textId); - return 1; + return NPC_TALK_STATE_TALKING; default: - return 2; + return NPC_TALK_STATE_ACTION; } } } - return 1; + return NPC_TALK_STATE_TALKING; } u16 EnGo2_GetTextIdGoronDmtBiggoron(PlayState* play, EnGo2* this) { @@ -611,7 +611,7 @@ u16 EnGo2_GetTextIdGoronDmtBiggoron(PlayState* play, EnGo2* this) { } } -s16 EnGo2_GetStateGoronDmtBiggoron(PlayState* play, EnGo2* this) { +s16 EnGo2_UpdateTalkStateGoronDmtBiggoron(PlayState* play, EnGo2* this) { s32 unusedPad; u8 dialogState = this->dialogState; @@ -619,7 +619,7 @@ s16 EnGo2_GetStateGoronDmtBiggoron(PlayState* play, EnGo2* this) { case TEXT_STATE_DONE: if (this->actor.textId == 0x305E) { if((!gSaveContext.n64ddFlag && gSaveContext.bgsFlag) || (gSaveContext.n64ddFlag && Flags_GetTreasure(play, 0x1F))) { - return 0; + return NPC_TALK_STATE_IDLE; } if(gSaveContext.n64ddFlag) { @@ -629,9 +629,9 @@ s16 EnGo2_GetStateGoronDmtBiggoron(PlayState* play, EnGo2* this) { EnGo2_GetItem(this, play, GI_SWORD_BGS); } this->actionFunc = EnGo2_SetupGetItem; - return 2; + return NPC_TALK_STATE_ACTION; } else { - return 0; + return NPC_TALK_STATE_IDLE; } case TEXT_STATE_DONE_FADING: switch (this->actor.textId) { @@ -664,12 +664,12 @@ s16 EnGo2_GetStateGoronDmtBiggoron(PlayState* play, EnGo2* this) { EnGo2_GetItem(this, play, getItemId); } this->actionFunc = EnGo2_SetupGetItem; - return 2; + return NPC_TALK_STATE_ACTION; } this->actor.textId = 0x3056; Message_ContinueTextbox(play, this->actor.textId); } - return 1; + return NPC_TALK_STATE_TALKING; } break; case TEXT_STATE_EVENT: @@ -678,10 +678,10 @@ s16 EnGo2_GetStateGoronDmtBiggoron(PlayState* play, EnGo2* this) { play->msgCtx.msgMode = MSGMODE_PAUSED; this->actionFunc = EnGo2_BiggoronEyedrops; } - return 2; + return NPC_TALK_STATE_ACTION; } } - return 1; + return NPC_TALK_STATE_TALKING; } u16 EnGo2_GetTextIdGoronFireGeneric(PlayState* play, EnGo2* this) { @@ -692,20 +692,20 @@ u16 EnGo2_GetTextIdGoronFireGeneric(PlayState* play, EnGo2* this) { } } -s16 EnGo2_GetStateGoronFireGeneric(PlayState* play, EnGo2* this) { +s16 EnGo2_UpdateTalkStateGoronFireGeneric(PlayState* play, EnGo2* this) { switch (Message_GetState(&play->msgCtx)) { case TEXT_STATE_CLOSING: - return 0; + return NPC_TALK_STATE_IDLE; case TEXT_STATE_EVENT: if (Message_ShouldAdvance(play)) { if (this->actor.textId == 0x3071) { this->actor.textId = EnGo2_GoronFireGenericGetTextId(this); Message_ContinueTextbox(play, this->actor.textId); } - return 1; + return NPC_TALK_STATE_TALKING; } default: - return 1; + return NPC_TALK_STATE_TALKING; } } @@ -713,14 +713,14 @@ u16 EnGo2_GetTextIdGoronCityStairwell(PlayState* play, EnGo2* this) { return !LINK_IS_ADULT ? gSaveContext.infTable[14] & 0x8 ? 0x3022 : 0x300E : 0x3043; } -s16 EnGo2_GetStateGoronCityStairwell(PlayState* play, EnGo2* this) { +s16 EnGo2_UpdateTalkStateGoronCityStairwell(PlayState* play, EnGo2* this) { if (Message_GetState(&play->msgCtx) == TEXT_STATE_CLOSING) { if (this->actor.textId == 0x300E) { gSaveContext.infTable[14] |= 0x8; } - return 0; + return NPC_TALK_STATE_IDLE; } else { - return 1; + return NPC_TALK_STATE_TALKING; } } @@ -729,11 +729,11 @@ u16 EnGo2_GetTextIdGoronMarketBazaar(PlayState* play, EnGo2* this) { return 0x7122; } -s16 EnGo2_GetStateGoronMarketBazaar(PlayState* play, EnGo2* this) { +s16 EnGo2_UpdateTalkStateGoronMarketBazaar(PlayState* play, EnGo2* this) { if (Message_GetState(&play->msgCtx) == TEXT_STATE_CLOSING) { - return 0; + return NPC_TALK_STATE_IDLE; } else { - return 1; + return NPC_TALK_STATE_TALKING; } } @@ -749,14 +749,14 @@ u16 EnGo2_GetTextIdGoronCityLostWoods(PlayState* play, EnGo2* this) { } } -s16 EnGo2_GetStateGoronCityLostWoods(PlayState* play, EnGo2* this) { +s16 EnGo2_UpdateTalkStateGoronCityLostWoods(PlayState* play, EnGo2* this) { if (Message_GetState(&play->msgCtx) == TEXT_STATE_CLOSING) { if (this->actor.textId == 0x3024) { gSaveContext.infTable[14] |= 0x40; } - return 0; + return NPC_TALK_STATE_IDLE; } else { - return 1; + return NPC_TALK_STATE_TALKING; } } @@ -769,11 +769,11 @@ u16 EnGo2_GetTextIdGoronDmtFairyHint(PlayState* play, EnGo2* this) { } } -s16 EnGo2_GetStateGoronDmtFairyHint(PlayState* play, EnGo2* this) { +s16 EnGo2_UpdateTalkStateGoronDmtFairyHint(PlayState* play, EnGo2* this) { if (Message_GetState(&play->msgCtx) == TEXT_STATE_CLOSING) { - return 0; + return NPC_TALK_STATE_IDLE; } else { - return 1; + return NPC_TALK_STATE_TALKING; } } @@ -817,52 +817,52 @@ u16 EnGo2_GetTextId(PlayState* play, Actor* thisx) { } } -s16 EnGo2_GetState(PlayState* play, Actor* thisx) { +s16 EnGo2_UpdateTalkState(PlayState* play, Actor* thisx) { EnGo2* this = (EnGo2*)thisx; switch (this->actor.params & 0x1F) { case GORON_CITY_ROLLING_BIG: - return EnGo2_GetStateGoronCityRollingBig(play, this); + return EnGo2_UpdateTalkStateGoronCityRollingBig(play, this); case GORON_CITY_LINK: - return EnGo2_GetStateGoronCityLink(play, this); + return EnGo2_UpdateTalkStateGoronCityLink(play, this); case GORON_DMT_BIGGORON: - return EnGo2_GetStateGoronDmtBiggoron(play, this); + return EnGo2_UpdateTalkStateGoronDmtBiggoron(play, this); case GORON_FIRE_GENERIC: - return EnGo2_GetStateGoronFireGeneric(play, this); + return EnGo2_UpdateTalkStateGoronFireGeneric(play, this); case GORON_DMT_BOMB_FLOWER: - return EnGo2_GetStateGoronDmtBombFlower(play, this); + return EnGo2_UpdateTalkStateGoronDmtBombFlower(play, this); case GORON_DMT_ROLLING_SMALL: - return EnGo2_GetStateGoronDmtRollingSmall(play, this); + return EnGo2_UpdateTalkStateGoronDmtRollingSmall(play, this); case GORON_DMT_DC_ENTRANCE: - return EnGo2_GetStateGoronDmtDcEntrance(play, this); + return EnGo2_UpdateTalkStateGoronDmtDcEntrance(play, this); case GORON_CITY_ENTRANCE: - return EnGo2_GetStateGoronCityEntrance(play, this); + return EnGo2_UpdateTalkStateGoronCityEntrance(play, this); case GORON_CITY_ISLAND: - return EnGo2_GetStateGoronCityIsland(play, this); + return EnGo2_UpdateTalkStateGoronCityIsland(play, this); case GORON_CITY_LOWEST_FLOOR: - return EnGo2_GetStateGoronCityLowestFloor(play, this); + return EnGo2_UpdateTalkStateGoronCityLowestFloor(play, this); case GORON_CITY_STAIRWELL: - return EnGo2_GetStateGoronCityStairwell(play, this); + return EnGo2_UpdateTalkStateGoronCityStairwell(play, this); case GORON_CITY_LOST_WOODS: - return EnGo2_GetStateGoronCityLostWoods(play, this); + return EnGo2_UpdateTalkStateGoronCityLostWoods(play, this); case GORON_DMT_FAIRY_HINT: - return EnGo2_GetStateGoronDmtFairyHint(play, this); + return EnGo2_UpdateTalkStateGoronDmtFairyHint(play, this); case GORON_MARKET_BAZAAR: - return EnGo2_GetStateGoronMarketBazaar(play, this); + return EnGo2_UpdateTalkStateGoronMarketBazaar(play, this); } } s32 func_80A44790(EnGo2* this, PlayState* play) { if ((this->actor.params & 0x1F) != GORON_DMT_BIGGORON && (this->actor.params & 0x1F) != GORON_CITY_ROLLING_BIG) { - return func_800343CC(play, &this->actor, &this->unk_194.unk_00, this->unk_218, EnGo2_GetTextId, - EnGo2_GetState); + return Npc_UpdateTalking(play, &this->actor, &this->interactInfo.talkState, this->unk_218, EnGo2_GetTextId, + EnGo2_UpdateTalkState); } else if (((this->actor.params & 0x1F) == GORON_DMT_BIGGORON) && ((this->collider.base.ocFlags2 & 1) == 0)) { return false; } else { if (Actor_ProcessTalkRequest(&this->actor, play)) { - this->unk_194.unk_00 = 1; + this->interactInfo.talkState = NPC_TALK_STATE_TALKING; return true; - } else if (this->unk_194.unk_00 != 0) { - this->unk_194.unk_00 = EnGo2_GetState(play, &this->actor); + } else if (this->interactInfo.talkState != NPC_TALK_STATE_IDLE) { + this->interactInfo.talkState = EnGo2_UpdateTalkState(play, &this->actor); return false; } else if (func_8002F2CC(&this->actor, play, this->unk_218)) { this->actor.textId = EnGo2_GetTextId(play, &this->actor); @@ -1127,10 +1127,10 @@ void func_80A45288(EnGo2* this, PlayState* play) { s32 linkAge; if (this->actionFunc != EnGo2_GoronFireGenericAction) { - this->unk_194.unk_18 = player->actor.world.pos; + this->interactInfo.trackPos = player->actor.world.pos; linkAge = gSaveContext.linkAge; - this->unk_194.unk_14 = D_80A482D8[this->actor.params & 0x1F][linkAge]; - func_80034A14(&this->actor, &this->unk_194, 4, this->unk_26E); + this->interactInfo.yOffset = D_80A482D8[this->actor.params & 0x1F][linkAge]; + Npc_TrackPoint(&this->actor, &this->interactInfo, 4, this->trackingMode); } if ((this->actionFunc != EnGo2_SetGetItem) && (this->isAwake == true)) { if (func_80A44790(this, play)) { @@ -1150,7 +1150,7 @@ void func_80A45360(EnGo2* this, f32* alpha) { void EnGo2_RollForward(EnGo2* this) { f32 speedXZ = this->actor.speedXZ; - if (this->unk_194.unk_00 != 0) { + if (this->interactInfo.talkState != NPC_TALK_STATE_IDLE) { this->actor.speedXZ = 0.0f; } @@ -1219,13 +1219,13 @@ s32 EnGo2_IsCameraModified(EnGo2* this, PlayState* play) { void EnGo2_DefaultWakingUp(EnGo2* this) { if (EnGo2_IsWakingUp(this)) { - this->unk_26E = 2; + this->trackingMode = NPC_TRACKING_HEAD_AND_TORSO; } else { - this->unk_26E = 1; + this->trackingMode = NPC_TRACKING_NONE; } - if (this->unk_194.unk_00 != 0) { - this->unk_26E = 4; + if (this->interactInfo.talkState != NPC_TALK_STATE_IDLE) { + this->trackingMode = NPC_TRACKING_FULL_BODY; } this->isAwake = true; @@ -1236,20 +1236,20 @@ void EnGo2_WakingUp(EnGo2* this) { s32 isTrue = true; xyzDist = SQ(xyzDist); - this->unk_26E = 1; - if ((this->actor.xyzDistToPlayerSq <= xyzDist) || (this->unk_194.unk_00 != 0)) { - this->unk_26E = 4; + this->trackingMode = NPC_TRACKING_NONE; + if ((this->actor.xyzDistToPlayerSq <= xyzDist) || (this->interactInfo.talkState != NPC_TALK_STATE_IDLE)) { + this->trackingMode = NPC_TRACKING_FULL_BODY; } this->isAwake = isTrue; } void EnGo2_BiggoronWakingUp(EnGo2* this) { - if (EnGo2_IsWakingUp(this) || this->unk_194.unk_00 != 0) { - this->unk_26E = 2; + if (EnGo2_IsWakingUp(this) || this->interactInfo.talkState != NPC_TALK_STATE_IDLE) { + this->trackingMode = NPC_TRACKING_HEAD_AND_TORSO; this->isAwake = true; } else { - this->unk_26E = 1; + this->trackingMode = NPC_TRACKING_NONE; this->isAwake = false; } } @@ -1258,7 +1258,7 @@ void EnGo2_SelectGoronWakingUp(EnGo2* this) { switch (this->actor.params & 0x1F) { case GORON_DMT_BOMB_FLOWER: this->isAwake = true; - this->unk_26E = EnGo2_IsWakingUp(this) ? 2 : 1; + this->trackingMode = EnGo2_IsWakingUp(this) ? NPC_TRACKING_HEAD_AND_TORSO : NPC_TRACKING_NONE; break; case GORON_FIRE_GENERIC: EnGo2_WakingUp(this); @@ -1343,7 +1343,7 @@ void EnGo2_RollingAnimation(EnGo2* this, PlayState* play) { this->skelAnime.playSpeed = -1.0f; } EnGo2_SwapInitialFrameAnimFrameCount(this); - this->unk_26E = 1; + this->trackingMode = NPC_TRACKING_NONE; this->unk_211 = false; this->isAwake = false; this->actionFunc = EnGo2_CurledUp; @@ -1448,30 +1448,31 @@ s32 EnGo2_IsFreeingGoronInFire(EnGo2* this, PlayState* play) { } s32 EnGo2_IsGoronDmtBombFlower(EnGo2* this) { - if ((this->actor.params & 0x1F) != GORON_DMT_BOMB_FLOWER || this->unk_194.unk_00 != 2) { + if ((this->actor.params & 0x1F) != GORON_DMT_BOMB_FLOWER || this->interactInfo.talkState != NPC_TALK_STATE_ACTION) { return false; } Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_3); - this->unk_194.unk_00 = 0; + this->interactInfo.talkState = NPC_TALK_STATE_IDLE; this->isAwake = false; - this->unk_26E = 1; + this->trackingMode = NPC_TRACKING_NONE; this->actionFunc = EnGo2_GoronDmtBombFlowerAnimation; return true; } s32 EnGo2_IsGoronRollingBig(EnGo2* this, PlayState* play) { - if ((this->actor.params & 0x1F) != GORON_CITY_ROLLING_BIG || (this->unk_194.unk_00 != 2)) { + if ((this->actor.params & 0x1F) != GORON_CITY_ROLLING_BIG || + (this->interactInfo.talkState != NPC_TALK_STATE_ACTION)) { return false; } - this->unk_194.unk_00 = 0; + this->interactInfo.talkState = NPC_TALK_STATE_IDLE; EnGo2_RollingAnimation(this, play); this->actionFunc = EnGo2_GoronRollingBigContinueRolling; return true; } s32 EnGo2_IsGoronFireGeneric(EnGo2* this) { - if ((this->actor.params & 0x1F) != GORON_FIRE_GENERIC || this->unk_194.unk_00 == 0) { + if ((this->actor.params & 0x1F) != GORON_FIRE_GENERIC || this->interactInfo.talkState == NPC_TALK_STATE_IDLE) { return false; } this->actionFunc = EnGo2_GoronFireGenericAction; @@ -1487,7 +1488,7 @@ s32 EnGo2_IsGoronLinkReversing(EnGo2* this) { } s32 EnGo2_IsRolling(EnGo2* this) { - if (this->unk_194.unk_00 == 0 || this->actor.speedXZ < 1.0f) { + if (this->interactInfo.talkState == NPC_TALK_STATE_IDLE || this->actor.speedXZ < 1.0f) { return false; } if (EnGo2_IsRollingOnGround(this, 2, 20.0 / 3.0f, 0)) { @@ -1555,7 +1556,7 @@ void EnGo2_GoronFireClearCamera(EnGo2* this, PlayState* play) { void EnGo2_BiggoronAnimation(EnGo2* this) { if (INV_CONTENT(ITEM_TRADE_ADULT) >= ITEM_SWORD_BROKEN && INV_CONTENT(ITEM_TRADE_ADULT) <= ITEM_EYEDROPS && - (this->actor.params & 0x1F) == GORON_DMT_BIGGORON && this->unk_194.unk_00 == 0) { + (this->actor.params & 0x1F) == GORON_DMT_BIGGORON && this->interactInfo.talkState == NPC_TALK_STATE_IDLE) { if (DECR(this->animTimer) == 0) { this->animTimer = Rand_S16Offset(30, 30); func_800F4524(&D_801333D4, NA_SE_EN_GOLON_EYE_BIG, 60); @@ -1601,7 +1602,7 @@ void EnGo2_Init(Actor* thisx, PlayState* play) { this->goronState = 0; this->waypoint = 0; this->unk_216 = this->actor.shape.rot.z; - this->unk_26E = 1; + this->trackingMode = NPC_TRACKING_NONE; this->path = Path_GetByIndex(play, (this->actor.params & 0x3E0) >> 5, 0x1F); this->getItemEntry = (GetItemEntry)GET_ITEM_NONE; switch (this->actor.params & 0x1F) { @@ -1853,7 +1854,7 @@ void EnGo2_SetupGetItem(EnGo2* this, PlayState* play) { void EnGo2_SetGetItem(EnGo2* this, PlayState* play) { if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play)) { - this->unk_194.unk_00 = 0; + this->interactInfo.talkState = NPC_TALK_STATE_IDLE; switch (this->getItemId) { case GI_CLAIM_CHECK: Environment_ClearBgsDayCount(); @@ -1891,7 +1892,7 @@ void EnGo2_BiggoronEyedrops(EnGo2* this, PlayState* play) { Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_5); this->actor.flags &= ~ACTOR_FLAG_0; this->actor.shape.rot.y += 0x5B0; - this->unk_26E = 1; + this->trackingMode = NPC_TRACKING_NONE; this->animTimer = gSaveContext.n64ddFlag ? 0 : (this->skelAnime.endFrame + 60.0f + 60.0f); // eyeDrops animation timer this->eyeMouthTexState = 2; this->unk_20C = 0; @@ -1923,7 +1924,7 @@ void EnGo2_BiggoronEyedrops(EnGo2* this, PlayState* play) { if (Message_GetState(&play->msgCtx) == TEXT_STATE_CLOSING) { Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_1); this->actor.flags |= ACTOR_FLAG_0; - this->unk_26E = 2; + this->trackingMode = NPC_TRACKING_HEAD_AND_TORSO; this->skelAnime.playSpeed = 0.0f; this->skelAnime.curFrame = this->skelAnime.endFrame; if (gSaveContext.n64ddFlag) { @@ -1964,7 +1965,7 @@ void EnGo2_GoronLinkStopRolling(EnGo2* this, PlayState* play) { player->actor.freezeTimer = 10; } else { gSaveContext.infTable[16] |= 0x1000; - this->unk_26E = 1; + this->trackingMode = NPC_TRACKING_NONE; this->unk_211 = false; this->isAwake = false; this->actionFunc = EnGo2_CurledUp; @@ -1988,8 +1989,8 @@ void EnGo2_GoronFireGenericAction(EnGo2* this, PlayState* play) { this->animTimer = 60; this->actor.gravity = 0.0f; this->actor.speedXZ = 2.0f; - this->unk_194.unk_08 = D_80A4854C; - this->unk_194.unk_0E = D_80A4854C; + this->interactInfo.headRot = D_80A4854C; + this->interactInfo.torsoRot = D_80A4854C; this->goronState++; this->goronState++; player->actor.world.rot.y = this->actor.world.rot.y; @@ -2052,7 +2053,7 @@ void EnGo2_Update(Actor* thisx, PlayState* play) { EnGo2_RollForward(this); Actor_UpdateBgCheckInfo(play, &this->actor, (f32)this->collider.dim.height * 0.5f, (f32)this->collider.dim.radius * 0.6f, 0.0f, 5); - if (this->unk_194.unk_00 == 0) { + if (this->interactInfo.talkState == NPC_TALK_STATE_IDLE) { func_80A44AB0(this, play); } this->actionFunc(this, play); @@ -2102,7 +2103,7 @@ s32 EnGo2_OverrideLimbDraw(PlayState* play, s32 limb, Gfx** dList, Vec3f* pos, V if (limb == 17) { Matrix_Translate(2800.0f + CVarGetFloat("gCosmetics.Goron_NeckLength", 0.0f), 0.0f, 0.0f, MTXMODE_APPLY); - vec1 = this->unk_194.unk_08; + vec1 = this->interactInfo.headRot; float1 = (vec1.y / (f32)0x8000) * M_PI; Matrix_RotateX(float1, MTXMODE_APPLY); float1 = (vec1.x / (f32)0x8000) * M_PI; @@ -2110,7 +2111,7 @@ s32 EnGo2_OverrideLimbDraw(PlayState* play, s32 limb, Gfx** dList, Vec3f* pos, V Matrix_Translate(-2800.0f + CVarGetFloat("gCosmetics.Goron_NeckLength", 0.0f), 0.0f, 0.0f, MTXMODE_APPLY); } if (limb == 10) { - vec1 = this->unk_194.unk_0E; + vec1 = this->interactInfo.torsoRot; float1 = (vec1.y / (f32)0x8000) * M_PI; Matrix_RotateY(float1, MTXMODE_APPLY); float1 = (vec1.x / (f32)0x8000) * M_PI; diff --git a/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.h b/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.h index bc9e5b5ec06..86ac0c32e0d 100644 --- a/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.h +++ b/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.h @@ -69,7 +69,7 @@ typedef struct EnGo2 { /* 0x0000 */ Actor actor; /* 0x014C */ SkelAnime skelAnime; /* 0x0190 */ EnGo2ActionFunc actionFunc; - /* 0x0194 */ struct_80034A14_arg1 unk_194; + /* 0x0194 */ NpcInteractInfo interactInfo; /* 0x01BC */ ColliderCylinder collider; /* 0x0208 */ Path* path; /* 0x020C */ u8 unk_20C; // counter for GORON_CITY_LINK animation @@ -92,7 +92,7 @@ typedef struct EnGo2 { /* 0x0224 */ s16 blinkTimer; /* 0x0226 */ s16 unk_226[18]; // Remains unknown /* 0x024A */ s16 unk_24A[18]; // Remains unknown - /* 0x026E */ u16 unk_26E; // Remains unknown = 1, 2, or 4: used in func_80034A14 + /* 0x026E */ u16 trackingMode; /* 0x0270 */ EnGoEffect dustEffects[10]; /* 0x04A0 */ Vec3f eye; /* 0x04AC */ Vec3f at; diff --git a/soh/src/overlays/actors/ovl_En_Guest/z_en_guest.c b/soh/src/overlays/actors/ovl_En_Guest/z_en_guest.c index 44be982cd91..bdf90381a7a 100644 --- a/soh/src/overlays/actors/ovl_En_Guest/z_en_guest.c +++ b/soh/src/overlays/actors/ovl_En_Guest/z_en_guest.c @@ -150,13 +150,13 @@ void func_80A505CC(Actor* thisx, PlayState* play) { func_80A5046C(this); this->actionFunc(this, play); - this->unk_2A0.unk_18 = player->actor.world.pos; + this->interactInfo.trackPos = player->actor.world.pos; if (LINK_IS_ADULT) { - this->unk_2A0.unk_14 = 10.0f; + this->interactInfo.yOffset = 10.0f; } else { - this->unk_2A0.unk_14 = 20.0f; + this->interactInfo.yOffset = 20.0f; } - func_80034A14(&this->actor, &this->unk_2A0, 6, 2); + Npc_TrackPoint(&this->actor, &this->interactInfo, 6, NPC_TRACKING_HEAD_AND_TORSO); func_80034F54(play, this->unk_2CC, this->unk_2EC, 16); @@ -189,14 +189,14 @@ s32 EnGuest_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* if (limbIndex == 15) { *dList = object_boj_DL_0059B0; Matrix_Translate(1400.0f, 0.0f, 0.0f, MTXMODE_APPLY); - sp3C = this->unk_2A0.unk_08; + sp3C = this->interactInfo.headRot; Matrix_RotateX((sp3C.y / 32768.0f) * M_PI, MTXMODE_APPLY); Matrix_RotateZ((sp3C.x / 32768.0f) * M_PI, MTXMODE_APPLY); Matrix_Translate(-1400.0f, 0.0f, 0.0f, MTXMODE_APPLY); } if (limbIndex == 8) { - sp3C = this->unk_2A0.unk_0E; + sp3C = this->interactInfo.torsoRot; Matrix_RotateX((-sp3C.y / 32768.0f) * M_PI, MTXMODE_APPLY); Matrix_RotateZ((sp3C.x / 32768.0f) * M_PI, MTXMODE_APPLY); } diff --git a/soh/src/overlays/actors/ovl_En_Guest/z_en_guest.h b/soh/src/overlays/actors/ovl_En_Guest/z_en_guest.h index 7be3b5852ff..4cf72a26c3a 100644 --- a/soh/src/overlays/actors/ovl_En_Guest/z_en_guest.h +++ b/soh/src/overlays/actors/ovl_En_Guest/z_en_guest.h @@ -15,7 +15,7 @@ typedef struct EnGuest { /* 0x01F0 */ Vec3s morphTable[16]; /* 0x0250 */ EnGuestActionFunc actionFunc; /* 0x0254 */ ColliderCylinder collider; - /* 0x02A0 */ struct_80034A14_arg1 unk_2A0; + /* 0x02A0 */ NpcInteractInfo interactInfo; /* 0x02C8 */ s16 unk_2C8; /* 0x02CA */ s16 unk_2CA; /* 0x02CC */ s16 unk_2CC[16]; diff --git a/soh/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.c b/soh/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.c index 214e56e9776..77921b89dc2 100644 --- a/soh/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.c +++ b/soh/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.c @@ -377,13 +377,13 @@ void EnHeishi4_Update(Actor* thisx, PlayState* play) { thisx->world.pos.z = this->pos.z; Actor_SetFocus(thisx, this->height); if (this->type != HEISHI4_AT_MARKET_DYING) { - this->unk_28C.unk_18 = player->actor.world.pos; + this->interactInfo.trackPos = player->actor.world.pos; if (!LINK_IS_ADULT) { - this->unk_28C.unk_18.y = (player->actor.world.pos.y - 10.0f); + this->interactInfo.trackPos.y = player->actor.world.pos.y - 10.0f; } - func_80034A14(thisx, &this->unk_28C, 2, 4); - this->unk_260 = this->unk_28C.unk_08; - this->unk_266 = this->unk_28C.unk_0E; + Npc_TrackPoint(thisx, &this->interactInfo, 2, NPC_TRACKING_FULL_BODY); + this->unk_260 = this->interactInfo.headRot; + this->unk_266 = this->interactInfo.torsoRot; } this->unk_27E += 1; this->actionFunc(this, play); diff --git a/soh/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.h b/soh/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.h index c69a139bdd9..d7c57d78dd8 100644 --- a/soh/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.h +++ b/soh/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.h @@ -31,7 +31,7 @@ typedef struct EnHeishi4 { /* 0x0282 */ s16 unk_282; /* 0x0284 */ s16 unk_284; /* 0x0288 */ f32 unk_288; - /* 0x028C */ struct_80034A14_arg1 unk_28C; + /* 0x028C */ NpcInteractInfo interactInfo; /* 0x02B4 */ u8 unk_2B4; /* 0x02B6 */ char unk_2B6[7]; /* 0x02BC */ ColliderCylinder collider; diff --git a/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c b/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c index 66b0af42df9..b7eb3a30154 100644 --- a/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c +++ b/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c @@ -566,7 +566,7 @@ s16 func_80A70058(PlayState* play, Actor* thisx) { case TEXT_STATE_SONG_DEMO_DONE: case TEXT_STATE_8: case TEXT_STATE_9: - return 1; + return NPC_TALK_STATE_TALKING; case TEXT_STATE_DONE_FADING: switch (this->actor.textId) { case 0x709E: @@ -587,7 +587,7 @@ s16 func_80A70058(PlayState* play, Actor* thisx) { } break; } - return 1; + return NPC_TALK_STATE_TALKING; case TEXT_STATE_CLOSING: switch (this->actor.textId) { case 0x70F0: @@ -674,16 +674,16 @@ s16 func_80A70058(PlayState* play, Actor* thisx) { this->actionFunc = func_80A714C4; break; } - return 0; + return NPC_TALK_STATE_IDLE; case TEXT_STATE_EVENT: if (!Message_ShouldAdvance(play)) { - return 1; + return NPC_TALK_STATE_TALKING; } else { - return 2; + return NPC_TALK_STATE_ACTION; } } - return 1; + return NPC_TALK_STATE_TALKING; } void EnHy_UpdateEyes(EnHy* this) { @@ -773,42 +773,46 @@ void func_80A70834(EnHy* this, PlayState* play) { void func_80A70978(EnHy* this, PlayState* play) { Player* player = GET_PLAYER(play); - s16 phi_a3; + s16 trackingMode; switch (this->actor.params & 0x7F) { case ENHY_TYPE_BOJ_3: case ENHY_TYPE_BJI_7: case ENHY_TYPE_BOJ_9: case ENHY_TYPE_BOJ_10: - phi_a3 = (this->unk_1E8.unk_00 == 0) ? 1 : 2; + trackingMode = + (this->interactInfo.talkState == NPC_TALK_STATE_IDLE) ? NPC_TRACKING_NONE : NPC_TRACKING_HEAD_AND_TORSO; break; case ENHY_TYPE_BOJ_12: - phi_a3 = 1; + trackingMode = NPC_TRACKING_NONE; break; case ENHY_TYPE_AHG_2: case ENHY_TYPE_AHG_17: - phi_a3 = 4; + trackingMode = NPC_TRACKING_FULL_BODY; break; case ENHY_TYPE_AOB: case ENHY_TYPE_BOB_18: - phi_a3 = (this->unk_1E8.unk_00 == 0) ? 2 : 4; + trackingMode = (this->interactInfo.talkState == NPC_TALK_STATE_IDLE) ? NPC_TRACKING_HEAD_AND_TORSO + : NPC_TRACKING_FULL_BODY; break; default: - phi_a3 = 2; + trackingMode = NPC_TRACKING_HEAD_AND_TORSO; break; } - this->unk_1E8.unk_18 = player->actor.world.pos; + this->interactInfo.trackPos = player->actor.world.pos; if (LINK_IS_ADULT) { - this->unk_1E8.unk_14 = sInit1Info[this->actor.params & 0x7F].unkValueAdult; + this->interactInfo.yOffset = sInit1Info[this->actor.params & 0x7F].unkValueAdult; } else { - this->unk_1E8.unk_14 = sInit1Info[this->actor.params & 0x7F].unkValueChild; + this->interactInfo.yOffset = sInit1Info[this->actor.params & 0x7F].unkValueChild; } - func_80034A14(&this->actor, &this->unk_1E8, sInit1Info[this->actor.params & 0x7F].unkPresetIndex, phi_a3); + Npc_TrackPoint(&this->actor, &this->interactInfo, sInit1Info[this->actor.params & 0x7F].unkPresetIndex, + trackingMode); - if (func_800343CC(play, &this->actor, &this->unk_1E8.unk_00, this->unkRange, func_80A6F810, func_80A70058)) { + if (Npc_UpdateTalking(play, &this->actor, &this->interactInfo.talkState, this->unkRange, func_80A6F810, + func_80A70058)) { func_80A70834(this, play); } } @@ -978,7 +982,7 @@ void EnHy_InitImpl(EnHy* this, PlayState* play) { } void func_80A710F8(EnHy* this, PlayState* play) { - if (this->unk_1E8.unk_00 != 0) { + if (this->interactInfo.talkState != NPC_TALK_STATE_IDLE) { if (this->skelAnime.animation != &gObjOsAnim_0BFC) { Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENHY_ANIM_26); } @@ -1028,11 +1032,11 @@ void func_80A7134C(EnHy* this, PlayState* play) { s16 yaw; f32 distSq; - if ((this->skelAnime.animation == &gObjOsAnim_2160) && (this->unk_1E8.unk_00 != 0)) { + if ((this->skelAnime.animation == &gObjOsAnim_2160) && (this->interactInfo.talkState != NPC_TALK_STATE_IDLE)) { Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENHY_ANIM_8); } - if ((this->skelAnime.animation == &gObjOsAnim_265C) && (this->unk_1E8.unk_00 == 0)) { + if ((this->skelAnime.animation == &gObjOsAnim_265C) && (this->interactInfo.talkState == NPC_TALK_STATE_IDLE)) { Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENHY_ANIM_7); } @@ -1104,7 +1108,7 @@ void EnHy_Update(Actor* thisx, PlayState* play) { SkelAnime_Update(&this->skelAnime); EnHy_UpdateEyes(this); - if (this->unk_1E8.unk_00 == 0) { + if (this->interactInfo.talkState == NPC_TALK_STATE_IDLE) { Actor_MoveForward(&this->actor); } @@ -1141,14 +1145,14 @@ s32 EnHy_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* po if (limbIndex == 15) { Matrix_Translate(1400.0f, 0.0f, 0.0f, MTXMODE_APPLY); - sp48 = this->unk_1E8.unk_08; + sp48 = this->interactInfo.headRot; Matrix_RotateX((sp48.y / (f32)0x8000) * M_PI, MTXMODE_APPLY); Matrix_RotateZ((sp48.x / (f32)0x8000) * M_PI, MTXMODE_APPLY); Matrix_Translate(-1400.0f, 0.0f, 0.0f, MTXMODE_APPLY); } if (limbIndex == 8) { - sp48 = this->unk_1E8.unk_0E; + sp48 = this->interactInfo.torsoRot; Matrix_RotateX((-sp48.y / (f32)0x8000) * M_PI, MTXMODE_APPLY); Matrix_RotateZ((sp48.x / (f32)0x8000) * M_PI, MTXMODE_APPLY); } diff --git a/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.h b/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.h index 98a5e0d0e4d..6a5ed268023 100644 --- a/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.h +++ b/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.h @@ -44,7 +44,7 @@ typedef struct EnHy { /* 0x0198 */ s8 objBankIndexSkel1; // sets the object used when drawing the skeleton for limb <= 7 (lower part?) /* 0x0199 */ s8 objBankIndexOsAnime; /* 0x019C */ ColliderCylinder collider; - /* 0x01E8 */ struct_80034A14_arg1 unk_1E8; + /* 0x01E8 */ NpcInteractInfo interactInfo; /* 0x0210 */ Path* path; /* 0x0214 */ s8 waypoint; /* 0x0215 */ s8 unk_215; diff --git a/soh/src/overlays/actors/ovl_En_In/z_en_in.c b/soh/src/overlays/actors/ovl_En_In/z_en_in.c index 123f23df530..720f371b47d 100644 --- a/soh/src/overlays/actors/ovl_En_In/z_en_in.c +++ b/soh/src/overlays/actors/ovl_En_In/z_en_in.c @@ -193,14 +193,14 @@ u16 func_80A79168(PlayState* play, Actor* thisx) { } s16 func_80A791CC(PlayState* play, Actor* thisx) { - s32 ret = 0; + s32 ret = NPC_TALK_STATE_IDLE; switch (thisx->textId) { case 0x2045: gSaveContext.infTable[9] |= 0x80; break; case 0x203E: - ret = 2; + ret = NPC_TALK_STATE_ACTION; break; case 0x203F: gSaveContext.eventChkInf[1] |= 2; @@ -212,7 +212,7 @@ s16 func_80A791CC(PlayState* play, Actor* thisx) { s16 func_80A7924C(PlayState* play, Actor* thisx) { EnIn* this = (EnIn*)thisx; - s32 sp18 = 1; + s32 sp18 = NPC_TALK_STATE_TALKING; switch (this->actor.textId) { case 0x2030: @@ -239,7 +239,7 @@ s16 func_80A7924C(PlayState* play, Actor* thisx) { case 0x2036: case 0x2037: if (play->msgCtx.choiceIndex == 1) { - sp18 = 2; + sp18 = NPC_TALK_STATE_ACTION; } else { this->actor.textId = 0x201F; Message_ContinueTextbox(play, this->actor.textId); @@ -247,7 +247,7 @@ s16 func_80A7924C(PlayState* play, Actor* thisx) { break; case 0x2038: if (play->msgCtx.choiceIndex == 0 && gSaveContext.rupees >= 50) { - sp18 = 2; + sp18 = NPC_TALK_STATE_ACTION; } else { this->actor.textId = 0x2039; Message_ContinueTextbox(play, this->actor.textId); @@ -256,7 +256,7 @@ s16 func_80A7924C(PlayState* play, Actor* thisx) { break; case 0x205B: if (play->msgCtx.choiceIndex == 0 && gSaveContext.rupees >= 50) { - sp18 = 2; + sp18 = NPC_TALK_STATE_ACTION; } else { Message_ContinueTextbox(play, this->actor.textId = 0x2039); gSaveContext.eventInf[0] &= ~0xF; @@ -272,20 +272,20 @@ s16 func_80A7924C(PlayState* play, Actor* thisx) { } s16 func_80A7949C(PlayState* play, Actor* thisx) { - s32 phi_v1 = 1; + s32 phi_v1 = NPC_TALK_STATE_TALKING; if (thisx->textId == 0x2035) { Rupees_ChangeBy(-10); thisx->textId = 0x205C; Message_ContinueTextbox(play, thisx->textId); } else { - phi_v1 = 2; + phi_v1 = NPC_TALK_STATE_ACTION; } return phi_v1; } s16 func_80A79500(PlayState* play, Actor* thisx) { - s16 sp1E = 1; + s16 sp1E = NPC_TALK_STATE_TALKING; osSyncPrintf("message_check->(%d[%x])\n", Message_GetState(&play->msgCtx), thisx->textId); switch (Message_GetState(&play->msgCtx)) { @@ -318,25 +318,25 @@ s16 func_80A79500(PlayState* play, Actor* thisx) { void func_80A795C8(EnIn* this, PlayState* play) { Player* player = GET_PLAYER(play); - s16 phi_a3; + s16 npcTrackingMode; if (this->skelAnime.animation == &object_in_Anim_0003B4 || this->skelAnime.animation == &object_in_Anim_001BE0 || this->skelAnime.animation == &object_in_Anim_013D60) { - phi_a3 = 1; + npcTrackingMode = NPC_TRACKING_NONE; } else { - phi_a3 = 0; + npcTrackingMode = NPC_TRACKING_PLAYER_AUTO_TURN; } if (this->actionFunc == func_80A7A568) { - phi_a3 = 4; + npcTrackingMode = NPC_TRACKING_FULL_BODY; } if (this->actionFunc == func_80A7B024) { - this->unk_308.unk_18 = play->view.eye; - this->unk_308.unk_14 = 60.0f; + this->interactInfo.trackPos = play->view.eye; + this->interactInfo.yOffset = 60.0f; } else { - this->unk_308.unk_18 = player->actor.world.pos; - this->unk_308.unk_14 = 16.0f; + this->interactInfo.trackPos = player->actor.world.pos; + this->interactInfo.yOffset = 16.0f; } - func_80034A14(&this->actor, &this->unk_308, 1, phi_a3); + Npc_TrackPoint(&this->actor, &this->interactInfo, 1, npcTrackingMode); } void func_80A79690(SkelAnime* skelAnime, EnIn* this, PlayState* play) { @@ -459,10 +459,10 @@ void func_80A79C78(EnIn* this, PlayState* play) { sp3C.z = sp48.z + 40.0f; Play_CameraSetAtEye(play, this->camId, &sp48, &sp3C); this->actor.shape.rot.y = Math_Vec3f_Yaw(&this->actor.world.pos, &sp3C); - this->unk_308.unk_08 = zeroVec; - this->unk_308.unk_0E = zeroVec; + this->interactInfo.headRot = zeroVec; + this->interactInfo.torsoRot = zeroVec; Message_StartTextbox(play, 0x2025, NULL); - this->unk_308.unk_00 = 1; + this->interactInfo.talkState = NPC_TALK_STATE_TALKING; player->actor.world.pos = this->actor.world.pos; player->actor.world.pos.x += 100.0f * Math_SinS(this->actor.shape.rot.y); player->actor.world.pos.z += 100.0f * Math_CosS(this->actor.shape.rot.y); @@ -521,7 +521,7 @@ void func_80A79FB0(EnIn* this, PlayState* play) { } Actor_SetScale(&this->actor, 0.01f); this->actor.targetMode = 6; - this->unk_308.unk_00 = 0; + this->interactInfo.talkState = NPC_TALK_STATE_IDLE; this->actionFunc = func_80A7A4BC; switch (func_80A79830(this, play)) { @@ -638,7 +638,7 @@ void func_80A7A4BC(EnIn* this, PlayState* play) { } void func_80A7A4C8(EnIn* this, PlayState* play) { - if (this->unk_308.unk_00 == 2) { + if (this->interactInfo.talkState == NPC_TALK_STATE_ACTION) { func_80A79BAC(this, play, 1, 0x20); gSaveContext.eventInf[0] = (gSaveContext.eventInf[0] & ~0x000F) | 0x0001; gSaveContext.eventInf[0] = (gSaveContext.eventInf[0] & ~0x8000) | 0x8000; @@ -646,7 +646,7 @@ void func_80A7A4C8(EnIn* this, PlayState* play) { Environment_ForcePlaySequence(NA_BGM_HORSE); play->msgCtx.stateTimer = 0; play->msgCtx.msgMode = MSGMODE_TEXT_CLOSING; - this->unk_308.unk_00 = 0; + this->interactInfo.talkState = NPC_TALK_STATE_IDLE; } } @@ -663,12 +663,12 @@ void func_80A7A568(EnIn* this, PlayState* play) { func_80A79C78(this, play); this->actionFunc = func_80A7B024; gSaveContext.timer1State = 0; - } else if (this->unk_308.unk_00 == 2) { + } else if (this->interactInfo.talkState == NPC_TALK_STATE_ACTION) { if (play->msgCtx.choiceIndex == 0) { if (gSaveContext.rupees < 50) { play->msgCtx.stateTimer = 4; play->msgCtx.msgMode = MSGMODE_TEXT_CLOSING; - this->unk_308.unk_00 = 0; + this->interactInfo.talkState = NPC_TALK_STATE_IDLE; return; } gSaveContext.eventInf[0] = @@ -692,20 +692,20 @@ void func_80A7A568(EnIn* this, PlayState* play) { play->msgCtx.stateTimer = 0; gSaveContext.eventInf[0] = (gSaveContext.eventInf[0] & ~0x8000) | 0x8000; play->msgCtx.msgMode = MSGMODE_TEXT_CLOSING; - this->unk_308.unk_00 = 0; + this->interactInfo.talkState = NPC_TALK_STATE_IDLE; } } void func_80A7A770(EnIn* this, PlayState* play) { - if (this->unk_308.unk_00 == 0) { + if (this->interactInfo.talkState == NPC_TALK_STATE_IDLE) { this->actor.flags |= ACTOR_FLAG_16; - } else if (this->unk_308.unk_00 == 2) { + } else if (this->interactInfo.talkState == NPC_TALK_STATE_ACTION) { Rupees_ChangeBy(-50); this->actor.flags &= ~ACTOR_FLAG_16; EnIn_ChangeAnim(this, ENIN_ANIM_3); this->actionFunc = func_80A7A848; gSaveContext.eventInf[0] = (gSaveContext.eventInf[0] & ~0x0F) | 7; - this->unk_308.unk_00 = 0; + this->interactInfo.talkState = NPC_TALK_STATE_IDLE; gSaveContext.eventInf[0] = (gSaveContext.eventInf[0] & 0xFFFF) | 0x20; if (!(gSaveContext.eventInf[0] & 0x40)) { play->msgCtx.stateTimer = 4; @@ -715,7 +715,7 @@ void func_80A7A770(EnIn* this, PlayState* play) { } void func_80A7A848(EnIn* this, PlayState* play) { - if (this->unk_308.unk_00 == 2) { + if (this->interactInfo.talkState == NPC_TALK_STATE_ACTION) { if ((play->msgCtx.choiceIndex == 0 && gSaveContext.rupees < 50) || play->msgCtx.choiceIndex == 1) { gSaveContext.eventInf[0] &= ~0xF; this->actionFunc = func_80A7A4C8; @@ -726,14 +726,14 @@ void func_80A7A848(EnIn* this, PlayState* play) { play->msgCtx.stateTimer = 0; play->msgCtx.msgMode = MSGMODE_TEXT_CLOSING; } - this->unk_308.unk_00 = 0; + this->interactInfo.talkState = NPC_TALK_STATE_IDLE; gSaveContext.eventInf[0] &= ~0x20; gSaveContext.eventInf[0] &= ~0x40; } } void func_80A7A940(EnIn* this, PlayState* play) { - if (this->unk_308.unk_00 == 0) { + if (this->interactInfo.talkState == NPC_TALK_STATE_IDLE) { this->actor.flags |= ACTOR_FLAG_16; return; } @@ -743,14 +743,14 @@ void func_80A7A940(EnIn* this, PlayState* play) { Audio_PlayActorSound2(&this->actor, NA_SE_VO_IN_LOST); } } - if (this->unk_308.unk_00 == 2) { + if (this->interactInfo.talkState == NPC_TALK_STATE_ACTION) { this->actor.flags &= ~ACTOR_FLAG_16; func_80A79BAC(this, play, 2, 0x26); gSaveContext.eventInf[0] = (gSaveContext.eventInf[0] & ~0x000F) | 0x0002; gSaveContext.eventInf[0] = (gSaveContext.eventInf[0] & ~0x8000) | 0x8000; play->msgCtx.stateTimer = 0; play->msgCtx.msgMode = MSGMODE_TEXT_CLOSING; - this->unk_308.unk_00 = 0; + this->interactInfo.talkState = NPC_TALK_STATE_IDLE; gSaveContext.eventInf[0] = (gSaveContext.eventInf[0] & 0xFFFF) | 0x40; } } @@ -786,7 +786,7 @@ void func_80A7AA40(EnIn* this, PlayState* play) { Play_CameraSetAtEye(play, this->camId, &sp30, &sp24); this->actor.textId = 0x203B; Message_StartTextbox(play, this->actor.textId, NULL); - this->unk_308.unk_00 = 1; + this->interactInfo.talkState = NPC_TALK_STATE_TALKING; this->unk_1FC = 0; play->csCtx.frames = 0; ShrinkWindow_SetVal(0x20); @@ -811,16 +811,16 @@ void func_80A7ABD4(EnIn* this, PlayState* play) { } } } - if (this->unk_308.unk_00 != 0) { - if (this->unk_308.unk_00 == 2) { + if (this->interactInfo.talkState != NPC_TALK_STATE_IDLE) { + if (this->interactInfo.talkState == NPC_TALK_STATE_ACTION) { if (this->actor.textId == 0x203B) { this->actor.textId = 0x203C; Message_StartTextbox(play, this->actor.textId, NULL); - this->unk_308.unk_00 = 1; + this->interactInfo.talkState = NPC_TALK_STATE_TALKING; EnIn_ChangeAnim(this, ENIN_ANIM_3); } else { play->msgCtx.msgMode = MSGMODE_TEXT_CLOSING; - this->unk_308.unk_00 = 0; + this->interactInfo.talkState = NPC_TALK_STATE_IDLE; } } } else { @@ -872,10 +872,10 @@ void func_80A7AEF0(EnIn* this, PlayState* play) { play->sceneLoadFlag = 0x14; play->fadeTransition = 5; this->actionFunc = func_80A7B018; - } else if (this->unk_308.unk_00 == 2) { + } else if (this->interactInfo.talkState == NPC_TALK_STATE_ACTION) { play->msgCtx.stateTimer = 4; play->msgCtx.msgMode = MSGMODE_TEXT_CLOSING; - this->unk_308.unk_00 = 0; + this->interactInfo.talkState = NPC_TALK_STATE_IDLE; } } @@ -889,7 +889,7 @@ void func_80A7B024(EnIn* this, PlayState* play) { player->rideActor->freezeTimer = 10; } player->actor.freezeTimer = 10; - if (this->unk_308.unk_00 == 2) { + if (this->interactInfo.talkState == NPC_TALK_STATE_ACTION) { if (!(gSaveContext.eventChkInf[1] & 0x800) && (gSaveContext.infTable[10] & 0x800)) { gSaveContext.eventChkInf[1] |= 0x800; gSaveContext.infTable[10] |= 0x800; @@ -899,7 +899,7 @@ void func_80A7B024(EnIn* this, PlayState* play) { gSaveContext.eventInf[0] = (gSaveContext.eventInf[0] & ~0x8000) | 0x8000; play->msgCtx.stateTimer = 4; play->msgCtx.msgMode = MSGMODE_TEXT_CLOSING; - this->unk_308.unk_00 = 0; + this->interactInfo.talkState = NPC_TALK_STATE_IDLE; } } @@ -925,13 +925,13 @@ void EnIn_Update(Actor* thisx, PlayState* play) { this->actionFunc(this, play); if (this->actionFunc != func_80A7A304) { func_80A79AB4(this, play); - if (gSaveContext.timer2Value < 6 && gSaveContext.timer2State != 0 && this->unk_308.unk_00 == 0) { + if (gSaveContext.timer2Value < 6 && gSaveContext.timer2State != 0 && this->interactInfo.talkState == NPC_TALK_STATE_IDLE) { if (Actor_ProcessTalkRequest(&this->actor, play)) {} } else { - func_800343CC(play, &this->actor, &this->unk_308.unk_00, + Npc_UpdateTalking(play, &this->actor, &this->interactInfo.talkState, ((this->actor.targetMode == 6) ? 80.0f : 320.0f) + this->collider.dim.radius, func_80A79168, func_80A79500); - if (this->unk_308.unk_00 != 0) { + if (this->interactInfo.talkState != NPC_TALK_STATE_IDLE) { this->unk_1FA = this->unk_1F8; this->unk_1F8 = Message_GetState(&play->msgCtx); } @@ -951,13 +951,13 @@ s32 EnIn_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* po } if (limbIndex == INGO_HEAD_LIMB) { Matrix_Translate(1500.0f, 0.0f, 0.0f, MTXMODE_APPLY); - sp2C = this->unk_308.unk_08; + sp2C = this->interactInfo.headRot; Matrix_RotateZ(BINANG_TO_RAD(sp2C.x), MTXMODE_APPLY); Matrix_RotateX(BINANG_TO_RAD(sp2C.y), MTXMODE_APPLY); Matrix_Translate(-1500.0f, 0.0f, 0.0f, MTXMODE_APPLY); } if (limbIndex == INGO_CHEST_LIMB) { - sp2C = this->unk_308.unk_0E; + sp2C = this->interactInfo.torsoRot; Matrix_RotateX(BINANG_TO_RAD(sp2C.x), MTXMODE_APPLY); Matrix_RotateY(BINANG_TO_RAD(sp2C.y), MTXMODE_APPLY); } diff --git a/soh/src/overlays/actors/ovl_En_In/z_en_in.h b/soh/src/overlays/actors/ovl_En_In/z_en_in.h index 6494f875d9a..e926a00eefb 100644 --- a/soh/src/overlays/actors/ovl_En_In/z_en_in.h +++ b/soh/src/overlays/actors/ovl_En_In/z_en_in.h @@ -58,7 +58,7 @@ typedef struct EnIn { /* 0x02FC */ f32 unk_2FC; /* 0x0300 */ f32 unk_300; /* 0x0304 */ f32 unk_304; - /* 0x0308 */ struct_80034A14_arg1 unk_308; + /* 0x0308 */ NpcInteractInfo interactInfo; /* 0x0330 */ Vec3s unk_330[INGO_LIMB_MAX]; } EnIn; // size = 0x03A8 diff --git a/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c b/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c index 5f5d146fb72..5c8a4167159 100644 --- a/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c +++ b/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c @@ -533,9 +533,9 @@ s16 func_80A97738(PlayState* play, Actor* thisx) { gSaveContext.infTable[11] |= 0x80; break; case 0x10BA: - return 1; + return NPC_TALK_STATE_TALKING; } - return 0; + return NPC_TALK_STATE_IDLE; case TEXT_STATE_DONE_FADING: switch (this->actor.textId) { case 0x10B7: @@ -546,7 +546,7 @@ s16 func_80A97738(PlayState* play, Actor* thisx) { this->unk_210 = 1; } } - return 1; + return NPC_TALK_STATE_TALKING; case TEXT_STATE_CHOICE: if (Message_ShouldAdvance(play)) { switch (this->actor.textId) { @@ -569,17 +569,17 @@ s16 func_80A97738(PlayState* play, Actor* thisx) { case 0x10B8: this->actor.textId = (play->msgCtx.choiceIndex == 0) ? 0x10BA : 0x10B9; - return (play->msgCtx.choiceIndex == 0) ? 2 : 1; + return (play->msgCtx.choiceIndex == 0) ? NPC_TALK_STATE_ACTION : NPC_TALK_STATE_TALKING; } - return 1; + return NPC_TALK_STATE_TALKING; } break; case TEXT_STATE_DONE: if (Message_ShouldAdvance(play)) { - return 3; + return NPC_TALK_STATE_ITEM_GIVEN; } } - return 1; + return NPC_TALK_STATE_TALKING; } s32 EnKo_GetForestQuestState(EnKo* this) { @@ -664,108 +664,108 @@ s32 EnKo_IsWithinTalkAngle(EnKo* this) { } s32 func_80A97D68(EnKo* this, PlayState* play) { - s16 arg3; + s16 trackingMode; - if (this->unk_1E8.unk_00 != 0) { + if (this->interactInfo.talkState != NPC_TALK_STATE_IDLE) { if ((this->skelAnime.animation == &gObjOsAnim_6A60) == false) { Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENKO_ANIM_32); } - arg3 = 2; + trackingMode = NPC_TRACKING_HEAD_AND_TORSO; } else { if ((this->skelAnime.animation == &gObjOsAnim_7830) == false) { Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENKO_ANIM_33); } - arg3 = 1; + trackingMode = NPC_TRACKING_NONE; } - func_80034A14(&this->actor, &this->unk_1E8, 2, arg3); + Npc_TrackPoint(&this->actor, &this->interactInfo, 2, trackingMode); return EnKo_IsWithinTalkAngle(this); } s32 func_80A97E18(EnKo* this, PlayState* play) { - s16 arg3; + s16 trackingMode; func_80034F54(play, this->unk_2E4, this->unk_304, 16); if (EnKo_IsWithinTalkAngle(this) == true) { - arg3 = 2; + trackingMode = NPC_TRACKING_HEAD_AND_TORSO; } else { - arg3 = 1; + trackingMode = NPC_TRACKING_NONE; } - if (this->unk_1E8.unk_00 != 0) { - arg3 = 4; + if (this->interactInfo.talkState != NPC_TALK_STATE_IDLE) { + trackingMode = NPC_TRACKING_FULL_BODY; } else if (this->lookDist < this->actor.xzDistToPlayer) { - arg3 = 1; + trackingMode = NPC_TRACKING_NONE; } - func_80034A14(&this->actor, &this->unk_1E8, 2, arg3); + Npc_TrackPoint(&this->actor, &this->interactInfo, 2, trackingMode); return 1; } s32 func_80A97EB0(EnKo* this, PlayState* play) { - s16 arg3; + s16 trackingMode; s32 result; func_80034F54(play, this->unk_2E4, this->unk_304, 16); result = EnKo_IsWithinTalkAngle(this); - arg3 = (result == true) ? 2 : 1; - func_80034A14(&this->actor, &this->unk_1E8, 2, arg3); + trackingMode = (result == true) ? NPC_TRACKING_HEAD_AND_TORSO : NPC_TRACKING_NONE; + Npc_TrackPoint(&this->actor, &this->interactInfo, 2, trackingMode); return result; } s32 func_80A97F20(EnKo* this, PlayState* play) { func_80034F54(play, this->unk_2E4, this->unk_304, 16); - func_80034A14(&this->actor, &this->unk_1E8, 2, 4); + Npc_TrackPoint(&this->actor, &this->interactInfo, 2, NPC_TRACKING_FULL_BODY); return 1; } s32 func_80A97F70(EnKo* this, PlayState* play) { - s16 arg3; + s16 trackingMode; - if (this->unk_1E8.unk_00 != 0) { + if (this->interactInfo.talkState != NPC_TALK_STATE_IDLE) { if ((this->skelAnime.animation == &gObjOsAnim_8F6C) == false) { Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENKO_ANIM_29); } func_80034F54(play, this->unk_2E4, this->unk_304, 16); - arg3 = 2; + trackingMode = NPC_TRACKING_HEAD_AND_TORSO; } else { if ((this->skelAnime.animation == &gObjOsAnim_7D94) == false) { Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENKO_ANIM_30); } - arg3 = 1; + trackingMode = NPC_TRACKING_NONE; } - func_80034A14(&this->actor, &this->unk_1E8, 5, arg3); + Npc_TrackPoint(&this->actor, &this->interactInfo, 5, trackingMode); return EnKo_IsWithinTalkAngle(this); } s32 func_80A98034(EnKo* this, PlayState* play) { - s16 arg3; + s16 trackingMode; s32 result; - if (this->unk_1E8.unk_00 != 0) { + if (this->interactInfo.talkState != NPC_TALK_STATE_IDLE) { if ((this->skelAnime.animation == &gObjOsAnim_8F6C) == false) { Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENKO_ANIM_29); } func_80034F54(play, this->unk_2E4, this->unk_304, 16); result = EnKo_IsWithinTalkAngle(this); - arg3 = (result == true) ? 2 : 1; + trackingMode = (result == true) ? NPC_TRACKING_HEAD_AND_TORSO : NPC_TRACKING_NONE; } else { if ((this->skelAnime.animation == &gObjOsAnim_879C) == false) { Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENKO_ANIM_31); } - arg3 = 1; + trackingMode = NPC_TRACKING_NONE; result = EnKo_IsWithinTalkAngle(this); } - func_80034A14(&this->actor, &this->unk_1E8, 5, arg3); + Npc_TrackPoint(&this->actor, &this->interactInfo, 5, trackingMode); return result; } // Same as func_80A97F20 s32 func_80A98124(EnKo* this, PlayState* play) { func_80034F54(play, this->unk_2E4, this->unk_304, 16); - func_80034A14(&this->actor, &this->unk_1E8, 2, 4); + Npc_TrackPoint(&this->actor, &this->interactInfo, 2, NPC_TRACKING_FULL_BODY); return 1; } s32 func_80A98174(EnKo* this, PlayState* play) { - if (this->unk_1E8.unk_00 != 0) { + if (this->interactInfo.talkState != NPC_TALK_STATE_IDLE) { if (Animation_OnFrame(&this->skelAnime, 18.0f)) { this->skelAnime.playSpeed = 0.0f; } @@ -775,7 +775,8 @@ s32 func_80A98174(EnKo* this, PlayState* play) { if (this->skelAnime.playSpeed == 0.0f) { func_80034F54(play, this->unk_2E4, this->unk_304, 16); } - func_80034A14(&this->actor, &this->unk_1E8, 2, (this->skelAnime.playSpeed == 0.0f) ? 2 : 1); + Npc_TrackPoint(&this->actor, &this->interactInfo, 2, + (this->skelAnime.playSpeed == 0.0f) ? NPC_TRACKING_HEAD_AND_TORSO : NPC_TRACKING_NONE); return EnKo_IsWithinTalkAngle(this); } @@ -937,19 +938,19 @@ void func_80A9877C(EnKo* this, PlayState* play) { Player* player = GET_PLAYER(play); if ((play->csCtx.state != 0) || (gDbgCamEnabled != 0)) { - this->unk_1E8.unk_18 = play->view.eye; - this->unk_1E8.unk_14 = 40.0f; + this->interactInfo.trackPos = play->view.eye; + this->interactInfo.yOffset = 40.0f; if (ENKO_TYPE != ENKO_TYPE_CHILD_0) { - func_80034A14(&this->actor, &this->unk_1E8, 2, 2); + Npc_TrackPoint(&this->actor, &this->interactInfo, 2, NPC_TRACKING_HEAD_AND_TORSO); } } else { - this->unk_1E8.unk_18 = player->actor.world.pos; - this->unk_1E8.unk_14 = func_80A97BC0(this); - if ((func_80A98ECC(this, play) == 0) && (this->unk_1E8.unk_00 == 0)) { + this->interactInfo.trackPos = player->actor.world.pos; + this->interactInfo.yOffset = func_80A97BC0(this); + if ((func_80A98ECC(this, play) == 0) && (this->interactInfo.talkState == NPC_TALK_STATE_IDLE)) { return; } } - if (func_800343CC(play, &this->actor, &this->unk_1E8.unk_00, this->lookDist, func_80A97610, func_80A97738) && + if (Npc_UpdateTalking(play, &this->actor, &this->interactInfo.talkState, this->lookDist, func_80A97610, func_80A97738) && ENKO_TYPE == ENKO_TYPE_CHILD_FADO && play->sceneNum == SCENE_SPOT10) { this->actor.textId = INV_CONTENT(ITEM_TRADE_ADULT) > ITEM_ODD_POTION ? 0x10B9 : 0x10DF; @@ -1203,10 +1204,11 @@ void func_80A99048(EnKo* this, PlayState* play) { } void func_80A99384(EnKo* this, PlayState* play) { - if (ENKO_TYPE == ENKO_TYPE_CHILD_FADO && this->unk_1E8.unk_00 != 0 && this->actor.textId == 0x10B9) { + if (ENKO_TYPE == ENKO_TYPE_CHILD_FADO && this->interactInfo.talkState != NPC_TALK_STATE_IDLE && + this->actor.textId == 0x10B9) { Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENKO_ANIM_7); this->actionFunc = func_80A99438; - } else if (ENKO_TYPE == ENKO_TYPE_CHILD_FADO && this->unk_1E8.unk_00 == 2) { + } else if (ENKO_TYPE == ENKO_TYPE_CHILD_FADO && this->interactInfo.talkState == NPC_TALK_STATE_ACTION) { this->actionFunc = func_80A99504; play->msgCtx.stateTimer = 4; play->msgCtx.msgMode = MSGMODE_TEXT_CLOSING; @@ -1214,12 +1216,12 @@ void func_80A99384(EnKo* this, PlayState* play) { } void func_80A99438(EnKo* this, PlayState* play) { - if (ENKO_TYPE == ENKO_TYPE_CHILD_FADO && this->unk_1E8.unk_00 == 2) { + if (ENKO_TYPE == ENKO_TYPE_CHILD_FADO && this->interactInfo.talkState == NPC_TALK_STATE_ACTION) { Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENKO_ANIM_6); this->actionFunc = func_80A99504; play->msgCtx.stateTimer = 4; play->msgCtx.msgMode = MSGMODE_TEXT_CLOSING; - } else if (this->unk_1E8.unk_00 == 0 || this->actor.textId != 0x10B9) { + } else if (this->interactInfo.talkState == NPC_TALK_STATE_IDLE || this->actor.textId != 0x10B9) { Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENKO_ANIM_6); this->actionFunc = func_80A99384; } @@ -1242,10 +1244,10 @@ void func_80A99504(EnKo* this, PlayState* play) { } void func_80A99560(EnKo* this, PlayState* play) { - if (this->unk_1E8.unk_00 == 3) { + if (this->interactInfo.talkState == NPC_TALK_STATE_ITEM_GIVEN) { this->actor.textId = 0x10B9; Message_ContinueTextbox(play, this->actor.textId); - this->unk_1E8.unk_00 = 1; + this->interactInfo.talkState = NPC_TALK_STATE_TALKING; gSaveContext.itemGetInf[3] |= 2; this->actionFunc = func_80A99384; } @@ -1263,7 +1265,7 @@ void func_80A995CC(EnKo* this, PlayState* play) { this->actor.world.pos.z += 80.0f * Math_CosS(homeYawToPlayer); this->actor.shape.rot.y = this->actor.world.rot.y = this->actor.yawTowardsPlayer; - if (this->unk_1E8.unk_00 == 0 || !this->actor.isTargeted) { + if (this->interactInfo.talkState == NPC_TALK_STATE_IDLE || !this->actor.isTargeted) { temp_f2 = fabsf((f32)this->actor.yawTowardsPlayer - homeYawToPlayer) * 0.001f * 3.0f; if (temp_f2 < 1.0f) { this->skelAnime.playSpeed = 1.0f; @@ -1291,7 +1293,7 @@ void EnKo_Update(Actor* thisx, PlayState* play) { func_80A98DB4(this, play); } } - if (this->unk_1E8.unk_00 == 0) { + if (this->interactInfo.talkState == NPC_TALK_STATE_IDLE) { Actor_MoveForward(&this->actor); } if (func_80A97C7C(this)) { @@ -1330,13 +1332,13 @@ s32 EnKo_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* po gSegments[6] = VIRTUAL_TO_PHYSICAL(play->objectCtx.status[this->legsObjectBankIdx].segment); } if (limbIndex == 8) { - sp40 = this->unk_1E8.unk_0E; + sp40 = this->interactInfo.torsoRot; Matrix_RotateX(BINANG_TO_RAD(-sp40.y), MTXMODE_APPLY); Matrix_RotateZ(BINANG_TO_RAD(sp40.x), MTXMODE_APPLY); } if (limbIndex == 15) { Matrix_Translate(1200.0f, 0.0f, 0.0f, MTXMODE_APPLY); - sp40 = this->unk_1E8.unk_08; + sp40 = this->interactInfo.headRot; Matrix_RotateX(BINANG_TO_RAD(sp40.y), MTXMODE_APPLY); Matrix_RotateZ(BINANG_TO_RAD(sp40.x), MTXMODE_APPLY); Matrix_Translate(-1200.0f, 0.0f, 0.0f, MTXMODE_APPLY); diff --git a/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.h b/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.h index 5f029a9f68a..c247f53b995 100644 --- a/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.h +++ b/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.h @@ -18,7 +18,7 @@ typedef struct EnKo { /* 0x0197 */ s8 osAnimeBankIndex; /* 0x0198 */ ColliderCylinder collider; /* 0x01E4 */ Path* path; - /* 0x01E8 */ struct_80034A14_arg1 unk_1E8; + /* 0x01E8 */ NpcInteractInfo interactInfo; /* 0x0210 */ u8 unk_210; // block trade quest sfx /* 0x0212 */ s16 forestQuestState; /* 0x0214 */ s16 blinkTimer; diff --git a/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c b/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c index d44e52569a5..c9f3f6112b6 100644 --- a/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c +++ b/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c @@ -125,18 +125,18 @@ u16 EnKz_GetText(PlayState* play, Actor* thisx) { s16 func_80A9C6C0(PlayState* play, Actor* thisx) { EnKz* this = (EnKz*)thisx; - s16 ret = 1; + s16 ret = NPC_TALK_STATE_TALKING; switch (Message_GetState(&play->msgCtx)) { case TEXT_STATE_DONE: - ret = 0; + ret = NPC_TALK_STATE_IDLE; switch (this->actor.textId) { case 0x4012: gSaveContext.infTable[19] |= 0x200; - ret = 2; + ret = NPC_TALK_STATE_ACTION; break; case 0x401B: - ret = !Message_ShouldAdvance(play) ? 1 : 2; + ret = !Message_ShouldAdvance(play) ? NPC_TALK_STATE_TALKING : NPC_TALK_STATE_ACTION; break; case 0x401F: gSaveContext.infTable[19] |= 0x200; @@ -162,7 +162,7 @@ s16 func_80A9C6C0(PlayState* play, Actor* thisx) { if (this->actor.textId == 0x4014) { if (play->msgCtx.choiceIndex == 0) { EnKz_SetupGetItem(this, play); - ret = 2; + ret = NPC_TALK_STATE_ACTION; } else { this->actor.textId = 0x4016; Message_ContinueTextbox(play, this->actor.textId); @@ -171,7 +171,7 @@ s16 func_80A9C6C0(PlayState* play, Actor* thisx) { break; case TEXT_STATE_EVENT: if (Message_ShouldAdvance(play)) { - ret = 2; + ret = NPC_TALK_STATE_ACTION; } break; case TEXT_STATE_NONE: @@ -195,8 +195,8 @@ void EnKz_UpdateEyes(EnKz* this) { } } -s32 func_80A9C95C(PlayState* play, EnKz* this, s16* arg2, f32 unkf, callback1_800343CC callback1, - callback2_800343CC callback2) { +s32 func_80A9C95C(PlayState* play, EnKz* this, s16* talkState, f32 unkf, NpcGetTextIdFunc getTextId, + NpcUpdateTalkStateFunc updateTalkState) { Player* player = GET_PLAYER(play); s16 sp32; s16 sp30; @@ -204,12 +204,12 @@ s32 func_80A9C95C(PlayState* play, EnKz* this, s16* arg2, f32 unkf, callback1_80 f32 yaw; if (Actor_ProcessTalkRequest(&this->actor, play)) { - *arg2 = 1; + *talkState = NPC_TALK_STATE_TALKING; return 1; } - if (*arg2 != 0) { - *arg2 = callback2(play, &this->actor); + if (*talkState != NPC_TALK_STATE_IDLE) { + *talkState = updateTalkState(play, &this->actor); return 0; } @@ -234,7 +234,7 @@ s32 func_80A9C95C(PlayState* play, EnKz* this, s16* arg2, f32 unkf, callback1_80 return 0; } this->actor.xzDistToPlayer = xzDistToPlayer; - this->actor.textId = callback1(play, &this->actor); + this->actor.textId = getTextId(play, &this->actor); return 0; } @@ -242,7 +242,7 @@ s32 func_80A9C95C(PlayState* play, EnKz* this, s16* arg2, f32 unkf, callback1_80 void func_80A9CB18(EnKz* this, PlayState* play) { Player* player = GET_PLAYER(play); - if (func_80A9C95C(play, this, &this->unk_1E0.unk_00, 340.0f, EnKz_GetText, func_80A9C6C0)) { + if (func_80A9C95C(play, this, &this->interactInfo.talkState, 340.0f, EnKz_GetText, func_80A9C6C0)) { if (((gSaveContext.n64ddFlag && LINK_IS_CHILD) || this->actor.textId == 0x401A) && !(gSaveContext.eventChkInf[3] & 8)) { if (func_8002F368(play) == EXCH_ITEM_LETTER_RUTO) { this->actor.textId = 0x401B; @@ -341,7 +341,7 @@ void EnKz_Init(Actor* thisx, PlayState* play) { CollisionCheck_SetInfo2(&this->actor.colChkInfo, NULL, &sColChkInfoInit); Actor_SetScale(&this->actor, 0.01); this->actor.targetMode = 3; - this->unk_1E0.unk_00 = 0; + this->interactInfo.talkState = NPC_TALK_STATE_IDLE; Animation_ChangeByInfo(&this->skelanime, sAnimationInfo, ENKZ_ANIM_0); if (!gSaveContext.n64ddFlag) { @@ -388,9 +388,9 @@ void EnKz_Destroy(Actor* thisx, PlayState* play) { } void EnKz_PreMweepWait(EnKz* this, PlayState* play) { - if (this->unk_1E0.unk_00 == 2) { + if (this->interactInfo.talkState == NPC_TALK_STATE_ACTION) { Animation_ChangeByInfo(&this->skelanime, sAnimationInfo, ENKZ_ANIM_2); - this->unk_1E0.unk_00 = 0; + this->interactInfo.talkState = NPC_TALK_STATE_IDLE; this->actionFunc = EnKz_SetupMweep; } else { func_80034F54(play, this->unk_2A6, this->unk_2BE, 12); @@ -449,7 +449,7 @@ void EnKz_StopMweep(EnKz* this, PlayState* play) { } void EnKz_Wait(EnKz* this, PlayState* play) { - if (this->unk_1E0.unk_00 == 2) { + if (this->interactInfo.talkState == NPC_TALK_STATE_ACTION) { this->actionFunc = EnKz_SetupGetItem; EnKz_SetupGetItem(this, play); } else { @@ -465,7 +465,7 @@ void EnKz_SetupGetItem(EnKz* this, PlayState* play) { if (Actor_HasParent(&this->actor, play)) { this->actor.parent = NULL; - this->unk_1E0.unk_00 = 1; + this->interactInfo.talkState = NPC_TALK_STATE_TALKING; this->actionFunc = EnKz_StartTimer; } else { if (gSaveContext.n64ddFlag) { @@ -497,7 +497,7 @@ void EnKz_StartTimer(EnKz* this, PlayState* play) { func_80088AA0(180); // start timer2 with 3 minutes gSaveContext.eventInf[1] &= ~1; } - this->unk_1E0.unk_00 = 0; + this->interactInfo.talkState = NPC_TALK_STATE_IDLE; this->actionFunc = EnKz_Wait; } } diff --git a/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.h b/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.h index 0c7eda2f861..37feb841a8d 100644 --- a/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.h +++ b/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.h @@ -13,7 +13,7 @@ typedef struct EnKz { /* 0x014C */ SkelAnime skelanime; /* 0x0190 */ EnKzActionFunc actionFunc; /* 0x0194 */ ColliderCylinder collider; - /* 0x01E0 */ struct_80034A14_arg1 unk_1E0; + /* 0x01E0 */ NpcInteractInfo interactInfo; /* 0x0208 */ u8 sfxPlayed; /* 0x0209 */ u8 isTrading; /* 0x020A */ s16 waypoint; diff --git a/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c b/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c index 02a68cd1adc..cbf7c2bc445 100644 --- a/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c +++ b/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c @@ -137,7 +137,7 @@ u16 EnMa1_GetText(PlayState* play, Actor* thisx) { } s16 func_80AA0778(PlayState* play, Actor* thisx) { - s16 ret = 1; + s16 ret = NPC_TALK_STATE_TALKING; switch (Message_GetState(&play->msgCtx)) { case TEXT_STATE_CLOSING: @@ -145,40 +145,40 @@ s16 func_80AA0778(PlayState* play, Actor* thisx) { case 0x2041: gSaveContext.infTable[8] |= 0x10; gSaveContext.eventChkInf[1] |= 1; - ret = 0; + ret = NPC_TALK_STATE_IDLE; break; case 0x2043: - ret = 1; + ret = NPC_TALK_STATE_TALKING; break; case 0x2047: gSaveContext.eventChkInf[1] |= 0x20; - ret = 0; + ret = NPC_TALK_STATE_IDLE; break; case 0x2048: gSaveContext.infTable[8] |= 0x20; - ret = 0; + ret = NPC_TALK_STATE_IDLE; break; case 0x2049: gSaveContext.eventChkInf[1] |= 0x40; - ret = 0; + ret = NPC_TALK_STATE_IDLE; break; case 0x2061: - ret = 2; + ret = NPC_TALK_STATE_ACTION; break; default: - ret = 0; + ret = NPC_TALK_STATE_IDLE; break; } break; case TEXT_STATE_CHOICE: case TEXT_STATE_EVENT: if (Message_ShouldAdvance(play)) { - ret = 2; + ret = NPC_TALK_STATE_ACTION; } break; case TEXT_STATE_DONE: if (Message_ShouldAdvance(play)) { - ret = 3; + ret = NPC_TALK_STATE_ITEM_GIVEN; } break; case TEXT_STATE_NONE: @@ -187,7 +187,7 @@ s16 func_80AA0778(PlayState* play, Actor* thisx) { case TEXT_STATE_SONG_DEMO_DONE: case TEXT_STATE_8: case TEXT_STATE_9: - ret = 1; + ret = NPC_TALK_STATE_TALKING; break; } return ret; @@ -252,23 +252,23 @@ void EnMa1_ChangeAnim(EnMa1* this, s32 index) { void func_80AA0AF4(EnMa1* this, PlayState* play) { Player* player = GET_PLAYER(play); - s16 phi_a3; + s16 trackingMode; - if ((this->unk_1E8.unk_00 == 0) && (this->skelAnime.animation == &gMalonChildSingAnim)) { - phi_a3 = 1; + if ((this->interactInfo.talkState == NPC_TALK_STATE_IDLE) && (this->skelAnime.animation == &gMalonChildSingAnim)) { + trackingMode = NPC_TRACKING_NONE; } else { - phi_a3 = 0; + trackingMode = NPC_TRACKING_PLAYER_AUTO_TURN; } - this->unk_1E8.unk_18 = player->actor.world.pos; - this->unk_1E8.unk_18.y -= -10.0f; + this->interactInfo.trackPos = player->actor.world.pos; + this->interactInfo.trackPos.y -= -10.0f; - func_80034A14(&this->actor, &this->unk_1E8, 0, phi_a3); + Npc_TrackPoint(&this->actor, &this->interactInfo, 0, trackingMode); } void func_80AA0B74(EnMa1* this) { if (this->skelAnime.animation == &gMalonChildSingAnim) { - if (this->unk_1E8.unk_00 == 0) { + if (this->interactInfo.talkState == NPC_TALK_STATE_IDLE) { if (this->unk_1E0 != 0) { this->unk_1E0 = 0; func_800F6584(0); @@ -306,7 +306,7 @@ void EnMa1_Init(Actor* thisx, PlayState* play) { Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 0.0f, 0.0f, 4); Actor_SetScale(&this->actor, 0.01f); this->actor.targetMode = 6; - this->unk_1E8.unk_00 = 0; + this->interactInfo.talkState = NPC_TALK_STATE_IDLE; // To avoid missing a check, we want Malon to have the actionFunc for singing, but not reacting to Ocarina, if any of // the following are true. @@ -336,7 +336,7 @@ void EnMa1_Destroy(Actor* thisx, PlayState* play) { } void func_80AA0D88(EnMa1* this, PlayState* play) { - if (this->unk_1E8.unk_00 != 0) { + if (this->interactInfo.talkState != NPC_TALK_STATE_IDLE) { if (this->skelAnime.animation != &gMalonChildIdleAnim) { EnMa1_ChangeAnim(this, ENMA1_ANIM_1); } @@ -356,7 +356,7 @@ void func_80AA0D88(EnMa1* this, PlayState* play) { // 2. We haven't obtained Malon's Weird Egg Check (Randomizer only) OR // 3. We have Epona's Song? (Vanilla only, not sure why it's here but I didn't write that one) } else if ((!(gSaveContext.eventChkInf[1] & 0x10) || (gSaveContext.n64ddFlag && !Randomizer_ObtainedMalonHCReward())) || (CHECK_QUEST_ITEM(QUEST_SONG_EPONA) && !gSaveContext.n64ddFlag)) { - if (this->unk_1E8.unk_00 == 2) { + if (this->interactInfo.talkState == NPC_TALK_STATE_ACTION) { this->actionFunc = func_80AA0EA0; play->msgCtx.stateTimer = 4; play->msgCtx.msgMode = MSGMODE_TEXT_CLOSING; @@ -379,8 +379,8 @@ void func_80AA0EA0(EnMa1* this, PlayState* play) { } void func_80AA0EFC(EnMa1* this, PlayState* play) { - if (this->unk_1E8.unk_00 == 3) { - this->unk_1E8.unk_00 = 0; + if (this->interactInfo.talkState == NPC_TALK_STATE_ITEM_GIVEN) { + this->interactInfo.talkState = NPC_TALK_STATE_IDLE; this->actionFunc = func_80AA0D88; gSaveContext.eventChkInf[1] |= 4; play->msgCtx.msgMode = MSGMODE_TEXT_CLOSING; @@ -401,14 +401,14 @@ void GivePlayerRandoRewardMalon(EnMa1* malon, PlayState* play, RandomizerCheck c GiveItemEntryFromActor(&malon->actor, play, getItemEntry, 10000.0f, 100.0f); } // make malon sing again after giving the item. - malon->unk_1E8.unk_00 = 0; + malon->interactInfo.talkState = NPC_TALK_STATE_IDLE; malon->unk_1E0 = 1; } void func_80AA0F44(EnMa1* this, PlayState* play) { Player* player = GET_PLAYER(play); - if (this->unk_1E8.unk_00 != 0) { + if (this->interactInfo.talkState != NPC_TALK_STATE_IDLE) { if (this->skelAnime.animation != &gMalonChildIdleAnim) { EnMa1_ChangeAnim(this, ENMA1_ANIM_1); } @@ -425,7 +425,7 @@ void func_80AA0F44(EnMa1* this, PlayState* play) { player->unk_6A8 = &this->actor; this->actor.textId = 0x2061; Message_StartTextbox(play, this->actor.textId, NULL); - this->unk_1E8.unk_00 = 1; + this->interactInfo.talkState = NPC_TALK_STATE_TALKING; this->actor.flags |= ACTOR_FLAG_16; // when rando'ed, skip to the Item Giving. Otherwise go to the song teaching code. this->actionFunc = gSaveContext.n64ddFlag ? func_80AA1150 : func_80AA106C; @@ -445,7 +445,7 @@ void func_80AA0F44(EnMa1* this, PlayState* play) { void func_80AA106C(EnMa1* this, PlayState* play) { GET_PLAYER(play)->stateFlags2 |= 0x800000; - if (this->unk_1E8.unk_00 == 2) { + if (this->interactInfo.talkState == NPC_TALK_STATE_ACTION) { Audio_OcaSetInstrument(2); func_8010BD58(play, OCARINA_ACTION_TEACH_EPONA); this->actor.flags &= ~ACTOR_FLAG_16; @@ -519,8 +519,8 @@ void EnMa1_Update(Actor* thisx, PlayState* play) { EnMa1_UpdateEyes(this); this->actionFunc(this, play); if (this->actionFunc != EnMa1_DoNothing) { - func_800343CC(play, &this->actor, &this->unk_1E8.unk_00, (f32)this->collider.dim.radius + 30.0f, - EnMa1_GetText, func_80AA0778); + Npc_UpdateTalking(play, &this->actor, &this->interactInfo.talkState, (f32)this->collider.dim.radius + 30.0f, + EnMa1_GetText, func_80AA0778); } func_80AA0B74(this); func_80AA0AF4(this, play); @@ -535,13 +535,13 @@ s32 EnMa1_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* p } if (limbIndex == 15) { Matrix_Translate(1400.0f, 0.0f, 0.0f, MTXMODE_APPLY); - vec = this->unk_1E8.unk_08; + vec = this->interactInfo.headRot; Matrix_RotateX((vec.y / 32768.0f) * M_PI, MTXMODE_APPLY); Matrix_RotateZ((vec.x / 32768.0f) * M_PI, MTXMODE_APPLY); Matrix_Translate(-1400.0f, 0.0f, 0.0f, MTXMODE_APPLY); } if (limbIndex == 8) { - vec = this->unk_1E8.unk_0E; + vec = this->interactInfo.torsoRot; Matrix_RotateX((-vec.y / 32768.0f) * M_PI, MTXMODE_APPLY); Matrix_RotateZ((-vec.x / 32768.0f) * M_PI, MTXMODE_APPLY); } diff --git a/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.h b/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.h index 2ae4c95cace..55b53bd723d 100644 --- a/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.h +++ b/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.h @@ -17,7 +17,7 @@ typedef struct EnMa1 { /* 0x01E2 */ s16 blinkTimer; /* 0x01E4 */ s16 eyeIndex; /* 0x01E6 */ s16 mouthIndex; - /* 0x01E8 */ struct_80034A14_arg1 unk_1E8; + /* 0x01E8 */ NpcInteractInfo interactInfo; } EnMa1; // size = 0x0210 #endif diff --git a/soh/src/overlays/actors/ovl_En_Ma2/z_en_ma2.c b/soh/src/overlays/actors/ovl_En_Ma2/z_en_ma2.c index 92c3bc02978..8b7e6f3d530 100644 --- a/soh/src/overlays/actors/ovl_En_Ma2/z_en_ma2.c +++ b/soh/src/overlays/actors/ovl_En_Ma2/z_en_ma2.c @@ -91,21 +91,21 @@ u16 func_80AA19A0(PlayState* play, Actor* thisx) { } s16 func_80AA1A38(PlayState* play, Actor* thisx) { - s16 ret = 1; + s16 ret = NPC_TALK_STATE_TALKING; switch (Message_GetState(&play->msgCtx)) { case TEXT_STATE_CLOSING: switch (thisx->textId) { case 0x2051: gSaveContext.infTable[8] |= 0x1000; - ret = 2; + ret = NPC_TALK_STATE_ACTION; break; case 0x2053: gSaveContext.infTable[8] |= 0x2000; - ret = 0; + ret = NPC_TALK_STATE_IDLE; break; default: - ret = 0; + ret = NPC_TALK_STATE_IDLE; break; } break; @@ -124,18 +124,18 @@ s16 func_80AA1A38(PlayState* play, Actor* thisx) { void func_80AA1AE4(EnMa2* this, PlayState* play) { Player* player = GET_PLAYER(play); - s16 phi_a3; + s16 trackingMode; - if ((this->unk_1E0.unk_00 == 0) && (this->skelAnime.animation == &gMalonAdultSingAnim)) { - phi_a3 = 1; + if ((this->interactInfo.talkState == NPC_TALK_STATE_IDLE) && (this->skelAnime.animation == &gMalonAdultSingAnim)) { + trackingMode = NPC_TRACKING_NONE; } else { - phi_a3 = 0; + trackingMode = NPC_TRACKING_PLAYER_AUTO_TURN; } - this->unk_1E0.unk_18 = player->actor.world.pos; - this->unk_1E0.unk_14 = 0.0f; + this->interactInfo.trackPos = player->actor.world.pos; + this->interactInfo.yOffset = 0.0f; - func_80034A14(&this->actor, &this->unk_1E0, 0, phi_a3); + Npc_TrackPoint(&this->actor, &this->interactInfo, 0, trackingMode); } u16 func_80AA1B58(EnMa2* this, PlayState* play) { @@ -166,7 +166,7 @@ s32 func_80AA1C68(EnMa2* this) { if (this->skelAnime.animation != &gMalonAdultSingAnim) { return 0; } - if (this->unk_1E0.unk_00 != 0) { + if (this->interactInfo.talkState != NPC_TALK_STATE_IDLE) { return 0; } this->blinkTimer = 0; @@ -196,7 +196,7 @@ void EnMa2_ChangeAnim(EnMa2* this, s32 index) { void func_80AA1DB4(EnMa2* this, PlayState* play) { if (this->skelAnime.animation == &gMalonAdultSingAnim) { - if (this->unk_1E0.unk_00 == 0) { + if (this->interactInfo.talkState == NPC_TALK_STATE_IDLE) { if (this->unk_20A != 0) { func_800F6584(0); this->unk_20A = 0; @@ -245,7 +245,7 @@ void EnMa2_Init(Actor* thisx, PlayState* play) { Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 0.0f, 0.0f, 4); Actor_SetScale(&this->actor, 0.01f); this->actor.targetMode = 6; - this->unk_1E0.unk_00 = 0; + this->interactInfo.talkState = NPC_TALK_STATE_IDLE; } void EnMa2_Destroy(Actor* thisx, PlayState* play) { @@ -256,9 +256,9 @@ void EnMa2_Destroy(Actor* thisx, PlayState* play) { } void func_80AA2018(EnMa2* this, PlayState* play) { - if (this->unk_1E0.unk_00 == 2) { + if (this->interactInfo.talkState == NPC_TALK_STATE_ACTION) { this->actor.flags &= ~ACTOR_FLAG_16; - this->unk_1E0.unk_00 = 0; + this->interactInfo.talkState = NPC_TALK_STATE_IDLE; } } @@ -298,7 +298,7 @@ void func_80AA21C8(EnMa2* this, PlayState* play) { if (DECR(this->unk_208)) { player->stateFlags2 |= 0x800000; } else { - if (this->unk_1E0.unk_00 == 0) { + if (this->interactInfo.talkState == NPC_TALK_STATE_IDLE) { this->actor.flags |= ACTOR_FLAG_16; Message_CloseTextbox(play); } else { @@ -320,8 +320,8 @@ void EnMa2_Update(Actor* thisx, PlayState* play) { func_80AA1DB4(this, play); func_80AA1AE4(this, play); if (this->actionFunc != func_80AA20E4) { - func_800343CC(play, &this->actor, &this->unk_1E0.unk_00, (f32)this->collider.dim.radius + 30.0f, - func_80AA19A0, func_80AA1A38); + Npc_UpdateTalking(play, &this->actor, &this->interactInfo.talkState, (f32)this->collider.dim.radius + 30.0f, + func_80AA19A0, func_80AA1A38); } } @@ -334,13 +334,13 @@ s32 EnMa2_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* p } if (limbIndex == MALON_ADULT_HEAD_LIMB) { Matrix_Translate(1400.0f, 0.0f, 0.0f, MTXMODE_APPLY); - vec = this->unk_1E0.unk_08; + vec = this->interactInfo.headRot; Matrix_RotateX((vec.y / 32768.0f) * M_PI, MTXMODE_APPLY); Matrix_RotateZ((vec.x / 32768.0f) * M_PI, MTXMODE_APPLY); Matrix_Translate(-1400.0f, 0.0f, 0.0f, MTXMODE_APPLY); } if (limbIndex == MALON_ADULT_CHEST_AND_NECK_LIMB) { - vec = this->unk_1E0.unk_0E; + vec = this->interactInfo.torsoRot; Matrix_RotateY((-vec.y / 32768.0f) * M_PI, MTXMODE_APPLY); Matrix_RotateX((-vec.x / 32768.0f) * M_PI, MTXMODE_APPLY); } diff --git a/soh/src/overlays/actors/ovl_En_Ma2/z_en_ma2.h b/soh/src/overlays/actors/ovl_En_Ma2/z_en_ma2.h index ef8a4a996e3..20f0cd6debe 100644 --- a/soh/src/overlays/actors/ovl_En_Ma2/z_en_ma2.h +++ b/soh/src/overlays/actors/ovl_En_Ma2/z_en_ma2.h @@ -36,7 +36,7 @@ typedef struct EnMa2 { /* 0x014C */ SkelAnime skelAnime; /* 0x0190 */ EnMa2ActionFunc actionFunc; /* 0x0194 */ ColliderCylinder collider; - /* 0x01E0 */ struct_80034A14_arg1 unk_1E0; + /* 0x01E0 */ NpcInteractInfo interactInfo; /* 0x0208 */ s16 unk_208; /* 0x020A */ s16 unk_20A; /* 0x020C */ s16 blinkTimer; diff --git a/soh/src/overlays/actors/ovl_En_Ma3/z_en_ma3.c b/soh/src/overlays/actors/ovl_En_Ma3/z_en_ma3.c index c0a0f25405a..429b44e0b98 100644 --- a/soh/src/overlays/actors/ovl_En_Ma3/z_en_ma3.c +++ b/soh/src/overlays/actors/ovl_En_Ma3/z_en_ma3.c @@ -110,7 +110,7 @@ u16 func_80AA2AA0(PlayState* play, Actor* thisx) { } s16 func_80AA2BD4(PlayState* play, Actor* thisx) { - s16 ret = 1; + s16 ret = NPC_TALK_STATE_TALKING; switch (Message_GetState(&play->msgCtx)) { case TEXT_STATE_EVENT: @@ -141,7 +141,7 @@ s16 func_80AA2BD4(PlayState* play, Actor* thisx) { switch (thisx->textId) { case 0x2000: gSaveContext.infTable[11] |= 0x100; - ret = 0; + ret = NPC_TALK_STATE_IDLE; break; case 0x208F: gSaveContext.eventChkInf[1] |= 0x4000; @@ -153,18 +153,18 @@ s16 func_80AA2BD4(PlayState* play, Actor* thisx) { case 0x208E: gSaveContext.eventInf[0] &= ~0x400; thisx->flags &= ~ACTOR_FLAG_16; - ret = 0; + ret = NPC_TALK_STATE_IDLE; gSaveContext.timer1State = 0xA; break; case 0x2002: gSaveContext.infTable[11] |= 0x200; case 0x2003: if (!(gSaveContext.eventInf[0] & 0x400)) { - ret = 0; + ret = NPC_TALK_STATE_IDLE; } break; default: - ret = 0; + ret = NPC_TALK_STATE_IDLE; } break; case TEXT_STATE_NONE: @@ -181,17 +181,17 @@ s16 func_80AA2BD4(PlayState* play, Actor* thisx) { void func_80AA2E54(EnMa3* this, PlayState* play) { Player* player = GET_PLAYER(play); - s16 phi_a3; + s16 trackingMode; - if ((this->unk_1E0.unk_00 == 0) && (this->skelAnime.animation == &gMalonAdultSingAnim)) { - phi_a3 = 1; + if ((this->interactInfo.talkState == NPC_TALK_STATE_IDLE) && (this->skelAnime.animation == &gMalonAdultSingAnim)) { + trackingMode = NPC_TRACKING_NONE; } else { - phi_a3 = 0; + trackingMode = NPC_TRACKING_PLAYER_AUTO_TURN; } - this->unk_1E0.unk_18 = player->actor.world.pos; - this->unk_1E0.unk_14 = 0.0f; - func_80034A14(&this->actor, &this->unk_1E0, 0, phi_a3); + this->interactInfo.trackPos = player->actor.world.pos; + this->interactInfo.yOffset = 0.0f; + Npc_TrackPoint(&this->actor, &this->interactInfo, 0, trackingMode); } s32 func_80AA2EC8(EnMa3* this, PlayState* play) { @@ -211,7 +211,7 @@ s32 func_80AA2F28(EnMa3* this) { if (this->skelAnime.animation != &gMalonAdultSingAnim) { return 0; } - if (this->unk_1E0.unk_00 != 0) { + if (this->interactInfo.talkState != NPC_TALK_STATE_IDLE) { return 0; } this->blinkTimer = 0; @@ -265,7 +265,7 @@ void EnMa3_Init(Actor* thisx, PlayState* play) { Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 0.0f, 0.0f, 4); Actor_SetScale(&this->actor, 0.01f); - this->unk_1E0.unk_00 = (u16)0; + this->interactInfo.talkState = NPC_TALK_STATE_IDLE; } void EnMa3_Destroy(Actor* thisx, PlayState* play) { @@ -276,9 +276,9 @@ void EnMa3_Destroy(Actor* thisx, PlayState* play) { } void func_80AA3200(EnMa3* this, PlayState* play) { - if (this->unk_1E0.unk_00 == 2) { + if (this->interactInfo.talkState == NPC_TALK_STATE_ACTION) { this->actor.flags &= ~ACTOR_FLAG_16; - this->unk_1E0.unk_00 = 0; + this->interactInfo.talkState = NPC_TALK_STATE_IDLE; } } @@ -292,9 +292,9 @@ void EnMa3_Update(Actor* thisx, PlayState* play) { EnMa3_UpdateEyes(this); this->actionFunc(this, play); func_80AA2E54(this, play); - func_800343CC(play, &this->actor, &this->unk_1E0.unk_00, (f32)this->collider.dim.radius + 150.0f, - func_80AA2AA0, func_80AA2BD4); - if (this->unk_1E0.unk_00 == 0) { + Npc_UpdateTalking(play, &this->actor, &this->interactInfo.talkState, (f32)this->collider.dim.radius + 150.0f, + func_80AA2AA0, func_80AA2BD4); + if (this->interactInfo.talkState == NPC_TALK_STATE_IDLE) { if (this->unk_20A != 0) { func_800F6584(0); this->unk_20A = 0; @@ -314,13 +314,13 @@ s32 EnMa3_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* p } if (limbIndex == MALON_ADULT_LIMB_HEAD) { Matrix_Translate(1400.0f, 0.0f, 0.0f, MTXMODE_APPLY); - vec = this->unk_1E0.unk_08; + vec = this->interactInfo.headRot; Matrix_RotateX((vec.y / 32768.0f) * M_PI, MTXMODE_APPLY); Matrix_RotateZ((vec.x / 32768.0f) * M_PI, MTXMODE_APPLY); Matrix_Translate(-1400.0f, 0.0f, 0.0f, MTXMODE_APPLY); } if (limbIndex == MALON_ADULT_LIMB_CHEST_AND_NECK) { - vec = this->unk_1E0.unk_0E; + vec = this->interactInfo.torsoRot; Matrix_RotateY((-vec.y / 32768.0f) * M_PI, MTXMODE_APPLY); Matrix_RotateX((-vec.x / 32768.0f) * M_PI, MTXMODE_APPLY); } diff --git a/soh/src/overlays/actors/ovl_En_Ma3/z_en_ma3.h b/soh/src/overlays/actors/ovl_En_Ma3/z_en_ma3.h index 8f82c00f73f..7500379056a 100644 --- a/soh/src/overlays/actors/ovl_En_Ma3/z_en_ma3.h +++ b/soh/src/overlays/actors/ovl_En_Ma3/z_en_ma3.h @@ -36,7 +36,7 @@ typedef struct EnMa3 { /* 0x014C */ SkelAnime skelAnime; /* 0x0190 */ EnMa3ActionFunc actionFunc; /* 0x0194 */ ColliderCylinder collider; - /* 0x01E0 */ struct_80034A14_arg1 unk_1E0; + /* 0x01E0 */ NpcInteractInfo interactInfo; /* 0x0208 */ s16 unk_208; /* 0x020A */ s16 unk_20A; /* 0x020C */ s16 blinkTimer; diff --git a/soh/src/overlays/actors/ovl_En_Md/z_en_md.c b/soh/src/overlays/actors/ovl_En_Md/z_en_md.c index cf788bf076c..658822523c6 100644 --- a/soh/src/overlays/actors/ovl_En_Md/z_en_md.c +++ b/soh/src/overlays/actors/ovl_En_Md/z_en_md.c @@ -297,7 +297,7 @@ void func_80AAA93C(EnMd* this) { } void func_80AAAA24(EnMd* this) { - if (this->unk_1E0.unk_00 != 0) { + if (this->interactInfo.talkState != NPC_TALK_STATE_IDLE) { switch (this->actor.textId) { case 0x102F: if ((this->unk_208 == 0) && (this->unk_20B != 1)) { @@ -451,7 +451,7 @@ s16 func_80AAAF04(PlayState* play, Actor* thisx) { case TEXT_STATE_SONG_DEMO_DONE: case TEXT_STATE_8: case TEXT_STATE_9: - return 1; + return NPC_TALK_STATE_TALKING; case TEXT_STATE_CLOSING: switch (this->actor.textId) { case 0x1028: @@ -469,15 +469,15 @@ s16 func_80AAAF04(PlayState* play, Actor* thisx) { break; case 0x1033: case 0x1067: - return 2; + NPC_TALK_STATE_ACTION; } - return 0; + return NPC_TALK_STATE_IDLE; case TEXT_STATE_EVENT: if (Message_ShouldAdvance(play)) { - return 2; + NPC_TALK_STATE_ACTION; } default: - return 1; + return NPC_TALK_STATE_TALKING; } } @@ -526,7 +526,7 @@ void EnMd_UpdateEyes(EnMd* this) { void func_80AAB158(EnMd* this, PlayState* play) { Player* player = GET_PLAYER(play); s16 absYawDiff; - s16 temp; + s16 trackingMode; s16 temp2; s16 yawDiff; @@ -534,40 +534,41 @@ void func_80AAB158(EnMd* this, PlayState* play) { yawDiff = (f32)this->actor.yawTowardsPlayer - this->actor.shape.rot.y; absYawDiff = ABS(yawDiff); - temp = (absYawDiff <= func_800347E8(2)) ? 2 : 1; + trackingMode = + absYawDiff <= Npc_GetTrackingPresetMaxPlayerYaw(2) ? NPC_TRACKING_HEAD_AND_TORSO : NPC_TRACKING_NONE; temp2 = 1; } else { - temp = 1; + trackingMode = NPC_TRACKING_NONE; temp2 = 0; } - if (this->unk_1E0.unk_00 != 0) { - temp = 4; + if (this->interactInfo.talkState != NPC_TALK_STATE_IDLE) { + trackingMode = NPC_TRACKING_FULL_BODY; } if (this->actionFunc == func_80AABD0C) { - temp = 1; + trackingMode = NPC_TRACKING_NONE; temp2 = 0; } if (this->actionFunc == func_80AAB8F8) { - temp = 4; + trackingMode = NPC_TRACKING_FULL_BODY; temp2 = 1; } if ((play->csCtx.state != CS_STATE_IDLE) || gDbgCamEnabled) { - this->unk_1E0.unk_18 = play->view.eye; - this->unk_1E0.unk_14 = 40.0f; - temp = 2; + this->interactInfo.trackPos = play->view.eye; + this->interactInfo.yOffset = 40.0f; + trackingMode = NPC_TRACKING_HEAD_AND_TORSO; } else { - this->unk_1E0.unk_18 = player->actor.world.pos; - this->unk_1E0.unk_14 = (gSaveContext.linkAge > 0) ? 0.0f : -18.0f; + this->interactInfo.trackPos = player->actor.world.pos; + this->interactInfo.yOffset = (gSaveContext.linkAge > 0) ? 0.0f : -18.0f; } - func_80034A14(&this->actor, &this->unk_1E0, 2, temp); + Npc_TrackPoint(&this->actor, &this->interactInfo, 2, trackingMode); if (this->actionFunc != func_80AABC10) { if (temp2) { - func_800343CC(play, &this->actor, &this->unk_1E0.unk_00, this->collider.dim.radius + 30.0f, - EnMd_GetText, func_80AAAF04); + Npc_UpdateTalking(play, &this->actor, &this->interactInfo.talkState, this->collider.dim.radius + 30.0f, + EnMd_GetText, func_80AAAF04); } } } @@ -690,7 +691,7 @@ void EnMd_Destroy(Actor* thisx, PlayState* play) { void func_80AAB874(EnMd* this, PlayState* play) { if (this->skelAnime.animation == &gMidoHandsOnHipsIdleAnim) { func_80034F54(play, this->unk_214, this->unk_236, 17); - } else if ((this->unk_1E0.unk_00 == 0) && (this->unk_20B != 7)) { + } else if ((this->interactInfo.talkState == NPC_TALK_STATE_IDLE) && (this->unk_20B != 7)) { func_80AAA92C(this, 7); } @@ -712,7 +713,7 @@ void func_80AAB948(EnMd* this, PlayState* play) { func_80AAAA24(this); - if (this->unk_1E0.unk_00 == 0) { + if (this->interactInfo.talkState == NPC_TALK_STATE_IDLE) { this->actor.world.rot.y = this->actor.yawTowardsPlayer; this->actor.shape.rot.y = this->actor.yawTowardsPlayer; @@ -728,7 +729,7 @@ void func_80AAB948(EnMd* this, PlayState* play) { this->skelAnime.playSpeed = CLAMP(temp, 1.0f, 3.0f); } - if (this->unk_1E0.unk_00 == 2) { + if (this->interactInfo.talkState == NPC_TALK_STATE_ACTION) { if (CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD) && !(gSaveContext.eventChkInf[1] & 0x1000) && (play->sceneNum == SCENE_SPOT04)) { play->msgCtx.msgMode = MSGMODE_PAUSED; @@ -744,7 +745,7 @@ void func_80AAB948(EnMd* this, PlayState* play) { func_80AAA92C(this, 3); func_80AAA93C(this); this->waypoint = 1; - this->unk_1E0.unk_00 = 0; + this->interactInfo.talkState = NPC_TALK_STATE_IDLE; this->actionFunc = func_80AABD0C; this->actor.speedXZ = 1.5f; return; @@ -754,7 +755,7 @@ void func_80AAB948(EnMd* this, PlayState* play) { func_80034F54(play, this->unk_214, this->unk_236, 17); } - if ((this->unk_1E0.unk_00 == 0) && (play->sceneNum == SCENE_SPOT10)) { + if ((this->interactInfo.talkState == NPC_TALK_STATE_IDLE) && (play->sceneNum == SCENE_SPOT10)) { if (player->stateFlags2 & 0x1000000) { player->stateFlags2 |= 0x2000000; player->unk_6A8 = &this->actor; @@ -834,13 +835,13 @@ s32 EnMd_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* po if (limbIndex == 16) { Matrix_Translate(1200.0f, 0.0f, 0.0f, MTXMODE_APPLY); - vec = this->unk_1E0.unk_08; + vec = this->interactInfo.headRot; Matrix_RotateX((vec.y / 32768.0f) * M_PI, MTXMODE_APPLY); Matrix_RotateZ((vec.x / 32768.0f) * M_PI, MTXMODE_APPLY); Matrix_Translate(-1200.0f, 0.0f, 0.0f, MTXMODE_APPLY); } if (limbIndex == 9) { - vec = this->unk_1E0.unk_0E; + vec = this->interactInfo.torsoRot; Matrix_RotateX((vec.x / 32768.0f) * M_PI, MTXMODE_APPLY); Matrix_RotateY((vec.y / 32768.0f) * M_PI, MTXMODE_APPLY); } diff --git a/soh/src/overlays/actors/ovl_En_Md/z_en_md.h b/soh/src/overlays/actors/ovl_En_Md/z_en_md.h index c9f38449d96..5cd20a2d337 100644 --- a/soh/src/overlays/actors/ovl_En_Md/z_en_md.h +++ b/soh/src/overlays/actors/ovl_En_Md/z_en_md.h @@ -13,7 +13,7 @@ typedef struct EnMd { /* 0x014C */ SkelAnime skelAnime; /* 0x0190 */ EnMdActionFunc actionFunc; /* 0x0194 */ ColliderCylinder collider; - /* 0x01E0 */ struct_80034A14_arg1 unk_1E0; + /* 0x01E0 */ NpcInteractInfo interactInfo; /* 0x0208 */ u8 unk_208; /* 0x0209 */ u8 unk_209; /* 0x020A */ u8 unk_20A; diff --git a/soh/src/overlays/actors/ovl_En_Mu/z_en_mu.c b/soh/src/overlays/actors/ovl_En_Mu/z_en_mu.c index ac76e924215..df18d4ff060 100644 --- a/soh/src/overlays/actors/ovl_En_Mu/z_en_mu.c +++ b/soh/src/overlays/actors/ovl_En_Mu/z_en_mu.c @@ -15,7 +15,7 @@ void EnMu_Update(Actor* thisx, PlayState* play); void EnMu_Draw(Actor* thisx, PlayState* play); void EnMu_Pose(EnMu* this, PlayState* play); -s16 EnMu_CheckDialogState(PlayState* play, Actor* thisx); +s16 EnMu_UpdateTalkState(PlayState* play, Actor* thisx); static ColliderCylinderInit D_80AB0BD0 = { { @@ -105,7 +105,7 @@ u16 EnMu_GetFaceReaction(PlayState* play, Actor* thisx) { return this->defFaceReaction; } -s16 EnMu_CheckDialogState(PlayState* play, Actor* thisx) { +s16 EnMu_UpdateTalkState(PlayState* play, Actor* thisx) { EnMu* this = (EnMu*)thisx; switch (Message_GetState(&play->msgCtx)) { @@ -118,12 +118,12 @@ s16 EnMu_CheckDialogState(PlayState* play, Actor* thisx) { case TEXT_STATE_SONG_DEMO_DONE: case TEXT_STATE_8: case TEXT_STATE_9: - return 1; + return NPC_TALK_STATE_TALKING; case TEXT_STATE_CLOSING: EnMu_Interact(this, play); - return 0; + return NPC_TALK_STATE_IDLE; default: - return 1; + return NPC_TALK_STATE_TALKING; } } @@ -169,8 +169,8 @@ void EnMu_Update(Actor* thisx, PlayState* play) { Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 0.0f, 0.0f, 4); this->actionFunc(this, play); talkDist = this->collider.dim.radius + 30.0f; - func_800343CC(play, &this->actor, &this->npcInfo.unk_00, talkDist, EnMu_GetFaceReaction, - EnMu_CheckDialogState); + Npc_UpdateTalking(play, &this->actor, &this->npcInfo.talkState, talkDist, EnMu_GetFaceReaction, + EnMu_UpdateTalkState); this->actor.focus.pos = this->actor.world.pos; this->actor.focus.pos.y += 60.0f; diff --git a/soh/src/overlays/actors/ovl_En_Mu/z_en_mu.h b/soh/src/overlays/actors/ovl_En_Mu/z_en_mu.h index 9514acfacd4..b1d7995598e 100644 --- a/soh/src/overlays/actors/ovl_En_Mu/z_en_mu.h +++ b/soh/src/overlays/actors/ovl_En_Mu/z_en_mu.h @@ -13,7 +13,7 @@ typedef struct EnMu { /* 0x014C */ SkelAnime skelAnime; /* 0x0190 */ EnMuActionFunc actionFunc; /* 0x0194 */ ColliderCylinder collider; - /* 0x01E0 */ struct_80034A14_arg1 npcInfo; + /* 0x01E0 */ NpcInteractInfo npcInfo; /* 0x0208 */ u16 defFaceReaction; /* 0x020A */ s16 unk_20A[16]; /* 0x022A */ s16 unk_22A[17]; diff --git a/soh/src/overlays/actors/ovl_En_Nb/z_en_nb.c b/soh/src/overlays/actors/ovl_En_Nb/z_en_nb.c index a0cf10079e6..06dc6b868dd 100644 --- a/soh/src/overlays/actors/ovl_En_Nb/z_en_nb.c +++ b/soh/src/overlays/actors/ovl_En_Nb/z_en_nb.c @@ -152,17 +152,17 @@ void EnNb_Destroy(Actor* thisx, PlayState* play) { void func_80AB0FBC(EnNb* this, PlayState* play) { Player* player = GET_PLAYER(play); - this->unk_300.unk_18 = player->actor.world.pos; - this->unk_300.unk_14 = kREG(16) + 9.0f; - func_80034A14(&this->actor, &this->unk_300, kREG(17) + 0xC, 2); + this->interactInfo.trackPos = player->actor.world.pos; + this->interactInfo.yOffset = kREG(16) + 9.0f; + Npc_TrackPoint(&this->actor, &this->interactInfo, kREG(17) + 0xC, NPC_TRACKING_HEAD_AND_TORSO); } void func_80AB1040(EnNb* this, PlayState* play) { Player* player = GET_PLAYER(play); - this->unk_300.unk_18 = player->actor.world.pos; - this->unk_300.unk_14 = kREG(16) + 9.0f; - func_80034A14(&this->actor, &this->unk_300, kREG(17) + 0xC, 4); + this->interactInfo.trackPos = player->actor.world.pos; + this->interactInfo.yOffset = kREG(16) + 9.0f; + Npc_TrackPoint(&this->actor, &this->interactInfo, kREG(17) + 0xC, NPC_TRACKING_FULL_BODY); } void func_80AB10C4(EnNb* this) { @@ -170,10 +170,10 @@ void func_80AB10C4(EnNb* this) { Vec3s* tempPtr; Vec3s* tempPtr2; - tempPtr = &this->unk_300.unk_08; + tempPtr = &this->interactInfo.headRot; Math_SmoothStepToS(&tempPtr->x, 0, 20, 6200, 100); Math_SmoothStepToS(&tempPtr->y, 0, 20, 6200, 100); - tempPtr2 = &this->unk_300.unk_0E; + tempPtr2 = &this->interactInfo.torsoRot; Math_SmoothStepToS(&tempPtr2->x, 0, 20, 6200, 100); Math_SmoothStepToS(&tempPtr2->y, 0, 20, 6200, 100); } @@ -1455,17 +1455,17 @@ void EnNb_Init(Actor* thisx, PlayState* play) { s32 EnNb_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, void* thisx) { EnNb* this = (EnNb*)thisx; - struct_80034A14_arg1* unk_300 = &this->unk_300; + NpcInteractInfo* interactInfo = &this->interactInfo; s32 ret = false; if (this->headTurnFlag != 0) { if (limbIndex == NB_LIMB_TORSO) { - rot->x += unk_300->unk_0E.y; - rot->y -= unk_300->unk_0E.x; + rot->x += interactInfo->torsoRot.y; + rot->y -= interactInfo->torsoRot.x; ret = false; } else if (limbIndex == NB_LIMB_HEAD) { - rot->x += unk_300->unk_08.y; - rot->z += unk_300->unk_08.x; + rot->x += interactInfo->headRot.y; + rot->z += interactInfo->headRot.x; ret = false; } } diff --git a/soh/src/overlays/actors/ovl_En_Nb/z_en_nb.h b/soh/src/overlays/actors/ovl_En_Nb/z_en_nb.h index e112e2a4c69..84f4bf4fefd 100644 --- a/soh/src/overlays/actors/ovl_En_Nb/z_en_nb.h +++ b/soh/src/overlays/actors/ovl_En_Nb/z_en_nb.h @@ -52,7 +52,7 @@ typedef struct EnNb { /* 0x02F0 */ Vec3f finalPos; /* 0x02FC */ s16 pathYaw; /* 0x02FE */ u16 movementTimer; - /* 0x0300 */ struct_80034A14_arg1 unk_300; + /* 0x0300 */ NpcInteractInfo interactInfo; } EnNb; // size = 0x0328 typedef enum { diff --git a/soh/src/overlays/actors/ovl_En_Niw_Girl/z_en_niw_girl.c b/soh/src/overlays/actors/ovl_En_Niw_Girl/z_en_niw_girl.c index ad948a91bee..d6013fc7989 100644 --- a/soh/src/overlays/actors/ovl_En_Niw_Girl/z_en_niw_girl.c +++ b/soh/src/overlays/actors/ovl_En_Niw_Girl/z_en_niw_girl.c @@ -204,13 +204,13 @@ void EnNiwGirl_Update(Actor* thisx, PlayState* play) { this->unk_280 = 30.0f; Actor_SetFocus(&this->actor, 30.0f); if (tempActionFunc == this->actionFunc) { - this->unk_2D4.unk_18 = player->actor.world.pos; + this->interactInfo.trackPos = player->actor.world.pos; if (!LINK_IS_ADULT) { - this->unk_2D4.unk_18.y = player->actor.world.pos.y - 10.0f; + this->interactInfo.trackPos.y = player->actor.world.pos.y - 10.0f; } - func_80034A14(&this->actor, &this->unk_2D4, 2, 4); - this->unk_260 = this->unk_2D4.unk_08; - this->unk_266 = this->unk_2D4.unk_0E; + Npc_TrackPoint(&this->actor, &this->interactInfo, 2, NPC_TRACKING_FULL_BODY); + this->unk_260 = this->interactInfo.headRot; + this->unk_266 = this->interactInfo.torsoRot; } else { Math_SmoothStepToS(&this->unk_266.y, 0, 5, 3000, 0); Math_SmoothStepToS(&this->unk_260.y, 0, 5, 3000, 0); diff --git a/soh/src/overlays/actors/ovl_En_Niw_Girl/z_en_niw_girl.h b/soh/src/overlays/actors/ovl_En_Niw_Girl/z_en_niw_girl.h index 4a2476d1419..812f1d88eab 100644 --- a/soh/src/overlays/actors/ovl_En_Niw_Girl/z_en_niw_girl.h +++ b/soh/src/overlays/actors/ovl_En_Niw_Girl/z_en_niw_girl.h @@ -29,7 +29,7 @@ typedef struct EnNiwGirl { /* 0x0280 */ f32 unk_280; /* 0x0284 */ EnNiw* chasedEnNiw; /* 0x0288 */ ColliderCylinder collider; - /* 0x02D4 */ struct_80034A14_arg1 unk_2D4; + /* 0x02D4 */ NpcInteractInfo interactInfo; } EnNiwGirl; // size = 0x02FC #endif diff --git a/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c b/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c index 0cff223ae20..63522dc64e9 100644 --- a/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c +++ b/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c @@ -527,13 +527,13 @@ void EnNiwLady_Update(Actor* thisx, PlayState* play) { Player* player = GET_PLAYER(play); Actor_SetFocus(thisx, 60.0f); - this->unk_288.unk_18 = player->actor.world.pos; + this->interactInfo.trackPos = player->actor.world.pos; if (!LINK_IS_ADULT) { - this->unk_288.unk_18.y = player->actor.world.pos.y - 10.0f; + this->interactInfo.trackPos.y = player->actor.world.pos.y - 10.0f; } - func_80034A14(thisx, &this->unk_288, 2, 4); - this->unk_254 = this->unk_288.unk_08; - this->unk_25A = this->unk_288.unk_0E; + Npc_TrackPoint(thisx, &this->interactInfo, 2, NPC_TRACKING_FULL_BODY); + this->unk_254 = this->interactInfo.headRot; + this->unk_25A = this->interactInfo.torsoRot; if (this->unk_276 == 0) { Math_SmoothStepToS(&this->unk_254.y, 0, 5, 3000, 0); } diff --git a/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.h b/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.h index fa35b78a608..01056059346 100644 --- a/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.h +++ b/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.h @@ -38,7 +38,7 @@ typedef struct EnNiwLady { /* 0x0280 */ s8 objectAneIndex; /* 0x0281 */ s8 objectOsAnimeIndex; /* 0x0284 */ s32 getItemId; - /* 0x0288 */ struct_80034A14_arg1 unk_288; + /* 0x0288 */ NpcInteractInfo interactInfo; /* 0x02B0 */ ColliderCylinder collider; /* 0x02FC */ GetItemEntry getItemEntry; } EnNiwLady; // size = 0x02FC diff --git a/soh/src/overlays/actors/ovl_En_Ru1/z_en_ru1.c b/soh/src/overlays/actors/ovl_En_Ru1/z_en_ru1.c index bce28e04566..6894a1c9cee 100644 --- a/soh/src/overlays/actors/ovl_En_Ru1/z_en_ru1.c +++ b/soh/src/overlays/actors/ovl_En_Ru1/z_en_ru1.c @@ -1281,10 +1281,10 @@ void func_80AED83C(EnRu1* this) { Vec3s* tempPtr; Vec3s* tempPtr2; - tempPtr = &this->unk_374.unk_08; + tempPtr = &this->interactInfo.headRot; Math_SmoothStepToS(&tempPtr->x, 0, 0x14, 0x1838, 0x64); Math_SmoothStepToS(&tempPtr->y, 0, 0x14, 0x1838, 0x64); - tempPtr2 = &this->unk_374.unk_0E; + tempPtr2 = &this->interactInfo.torsoRot; Math_SmoothStepToS(&tempPtr2->x, 0, 0x14, 0x1838, 0x64); Math_SmoothStepToS(&tempPtr2->y, 0, 0x14, 0x1838, 0x64); } @@ -1292,7 +1292,7 @@ void func_80AED83C(EnRu1* this) { void func_80AED8DC(EnRu1* this) { s32 temp_hi; s16* unk_2AC = &this->unk_2AC; - s16* someY = &this->unk_374.unk_08.y; + s16* someY = &this->interactInfo.headRot.y; s16* unk_29E = &this->unk_29E; s32 pad[2]; @@ -1793,20 +1793,20 @@ void func_80AEEF68(EnRu1* this, PlayState* play) { Player* player = GET_PLAYER(play); s16 something; - this->unk_374.unk_18 = player->actor.world.pos; - this->unk_374.unk_14 = kREG(16) - 3.0f; + this->interactInfo.trackPos = player->actor.world.pos; + this->interactInfo.yOffset = kREG(16) - 3.0f; something = kREG(17) + 0xC; - func_80034A14(&this->actor, &this->unk_374, something, 2); + Npc_TrackPoint(&this->actor, &this->interactInfo, something, NPC_TRACKING_HEAD_AND_TORSO); } void func_80AEEFEC(EnRu1* this, PlayState* play) { Player* player = GET_PLAYER(play); s16 something; - this->unk_374.unk_18 = player->actor.world.pos; - this->unk_374.unk_14 = kREG(16) - 3.0f; + this->interactInfo.trackPos = player->actor.world.pos; + this->interactInfo.yOffset = kREG(16) - 3.0f; something = kREG(17) + 0xC; - func_80034A14(&this->actor, &this->unk_374, something, 4); + Npc_TrackPoint(&this->actor, &this->interactInfo, something, NPC_TRACKING_FULL_BODY); this->actor.world.rot.y = this->actor.shape.rot.y; } @@ -2266,8 +2266,8 @@ void EnRu1_Init(Actor* thisx, PlayState* play) { } void func_80AF0278(EnRu1* this, PlayState* play, s32 limbIndex, Vec3s* rot) { - Vec3s* vec1 = &this->unk_374.unk_0E; - Vec3s* vec2 = &this->unk_374.unk_08; + Vec3s* vec1 = &this->interactInfo.torsoRot; + Vec3s* vec2 = &this->interactInfo.headRot; switch (limbIndex) { case RUTO_CHILD_LEFT_UPPER_ARM: diff --git a/soh/src/overlays/actors/ovl_En_Ru1/z_en_ru1.h b/soh/src/overlays/actors/ovl_En_Ru1/z_en_ru1.h index a582c62eb2e..59a553baedd 100644 --- a/soh/src/overlays/actors/ovl_En_Ru1/z_en_ru1.h +++ b/soh/src/overlays/actors/ovl_En_Ru1/z_en_ru1.h @@ -54,7 +54,7 @@ typedef struct EnRu1 { /* 0x0360 */ f32 unk_360; /* 0x0364 */ Vec3f unk_364; /* 0x0370 */ f32 unk_370; - /* 0x0374 */ struct_80034A14_arg1 unk_374; + /* 0x0374 */ NpcInteractInfo interactInfo; } EnRu1; // size = 0x039C typedef enum { diff --git a/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c b/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c index 60045eaa4be..bb700f82b53 100644 --- a/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c +++ b/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c @@ -180,7 +180,7 @@ u16 func_80AF55E0(PlayState* play, Actor* thisx) { } s16 func_80AF56F4(PlayState* play, Actor* thisx) { - s16 ret = 1; + s16 ret = NPC_TALK_STATE_TALKING; EnSa* this = (EnSa*)thisx; switch (func_80AF5560(this, play)) { @@ -188,19 +188,19 @@ s16 func_80AF56F4(PlayState* play, Actor* thisx) { switch (this->actor.textId) { case 0x1002: gSaveContext.infTable[0] |= 2; - ret = 0; + ret = NPC_TALK_STATE_IDLE; break; case 0x1031: gSaveContext.eventChkInf[0] |= 8; gSaveContext.infTable[0] |= 8; - ret = 0; + ret = NPC_TALK_STATE_IDLE; break; case 0x1047: gSaveContext.infTable[0] |= 0x20; - ret = 0; + ret = NPC_TALK_STATE_IDLE; break; default: - ret = 0; + ret = NPC_TALK_STATE_IDLE; break; } break; @@ -219,9 +219,9 @@ s16 func_80AF56F4(PlayState* play, Actor* thisx) { void func_80AF57D8(EnSa* this, PlayState* play) { if (play->sceneNum != SCENE_SPOT05 || - ABS((s16)(this->actor.yawTowardsPlayer - this->actor.shape.rot.y)) < 0x1555 || this->unk_1E0.unk_00 != 0) { - func_800343CC(play, &this->actor, &this->unk_1E0.unk_00, this->collider.dim.radius + 30.0f, func_80AF55E0, - func_80AF56F4); + ABS((s16)(this->actor.yawTowardsPlayer - this->actor.shape.rot.y)) < 0x1555 || this->interactInfo.talkState != NPC_TALK_STATE_IDLE) { + Npc_UpdateTalking(play, &this->actor, &this->interactInfo.talkState, this->collider.dim.radius + 30.0f, + func_80AF55E0, func_80AF56F4); } } @@ -403,25 +403,25 @@ s32 func_80AF5DFC(EnSa* this, PlayState* play) { void func_80AF5F34(EnSa* this, PlayState* play) { Player* player = GET_PLAYER(play); - s16 phi_a3 = 0; + s16 trackingMode = NPC_TRACKING_PLAYER_AUTO_TURN; if (play->sceneNum == SCENE_SPOT04) { - phi_a3 = (this->actionFunc == func_80AF68E4) ? 1 : 4; + trackingMode = (this->actionFunc == func_80AF68E4) ? NPC_TRACKING_NONE : NPC_TRACKING_FULL_BODY; } if (play->sceneNum == SCENE_SPOT05) { - phi_a3 = (this->skelAnime.animation == &gSariaPlayingOcarinaAnim) ? 1 : 3; + trackingMode = (this->skelAnime.animation == &gSariaPlayingOcarinaAnim) ? NPC_TRACKING_NONE : NPC_TRACKING_HEAD; } if (play->sceneNum == SCENE_SPOT05 && this->actionFunc == func_80AF6448 && this->skelAnime.animation == &gSariaStopPlayingOcarinaAnim) { - phi_a3 = 1; + trackingMode = NPC_TRACKING_NONE; } if (play->sceneNum == SCENE_SPOT05 && this->actionFunc == func_80AF68E4 && this->skelAnime.animation == &gSariaOcarinaToMouthAnim) { - phi_a3 = 1; + trackingMode = NPC_TRACKING_NONE; } - this->unk_1E0.unk_18 = player->actor.world.pos; - this->unk_1E0.unk_14 = 4.0f; - func_80034A14(&this->actor, &this->unk_1E0, 2, phi_a3); + this->interactInfo.trackPos = player->actor.world.pos; + this->interactInfo.yOffset = 4.0f; + Npc_TrackPoint(&this->actor, &this->interactInfo, 2, trackingMode); } s32 func_80AF603C(EnSa* this) { @@ -429,7 +429,7 @@ s32 func_80AF603C(EnSa* this) { this->skelAnime.animation != &gSariaOcarinaToMouthAnim) { return 0; } - if (this->unk_1E0.unk_00 != 0) { + if (this->interactInfo.talkState != NPC_TALK_STATE_IDLE) { return 0; } this->unk_20E = 0; @@ -520,7 +520,7 @@ void EnSa_Init(Actor* thisx, PlayState* play) { Actor_SetScale(&this->actor, 0.01f); this->actor.targetMode = 6; - this->unk_1E0.unk_00 = 0; + this->interactInfo.talkState = NPC_TALK_STATE_IDLE; this->alpha = 255; this->unk_21A = this->actor.shape.rot; @@ -536,7 +536,7 @@ void EnSa_Destroy(Actor* thisx, PlayState* play) { void func_80AF6448(EnSa* this, PlayState* play) { if (play->sceneNum == SCENE_SPOT04) { - if (this->unk_1E0.unk_00 != 0) { + if (this->interactInfo.talkState != NPC_TALK_STATE_IDLE) { switch (this->actor.textId) { case 0x1002: if (this->unk_208 == 0 && this->unk_20B != 1) { @@ -604,14 +604,14 @@ void func_80AF6448(EnSa* this, PlayState* play) { EnSa_ChangeAnim(this, ENSA_ANIM1_6); } } - if (this->unk_1E0.unk_00 != 0 && play->sceneNum == SCENE_SPOT05) { + if (this->interactInfo.talkState != NPC_TALK_STATE_IDLE && play->sceneNum == SCENE_SPOT05) { Animation_Change(&this->skelAnime, &gSariaStopPlayingOcarinaAnim, 1.0f, 0.0f, 10.0f, ANIMMODE_ONCE, -10.0f); this->actionFunc = func_80AF67D0; } } void func_80AF67D0(EnSa* this, PlayState* play) { - if (this->unk_1E0.unk_00 == 0) { + if (this->interactInfo.talkState == NPC_TALK_STATE_IDLE) { Animation_Change(&this->skelAnime, &gSariaStopPlayingOcarinaAnim, 0.0f, 10.0f, 0.0f, ANIMMODE_ONCE, -10.0f); this->actionFunc = func_80AF6448; } @@ -783,14 +783,14 @@ s32 EnSa_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* po if (limbIndex == 16) { Matrix_Translate(900.0f, 0.0f, 0.0f, MTXMODE_APPLY); - sp18 = this->unk_1E0.unk_08; + sp18 = this->interactInfo.headRot; Matrix_RotateX(BINANG_TO_RAD(sp18.y), MTXMODE_APPLY); Matrix_RotateZ(BINANG_TO_RAD(sp18.x), MTXMODE_APPLY); Matrix_Translate(-900.0f, 0.0f, 0.0f, MTXMODE_APPLY); } if (limbIndex == 9) { - sp18 = this->unk_1E0.unk_0E; + sp18 = this->interactInfo.torsoRot; Matrix_RotateY(BINANG_TO_RAD(sp18.y), MTXMODE_APPLY); Matrix_RotateX(BINANG_TO_RAD(sp18.x), MTXMODE_APPLY); } diff --git a/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.h b/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.h index 65e853cacea..2965f04ab71 100644 --- a/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.h +++ b/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.h @@ -13,7 +13,7 @@ typedef struct EnSa { /* 0x014C */ SkelAnime skelAnime; /* 0x0190 */ EnSaActionFunc actionFunc; /* 0x0194 */ ColliderCylinder collider; - /* 0x01E0 */ struct_80034A14_arg1 unk_1E0; + /* 0x01E0 */ NpcInteractInfo interactInfo; /* 0x0208 */ u8 unk_208; /* 0x0209 */ u8 unk_209; /* 0x020A */ u8 unk_20A; diff --git a/soh/src/overlays/actors/ovl_En_Tg/z_en_tg.c b/soh/src/overlays/actors/ovl_En_Tg/z_en_tg.c index bd7dab2c49d..d9af596d692 100644 --- a/soh/src/overlays/actors/ovl_En_Tg/z_en_tg.c +++ b/soh/src/overlays/actors/ovl_En_Tg/z_en_tg.c @@ -79,7 +79,7 @@ u16 EnTg_GetTextId(PlayState* play, Actor* thisx) { } } -s16 EnTg_OnTextComplete(PlayState* play, Actor* thisx) { +s16 EnTg_UpdateTalkState(PlayState* play, Actor* thisx) { EnTg* this = (EnTg*)thisx; switch (Message_GetState(&play->msgCtx)) { @@ -133,7 +133,7 @@ void EnTg_Destroy(Actor* thisx, PlayState* play) { } void EnTg_SpinIfNotTalking(EnTg* this, PlayState* play) { - if (!this->isTalking) { + if (!this->interactInfo.talkState) { this->actor.shape.rot.y += 0x800; } } @@ -153,7 +153,7 @@ void EnTg_Update(Actor* thisx, PlayState* play) { Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 0.0f, 0.0f, 4); this->actionFunc(this, play); temp = this->collider.dim.radius + 30.0f; - func_800343CC(play, &this->actor, &this->isTalking, temp, EnTg_GetTextId, EnTg_OnTextComplete); + Npc_UpdateTalking(play, &this->actor, &this->interactInfo.talkState, temp, EnTg_GetTextId, EnTg_UpdateTalkState); } s32 EnTg_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, void* thisx) { diff --git a/soh/src/overlays/actors/ovl_En_Tg/z_en_tg.h b/soh/src/overlays/actors/ovl_En_Tg/z_en_tg.h index 2aba3839ace..583efc1a6df 100644 --- a/soh/src/overlays/actors/ovl_En_Tg/z_en_tg.h +++ b/soh/src/overlays/actors/ovl_En_Tg/z_en_tg.h @@ -13,8 +13,7 @@ typedef struct EnTg { /* 0x014C */ SkelAnime skelAnime; /* 0x0190 */ EnTgActionFunc actionFunc; /* 0x0194 */ ColliderCylinder collider; - /* 0x01E0 */ s16 isTalking; - /* 0x01E2 */ char unk_1E2[0x26]; + /* 0x01E0 */ NpcInteractInfo interactInfo; /* 0x0208 */ u8 nextDialogue; } EnTg; // size = 0x020C diff --git a/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.c b/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.c index 2cde9651921..625f4198334 100644 --- a/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.c +++ b/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.c @@ -355,7 +355,7 @@ u16 func_80B1C54C(PlayState* play, Actor* thisx) { } s16 func_80B1C5A0(PlayState* play, Actor* thisx) { - s32 ret = 1; + s32 ret = NPC_TALK_STATE_TALKING; switch (Message_GetState(&play->msgCtx)) { case TEXT_STATE_NONE: @@ -366,7 +366,7 @@ s16 func_80B1C5A0(PlayState* play, Actor* thisx) { if (thisx->textId == 0x5028) { gSaveContext.infTable[13] |= 0x0100; } - ret = 0; + ret = NPC_TALK_STATE_IDLE; break; case TEXT_STATE_DONE_FADING: break; @@ -382,7 +382,7 @@ s16 func_80B1C5A0(PlayState* play, Actor* thisx) { play->msgCtx.msgMode = MSGMODE_PAUSED; Rupees_ChangeBy(-10); gSaveContext.infTable[13] |= 0x0200; - return 2; + return NPC_TALK_STATE_ACTION; } Message_ContinueTextbox(play, thisx->textId); gSaveContext.infTable[13] |= 0x0200; @@ -391,7 +391,7 @@ s16 func_80B1C5A0(PlayState* play, Actor* thisx) { case TEXT_STATE_EVENT: if (Message_ShouldAdvance(play) && (thisx->textId == 0x0084 || thisx->textId == 0x0085)) { Message_CloseTextbox(play); - ret = 0; + ret = NPC_TALK_STATE_IDLE; } break; case TEXT_STATE_DONE: @@ -528,35 +528,35 @@ void EnTk_Rest(EnTk* this, PlayState* play) { s16 v1; s16 a1_; - if (this->h_1E0 != 0) { + if (this->interactInfo.talkState != NPC_TALK_STATE_IDLE) { v1 = this->actor.shape.rot.y; v1 -= this->h_21E; v1 = this->actor.yawTowardsPlayer - v1; - if (this->h_1E0 == 2) { + if (this->interactInfo.talkState == NPC_TALK_STATE_ACTION) { EnTk_DigAnim(this, play); - this->h_1E0 = 0; + this->interactInfo.talkState = NPC_TALK_STATE_IDLE; this->actionFunc = EnTk_Dig; return; } - func_800343CC(play, &this->actor, &this->h_1E0, this->collider.dim.radius + 30.0f, func_80B1C54C, - func_80B1C5A0); + Npc_UpdateTalking(play, &this->actor, &this->interactInfo.talkState, this->collider.dim.radius + 30.0f, + func_80B1C54C, func_80B1C5A0); } else if (EnTk_CheckFacingPlayer(this)) { v1 = this->actor.shape.rot.y; v1 -= this->h_21E; v1 = this->actor.yawTowardsPlayer - v1; this->actionCountdown = 0; - func_800343CC(play, &this->actor, &this->h_1E0, this->collider.dim.radius + 30.0f, func_80B1C54C, - func_80B1C5A0); + Npc_UpdateTalking(play, &this->actor, &this->interactInfo.talkState, this->collider.dim.radius + 30.0f, + func_80B1C54C, func_80B1C5A0); } else if (Actor_ProcessTalkRequest(&this->actor, play)) { v1 = this->actor.shape.rot.y; v1 -= this->h_21E; v1 = this->actor.yawTowardsPlayer - v1; this->actionCountdown = 0; - this->h_1E0 = 1; + this->interactInfo.talkState = NPC_TALK_STATE_TALKING; } else if (DECR(this->actionCountdown) == 0) { EnTk_WalkAnim(this, play); this->actionFunc = EnTk_Walk; @@ -571,9 +571,9 @@ void EnTk_Rest(EnTk* this, PlayState* play) { } void EnTk_Walk(EnTk* this, PlayState* play) { - if (this->h_1E0 == 2) { + if (this->interactInfo.talkState == NPC_TALK_STATE_ACTION) { EnTk_DigAnim(this, play); - this->h_1E0 = 0; + this->interactInfo.talkState = NPC_TALK_STATE_IDLE; this->actionFunc = EnTk_Dig; } else { this->actor.speedXZ = EnTk_Step(this, play); diff --git a/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.h b/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.h index 80dd6c29732..c60cb52003f 100644 --- a/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.h +++ b/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.h @@ -3,6 +3,7 @@ #include #include "global.h" +#include "z64.h" /* Dirt particle effect */ struct EnTkEff; @@ -29,8 +30,7 @@ typedef struct EnTk { /* 0x014C */ SkelAnime skelAnime; /* 0x0190 */ EnTkActionFunc actionFunc; /* 0x0194 */ ColliderCylinder collider; - /* 0x01E0 */ s16 h_1E0; - /* 0x01E2 */ char unk_1E2[0x26]; + /* 0x01E0 */ NpcInteractInfo interactInfo; /* 0x0208 */ u8 validDigHere; /* 0x0209 */ u8 rewardCount[4]; /* 0x0210 */ Actor* currentSpot; diff --git a/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c b/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c index 8b44ea2ad51..7ec5db7e571 100644 --- a/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c +++ b/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c @@ -368,20 +368,20 @@ void EnToryo_Update(Actor* thisx, PlayState* play) { this->actionFunc(this, play); if ((this->stateFlags & 8)) { - this->unk_1EC.unk_18.x = player->actor.focus.pos.x; - this->unk_1EC.unk_18.y = player->actor.focus.pos.y; - this->unk_1EC.unk_18.z = player->actor.focus.pos.z; + this->interactInfo.trackPos.x = player->actor.focus.pos.x; + this->interactInfo.trackPos.y = player->actor.focus.pos.y; + this->interactInfo.trackPos.z = player->actor.focus.pos.z; if ((this->stateFlags & 0x10)) { - func_80034A14(thisx, &this->unk_1EC, 0, 4); + Npc_TrackPoint(thisx, &this->interactInfo, 0, NPC_TRACKING_FULL_BODY); return; } rot = thisx->yawTowardsPlayer - thisx->shape.rot.y; if ((rot < 14563.0f) && (rot > -14563.0f)) { - func_80034A14(thisx, &this->unk_1EC, 0, 2); + Npc_TrackPoint(thisx, &this->interactInfo, 0, NPC_TRACKING_HEAD_AND_TORSO); } else { - func_80034A14(thisx, &this->unk_1EC, 0, 1); + Npc_TrackPoint(thisx, &this->interactInfo, 0, NPC_TRACKING_NONE); } } } @@ -401,12 +401,12 @@ s32 EnToryo_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* if ((this->stateFlags & 8)) { switch (limbIndex) { case 8: - rot->x += this->unk_1EC.unk_0E.y; - rot->y -= this->unk_1EC.unk_0E.x; + rot->x += this->interactInfo.torsoRot.y; + rot->y -= this->interactInfo.torsoRot.x; break; case 15: - rot->x += this->unk_1EC.unk_08.y; - rot->z += this->unk_1EC.unk_08.x; + rot->x += this->interactInfo.headRot.y; + rot->z += this->interactInfo.headRot.x; break; } } diff --git a/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.h b/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.h index a0aeda85009..8e44ed0a911 100644 --- a/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.h +++ b/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.h @@ -17,7 +17,7 @@ typedef struct EnToryo { /* 0x01E4 */ s32 unk_1E4; /* 0x01E8 */ u16 stateFlags; /* 0x01EA */ s16 unk_1EA; - /* 0x01EC */ struct_80034A14_arg1 unk_1EC; + /* 0x01EC */ NpcInteractInfo interactInfo; /* 0x0214 */ Vec3s jointTable[17]; /* 0x027A */ Vec3s morphTable[17]; } EnToryo; // size = 0x02E0 diff --git a/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c b/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c index 09089bdb6ce..89c478cb5bb 100644 --- a/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c +++ b/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c @@ -79,9 +79,9 @@ void EnXc_Destroy(Actor* thisx, PlayState* play) { void EnXc_CalculateHeadTurn(EnXc* this, PlayState* play) { Player* player = GET_PLAYER(play); - this->npcInfo.unk_18 = player->actor.world.pos; - this->npcInfo.unk_14 = kREG(16) - 3.0f; - func_80034A14(&this->actor, &this->npcInfo, kREG(17) + 0xC, 2); + this->interactInfo.trackPos = player->actor.world.pos; + this->interactInfo.yOffset = kREG(16) - 3.0f; + Npc_TrackPoint(&this->actor, &this->interactInfo, kREG(17) + 0xC, NPC_TRACKING_HEAD_AND_TORSO); } void EnXc_SetEyePattern(EnXc* this) { @@ -2410,11 +2410,11 @@ s32 EnXc_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* po if (this->unk_30C != 0) { if (limbIndex == 9) { - rot->x += this->npcInfo.unk_0E.y; - rot->y -= this->npcInfo.unk_0E.x; + rot->x += this->interactInfo.torsoRot.y; + rot->y -= this->interactInfo.torsoRot.x; } else if (limbIndex == 16) { - rot->x += this->npcInfo.unk_08.y; - rot->z += this->npcInfo.unk_08.x; + rot->x += this->interactInfo.headRot.y; + rot->z += this->interactInfo.headRot.x; } } return 0; diff --git a/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.h b/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.h index 1dea813af86..72f1e63bd71 100644 --- a/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.h +++ b/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.h @@ -139,7 +139,7 @@ typedef struct EnXc { /* 0x02C0 */ ColliderCylinder collider; /* 0x030C */ s32 unk_30C; /* 0x0310 */ Actor* flameActor; - /* 0x0314 */ struct_80034A14_arg1 npcInfo; + /* 0x0314 */ NpcInteractInfo interactInfo; } EnXc; // size = 0x033C #endif diff --git a/soh/src/overlays/actors/ovl_En_Zl3/z_en_zl3.c b/soh/src/overlays/actors/ovl_En_Zl3/z_en_zl3.c index efc8e2b7ddf..a5d09cfbd40 100644 --- a/soh/src/overlays/actors/ovl_En_Zl3/z_en_zl3.c +++ b/soh/src/overlays/actors/ovl_En_Zl3/z_en_zl3.c @@ -151,8 +151,8 @@ void func_80B536B4(EnZl3* this) { void func_80B536C4(EnZl3* this) { s32 pad[2]; - Vec3s* vec1 = &this->unk_3F8.unk_08; - Vec3s* vec2 = &this->unk_3F8.unk_0E; + Vec3s* vec1 = &this->interactInfo.headRot; + Vec3s* vec2 = &this->interactInfo.torsoRot; Math_SmoothStepToS(&vec1->x, 0, 20, 6200, 100); Math_SmoothStepToS(&vec1->y, 0, 20, 6200, 100); @@ -163,9 +163,9 @@ void func_80B536C4(EnZl3* this) { void func_80B53764(EnZl3* this, PlayState* play) { Player* player = GET_PLAYER(play); - this->unk_3F8.unk_18 = player->actor.world.pos; - this->unk_3F8.unk_14 = kREG(16) - 16.0f; - func_80034A14(&this->actor, &this->unk_3F8, kREG(17) + 0xC, 2); + this->interactInfo.trackPos = player->actor.world.pos; + this->interactInfo.yOffset = kREG(16) - 16.0f; + Npc_TrackPoint(&this->actor, &this->interactInfo, kREG(17) + 0xC, NPC_TRACKING_HEAD_AND_TORSO); } s32 func_80B537E8(EnZl3* this) { @@ -603,8 +603,8 @@ s32 func_80B5458C(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s Mtx* sp78; MtxF sp38; Vec3s sp30; - Vec3s* unk_3F8_unk_08 = &this->unk_3F8.unk_08; - Vec3s* unk_3F8_unk_0E = &this->unk_3F8.unk_0E; + Vec3s* unk_3F8_unk_08 = &this->interactInfo.headRot; + Vec3s* unk_3F8_unk_0E = &this->interactInfo.torsoRot; if (limbIndex == 14) { sp78 = Graph_Alloc(play->state.gfxCtx, sizeof(Mtx) * 7); @@ -1968,18 +1968,18 @@ void func_80B57D60(EnZl3* this, PlayState* play) { s32 func_80B57D80(EnZl3* this, PlayState* play) { s32 pad; s16* sp32 = &this->actor.shape.rot.y; - struct_80034A14_arg1* unk_3F8 = &this->unk_3F8; + NpcInteractInfo* interactInfo = &this->interactInfo; Player* player = GET_PLAYER(play); s32 unk_314 = this->unk_314; s16 temp_v0 = func_80B57104(this, unk_314); s32 pad2; s16 phi_v1; - unk_3F8->unk_18.y = player->actor.world.pos.y; - unk_3F8->unk_18.x = (Math_SinS(temp_v0) * this->actor.xzDistToPlayer) + this->actor.world.pos.x; - unk_3F8->unk_18.z = (Math_CosS(temp_v0) * this->actor.xzDistToPlayer) + this->actor.world.pos.z; - unk_3F8->unk_14 = kREG(16) - 16.0f; - func_80034A14(&this->actor, unk_3F8, kREG(17) + 0xC, 4); + interactInfo->trackPos.y = player->actor.world.pos.y; + interactInfo->trackPos.x = (Math_SinS(temp_v0) * this->actor.xzDistToPlayer) + this->actor.world.pos.x; + interactInfo->trackPos.z = (Math_CosS(temp_v0) * this->actor.xzDistToPlayer) + this->actor.world.pos.z; + interactInfo->yOffset = kREG(16) - 16.0f; + Npc_TrackPoint(&this->actor, interactInfo, kREG(17) + 0xC, NPC_TRACKING_FULL_BODY); phi_v1 = ABS(temp_v0 - *sp32); if (phi_v1 <= 0x320) { @@ -2446,7 +2446,7 @@ s32 func_80B5944C(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s if (limbIndex == 14) { Mtx* mtx = Graph_Alloc(play->state.gfxCtx, sizeof(Mtx) * 7); EnZl3* this = (EnZl3*)thisx; - Vec3s* vec = &this->unk_3F8.unk_08; + Vec3s* vec = &this->interactInfo.headRot; gSPSegment(gfx[0]++, 0x0C, mtx); diff --git a/soh/src/overlays/actors/ovl_En_Zl3/z_en_zl3.h b/soh/src/overlays/actors/ovl_En_Zl3/z_en_zl3.h index cfd9da535c9..085225b070b 100644 --- a/soh/src/overlays/actors/ovl_En_Zl3/z_en_zl3.h +++ b/soh/src/overlays/actors/ovl_En_Zl3/z_en_zl3.h @@ -65,7 +65,7 @@ typedef struct EnZl3 { /* 0x03EC */ f32 unk_3EC; /* 0x03F0 */ f32 unk_3F0; /* 0x03F4 */ f32 unk_3F4; - /* 0x03F8 */ struct_80034A14_arg1 unk_3F8; + /* 0x03F8 */ NpcInteractInfo interactInfo; } EnZl3; // size = 0x0420 #endif diff --git a/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c b/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c index 3e1d7b462e4..3d32a0524a5 100644 --- a/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c +++ b/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c @@ -245,10 +245,10 @@ s16 func_80B5B9B0(PlayState* play, Actor* thisx) { EnZl4* this = (EnZl4*)thisx; if (Message_GetState(&play->msgCtx) == TEXT_STATE_CLOSING) { - return false; + return NPC_TALK_STATE_IDLE; } - return true; + return NPC_TALK_STATE_TALKING; } void EnZl4_UpdateFace(EnZl4* this) { @@ -323,8 +323,8 @@ void EnZl4_SetMove(EnZl4* this, PlayState* play) { void func_80B5BB78(EnZl4* this, PlayState* play) { Player* player = GET_PLAYER(play); - this->unk_1E0.unk_18 = player->actor.world.pos; - func_80034A14(&this->actor, &this->unk_1E0, 2, 2); + this->interactInfo.trackPos = player->actor.world.pos; + Npc_TrackPoint(&this->actor, &this->interactInfo, 2, NPC_TRACKING_HEAD_AND_TORSO); } void EnZl4_GetActionStartPos(CsCmdActorAction* action, Vec3f* vec) { @@ -1211,17 +1211,17 @@ void EnZl4_Cutscene(EnZl4* this, PlayState* play) { } break; } - this->unk_1E0.unk_18 = player->actor.world.pos; - func_80034A14(&this->actor, &this->unk_1E0, 2, (this->csState == ZL4_CS_WINDOW) ? 2 : 1); + this->interactInfo.trackPos = player->actor.world.pos; + Npc_TrackPoint(&this->actor, &this->interactInfo, 2, + (this->csState == ZL4_CS_WINDOW) ? NPC_TRACKING_HEAD_AND_TORSO : NPC_TRACKING_NONE); if (EnZl4_InMovingAnim(this)) { EnZl4_SetMove(this, play); } } void EnZl4_Idle(EnZl4* this, PlayState* play) { - func_800343CC(play, &this->actor, &this->unk_1E0.unk_00, this->collider.dim.radius + 60.0f, EnZl4_GetText, - func_80B5B9B0); - + Npc_UpdateTalking(play, &this->actor, &this->interactInfo.talkState, this->collider.dim.radius + 60.0f, + EnZl4_GetText, func_80B5B9B0); func_80B5BB78(this, play); if (gSaveContext.n64ddFlag) { @@ -1285,14 +1285,14 @@ s32 EnZl4_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* p Vec3s sp1C; if (limbIndex == 17) { - sp1C = this->unk_1E0.unk_08; + sp1C = this->interactInfo.headRot; Matrix_Translate(900.0f, 0.0f, 0.0f, MTXMODE_APPLY); Matrix_RotateX((sp1C.y / (f32)0x8000) * M_PI, MTXMODE_APPLY); Matrix_RotateZ((sp1C.x / (f32)0x8000) * M_PI, MTXMODE_APPLY); Matrix_Translate(-900.0f, 0.0f, 0.0f, MTXMODE_APPLY); } if (limbIndex == 10) { - sp1C = this->unk_1E0.unk_0E; + sp1C = this->interactInfo.torsoRot; Matrix_RotateY((sp1C.y / (f32)0x8000) * M_PI, MTXMODE_APPLY); Matrix_RotateX((sp1C.x / (f32)0x8000) * M_PI, MTXMODE_APPLY); } diff --git a/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.h b/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.h index 0b9dbca936e..601ed690590 100644 --- a/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.h +++ b/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.h @@ -14,7 +14,7 @@ typedef struct EnZl4 { /* 0x014C */ SkelAnime skelAnime; /* 0x0190 */ EnZl4ActionFunc actionFunc; /* 0x0194 */ ColliderCylinder collider; - /* 0x01E0 */ struct_80034A14_arg1 unk_1E0; + /* 0x01E0 */ NpcInteractInfo interactInfo; /* 0x0208 */ u8 talkState; /* 0x0209 */ u8 csState; /* 0x020A */ u8 leftEyeState; diff --git a/soh/src/overlays/actors/ovl_En_Zo/z_en_zo.c b/soh/src/overlays/actors/ovl_En_Zo/z_en_zo.c index 78ef6e2984b..885c5870897 100644 --- a/soh/src/overlays/actors/ovl_En_Zo/z_en_zo.c +++ b/soh/src/overlays/actors/ovl_En_Zo/z_en_zo.c @@ -456,13 +456,13 @@ s16 func_80B61298(PlayState* play, Actor* thisx) { case TEXT_STATE_SONG_DEMO_DONE: case TEXT_STATE_8: case TEXT_STATE_9: - return 1; + return NPC_TALK_STATE_TALKING; case TEXT_STATE_CLOSING: switch (thisx->textId) { case 0x4020: case 0x4021: - return 0; + return NPC_TALK_STATE_IDLE; case 0x4008: gSaveContext.infTable[18] |= 0x10; break; @@ -471,12 +471,12 @@ s16 func_80B61298(PlayState* play, Actor* thisx) { break; } gSaveContext.eventChkInf[3] |= 1; - return 0; + return NPC_TALK_STATE_IDLE; case TEXT_STATE_CHOICE: switch (Message_ShouldAdvance(play)) { case 0: - return 1; + return NPC_TALK_STATE_TALKING; default: if (thisx->textId == 0x400C) { thisx->textId = (play->msgCtx.choiceIndex == 0) ? 0x400D : 0x400E; @@ -484,18 +484,18 @@ s16 func_80B61298(PlayState* play, Actor* thisx) { } break; } - return 1; + return NPC_TALK_STATE_TALKING; case TEXT_STATE_EVENT: switch (Message_ShouldAdvance(play)) { case 0: - return 1; + return NPC_TALK_STATE_TALKING; default: - return 2; + return NPC_TALK_STATE_ACTION; } } - return 1; + return NPC_TALK_STATE_TALKING; } void EnZo_Blink(EnZo* this) { @@ -511,16 +511,17 @@ void EnZo_Blink(EnZo* this) { void EnZo_Dialog(EnZo* this, PlayState* play) { Player* player = GET_PLAYER(play); - this->unk_194.unk_18 = player->actor.world.pos; + this->interactInfo.trackPos = player->actor.world.pos; if (this->actionFunc == EnZo_Standing) { // Look down at link if young, look up if old - this->unk_194.unk_14 = !LINK_IS_ADULT ? 10.0f : -10.0f; + this->interactInfo.yOffset = !LINK_IS_ADULT ? 10.0f : -10.0f; } else { - this->unk_194.unk_18.y = this->actor.world.pos.y; + this->interactInfo.trackPos.y = this->actor.world.pos.y; } - func_80034A14(&this->actor, &this->unk_194, 11, this->unk_64C); + Npc_TrackPoint(&this->actor, &this->interactInfo, 11, this->trackingMode); if (this->canSpeak == true) { - func_800343CC(play, &this->actor, &this->unk_194.unk_00, this->dialogRadius, func_80B61024, func_80B61298); + Npc_UpdateTalking(play, &this->actor, &this->interactInfo.talkState, this->dialogRadius, func_80B61024, + func_80B61298); } } @@ -548,7 +549,7 @@ void EnZo_SetAnimation(EnZo* this) { if (this->skelAnime.animation == &gZoraHandsOnHipsTappingFootAnim || this->skelAnime.animation == &gZoraOpenArmsAnim) { - if (this->unk_194.unk_00 == 0) { + if (this->interactInfo.talkState == NPC_TALK_STATE_IDLE) { if (this->actionFunc == EnZo_Standing) { animId = ENZO_ANIM_0; } else { @@ -557,12 +558,13 @@ void EnZo_SetAnimation(EnZo* this) { } } - if (this->unk_194.unk_00 != 0 && this->actor.textId == 0x4006 && + if (this->interactInfo.talkState != NPC_TALK_STATE_IDLE && this->actor.textId == 0x4006 && this->skelAnime.animation != &gZoraHandsOnHipsTappingFootAnim) { animId = ENZO_ANIM_6; } - if (this->unk_194.unk_00 != 0 && this->actor.textId == 0x4007 && this->skelAnime.animation != &gZoraOpenArmsAnim) { + if (this->interactInfo.talkState != NPC_TALK_STATE_IDLE && this->actor.textId == 0x4007 && + this->skelAnime.animation != &gZoraOpenArmsAnim) { animId = ENZO_ANIM_7; } @@ -593,9 +595,9 @@ void EnZo_Init(Actor* thisx, PlayState* play) { Actor_SetScale(&this->actor, 0.01f); this->actor.targetMode = 6; this->dialogRadius = this->collider.dim.radius + 30.0f; - this->unk_64C = 1; + this->trackingMode = NPC_TRACKING_NONE; this->canSpeak = false; - this->unk_194.unk_00 = 0; + this->interactInfo.talkState = NPC_TALK_STATE_IDLE; Actor_UpdateBgCheckInfo(play, &this->actor, this->collider.dim.height * 0.5f, this->collider.dim.radius, 0.0f, 5); @@ -620,20 +622,20 @@ void EnZo_Standing(EnZo* this, PlayState* play) { func_80034F54(play, this->unk_656, this->unk_67E, 20); EnZo_SetAnimation(this); - if (this->unk_194.unk_00 != 0) { - this->unk_64C = 4; + if (this->interactInfo.talkState != NPC_TALK_STATE_IDLE) { + this->trackingMode = NPC_TRACKING_FULL_BODY; return; } angle = ABS((s16)((f32)this->actor.yawTowardsPlayer - (f32)this->actor.shape.rot.y)); if (angle < 0x4718) { if (EnZo_PlayerInProximity(this, play)) { - this->unk_64C = 2; + this->trackingMode = NPC_TRACKING_HEAD_AND_TORSO; } else { - this->unk_64C = 1; + this->trackingMode = NPC_TRACKING_NONE; } } else { - this->unk_64C = 1; + this->trackingMode = NPC_TRACKING_NONE; } } @@ -663,7 +665,7 @@ void EnZo_TreadWater(EnZo* this, PlayState* play) { func_80034F54(play, this->unk_656, this->unk_67E, 20); if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { this->canSpeak = true; - this->unk_64C = 4; + this->trackingMode = NPC_TRACKING_FULL_BODY; this->skelAnime.playSpeed = 0.0f; } EnZo_SetAnimation(this); @@ -685,7 +687,7 @@ void EnZo_TreadWater(EnZo* this, PlayState* play) { f32 startFrame; Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENZO_ANIM_4); this->canSpeak = false; - this->unk_64C = 1; + this->trackingMode = NPC_TRACKING_NONE; this->actionFunc = EnZo_Dive; startFrame = this->skelAnime.startFrame; this->skelAnime.startFrame = this->skelAnime.endFrame; @@ -763,14 +765,14 @@ s32 EnZo_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* po if (limbIndex == 15) { Matrix_Translate(1800.0f, 0.0f, 0.0f, MTXMODE_APPLY); - vec = this->unk_194.unk_08; + vec = this->interactInfo.headRot; Matrix_RotateX((vec.y / 32768.0f) * M_PI, MTXMODE_APPLY); Matrix_RotateZ((vec.x / 32768.0f) * M_PI, MTXMODE_APPLY); Matrix_Translate(-1800.0f, 0.0f, 0.0f, MTXMODE_APPLY); } if (limbIndex == 8) { - vec = this->unk_194.unk_0E; + vec = this->interactInfo.torsoRot; Matrix_RotateX((-vec.y / 32768.0f) * M_PI, MTXMODE_APPLY); Matrix_RotateZ((vec.x / 32768.0f) * M_PI, MTXMODE_APPLY); } diff --git a/soh/src/overlays/actors/ovl_En_Zo/z_en_zo.h b/soh/src/overlays/actors/ovl_En_Zo/z_en_zo.h index 4a6c30c9466..c99177fad8a 100644 --- a/soh/src/overlays/actors/ovl_En_Zo/z_en_zo.h +++ b/soh/src/overlays/actors/ovl_En_Zo/z_en_zo.h @@ -24,7 +24,7 @@ typedef struct EnZo { /* 0x0000 */ Actor actor; /* 0x014C */ SkelAnime skelAnime; /* 0x0190 */ EnZoActionFunc actionFunc; - /* 0x0194 */ struct_80034A14_arg1 unk_194; + /* 0x0194 */ NpcInteractInfo interactInfo; /* 0x01BC */ ColliderCylinder collider; /* 0x0208 */ u8 canSpeak; /* 0x020A */ Vec3s jointTable[20]; @@ -32,7 +32,7 @@ typedef struct EnZo { /* 0x02FC */ EnZoEffect effects[15]; /* 0x0644 */ f32 dialogRadius; /* 0x0648 */ f32 alpha; - /* 0x064C */ s16 unk_64C; + /* 0x064C */ s16 trackingMode; /* 0x064E */ s16 rippleTimer; /* 0x0650 */ s16 timeToDive; /* 0x0652 */ s16 blinkTimer; From edceb2d460c2c24b578a496688d8fa9418ca7dfb Mon Sep 17 00:00:00 2001 From: Christopher Leggett Date: Thu, 19 Jan 2023 03:32:05 -0500 Subject: [PATCH 04/22] Adds lock/unlock all buttons to Cosmetics Editor. (#2225) * Adds lock/unlock all buttons to Cosmetics Editor. Adds Lock All and Unlock All, which locks all visible cosmetics options (i.e. does not lock the advanced options if Advanced isn't checked, just like the existing randomize all buttons), and a Lock All Advanced and Unlock All Advanced button that is only visible while the Advanced Options are enabled. * Updates latest develop and CVar API Changes. --- .../cosmetics/CosmeticsEditor.cpp | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp index 141f0da7e12..ebfca5df8a5 100644 --- a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp +++ b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp @@ -1669,6 +1669,25 @@ void DrawCosmeticsEditor(bool& open) { ImGui::SameLine(); UIWidgets::EnhancementCombobox("gCosmetics.DefaultColorScheme", colorSchemes, 2, 0); UIWidgets::EnhancementCheckbox("Advanced Mode", "gCosmetics.AdvancedMode"); + if (CVarGetInteger("gCosmetics.AdvancedMode", 0)) { + if (ImGui::Button("Lock All Advanced", ImVec2(ImGui::GetContentRegionAvail().x / 2, 30.0f))) { + for (auto& [id, cosmeticOption] : cosmeticOptions) { + if (cosmeticOption.advancedOption) { + CVarSetInteger(cosmeticOption.lockedCvar, 1); + } + } + SohImGui::RequestCvarSaveOnNextTick(); + } + ImGui::SameLine(); + if (ImGui::Button("Unlock All Advanced", ImVec2(ImGui::GetContentRegionAvail().x, 30.0f))) { + for (auto& [id, cosmeticOption] : cosmeticOptions) { + if (cosmeticOption.advancedOption) { + CVarSetInteger(cosmeticOption.lockedCvar, 0); + } + } + SohImGui::RequestCvarSaveOnNextTick(); + } + } UIWidgets::EnhancementCheckbox("Sync Rainbow colors", "gCosmetics.RainbowSync"); UIWidgets::EnhancementSliderFloat("Rainbow Speed: %f", "##rainbowSpeed", "gCosmetics.RainbowSpeed", 0.03f, 1.0f, "", 0.6f, false); if (ImGui::Button("Randomize All", ImVec2(ImGui::GetContentRegionAvail().x / 2, 30.0f))) { @@ -1691,6 +1710,24 @@ void DrawCosmeticsEditor(bool& open) { SohImGui::RequestCvarSaveOnNextTick(); } + if (ImGui::Button("Lock All", ImVec2(ImGui::GetContentRegionAvail().x / 2, 30.0f))) { + for (auto& [id, cosmeticOption] : cosmeticOptions) { + if (!cosmeticOption.advancedOption || CVarGetInteger("gCosmetics.AdvancedMode", 0)) { + CVarSetInteger(cosmeticOption.lockedCvar, 1); + } + } + SohImGui::RequestCvarSaveOnNextTick(); + } + ImGui::SameLine(); + if (ImGui::Button("Unlock All", ImVec2(ImGui::GetContentRegionAvail().x, 30.0f))) { + for (auto& [id, cosmeticOption] : cosmeticOptions) { + if (!cosmeticOption.advancedOption || CVarGetInteger("gCosmetics.AdvancedMode", 0)) { + CVarSetInteger(cosmeticOption.lockedCvar, 0); + } + } + SohImGui::RequestCvarSaveOnNextTick(); + } + if (ImGui::BeginTabBar("CosmeticsContextTabBar", ImGuiTabBarFlags_NoCloseWithMiddleMouseButton)) { if (ImGui::BeginTabItem("Link & Items")) { DrawCosmeticGroup(GROUP_LINK); From a335aba98729b1933c439f6d5d4939df4fb12708 Mon Sep 17 00:00:00 2001 From: Christopher Leggett Date: Thu, 19 Jan 2023 03:50:50 -0500 Subject: [PATCH 05/22] Adds option for showing sequence names on the overlay (#2237) * Adds option for showing sequence names on the overlay Allows sequences to appear on the overlay in the bottom right corner for a few seconds whenever a new one is loaded into the primary sequence player. This means it does not apply to fanfares or enemy bgm. Fanfares I chose not to display because it would cause a lot of text to display back to back in some areas, and enemy bgm would have some technical challenges with this due to the way it loads. Mainly because the Lost Woods music would load in Goron City the same way (as well as the opposite). * Fixes crash when a sequence without a name is attempted to be displayed. * Removes accidentally committed CMakeSettings.json * Updates CVar_GetS32 to CVarGetInteger --- soh/soh/Enhancements/sfx-editor/SfxEditor.cpp | 13 +++++++++++++ soh/soh/Enhancements/sfx-editor/SfxEditor.h | 1 + soh/src/code/audio_load.c | 6 ++++++ 3 files changed, 20 insertions(+) diff --git a/soh/soh/Enhancements/sfx-editor/SfxEditor.cpp b/soh/soh/Enhancements/sfx-editor/SfxEditor.cpp index f336189d0d2..19a862584e0 100644 --- a/soh/soh/Enhancements/sfx-editor/SfxEditor.cpp +++ b/soh/soh/Enhancements/sfx-editor/SfxEditor.cpp @@ -384,6 +384,14 @@ extern "C" u16 SfxEditor_GetReverseReplacementSeq(u16 seqId) { return static_cast(seqId); } +extern "C" const char* SfxEditor_GetSequenceName(u16 seqId) { + if (sfxEditorSequenceMap.contains(seqId)) { + const char *name = std::get<0>(sfxEditorSequenceMap.at(seqId)).c_str(); + return name; + } + return NULL; +} + void DrawSfxEditor(bool& open) { if (!open) { CVarSetInteger("gSfxEditor", 0); @@ -435,6 +443,11 @@ void DrawSfxEditor(bool& open) { UIWidgets::InsertHelpHoverText( "Disables the music change when getting close to enemies. Useful for hearing " "your custom music for each scene more often."); + UIWidgets::EnhancementCheckbox("Display Sequence Name on Overlay", "gSeqNameOverlay"); + UIWidgets::InsertHelpHoverText( + "Displays the name of the current sequence in the corner of the screen whenever a new sequence " + "is loaded to the main sequence player (does not apply to fanfares or enemy BGM)." + ); UIWidgets::PaddedSeparator(); UIWidgets::PaddedText("The following options are experimental and may cause music\nto sound odd or have other undesireable effects."); UIWidgets::EnhancementCheckbox("Lower Octaves of Unplayable High Notes", "gExperimentalOctaveDrop"); diff --git a/soh/soh/Enhancements/sfx-editor/SfxEditor.h b/soh/soh/Enhancements/sfx-editor/SfxEditor.h index 526cd41f9e7..5b1cd39fd77 100644 --- a/soh/soh/Enhancements/sfx-editor/SfxEditor.h +++ b/soh/soh/Enhancements/sfx-editor/SfxEditor.h @@ -3,6 +3,7 @@ void InitSfxEditor(); #ifndef __cplusplus +const char* SfxEditor_GetSequenceName(u16 seqId); void SfxEditor_AddSequence(char *otrPath, uint16_t seqNum); #endif diff --git a/soh/src/code/audio_load.c b/soh/src/code/audio_load.c index 7883aa405e3..03542f84fe4 100644 --- a/soh/src/code/audio_load.c +++ b/soh/src/code/audio_load.c @@ -612,6 +612,12 @@ s32 AudioLoad_SyncInitSeqPlayerInternal(s32 playerIdx, s32 seqId, s32 arg2) { seqPlayer->playerIdx = playerIdx; AudioSeq_SkipForwardSequence(seqPlayer); //! @bug missing return (but the return value is not used so it's not UB) + if (CVarGetInteger("gSeqNameOverlay", 0) && playerIdx == SEQ_PLAYER_BGM_MAIN) { + const char* sequenceName = SfxEditor_GetSequenceName(seqId); + if (sequenceName != NULL) { + Overlay_DisplayText(5.0f, sequenceName); + } + } } u8* AudioLoad_SyncLoadSeq(s32 seqId) { From 12737143c7c5470ba90963cf02c92d5de5cec019 Mon Sep 17 00:00:00 2001 From: Christopher Leggett Date: Thu, 19 Jan 2023 04:10:47 -0500 Subject: [PATCH 06/22] Adds option to add higher pitches to silver rupee jingle (#2246) * Adds option to add higher pitches to silver rupee jingle. Some rooms in Master Quest had 10 silver rupees, but the game was programmed to only play the jingle 5 times and then just went silent for the rest. This option adds 5 more transposition values to the array, and an option to play them (so that authentic behavior is preserved by default). * Adds the new option to Vanilla Plus preset and up Also adds it to the list to be reset back to 0 when applying the default preset. * Changes display name of checkbox. * Change CVar_GetS32 to CVarGetInteger --- soh/soh/Enhancements/presets.h | 7 +++++++ soh/soh/GameMenuBar.cpp | 4 ++++ soh/src/overlays/actors/ovl_En_G_Switch/z_en_g_switch.c | 4 ++-- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/soh/soh/Enhancements/presets.h b/soh/soh/Enhancements/presets.h index 8c6a3cab6e1..3cdcd6180ee 100644 --- a/soh/soh/Enhancements/presets.h +++ b/soh/soh/Enhancements/presets.h @@ -173,6 +173,7 @@ const std::vector enhancementsCvars = { "gBombchuBowlingNoBigCucco", "gBombchuBowlingAmmunition", "gCreditsFix", + "gSilverRupeeJingleExtend" }; const std::vector randomizerCvars = { @@ -320,6 +321,8 @@ const std::vector vanillaPlusPresetEntries = { PRESET_ENTRY_S32("gDekuNutUpgradeFix", 1), // Fix Navi text HUD position PRESET_ENTRY_S32("gNaviTextFix", 1), + // Extend Silver Rupee Jingle + PRESET_ENTRY_S32("gSilverRupeeJingleExtend", 1), // Red Ganon blood PRESET_ENTRY_S32("gRedGanonBlood", 1), @@ -383,6 +386,8 @@ const std::vector enhancedPresetEntries = { PRESET_ENTRY_S32("gDekuNutUpgradeFix", 1), // Fix Navi text HUD position PRESET_ENTRY_S32("gNaviTextFix", 1), + // Extend Silver Rupee Jingle + PRESET_ENTRY_S32("gSilverRupeeJingleExtend", 1), // Red Ganon blood PRESET_ENTRY_S32("gRedGanonBlood", 1), @@ -495,6 +500,8 @@ const std::vector randomizerPresetEntries = { PRESET_ENTRY_S32("gDekuNutUpgradeFix", 1), // Fix Navi text HUD position PRESET_ENTRY_S32("gNaviTextFix", 1), + // Extend Silver Rupee Jingle + PRESET_ENTRY_S32("gSilverRupeeJingleExtend", 1), // Red Ganon blood PRESET_ENTRY_S32("gRedGanonBlood", 1), diff --git a/soh/soh/GameMenuBar.cpp b/soh/soh/GameMenuBar.cpp index b6dea1dc57e..a1bcdbec12a 100644 --- a/soh/soh/GameMenuBar.cpp +++ b/soh/soh/GameMenuBar.cpp @@ -761,6 +761,10 @@ namespace GameMenuBar { UIWidgets::Tooltip("Fixes camera getting stuck on collision when standing still, also fixes slight shift back in camera when stop moving"); UIWidgets::PaddedEnhancementCheckbox("Fix Hanging Ledge Swing Rate", "gFixHangingLedgeSwingRate", true, false); UIWidgets::Tooltip("Fixes camera swing rate when player falls of a ledge and camera swings around"); + UIWidgets::PaddedEnhancementCheckbox("Fix Missing Jingle after 5 Silver Rupees", "gSilverRupeeJingleExtend", true, false); + UIWidgets::Tooltip( + "Adds 5 higher pitches for the Silver Rupee Jingle for the rooms with more than 5 Silver Rupees. " + "Currently only relevant in Master Quest."); ImGui::EndMenu(); } diff --git a/soh/src/overlays/actors/ovl_En_G_Switch/z_en_g_switch.c b/soh/src/overlays/actors/ovl_En_G_Switch/z_en_g_switch.c index e152da4f36b..1cbcf8b1e4a 100644 --- a/soh/src/overlays/actors/ovl_En_G_Switch/z_en_g_switch.c +++ b/soh/src/overlays/actors/ovl_En_G_Switch/z_en_g_switch.c @@ -226,10 +226,10 @@ void EnGSwitch_WaitForObject(EnGSwitch* this, PlayState* play) { } void EnGSwitch_SilverRupeeTracker(EnGSwitch* this, PlayState* play) { - static s8 majorScale[] = { 0, 2, 4, 5, 7 }; + static s8 majorScale[] = { 0, 2, 4, 5, 7, 9, 11, 13, 15, 17 }; if (this->noteIndex < sCollectedCount) { - if (sCollectedCount < 5) { + if (sCollectedCount < (CVarGetInteger("gSilverRupeeJingleExtend", 0) ? 10 : 5)) { // "sound?" osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 音? ☆☆☆☆☆ %d\n" VT_RST, this->noteIndex); Audio_PlaySoundTransposed(&D_801333D4, NA_SE_EV_FIVE_COUNT_LUPY, majorScale[this->noteIndex]); From d9662ab63ba59c815085630a0f25daece51f6532 Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Thu, 19 Jan 2023 04:33:07 -0500 Subject: [PATCH 07/22] fix: update cvar usage from merge --- soh/soh/OTRGlobals.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index f7e3ab2773a..14dbdae2fbb 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -498,7 +498,7 @@ extern "C" void InitOTR() { #ifdef ENABLE_CROWD_CONTROL CrowdControl::Instance = new CrowdControl(); CrowdControl::Instance->Init(); - if (CVar_GetS32("gCrowdControl", 0)) { + if (CVarGetInteger("gCrowdControl", 0)) { CrowdControl::Instance->Enable(); } else { CrowdControl::Instance->Disable(); From d6dbaacb0332037940b710e89d33b2681202b3d6 Mon Sep 17 00:00:00 2001 From: th-2021 <90853655+th-2021@users.noreply.github.com> Date: Thu, 19 Jan 2023 10:47:21 +0100 Subject: [PATCH 08/22] add OPTIONAL flag to avaid error when OTRGui is not build (#2299) --- OTRGui/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OTRGui/CMakeLists.txt b/OTRGui/CMakeLists.txt index 2933c05d37b..9eec59c8459 100644 --- a/OTRGui/CMakeLists.txt +++ b/OTRGui/CMakeLists.txt @@ -59,7 +59,7 @@ target_include_directories(${PROJECT_NAME} PRIVATE . ) -INSTALL(TARGETS OTRGui DESTINATION . COMPONENT ship) +INSTALL(TARGETS OTRGui DESTINATION . COMPONENT ship OPTIONAL) install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/assets DESTINATION . COMPONENT ship From c0ad43e50939fd57710c1b3c9cc85675a5091c26 Mon Sep 17 00:00:00 2001 From: Patrick12115 <115201185+Patrick12115@users.noreply.github.com> Date: Thu, 19 Jan 2023 04:54:29 -0500 Subject: [PATCH 09/22] Add Starting Songs Option (#2221) --- soh/soh/Enhancements/presets.h | 12 +++ .../randomizer/3drando/settings.cpp | 37 ++++++--- .../randomizer/3drando/spoiler_log.cpp | 22 +++++- .../Enhancements/randomizer/randomizer.cpp | 75 ++++++++++++++++++- .../Enhancements/randomizer/randomizerTypes.h | 12 +++ soh/src/code/z_sram.c | 13 ++++ 6 files changed, 157 insertions(+), 14 deletions(-) diff --git a/soh/soh/Enhancements/presets.h b/soh/soh/Enhancements/presets.h index 3cdcd6180ee..3a86dc341f0 100644 --- a/soh/soh/Enhancements/presets.h +++ b/soh/soh/Enhancements/presets.h @@ -260,11 +260,23 @@ const std::vector randomizerCvars = { "gRandomizeSkipTowerEscape", "gRandomizeStartingAge", "gRandomizeStartingConsumables", + "gRandomizeStartingBoleroOfFire", "gRandomizeStartingDekuShield", + "gRandomizeStartingEponasSong", "gRandomizeStartingKokiriSword", "gRandomizeStartingMapsCompasses", + "gRandomizeStartingMinuetOfForest", + "gRandomizeStartingNocturneOfShadow", "gRandomizeStartingOcarina", + "gRandomizeStartingPreludeOfLight", + "gRandomizeStartingRequiemOfSpirit", + "gRandomizeStartingSariasSong", + "gRandomizeStartingSerenadeOfWater", "gRandomizeStartingSkulltulaToken", + "gRandomizeStartingSongOfStorms", + "gRandomizeStartingSongOfTime", + "gRandomizeStartingSunsSong", + "gRandomizeStartingZeldasLullaby", "gRandomizeStoneCount", "gRandomizeSunlightArrows", "gRandomizeTokenCount", diff --git a/soh/soh/Enhancements/randomizer/3drando/settings.cpp b/soh/soh/Enhancements/randomizer/3drando/settings.cpp index 4dfa26afb69..213d8b602d0 100644 --- a/soh/soh/Enhancements/randomizer/3drando/settings.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/settings.cpp @@ -509,18 +509,18 @@ namespace Settings { &StartingRutoBottle, }; - Option StartingZeldasLullaby = Option::U8 ("Zelda's Lullaby", {"Off", "On"}, {""}); - Option StartingEponasSong = Option::U8 ("Epona's Song", {"Off", "On"}, {""}); - Option StartingSariasSong = Option::U8 ("Saria's Song", {"Off", "On"}, {""}); - Option StartingSunsSong = Option::U8 ("Sun's Song", {"Off", "On"}, {""}); - Option StartingSongOfTime = Option::U8 ("Song of Time", {"Off", "On"}, {""}); - Option StartingSongOfStorms = Option::U8 ("Song of Storms", {"Off", "On"}, {""}); - Option StartingMinuetOfForest = Option::U8 ("Minuet of Forest", {"Off", "On"}, {""}); - Option StartingBoleroOfFire = Option::U8 ("Bolero of Fire", {"Off", "On"}, {""}); - Option StartingSerenadeOfWater = Option::U8 ("Serenade of Water", {"Off", "On"}, {""}); - Option StartingRequiemOfSpirit = Option::U8 ("Requiem of Spirit", {"Off", "On"}, {""}); - Option StartingNocturneOfShadow = Option::U8 ("Nocturne of Shadow", {"Off", "On"}, {""}); - Option StartingPreludeOfLight = Option::U8 ("Prelude of Light", {"Off", "On"}, {""}); + Option StartingZeldasLullaby = Option::U8 ("Start with Zelda's Lullaby", {"Off", "On"}, {""}); + Option StartingEponasSong = Option::U8 ("Start with Epona's Song", {"Off", "On"}, {""}); + Option StartingSariasSong = Option::U8 ("Start with Saria's Song", {"Off", "On"}, {""}); + Option StartingSunsSong = Option::U8 ("Start with Sun's Song", {"Off", "On"}, {""}); + Option StartingSongOfTime = Option::U8 ("Start with Song of Time", {"Off", "On"}, {""}); + Option StartingSongOfStorms = Option::U8 ("Start with Song of Storms", {"Off", "On"}, {""}); + Option StartingMinuetOfForest = Option::U8 ("Start with Minuet of Forest", {"Off", "On"}, {""}); + Option StartingBoleroOfFire = Option::U8 ("Start with Bolero of Fire", {"Off", "On"}, {""}); + Option StartingSerenadeOfWater = Option::U8 ("Start with Serenade of Water", {"Off", "On"}, {""}); + Option StartingRequiemOfSpirit = Option::U8 ("Start with Requiem of Spirit", {"Off", "On"}, {""}); + Option StartingNocturneOfShadow = Option::U8 ("Start with Nocturne of Shadow", {"Off", "On"}, {""}); + Option StartingPreludeOfLight = Option::U8 ("Start with Prelude of Light", {"Off", "On"}, {""}); std::vector