Document Actor Ocarina Interaction (#1748)

* ocarina interaction

* cleanup

* 0x

* document zora exception

* add comment
This commit is contained in:
engineer124 2024-11-30 04:58:42 +11:00 committed by GitHub
parent b84e27c732
commit 4c3fa3efd4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 105 additions and 91 deletions

View File

@ -569,8 +569,12 @@ typedef enum DoorLockType {
// //
#define ACTOR_FLAG_10000000 (1 << 28) #define ACTOR_FLAG_10000000 (1 << 28)
//
#define ACTOR_FLAG_20000000 (1 << 29) // Signals that player has accepted an offer to use the ocarina to interact with an actor
// An exception is made for EN_ZOT, see `Player_ActionHandler_13`.
// Player will retain this flag until the player is finished playing the ocarina
// Actor will retain this flag until `Actor_OcarinaInteractionAccepted` is called or manually turned off by the actor
#define ACTOR_FLAG_OCARINA_INTERACTION (1 << 29)
// Camera will slowly drift to the actor while approaching it. // Camera will slowly drift to the actor while approaching it.
// Uses the attention system but `ACTOR_FLAG_ATTENTION_ENABLED` is not required. // Uses the attention system but `ACTOR_FLAG_ATTENTION_ENABLED` is not required.
@ -839,10 +843,10 @@ s32 Actor_OfferTalkNearColChkInfoCylinder(Actor* actor, struct PlayState* play);
s32 Actor_TextboxIsClosing(Actor* actor, struct PlayState* play); s32 Actor_TextboxIsClosing(Actor* actor, struct PlayState* play);
s32 Actor_ChangeFocus(Actor* actor1, struct PlayState* play, Actor* actor2); s32 Actor_ChangeFocus(Actor* actor1, struct PlayState* play, Actor* actor2);
s32 func_800B8718(Actor* actor, struct GameState* gameState); s32 Actor_OcarinaInteractionAccepted(Actor* actor, struct GameState* gameState);
s32 func_800B874C(Actor* actor, struct PlayState* play, f32 xzRange, f32 yRange); s32 Actor_OfferOcarinaInteraction(Actor* actor, struct PlayState* play, f32 xzRange, f32 yRange);
s32 func_800B8804(Actor* actor, struct PlayState* play, f32 xzRange); s32 Actor_OfferOcarinaInteractionNearby(Actor* actor, struct PlayState* play, f32 xzRange);
s32 func_800B886C(Actor* actor, struct PlayState* play); s32 Actor_NoOcarinaInteraction(Actor* actor, struct PlayState* play);
void Actor_GetScreenPos(struct PlayState* play, Actor* actor, s16* posX, s16* posY); void Actor_GetScreenPos(struct PlayState* play, Actor* actor, s16* posX, s16* posY);
bool Actor_OnScreen(struct PlayState* play, Actor* actor); bool Actor_OnScreen(struct PlayState* play, Actor* actor);
s32 Actor_HasParent(Actor* actor, struct PlayState* play); s32 Actor_HasParent(Actor* actor, struct PlayState* play);

View File

@ -1148,7 +1148,7 @@ typedef struct Player {
/* 0x164 */ Gfx** waistDLists; /* 0x164 */ Gfx** waistDLists;
/* 0x168 */ UNK_TYPE1 unk_168[0x4C]; /* 0x168 */ UNK_TYPE1 unk_168[0x4C];
/* 0x1B4 */ s16 unk_1B4; /* 0x1B4 */ s16 unk_1B4;
/* 0x1B6 */ char unk_1B6[2]; /* 0x1B6 */ UNK_TYPE1 unk_1B6[0x2];
/* 0x1B8 */ u8 giObjectLoading; /* 0x1B8 */ u8 giObjectLoading;
/* 0x1BC */ DmaRequest giObjectDmaRequest; /* 0x1BC */ DmaRequest giObjectDmaRequest;
/* 0x1DC */ OSMesgQueue giObjectLoadQueue; /* 0x1DC */ OSMesgQueue giObjectLoadQueue;
@ -1194,7 +1194,6 @@ typedef struct Player {
s16 doorBgCamIndex; // `BgCamIndex` used during a sliding door and spiral staircase cutscenes s16 doorBgCamIndex; // `BgCamIndex` used during a sliding door and spiral staircase cutscenes
} cv; // "Cutscene Variable": context dependent variable that has different meanings depending on what function is called } cv; // "Cutscene Variable": context dependent variable that has different meanings depending on what function is called
/* 0x3BC */ s16 subCamId; /* 0x3BC */ s16 subCamId;
/* 0x3BE */ char unk_3BE[2];
/* 0x3C0 */ Vec3f unk_3C0; /* 0x3C0 */ Vec3f unk_3C0;
/* 0x3CC */ s16 unk_3CC; /* 0x3CC */ s16 unk_3CC;
/* 0x3CE */ s8 unk_3CE; /* 0x3CE */ s8 unk_3CE;
@ -1208,7 +1207,7 @@ typedef struct Player {
/* 0x664 */ ColliderQuad shieldQuad; /* 0x664 */ ColliderQuad shieldQuad;
/* 0x6E4 */ ColliderCylinder shieldCylinder; /* 0x6E4 */ ColliderCylinder shieldCylinder;
/* 0x730 */ Actor* focusActor; // Actor that Player and the camera are looking at; Used for lock-on, talking, and more /* 0x730 */ Actor* focusActor; // Actor that Player and the camera are looking at; Used for lock-on, talking, and more
/* 0x734 */ char unk_734[4]; /* 0x734 */ UNK_TYPE1 unk_734[0x4];
/* 0x738 */ s32 zTargetActiveTimer; // Non-zero values indicate Z-Targeting should update; Values under 5 indicate lock-on is releasing /* 0x738 */ s32 zTargetActiveTimer; // Non-zero values indicate Z-Targeting should update; Values under 5 indicate lock-on is releasing
/* 0x73C */ s32 meleeWeaponEffectIndex[3]; /* 0x73C */ s32 meleeWeaponEffectIndex[3];
/* 0x748 */ PlayerActionFunc actionFunc; /* 0x748 */ PlayerActionFunc actionFunc;
@ -1229,9 +1228,9 @@ typedef struct Player {
/* 0xA87 */ s8 exchangeItemAction; // PlayerItemAction enum /* 0xA87 */ s8 exchangeItemAction; // PlayerItemAction enum
/* 0xA88 */ Actor* talkActor; /* 0xA88 */ Actor* talkActor;
/* 0xA8C */ f32 talkActorDistance; /* 0xA8C */ f32 talkActorDistance;
/* 0xA90 */ Actor* unk_A90; /* 0xA90 */ Actor* ocarinaInteractionActor;
/* 0xA94 */ f32 unk_A94; /* 0xA94 */ f32 ocarinaInteractionDistance;
/* 0xA98 */ Actor* unk_A98; /* 0xA98 */ UNK_TYPE1 unk_A98[0x4];
/* 0xA9C */ f32 secretRumbleCharge; // builds per frame until discharges with a rumble request /* 0xA9C */ f32 secretRumbleCharge; // builds per frame until discharges with a rumble request
/* 0xAA0 */ f32 closestSecretDistSq; // Used to augment `secretRumbleCharge`. Cleared every frame /* 0xAA0 */ f32 closestSecretDistSq; // Used to augment `secretRumbleCharge`. Cleared every frame
/* 0xAA4 */ s8 idleType; /* 0xAA4 */ s8 idleType;

View File

@ -2109,42 +2109,49 @@ PlayerItemAction Player_GetExchangeItemAction(PlayState* play) {
return player->exchangeItemAction; return player->exchangeItemAction;
} }
s32 func_800B8718(Actor* actor, GameState* gameState) { /**
if (actor->flags & ACTOR_FLAG_20000000) { * When a given ocarina interaction offer is accepted, Player will set `ACTOR_FLAG_OCARINA_INTERACTION` for that actor.
actor->flags &= ~ACTOR_FLAG_20000000; * An exception is made for EN_ZOT, see `Player_ActionHandler_13`.
* This function serves to acknowledge that the offer was accepted by Player, and notifies the actor
* that it should proceed with its own internal processes for handling further interactions.
*
* @return true if the ocarina interaction offer was accepted, false otherwise
*/
s32 Actor_OcarinaInteractionAccepted(Actor* actor, GameState* gameState) {
if (actor->flags & ACTOR_FLAG_OCARINA_INTERACTION) {
actor->flags &= ~ACTOR_FLAG_OCARINA_INTERACTION;
return true; return true;
} }
return false; return false;
} }
// Similar to Actor_OfferTalkExchange s32 Actor_OfferOcarinaInteraction(Actor* actor, PlayState* play, f32 xzRange, f32 yRange) {
s32 func_800B874C(Actor* actor, PlayState* play, f32 xzRange, f32 yRange) {
Player* player = GET_PLAYER(play); Player* player = GET_PLAYER(play);
if ((player->actor.flags & ACTOR_FLAG_20000000) || Player_InCsMode(play) || if ((player->actor.flags & ACTOR_FLAG_OCARINA_INTERACTION) || Player_InCsMode(play) ||
(yRange < fabsf(actor->playerHeightRel)) || ((player->unk_A94 < actor->xzDistToPlayer)) || (yRange < fabsf(actor->playerHeightRel)) || ((player->ocarinaInteractionDistance < actor->xzDistToPlayer)) ||
(xzRange < actor->xzDistToPlayer)) { (xzRange < actor->xzDistToPlayer)) {
return false; return false;
} }
player->unk_A90 = actor; player->ocarinaInteractionActor = actor;
player->unk_A94 = actor->xzDistToPlayer; player->ocarinaInteractionDistance = actor->xzDistToPlayer;
return true; return true;
} }
s32 func_800B8804(Actor* actor, PlayState* play, f32 xzRange) { s32 Actor_OfferOcarinaInteractionNearby(Actor* actor, PlayState* play, f32 xzRange) {
return func_800B874C(actor, play, xzRange, 20.0f); return Actor_OfferOcarinaInteraction(actor, play, xzRange, 20.0f);
} }
s32 func_800B882C(Actor* actor, PlayState* play) { s32 Actor_OfferOcarinaInteractionColChkInfoCylinder(Actor* actor, PlayState* play) {
f32 cylRadius = actor->colChkInfo.cylRadius + 50.0f; f32 cylRadius = actor->colChkInfo.cylRadius + 50.0f;
return func_800B8804(actor, play, cylRadius); return Actor_OfferOcarinaInteractionNearby(actor, play, cylRadius);
} }
s32 func_800B886C(Actor* actor, PlayState* play) { s32 Actor_NoOcarinaInteraction(Actor* actor, PlayState* play) {
if (!(GET_PLAYER(play)->actor.flags & ACTOR_FLAG_20000000)) { if (!(GET_PLAYER(play)->actor.flags & ACTOR_FLAG_OCARINA_INTERACTION)) {
return true; return true;
} }

View File

@ -1838,10 +1838,11 @@ void DmStk_Update(Actor* thisx, PlayState* play) {
// This handles the cutscene where the player takes out the Deku Pipes for the first time. // This handles the cutscene where the player takes out the Deku Pipes for the first time.
switch (this->dekuPipesCutsceneState) { switch (this->dekuPipesCutsceneState) {
case SK_DEKU_PIPES_CS_STATE_READY: case SK_DEKU_PIPES_CS_STATE_READY:
if (func_800B8718(&this->actor, &play->state)) { if (Actor_OcarinaInteractionAccepted(&this->actor, &play->state)) {
this->dekuPipesCutsceneState = SK_DEKU_PIPES_CS_STATE_PLAYER_USED_OCARINA; this->dekuPipesCutsceneState = SK_DEKU_PIPES_CS_STATE_PLAYER_USED_OCARINA;
} else { } else {
func_800B874C(&this->actor, play, this->actor.xzDistToPlayer, fabsf(this->actor.playerHeightRel)); Actor_OfferOcarinaInteraction(&this->actor, play, this->actor.xzDistToPlayer,
fabsf(this->actor.playerHeightRel));
} }
break; break;

View File

@ -193,7 +193,7 @@ void func_80997D38(EnGs* this, PlayState* play) {
} }
if (this->actor.params != ENGS_2) { if (this->actor.params != ENGS_2) {
func_800B874C(&this->actor, play, 100.0f, 100.0f); Actor_OfferOcarinaInteraction(&this->actor, play, 100.0f, 100.0f);
} }
} }
@ -1036,7 +1036,7 @@ void EnGs_Update(Actor* thisx, PlayState* play) {
play->msgCtx.msgLength = 0; play->msgCtx.msgLength = 0;
this->collider.base.acFlags &= ~AC_HIT; this->collider.base.acFlags &= ~AC_HIT;
func_80997DEC(this, play); func_80997DEC(this, play);
} else if (func_800B8718(&this->actor, &play->state)) { } else if (Actor_OcarinaInteractionAccepted(&this->actor, &play->state)) {
this->unk_19A |= 0x200; this->unk_19A |= 0x200;
this->collider.base.acFlags &= ~AC_HIT; this->collider.base.acFlags &= ~AC_HIT;
if (this->actor.csId != CS_ID_NONE) { if (this->actor.csId != CS_ID_NONE) {

View File

@ -353,7 +353,7 @@ void EnKakasi_IdleStanding(EnKakasi* this, PlayState* play) {
// first talk to scarecrow dialogue // first talk to scarecrow dialogue
this->picto.actor.textId = 0x1644; this->picto.actor.textId = 0x1644;
if (func_800B8718(&this->picto.actor, &play->state)) { if (Actor_OcarinaInteractionAccepted(&this->picto.actor, &play->state)) {
this->skelAnime.playSpeed = 1.0f; this->skelAnime.playSpeed = 1.0f;
EnKakasi_SetupSongTeach(this, play); EnKakasi_SetupSongTeach(this, play);
return; return;
@ -386,7 +386,7 @@ void EnKakasi_IdleStanding(EnKakasi* this, PlayState* play) {
} }
if (this->picto.actor.xzDistToPlayer < 120.0f) { if (this->picto.actor.xzDistToPlayer < 120.0f) {
Actor_OfferTalk(&this->picto.actor, play, 100.0f); Actor_OfferTalk(&this->picto.actor, play, 100.0f);
func_800B874C(&this->picto.actor, play, 100.0f, 80.0f); Actor_OfferOcarinaInteraction(&this->picto.actor, play, 100.0f, 80.0f);
} }
} }

View File

@ -425,7 +425,7 @@ void func_80959E18(EnMk* this, PlayState* play) {
return; return;
} }
if (func_800B8718(&this->actor, &play->state)) { if (Actor_OcarinaInteractionAccepted(&this->actor, &play->state)) {
play->msgCtx.ocarinaMode = OCARINA_MODE_END; play->msgCtx.ocarinaMode = OCARINA_MODE_END;
this->actionFunc = func_80959D28; this->actionFunc = func_80959D28;
if (GET_PLAYER_FORM == PLAYER_FORM_ZORA) { if (GET_PLAYER_FORM == PLAYER_FORM_ZORA) {
@ -446,7 +446,7 @@ void func_80959E18(EnMk* this, PlayState* play) {
this->unk_27A |= 1; this->unk_27A |= 1;
Actor_OfferTalk(&this->actor, play, 200.0f); Actor_OfferTalk(&this->actor, play, 200.0f);
if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_20_40) && CHECK_WEEKEVENTREG(WEEKEVENTREG_19_40)) { if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_20_40) && CHECK_WEEKEVENTREG(WEEKEVENTREG_19_40)) {
func_800B874C(&this->actor, play, 200.0f, 100.0f); Actor_OfferOcarinaInteraction(&this->actor, play, 200.0f, 100.0f);
} }
} else { } else {
this->unk_27A &= ~1; this->unk_27A &= ~1;

View File

@ -1464,7 +1464,7 @@ void EnMnk_MonkeyTiedUp_WaitForInstrument(EnMnk* this, PlayState* play) {
SkelAnime_Update(&this->skelAnime); SkelAnime_Update(&this->skelAnime);
SkelAnime_Update(&this->propSkelAnime); SkelAnime_Update(&this->propSkelAnime);
if (func_800B8718(&this->picto.actor, &play->state)) { if (Actor_OcarinaInteractionAccepted(&this->picto.actor, &play->state)) {
switch (gSaveContext.save.playerForm) { switch (gSaveContext.save.playerForm) {
case PLAYER_FORM_HUMAN: case PLAYER_FORM_HUMAN:
case PLAYER_FORM_FIERCE_DEITY: case PLAYER_FORM_FIERCE_DEITY:
@ -1508,7 +1508,7 @@ void EnMnk_MonkeyTiedUp_WaitForInstrument(EnMnk* this, PlayState* play) {
} else if (EnMnk_PlayerIsInTalkRange(this, play)) { } else if (EnMnk_PlayerIsInTalkRange(this, play)) {
this->picto.actor.textId = 0x8D3; this->picto.actor.textId = 0x8D3;
Actor_OfferTalk(&this->picto.actor, play, 100.0f); Actor_OfferTalk(&this->picto.actor, play, 100.0f);
func_800B874C(&this->picto.actor, play, 100.0f, 100.0f); Actor_OfferOcarinaInteraction(&this->picto.actor, play, 100.0f, 100.0f);
} }
} }
@ -1570,7 +1570,7 @@ void EnMnk_MonkeyTiedUp_Wait(EnMnk* this, PlayState* play) {
SkelAnime_Update(&this->propSkelAnime); SkelAnime_Update(&this->propSkelAnime);
} }
} }
if (func_800B8718(&this->picto.actor, &play->state)) { if (Actor_OcarinaInteractionAccepted(&this->picto.actor, &play->state)) {
this->picto.actor.textId = 0x8D8; this->picto.actor.textId = 0x8D8;
EnMnk_MonkeyTiedUp_SetAnim(this, MONKEY_TIEDUP_ANIM_KICKUPANDDOWN); EnMnk_MonkeyTiedUp_SetAnim(this, MONKEY_TIEDUP_ANIM_KICKUPANDDOWN);
this->actionFunc = EnMnk_MonkeyTiedUp_TeachSong; this->actionFunc = EnMnk_MonkeyTiedUp_TeachSong;
@ -1597,7 +1597,7 @@ void EnMnk_MonkeyTiedUp_Wait(EnMnk* this, PlayState* play) {
} else { } else {
this->picto.actor.textId = 0x8CA; this->picto.actor.textId = 0x8CA;
} }
func_800B874C(&this->picto.actor, play, 100.0f, 100.0f); Actor_OfferOcarinaInteraction(&this->picto.actor, play, 100.0f, 100.0f);
} else { } else {
this->picto.actor.textId = 0x8CC; this->picto.actor.textId = 0x8CC;
} }

View File

@ -88,7 +88,7 @@ void func_8093E518(EnOkarinaTag* this, PlayState* play) {
if (this->unk14A == -1) { if (this->unk14A == -1) {
var_v1 = 0; var_v1 = 0;
} }
if (func_800B8718(&this->actor, &play->state)) { if (Actor_OcarinaInteractionAccepted(&this->actor, &play->state)) {
Message_DisplayOcarinaStaff(play, OCARINA_ACTION_CHECK_HEALING + var_v1); Message_DisplayOcarinaStaff(play, OCARINA_ACTION_CHECK_HEALING + var_v1);
this->actionFunc = func_8093E68C; this->actionFunc = func_8093E68C;
} else { } else {
@ -106,7 +106,7 @@ void func_8093E518(EnOkarinaTag* this, PlayState* play) {
if (yRange == 0.0f) { if (yRange == 0.0f) {
yRange = 50000.0f; yRange = 50000.0f;
} }
func_800B874C(&this->actor, play, xzRange, yRange); Actor_OfferOcarinaInteraction(&this->actor, play, xzRange, yRange);
} }
} }

View File

@ -150,7 +150,7 @@ void func_80B1217C(EnOnpuman* this, PlayState* play) {
void func_80B121D8(EnOnpuman* this, PlayState* play) { void func_80B121D8(EnOnpuman* this, PlayState* play) {
s16 yaw; s16 yaw;
if (func_800B8718(&this->actor, &play->state)) { if (Actor_OcarinaInteractionAccepted(&this->actor, &play->state)) {
this->actionFunc = func_80B1202C; this->actionFunc = func_80B1202C;
Message_StartTextbox(play, 0x8D4, NULL); Message_StartTextbox(play, 0x8D4, NULL);
this->unk_2A0 = func_80B11F44(play); this->unk_2A0 = func_80B11F44(play);
@ -162,7 +162,7 @@ void func_80B121D8(EnOnpuman* this, PlayState* play) {
if (ABS_ALT(yaw) <= 0x4300) { if (ABS_ALT(yaw) <= 0x4300) {
this->actor.textId = 0x8D3; this->actor.textId = 0x8D3;
Actor_OfferTalk(&this->actor, play, 100.0f); Actor_OfferTalk(&this->actor, play, 100.0f);
func_800B874C(&this->actor, play, 100.0f, 100.0f); Actor_OfferOcarinaInteraction(&this->actor, play, 100.0f, 100.0f);
} }
} }
} }

View File

@ -111,17 +111,12 @@ void EnWarpTag_WaitForPlayer(EnWarptag* this, PlayState* play) {
* Unused ActionFunc: assigned in EnWarpTag_Init, no known variants use. * Unused ActionFunc: assigned in EnWarpTag_Init, no known variants use.
*/ */
void EnWarpTag_Unused809C09A0(EnWarptag* this, PlayState* play) { void EnWarpTag_Unused809C09A0(EnWarptag* this, PlayState* play) {
if (func_800B8718(&this->dyna.actor, &play->state)) { if (Actor_OcarinaInteractionAccepted(&this->dyna.actor, &play->state)) {
// func above: checks for ACTOR_FLAG_20000000, returns true and resets if set, else return false
// this actor doesnt have that flag set default, or in init, and this is called shortly after init
// and I doubt its set externally by another actor, so I believe this is unused
// might be a bug, they might have meant to set actor flag (0x2000 0000) up above but mistyped (0x200 0000)
// also WARPTAG_GET_3C0 should always return 2C0 -> 0xF for all known in-game uses, which is OOB
Message_DisplayOcarinaStaff(play, D_809C1000[WARPTAG_GET_3C0(&this->dyna.actor)]); Message_DisplayOcarinaStaff(play, D_809C1000[WARPTAG_GET_3C0(&this->dyna.actor)]);
this->actionFunc = EnWarpTag_Unused809C0A20; this->actionFunc = EnWarpTag_Unused809C0A20;
} else { } else {
func_800B8804(&this->dyna.actor, play, 50.0f); // updates player->unk_A90 Actor_OfferOcarinaInteractionNearby(&this->dyna.actor, play, 50.0f);
} }
} }

View File

@ -293,7 +293,7 @@ void func_80B9FCA0(EnZob* this, PlayState* play) {
this->actionFunc = func_80BA0728; this->actionFunc = func_80BA0728;
this->unk_304 = 0; this->unk_304 = 0;
EnZob_ChangeAnim(this, ENZOB_ANIM_6, ANIMMODE_ONCE); EnZob_ChangeAnim(this, ENZOB_ANIM_6, ANIMMODE_ONCE);
func_800B8718(&this->actor, &play->state); Actor_OcarinaInteractionAccepted(&this->actor, &play->state);
} }
void func_80B9FD24(EnZob* this, PlayState* play) { void func_80B9FD24(EnZob* this, PlayState* play) {
@ -543,7 +543,7 @@ void func_80BA0374(EnZob* this, PlayState* play) {
case 0x1207: case 0x1207:
Message_CloseTextbox(play); Message_CloseTextbox(play);
this->actionFunc = func_80BA0318; this->actionFunc = func_80BA0318;
player->unk_A90 = &this->actor; player->ocarinaInteractionActor = &this->actor;
player->stateFlags3 |= PLAYER_STATE3_20; player->stateFlags3 |= PLAYER_STATE3_20;
break; break;
} }
@ -581,7 +581,7 @@ void func_80BA0728(EnZob* this, PlayState* play) {
func_80B9F86C(this); func_80B9F86C(this);
if (func_800B8718(&this->actor, &play->state)) { if (Actor_OcarinaInteractionAccepted(&this->actor, &play->state)) {
if (GET_PLAYER_FORM == PLAYER_FORM_ZORA) { if (GET_PLAYER_FORM == PLAYER_FORM_ZORA) {
Message_StartTextbox(play, 0x1208, NULL); Message_StartTextbox(play, 0x1208, NULL);
SET_WEEKEVENTREG(WEEKEVENTREG_30_08); SET_WEEKEVENTREG(WEEKEVENTREG_30_08);
@ -601,7 +601,7 @@ void func_80BA0728(EnZob* this, PlayState* play) {
} else if ((this->actor.xzDistToPlayer < 180.0f) && (this->actor.xzDistToPlayer > 60.0f) && } else if ((this->actor.xzDistToPlayer < 180.0f) && (this->actor.xzDistToPlayer > 60.0f) &&
Player_IsFacingActor(&this->actor, 0x3000, play) && Actor_IsFacingPlayer(&this->actor, 0x3000)) { Player_IsFacingActor(&this->actor, 0x3000, play) && Actor_IsFacingPlayer(&this->actor, 0x3000)) {
Actor_OfferTalk(&this->actor, play, 150.0f); Actor_OfferTalk(&this->actor, play, 150.0f);
func_800B874C(&this->actor, play, 200.0f, 150.0f); Actor_OfferOcarinaInteraction(&this->actor, play, 200.0f, 150.0f);
} }
seqPos.x = this->actor.projectedPos.x; seqPos.x = this->actor.projectedPos.x;

View File

@ -1170,7 +1170,7 @@ void func_80B98BF4(EnZot* this, PlayState* play) {
} }
void func_80B98CA8(EnZot* this, PlayState* play) { void func_80B98CA8(EnZot* this, PlayState* play) {
if (func_800B8718(&this->actor, &play->state)) { if (Actor_OcarinaInteractionAccepted(&this->actor, &play->state)) {
play->msgCtx.ocarinaMode = OCARINA_MODE_END; play->msgCtx.ocarinaMode = OCARINA_MODE_END;
AudioOcarina_StartDefault(0xFFFF); AudioOcarina_StartDefault(0xFFFF);
this->actionFunc = func_80B98BF4; this->actionFunc = func_80B98BF4;
@ -1185,7 +1185,7 @@ void func_80B98CA8(EnZot* this, PlayState* play) {
} }
if ((GET_PLAYER_FORM == PLAYER_FORM_ZORA) || (this->actor.xzDistToPlayer < 100.0f)) { if ((GET_PLAYER_FORM == PLAYER_FORM_ZORA) || (this->actor.xzDistToPlayer < 100.0f)) {
func_800B874C(&this->actor, play, 120.0f, 100.0f); Actor_OfferOcarinaInteraction(&this->actor, play, 120.0f, 100.0f);
} }
} }

View File

@ -205,11 +205,11 @@ void func_80AC9AB8(ObjOcarinalift* this) {
} }
void func_80AC9AE0(ObjOcarinalift* this, PlayState* play) { void func_80AC9AE0(ObjOcarinalift* this, PlayState* play) {
if (func_800B8718(&this->dyna.actor, &play->state)) { if (Actor_OcarinaInteractionAccepted(&this->dyna.actor, &play->state)) {
Message_DisplayOcarinaStaff(play, OCARINA_ACTION_FREE_PLAY); Message_DisplayOcarinaStaff(play, OCARINA_ACTION_FREE_PLAY);
func_80AC9B48(this); func_80AC9B48(this);
} else if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { } else if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) {
func_800B8804(&this->dyna.actor, play, 40.0f); Actor_OfferOcarinaInteractionNearby(&this->dyna.actor, play, 40.0f);
} }
} }
@ -218,7 +218,7 @@ void func_80AC9B48(ObjOcarinalift* this) {
} }
void func_80AC9B5C(ObjOcarinalift* this, PlayState* play) { void func_80AC9B5C(ObjOcarinalift* this, PlayState* play) {
if (func_800B886C(&this->dyna.actor, play)) { if (Actor_NoOcarinaInteraction(&this->dyna.actor, play)) {
if (play->msgCtx.ocarinaMode == OCARINA_MODE_END) { if (play->msgCtx.ocarinaMode == OCARINA_MODE_END) {
if (play->msgCtx.lastPlayedSong == 0) { if (play->msgCtx.lastPlayedSong == 0) {
if (OBJOCARINALIFT_GET_C(&this->dyna.actor) != OBJOCARINALIFT_PARAM_1) { if (OBJOCARINALIFT_GET_C(&this->dyna.actor) != OBJOCARINALIFT_PARAM_1) {

View File

@ -4363,9 +4363,9 @@ s32 Player_SetAction(PlayState* play, Player* this, PlayerActionFunc actionFunc,
play->actorCtx.flags &= ~ACTORCTX_FLAG_PICTO_BOX_ON; play->actorCtx.flags &= ~ACTORCTX_FLAG_PICTO_BOX_ON;
if (this->actor.flags & ACTOR_FLAG_20000000) { if (this->actor.flags & ACTOR_FLAG_OCARINA_INTERACTION) {
AudioOcarina_SetInstrument(OCARINA_INSTRUMENT_OFF); AudioOcarina_SetInstrument(OCARINA_INSTRUMENT_OFF);
this->actor.flags &= ~ACTOR_FLAG_20000000; this->actor.flags &= ~ACTOR_FLAG_OCARINA_INTERACTION;
} else if ((Player_Action_96 == this->actionFunc) || (Player_Action_93 == this->actionFunc)) { } else if ((Player_Action_96 == this->actionFunc) || (Player_Action_93 == this->actionFunc)) {
this->actor.shape.shadowDraw = ActorShadow_DrawFeet; this->actor.shape.shadowDraw = ActorShadow_DrawFeet;
this->actor.shape.shadowScale = this->ageProperties->shadowScale; this->actor.shape.shadowScale = this->ageProperties->shadowScale;
@ -7902,10 +7902,10 @@ s32 Player_ActionHandler_13(Player* this, PlayState* play) {
: &gPlayerAnim_link_bottle_drink_demo_start); : &gPlayerAnim_link_bottle_drink_demo_start);
} }
} else { } else {
Actor* actorUnkA90 = this->unk_A90; Actor* ocarinaInteractionActor = this->ocarinaInteractionActor;
if ((actorUnkA90 == NULL) || (actorUnkA90->id == ACTOR_EN_ZOT) || if ((ocarinaInteractionActor == NULL) || (ocarinaInteractionActor->id == ACTOR_EN_ZOT) ||
(actorUnkA90->csId == CS_ID_NONE)) { (ocarinaInteractionActor->csId == CS_ID_NONE)) {
if (!func_808323C0(this, play->playerCsIds[PLAYER_CS_ID_ITEM_OCARINA])) { if (!func_808323C0(this, play->playerCsIds[PLAYER_CS_ID_ITEM_OCARINA])) {
return false; return false;
} }
@ -7919,12 +7919,15 @@ s32 Player_ActionHandler_13(Player* this, PlayState* play) {
Player_Anim_PlayOnceAdjusted(play, this, D_8085D17C[this->transformation]); Player_Anim_PlayOnceAdjusted(play, this, D_8085D17C[this->transformation]);
} }
this->stateFlags2 |= PLAYER_STATE2_USING_OCARINA; this->stateFlags2 |= PLAYER_STATE2_USING_OCARINA;
if (actorUnkA90 != NULL) { if (ocarinaInteractionActor != NULL) {
this->actor.flags |= ACTOR_FLAG_20000000; this->actor.flags |= ACTOR_FLAG_OCARINA_INTERACTION;
if (actorUnkA90->id == ACTOR_EN_ZOT) { if (ocarinaInteractionActor->id == ACTOR_EN_ZOT) {
this->unk_A94 = -1.0f; // Delays setting `ACTOR_FLAG_OCARINA_INTERACTION` until a Zora guitar strum.
// Uses a negative xzDist to signal this special case (normally unobtainable xzDist).
// See `func_80852290`.
this->ocarinaInteractionDistance = -1.0f;
} else { } else {
actorUnkA90->flags |= ACTOR_FLAG_20000000; ocarinaInteractionActor->flags |= ACTOR_FLAG_OCARINA_INTERACTION;
} }
} }
} }
@ -11435,7 +11438,7 @@ void Player_UpdateInterface(PlayState* play, Player* this) {
if (play->actorCtx.flags & ACTORCTX_FLAG_PICTO_BOX_ON) { if (play->actorCtx.flags & ACTORCTX_FLAG_PICTO_BOX_ON) {
doActionA = DO_ACTION_SNAP; doActionA = DO_ACTION_SNAP;
} else if (Player_InBlockingCsMode(play, this) || (this->actor.flags & ACTOR_FLAG_20000000) || } else if (Player_InBlockingCsMode(play, this) || (this->actor.flags & ACTOR_FLAG_OCARINA_INTERACTION) ||
(this->stateFlags1 & PLAYER_STATE1_CHARGING_SPIN_ATTACK) || (this->stateFlags1 & PLAYER_STATE1_CHARGING_SPIN_ATTACK) ||
(this->stateFlags3 & PLAYER_STATE3_80000) || (Player_Action_80 == this->actionFunc)) { (this->stateFlags3 & PLAYER_STATE3_80000) || (Player_Action_80 == this->actionFunc)) {
doActionA = DO_ACTION_NONE; doActionA = DO_ACTION_NONE;
@ -12673,9 +12676,9 @@ void Player_UpdateCommon(Player* this, PlayState* play, Input* input) {
this->exchangeItemAction = PLAYER_IA_NONE; this->exchangeItemAction = PLAYER_IA_NONE;
this->talkActorDistance = FLT_MAX; this->talkActorDistance = FLT_MAX;
} }
if (!(this->actor.flags & ACTOR_FLAG_20000000) && (this->unk_AA5 != PLAYER_UNKAA5_5)) { if (!(this->actor.flags & ACTOR_FLAG_OCARINA_INTERACTION) && (this->unk_AA5 != PLAYER_UNKAA5_5)) {
this->unk_A90 = NULL; this->ocarinaInteractionActor = NULL;
this->unk_A94 = FLT_MAX; this->ocarinaInteractionDistance = FLT_MAX;
} }
if (!(this->stateFlags1 & PLAYER_STATE1_CARRYING_ACTOR)) { if (!(this->stateFlags1 & PLAYER_STATE1_CARRYING_ACTOR)) {
this->interactRangeActor = NULL; this->interactRangeActor = NULL;
@ -17299,9 +17302,12 @@ void func_80852290(PlayState* play, Player* this) {
if ((play->msgCtx.ocarinaMode == OCARINA_MODE_ACTIVE) && if ((play->msgCtx.ocarinaMode == OCARINA_MODE_ACTIVE) &&
(play->msgCtx.ocarinaButtonIndex != OCARINA_BTN_INVALID)) { (play->msgCtx.ocarinaButtonIndex != OCARINA_BTN_INVALID)) {
if ((this->unk_A90 != NULL) && (this->unk_A94 < 0.0f)) { if ((this->ocarinaInteractionActor != NULL) && (this->ocarinaInteractionDistance < 0.0f)) {
this->unk_A90->flags |= ACTOR_FLAG_20000000; // Designed for tuning the guitar in zora hall for the zora: `ACTOR_EN_ZOT`
this->unk_A94 = 0.0f; // This actor will delay setting the `ACTOR_FLAG_OCARINA_INTERACTION` until here.
// This is signaled by a negative `ocarinaInteractionDistance`.
this->ocarinaInteractionActor->flags |= ACTOR_FLAG_OCARINA_INTERACTION;
this->ocarinaInteractionDistance = 0.0f;
} }
Player_Anim_PlayOnceAdjusted(play, this, D_8085D190[this->transformation]); Player_Anim_PlayOnceAdjusted(play, this, D_8085D190[this->transformation]);
@ -17379,16 +17385,18 @@ void Player_Action_63(Player* this, PlayState* play) {
(this->skelAnime.animation == D_8085D17C[this->transformation])) || (this->skelAnime.animation == D_8085D17C[this->transformation])) ||
((this->skelAnime.mode == ANIMMODE_LOOP) && (this->av2.actionVar2 == 0)))) { ((this->skelAnime.mode == ANIMMODE_LOOP) && (this->av2.actionVar2 == 0)))) {
func_808525C4(play, this); func_808525C4(play, this);
if (!(this->actor.flags & ACTOR_FLAG_20000000) || (this->unk_A90->id == ACTOR_EN_ZOT)) { if (!(this->actor.flags & ACTOR_FLAG_OCARINA_INTERACTION) ||
(this->ocarinaInteractionActor->id == ACTOR_EN_ZOT)) {
Message_DisplayOcarinaStaff(play, OCARINA_ACTION_FREE_PLAY); Message_DisplayOcarinaStaff(play, OCARINA_ACTION_FREE_PLAY);
} }
} else if (this->av2.actionVar2 != 0) { } else if (this->av2.actionVar2 != 0) {
if (play->msgCtx.ocarinaMode == OCARINA_MODE_END) { if (play->msgCtx.ocarinaMode == OCARINA_MODE_END) {
play->interfaceCtx.bButtonInterfaceDoActionActive = false; play->interfaceCtx.bButtonInterfaceDoActionActive = false;
CutsceneManager_Stop(play->playerCsIds[PLAYER_CS_ID_ITEM_OCARINA]); CutsceneManager_Stop(play->playerCsIds[PLAYER_CS_ID_ITEM_OCARINA]);
this->actor.flags &= ~ACTOR_FLAG_20000000; this->actor.flags &= ~ACTOR_FLAG_OCARINA_INTERACTION;
if ((this->talkActor != NULL) && (this->talkActor == this->unk_A90) && (this->unk_A94 >= 0.0f)) { if ((this->talkActor != NULL) && (this->talkActor == this->ocarinaInteractionActor) &&
(this->ocarinaInteractionDistance >= 0.0f)) {
Player_StartTalking(play, this->talkActor); Player_StartTalking(play, this->talkActor);
} else if (this->tatlTextId < 0) { } else if (this->tatlTextId < 0) {
this->talkActor = this->tatlActor; this->talkActor = this->tatlActor;
@ -17423,7 +17431,7 @@ void Player_Action_63(Player* this, PlayState* play) {
play->interfaceCtx.bButtonInterfaceDoActionActive = false; play->interfaceCtx.bButtonInterfaceDoActionActive = false;
CutsceneManager_Stop(play->playerCsIds[PLAYER_CS_ID_ITEM_OCARINA]); CutsceneManager_Stop(play->playerCsIds[PLAYER_CS_ID_ITEM_OCARINA]);
this->actor.flags &= ~ACTOR_FLAG_20000000; this->actor.flags &= ~ACTOR_FLAG_OCARINA_INTERACTION;
actor = Actor_Spawn(&play->actorCtx, play, var_v1 ? ACTOR_EN_TEST7 : ACTOR_EN_TEST6, actor = Actor_Spawn(&play->actorCtx, play, var_v1 ? ACTOR_EN_TEST7 : ACTOR_EN_TEST6,
this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, 0, 0,
@ -17443,7 +17451,7 @@ void Player_Action_63(Player* this, PlayState* play) {
play->interfaceCtx.bButtonInterfaceDoActionActive = false; play->interfaceCtx.bButtonInterfaceDoActionActive = false;
CutsceneManager_Stop(play->playerCsIds[PLAYER_CS_ID_ITEM_OCARINA]); CutsceneManager_Stop(play->playerCsIds[PLAYER_CS_ID_ITEM_OCARINA]);
this->actor.flags &= ~ACTOR_FLAG_20000000; this->actor.flags &= ~ACTOR_FLAG_OCARINA_INTERACTION;
Player_SetAction_PreserveItemAction(play, this, Player_Action_88, 0); Player_SetAction_PreserveItemAction(play, this, Player_Action_88, 0);
this->stateFlags1 |= PLAYER_STATE1_10000000 | PLAYER_STATE1_20000000; this->stateFlags1 |= PLAYER_STATE1_10000000 | PLAYER_STATE1_20000000;
} else if (this->unk_AA5 == PLAYER_UNKAA5_4) { } else if (this->unk_AA5 == PLAYER_UNKAA5_4) {

View File

@ -777,11 +777,11 @@
0x800B867C:("Actor_TextboxIsClosing",), 0x800B867C:("Actor_TextboxIsClosing",),
0x800B86C8:("Actor_ChangeFocus",), 0x800B86C8:("Actor_ChangeFocus",),
0x800B8708:("Player_GetExchangeItemId",), 0x800B8708:("Player_GetExchangeItemId",),
0x800B8718:("func_800B8718",), 0x800B8718:("Actor_OcarinaInteractionAccepted",),
0x800B874C:("func_800B874C",), 0x800B874C:("Actor_OfferOcarinaInteraction",),
0x800B8804:("func_800B8804",), 0x800B8804:("Actor_OfferOcarinaInteractionNearby",),
0x800B882C:("func_800B882C",), 0x800B882C:("Actor_OfferOcarinaInteractionColChkInfoCylinder",),
0x800B886C:("func_800B886C",), 0x800B886C:("Actor_NoOcarinaInteraction",),
0x800B8898:("Actor_GetScreenPos",), 0x800B8898:("Actor_GetScreenPos",),
0x800B8934:("Actor_OnScreen",), 0x800B8934:("Actor_OnScreen",),
0x800B89F8:("Actor_HasParent",), 0x800B89F8:("Actor_HasParent",),

View File

@ -291,11 +291,11 @@ asm/non_matchings/code/z_actor/Actor_OfferTalkNearColChkInfoCylinder.s,Actor_Off
asm/non_matchings/code/z_actor/Actor_TextboxIsClosing.s,Actor_TextboxIsClosing,0x800B867C,0x13 asm/non_matchings/code/z_actor/Actor_TextboxIsClosing.s,Actor_TextboxIsClosing,0x800B867C,0x13
asm/non_matchings/code/z_actor/Actor_ChangeFocus.s,Actor_ChangeFocus,0x800B86C8,0x10 asm/non_matchings/code/z_actor/Actor_ChangeFocus.s,Actor_ChangeFocus,0x800B86C8,0x10
asm/non_matchings/code/z_actor/Player_GetExchangeItemId.s,Player_GetExchangeItemId,0x800B8708,0x4 asm/non_matchings/code/z_actor/Player_GetExchangeItemId.s,Player_GetExchangeItemId,0x800B8708,0x4
asm/non_matchings/code/z_actor/func_800B8718.s,func_800B8718,0x800B8718,0xD asm/non_matchings/code/z_actor/Actor_OcarinaInteractionAccepted.s,Actor_OcarinaInteractionAccepted,0x800B8718,0xD
asm/non_matchings/code/z_actor/func_800B874C.s,func_800B874C,0x800B874C,0x2E asm/non_matchings/code/z_actor/Actor_OfferOcarinaInteraction.s,Actor_OfferOcarinaInteraction,0x800B874C,0x2E
asm/non_matchings/code/z_actor/func_800B8804.s,func_800B8804,0x800B8804,0xA asm/non_matchings/code/z_actor/Actor_OfferOcarinaInteractionNearby.s,Actor_OfferOcarinaInteractionNearby,0x800B8804,0xA
asm/non_matchings/code/z_actor/func_800B882C.s,func_800B882C,0x800B882C,0x10 asm/non_matchings/code/z_actor/Actor_OfferOcarinaInteractionColChkInfoCylinder.s,Actor_OfferOcarinaInteractionColChkInfoCylinder,0x800B882C,0x10
asm/non_matchings/code/z_actor/func_800B886C.s,func_800B886C,0x800B886C,0xB asm/non_matchings/code/z_actor/Actor_NoOcarinaInteraction.s,Actor_NoOcarinaInteraction,0x800B886C,0xB
asm/non_matchings/code/z_actor/Actor_GetScreenPos.s,Actor_GetScreenPos,0x800B8898,0x27 asm/non_matchings/code/z_actor/Actor_GetScreenPos.s,Actor_GetScreenPos,0x800B8898,0x27
asm/non_matchings/code/z_actor/Actor_OnScreen.s,Actor_OnScreen,0x800B8934,0x31 asm/non_matchings/code/z_actor/Actor_OnScreen.s,Actor_OnScreen,0x800B8934,0x31
asm/non_matchings/code/z_actor/Actor_HasParent.s,Actor_HasParent,0x800B89F8,0x9 asm/non_matchings/code/z_actor/Actor_HasParent.s,Actor_HasParent,0x800B89F8,0x9

1 asm/non_matchings/code/z_en_a_keep/EnAObj_Init.s EnAObj_Init 0x800A5AC0 0x2B
291 asm/non_matchings/code/z_actor/Actor_TextboxIsClosing.s Actor_TextboxIsClosing 0x800B867C 0x13
292 asm/non_matchings/code/z_actor/Actor_ChangeFocus.s Actor_ChangeFocus 0x800B86C8 0x10
293 asm/non_matchings/code/z_actor/Player_GetExchangeItemId.s Player_GetExchangeItemId 0x800B8708 0x4
294 asm/non_matchings/code/z_actor/func_800B8718.s asm/non_matchings/code/z_actor/Actor_OcarinaInteractionAccepted.s func_800B8718 Actor_OcarinaInteractionAccepted 0x800B8718 0xD
295 asm/non_matchings/code/z_actor/func_800B874C.s asm/non_matchings/code/z_actor/Actor_OfferOcarinaInteraction.s func_800B874C Actor_OfferOcarinaInteraction 0x800B874C 0x2E
296 asm/non_matchings/code/z_actor/func_800B8804.s asm/non_matchings/code/z_actor/Actor_OfferOcarinaInteractionNearby.s func_800B8804 Actor_OfferOcarinaInteractionNearby 0x800B8804 0xA
297 asm/non_matchings/code/z_actor/func_800B882C.s asm/non_matchings/code/z_actor/Actor_OfferOcarinaInteractionColChkInfoCylinder.s func_800B882C Actor_OfferOcarinaInteractionColChkInfoCylinder 0x800B882C 0x10
298 asm/non_matchings/code/z_actor/func_800B886C.s asm/non_matchings/code/z_actor/Actor_NoOcarinaInteraction.s func_800B886C Actor_NoOcarinaInteraction 0x800B886C 0xB
299 asm/non_matchings/code/z_actor/Actor_GetScreenPos.s Actor_GetScreenPos 0x800B8898 0x27
300 asm/non_matchings/code/z_actor/Actor_OnScreen.s Actor_OnScreen 0x800B8934 0x31
301 asm/non_matchings/code/z_actor/Actor_HasParent.s Actor_HasParent 0x800B89F8 0x9