From bb6177e936c535817eded229d1023d0556a67519 Mon Sep 17 00:00:00 2001 From: fig02 Date: Thu, 5 Sep 2024 12:44:06 -0400 Subject: [PATCH] Document `Target_ShouldReleaseLockOn` [Target Docs 8/8] (#2135) * target range and leash docs * format --- include/functions.h | 2 +- src/code/z_actor.c | 37 ++++++++++++++----- .../actors/ovl_player_actor/z_player.c | 6 +-- tools/disasm/ntsc-1.2/functions.txt | 2 +- 4 files changed, 32 insertions(+), 15 deletions(-) diff --git a/include/functions.h b/include/functions.h index 27cbbfd803..a0156d314d 100644 --- a/include/functions.h +++ b/include/functions.h @@ -382,7 +382,7 @@ void func_8002ED80(Actor* actor, PlayState* play, s32 flag); PosRot Actor_GetFocus(Actor* actor); PosRot Actor_GetWorld(Actor* actor); PosRot Actor_GetWorldPosShapeRot(Actor* actor); -s32 func_8002F0C8(Actor* actor, Player* player, s32 flag); +s32 Target_ShouldReleaseLockOn(Actor* actor, Player* player, s32 ignoreLeash); s32 Actor_TalkOfferAccepted(Actor* actor, PlayState* play); s32 Actor_OfferTalkExchange(Actor* actor, PlayState* play, f32 xzRange, f32 yRange, u32 exchangeItemId); s32 Actor_OfferTalkExchangeEquiCylinder(Actor* actor, PlayState* play, f32 radius, u32 exchangeItemId); diff --git a/src/code/z_actor.c b/src/code/z_actor.c index 78710229fe..c74f29f503 100644 --- a/src/code/z_actor.c +++ b/src/code/z_actor.c @@ -1629,29 +1629,46 @@ TargetRangeParams sTargetRanges[TARGET_MODE_MAX] = { }; /** - * Checks if an actor at distance `distSq` is inside the range specified by its targetMode + * Checks if an actor at `distSq` is inside the range specified by its `targetMode`. + * + * Note that this gets used for both the target range check and for the lock-on leash range check. + * Despite how the data is presented in `sTargetRanges`, the leash range is stored as a scale factor value. + * When checking the leash range, this scale factor is applied to the input distance and checked against + * the base `rangeSq` value, which was used to initiate the lock-on in the first place. */ u32 Target_ActorIsInRange(Actor* actor, f32 distSq) { return distSq < sTargetRanges[actor->targetMode].rangeSq; } -s32 func_8002F0C8(Actor* actor, Player* player, s32 flag) { +/** + * Returns true if an actor lock-on should be released. + * This function does not actually release the lock-on, as that is Player's responsibility. + * + * If an actor's update function is NULL or `ACTOR_FLAG_0` is unset, the lock-on should be released. + * + * There is also a check for Player exceeding the lock-on leash distance. + * Note that this check will be ignored if `ignoreLeash` is true. + * + */ +s32 Target_ShouldReleaseLockOn(Actor* actor, Player* player, s32 ignoreLeash) { if ((actor->update == NULL) || !(actor->flags & ACTOR_FLAG_0)) { return true; } - if (!flag) { - s16 var = (s16)(actor->yawTowardsPlayer - 0x8000) - player->actor.shape.rot.y; - s16 abs_var = ABS(var); - f32 dist; + if (!ignoreLeash) { + s16 yawDiff = (s16)(actor->yawTowardsPlayer - 0x8000) - player->actor.shape.rot.y; + s16 yawDiffAbs = ABS(yawDiff); + f32 distSq; - if ((player->focusActor == NULL) && (abs_var > 0x2AAA)) { - dist = MAXFLOAT; + if ((player->focusActor == NULL) && (yawDiffAbs > 0x2AAA)) { + // This function is only called (and is only relevant) when `player->focusActor != NULL`. + // This is unreachable. + distSq = MAXFLOAT; } else { - dist = actor->xyzDistToPlayerSq; + distSq = actor->xyzDistToPlayerSq; } - return !Target_ActorIsInRange(actor, sTargetRanges[actor->targetMode].leashScale * dist); + return !Target_ActorIsInRange(actor, sTargetRanges[actor->targetMode].leashScale * distSq); } return false; diff --git a/src/overlays/actors/ovl_player_actor/z_player.c b/src/overlays/actors/ovl_player_actor/z_player.c index ca8bff100e..bd15573594 100644 --- a/src/overlays/actors/ovl_player_actor/z_player.c +++ b/src/overlays/actors/ovl_player_actor/z_player.c @@ -3540,7 +3540,7 @@ s32 func_80836AB8(Player* this, s32 arg1) { // Update things related to Z Targeting void func_80836BEC(Player* this, PlayState* play) { - s32 sp1C = 0; + s32 ignoreLeash = false; s32 zTrigPressed = CHECK_BTN_ALL(sControlInput->cur.button, BTN_Z); Actor* actorToTarget; s32 pad; @@ -3567,7 +3567,7 @@ void func_80836BEC(Player* this, PlayState* play) { } if (this->unk_66C >= 6) { - sp1C = 1; + ignoreLeash = true; } cond = func_8083224C(play); @@ -3614,7 +3614,7 @@ void func_80836BEC(Player* this, PlayState* play) { if (this->focusActor != NULL) { if ((this->actor.category == ACTORCAT_PLAYER) && (this->focusActor != this->unk_684) && - func_8002F0C8(this->focusActor, this, sp1C)) { + Target_ShouldReleaseLockOn(this->focusActor, this, ignoreLeash)) { func_8008EDF0(this); this->stateFlags1 |= PLAYER_STATE1_30; } else if (this->focusActor != NULL) { diff --git a/tools/disasm/ntsc-1.2/functions.txt b/tools/disasm/ntsc-1.2/functions.txt index 63fc5ddabe..96900ef2c1 100644 --- a/tools/disasm/ntsc-1.2/functions.txt +++ b/tools/disasm/ntsc-1.2/functions.txt @@ -410,7 +410,7 @@ Actor_GetWorld = 0x80022CE4; // type:func Actor_GetWorldPosShapeRot = 0x80022D18; // type:func Target_WeightedDistToPlayerSq = 0x80022D94; // type:func Target_ActorIsInRange = 0x80022E64; // type:func -func_8002F0C8 = 0x80022EA0; // type:func +Target_ShouldReleaseLockOn = 0x80022EA0; // type:func Actor_TalkOfferAccepted = 0x80022F70; // type:func Actor_OfferTalkExchange = 0x80022FA0; // type:func Actor_OfferTalkExchangeEquiCylinder = 0x80023074; // type:func