diff --git a/include/z64player.h b/include/z64player.h index a9d360d27b..ebd5220e88 100644 --- a/include/z64player.h +++ b/include/z64player.h @@ -664,7 +664,7 @@ typedef struct WeaponInfo { #define PLAYER_STATE1_13 (1 << 13) #define PLAYER_STATE1_14 (1 << 14) #define PLAYER_STATE1_Z_TARGETING (1 << 15) // Either lock-on or parallel is active. This flag is never checked for and is practically unused. -#define PLAYER_STATE1_16 (1 << 16) +#define PLAYER_STATE1_FRIENDLY_ACTOR_FOCUS (1 << 16) // Currently focusing on a friendly actor. Includes friendly lock-on, talking, and more. Usually does not include hostile actor lock-on, see `PLAYER_STATE1_HOSTILE_LOCK_ON`. #define PLAYER_STATE1_PARALLEL (1 << 17) // "Parallel" mode, Z-Target without an actor lock-on #define PLAYER_STATE1_18 (1 << 18) #define PLAYER_STATE1_19 (1 << 19) diff --git a/src/code/z_player_lib.c b/src/code/z_player_lib.c index f520685079..e6d11311f4 100644 --- a/src/code/z_player_lib.c +++ b/src/code/z_player_lib.c @@ -618,7 +618,7 @@ void func_8008EE08(Player* this) { (this->stateFlags1 & (PLAYER_STATE1_21 | PLAYER_STATE1_23 | PLAYER_STATE1_27)) || (!(this->stateFlags1 & (PLAYER_STATE1_18 | PLAYER_STATE1_19)) && ((this->actor.world.pos.y - this->actor.floorHeight) < 100.0f))) { - this->stateFlags1 &= ~(PLAYER_STATE1_Z_TARGETING | PLAYER_STATE1_16 | PLAYER_STATE1_PARALLEL | + this->stateFlags1 &= ~(PLAYER_STATE1_Z_TARGETING | PLAYER_STATE1_FRIENDLY_ACTOR_FOCUS | PLAYER_STATE1_PARALLEL | PLAYER_STATE1_18 | PLAYER_STATE1_19 | PLAYER_STATE1_LOCK_ON_FORCED_TO_RELEASE); } else if (!(this->stateFlags1 & (PLAYER_STATE1_18 | PLAYER_STATE1_19 | PLAYER_STATE1_21))) { this->stateFlags1 |= PLAYER_STATE1_19; @@ -633,7 +633,7 @@ void func_8008EEAC(PlayState* play, Actor* actor) { func_8008EE08(this); this->focusActor = actor; this->unk_684 = actor; - this->stateFlags1 |= PLAYER_STATE1_16; + this->stateFlags1 |= PLAYER_STATE1_FRIENDLY_ACTOR_FOCUS; Camera_SetViewParam(Play_GetCamera(play, CAM_ID_MAIN), CAM_VIEW_TARGET, actor); Camera_RequestMode(Play_GetCamera(play, CAM_ID_MAIN), CAM_MODE_Z_TARGET_FRIENDLY); } diff --git a/src/overlays/actors/ovl_player_actor/z_player.c b/src/overlays/actors/ovl_player_actor/z_player.c index 0b956c86ac..65deb1994c 100644 --- a/src/overlays/actors/ovl_player_actor/z_player.c +++ b/src/overlays/actors/ovl_player_actor/z_player.c @@ -2318,8 +2318,25 @@ void func_80833A20(Player* this, s32 newMeleeWeaponState) { this->meleeWeaponState = newMeleeWeaponState; } -s32 func_80833B2C(Player* this) { - if (this->stateFlags1 & (PLAYER_STATE1_16 | PLAYER_STATE1_PARALLEL | PLAYER_STATE1_LOCK_ON_FORCED_TO_RELEASE)) { +/** + * This function checks for friendly (non-hostile) Z-Target related states. + * For hostile related lock-on states, see `Player_UpdateHostileLockOn` and `Player_CheckHostileLockOn`. + * + * Note that `PLAYER_STATE1_FRIENDLY_ACTOR_FOCUS` will include all `focusActor` use cases that relate to + * friendly actors. This function can return true when talking to an actor, for example. + * Despite that, this function is only relevant in the context of actor lock-on, which is a subset of actor focus. + * This is why the function name states `FriendlyLockOn` instead of `FriendlyActorFocus`. + * + * There is a special case that allows hostile actors to be treated as "friendly" if Player is carrying another actor + * See relevant code in `func_80836BEC` for more details. + * + * Additionally, `PLAYER_STATE1_LOCK_ON_FORCED_TO_RELEASE` will be set very briefly in some conditions when + * a lock-on is forced to release. In these niche cases, this function will apply to both friendly and hostile actors. + * Overall, it is safe to assume that this specific state flag is not very relevant for this function's use cases. + */ +s32 Player_FriendlyLockOnOrParallel(Player* this) { + if (this->stateFlags1 & + (PLAYER_STATE1_FRIENDLY_ACTOR_FOCUS | PLAYER_STATE1_PARALLEL | PLAYER_STATE1_LOCK_ON_FORCED_TO_RELEASE)) { return true; } else { return false; @@ -2335,7 +2352,7 @@ s32 func_80833B2C(Player* this) { * Note that `Player_CheckHostileLockOn` also exists to check if there is currently a hostile lock-on actor. * This function differs in that it first updates the flag if appropriate, then returns the same information. * - * @return true if there is curerntly a hostile lock-on actor, false otherwise + * @return true if there is currently a hostile lock-on actor, false otherwise */ s32 Player_UpdateHostileLockOn(Player* this) { if ((this->focusActor != NULL) && @@ -2357,12 +2374,26 @@ s32 Player_UpdateHostileLockOn(Player* this) { } } -int func_80833BCC(Player* this) { - return Player_CheckHostileLockOn(this) || func_80833B2C(this); +/** + * Returns true if currently Z-Targeting, false if not. + * Z-Targeting here is a blanket term that covers both the "actor lock-on" and "parallel" states. + * + * This variant of the function calls `Player_CheckHostileLockOn`, which does not update the hostile + * lock-on actor state. + */ +int Player_IsZTargeting(Player* this) { + return Player_CheckHostileLockOn(this) || Player_FriendlyLockOnOrParallel(this); } -int func_80833C04(Player* this) { - return Player_UpdateHostileLockOn(this) || func_80833B2C(this); +/** + * Returns true if currently Z-Targeting, false if not. + * Z-Targeting here is a blanket term that covers both the "actor lock-on" and "parallel" states. + * + * This variant of the function calls `Player_UpdateHostileLockOn`, which updates the hostile + * lock-on actor state before checking its state. + */ +int Player_IsZTargetingWithHostileUpdate(Player* this) { + return Player_UpdateHostileLockOn(this) || Player_FriendlyLockOnOrParallel(this); } void func_80833C3C(Player* this) { @@ -2635,8 +2666,8 @@ s32 func_80834758(PlayState* play, Player* this) { if (!(this->stateFlags1 & (PLAYER_STATE1_22 | PLAYER_STATE1_23 | PLAYER_STATE1_29)) && (play->shootingGalleryStatus == 0) && (this->heldItemAction == this->itemAction) && - (this->currentShield != PLAYER_SHIELD_NONE) && !Player_IsChildWithHylianShield(this) && func_80833BCC(this) && - CHECK_BTN_ALL(sControlInput->cur.button, BTN_R)) { + (this->currentShield != PLAYER_SHIELD_NONE) && !Player_IsChildWithHylianShield(this) && + Player_IsZTargeting(this) && CHECK_BTN_ALL(sControlInput->cur.button, BTN_R)) { anim = func_808346C4(play, this); frame = Animation_GetLastFrame(anim); @@ -2814,7 +2845,7 @@ int func_80834E7C(PlayState* play) { s32 func_80834EB8(Player* this, PlayState* play) { if ((this->unk_6AD == 0) || (this->unk_6AD == 2)) { - if (func_80833BCC(this) || + if (Player_IsZTargeting(this) || (Camera_CheckValidMode(Play_GetCamera(play, CAM_ID_MAIN), CAM_MODE_AIM_ADULT) == 0)) { return 1; } @@ -2973,7 +3004,7 @@ s32 func_808353D8(Player* this, PlayState* play) { this->unk_834--; } - if (func_80833BCC(this) || (this->unk_6AD != 0) || (this->stateFlags1 & PLAYER_STATE1_20)) { + if (Player_IsZTargeting(this) || (this->unk_6AD != 0) || (this->stateFlags1 & PLAYER_STATE1_20)) { if (this->unk_834 == 0) { this->unk_834++; } @@ -3665,11 +3696,16 @@ void func_80836BEC(Player* this, PlayState* play) { } if (this->focusActor != NULL) { - this->stateFlags1 &= ~(PLAYER_STATE1_16 | PLAYER_STATE1_PARALLEL); + this->stateFlags1 &= ~(PLAYER_STATE1_FRIENDLY_ACTOR_FOCUS | PLAYER_STATE1_PARALLEL); + // Check if an actor is not hostile, aka "friendly", to set `PLAYER_STATE1_FRIENDLY_ACTOR_FOCUS`. + // + // When carrying another actor, `PLAYER_STATE1_FRIENDLY_ACTOR_FOCUS` will be set even if the actor + // is hostile. This is a special case to allow Player to have more freedom of movement and be able + // to throw a carried actor at the lock-on actor, even if it is hostile. if ((this->stateFlags1 & PLAYER_STATE1_ACTOR_CARRY) || !CHECK_FLAG_ALL(this->focusActor->flags, ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_HOSTILE)) { - this->stateFlags1 |= PLAYER_STATE1_16; + this->stateFlags1 |= PLAYER_STATE1_FRIENDLY_ACTOR_FOCUS; } } else { if (this->stateFlags1 & PLAYER_STATE1_PARALLEL) { @@ -3793,7 +3829,7 @@ s32 Player_GetMovementSpeedAndYaw(Player* this, f32* outSpeedTarget, s16* outYaw *outYawTarget = Math_Vec3f_Yaw(&this->actor.world.pos, &this->focusActor->focus.pos); return false; } - } else if (func_80833B2C(this)) { + } else if (Player_FriendlyLockOnOrParallel(this)) { *outYawTarget = this->parallelYaw; } @@ -4116,7 +4152,7 @@ s32 func_80837818(Player* this) { sp18 = PLAYER_MWA_SPIN_ATTACK_1H; } else { if (controlStickDirection <= PLAYER_STICK_DIR_NONE) { - if (func_80833BCC(this)) { + if (Player_IsZTargeting(this)) { sp18 = PLAYER_MWA_FORWARD_SLASH_1H; } else { sp18 = PLAYER_MWA_RIGHT_SLASH_1H; @@ -4127,7 +4163,7 @@ s32 func_80837818(Player* this) { if (sp18 == PLAYER_MWA_STAB_1H) { this->stateFlags2 |= PLAYER_STATE2_30; - if (!func_80833BCC(this)) { + if (!Player_IsZTargeting(this)) { sp18 = PLAYER_MWA_FORWARD_SLASH_1H; } } @@ -5189,7 +5225,7 @@ void func_80839F30(Player* this, PlayState* play) { void func_80839F90(Player* this, PlayState* play) { if (Player_CheckHostileLockOn(this)) { func_80839E88(this, play); - } else if (func_80833B2C(this)) { + } else if (Player_FriendlyLockOnOrParallel(this)) { func_80839F30(this, play); } else { func_80853080(this, play); @@ -5201,7 +5237,7 @@ void func_80839FFC(Player* this, PlayState* play) { if (Player_CheckHostileLockOn(this)) { actionFunc = Player_Action_80840450; - } else if (func_80833B2C(this)) { + } else if (Player_FriendlyLockOnOrParallel(this)) { actionFunc = Player_Action_808407CC; } else { actionFunc = Player_Action_80840BC8; @@ -5970,7 +6006,7 @@ s32 Player_ActionChange_10(Player* this, PlayState* play) { controlStickDirection = this->controlStickDirections[this->controlStickDataIndex]; if (controlStickDirection <= PLAYER_STICK_DIR_FORWARD) { - if (func_80833BCC(this)) { + if (Player_IsZTargeting(this)) { if (this->actor.category != ACTORCAT_PLAYER) { if (controlStickDirection <= PLAYER_STICK_DIR_NONE) { func_808389E8(this, &gPlayerAnim_link_normal_jump, REG(69) / 100.0f, play); @@ -6076,7 +6112,8 @@ s32 Player_ActionChange_11(Player* this, PlayState* play) { if ((play->shootingGalleryStatus == 0) && (this->currentShield != PLAYER_SHIELD_NONE) && CHECK_BTN_ALL(sControlInput->cur.button, BTN_R) && - (Player_IsChildWithHylianShield(this) || (!func_80833B2C(this) && (this->focusActor == NULL)))) { + (Player_IsChildWithHylianShield(this) || + (!Player_FriendlyLockOnOrParallel(this) && (this->focusActor == NULL)))) { func_80832318(this); Player_DetachHeldActor(play, this); @@ -6215,7 +6252,7 @@ s32 func_8083C6B8(PlayState* play, Player* this) { void func_8083C858(Player* this, PlayState* play) { PlayerActionFunc actionFunc; - if (func_80833BCC(this)) { + if (Player_IsZTargeting(this)) { actionFunc = Player_Action_8084227C; } else { actionFunc = Player_Action_80842180; @@ -7617,7 +7654,8 @@ void Player_Action_80840450(Player* this, PlayState* play) { func_8083721C(this); if (!Player_TryActionChangeList(play, this, sActionChangeList1, true)) { - if (!Player_UpdateHostileLockOn(this) && (!func_80833B2C(this) || (func_80834B5C != this->upperActionFunc))) { + if (!Player_UpdateHostileLockOn(this) && + (!Player_FriendlyLockOnOrParallel(this) || (func_80834B5C != this->upperActionFunc))) { func_8083CF10(this, play); return; } @@ -7688,7 +7726,7 @@ void Player_Action_808407CC(Player* this, PlayState* play) { return; } - if (!func_80833B2C(this)) { + if (!Player_FriendlyLockOnOrParallel(this)) { func_80835DAC(play, this, Player_Action_80840BC8, 1); this->yaw = this->actor.shape.rot.y; return; @@ -7816,7 +7854,7 @@ void Player_Action_80840BC8(Player* this, PlayState* play) { return; } - if (func_80833B2C(this)) { + if (Player_FriendlyLockOnOrParallel(this)) { func_80839F30(this, play); return; } @@ -7889,7 +7927,7 @@ void Player_Action_80840DE4(Player* this, PlayState* play) { return; } - if (!func_80833B2C(this)) { + if (!Player_FriendlyLockOnOrParallel(this)) { func_80853080(this, play); return; } @@ -8007,7 +8045,7 @@ void Player_Action_808414F8(Player* this, PlayState* play) { func_80841138(this, play); if (!Player_TryActionChangeList(play, this, sActionChangeList4, true)) { - if (!func_80833C04(this)) { + if (!Player_IsZTargetingWithHostileUpdate(this)) { func_8083C8DC(this, play, this->yaw); return; } @@ -8099,14 +8137,14 @@ void Player_Action_8084193C(Player* this, PlayState* play) { func_80841860(play, this); if (!Player_TryActionChangeList(play, this, sActionChangeList5, true)) { - if (!func_80833C04(this)) { + if (!Player_IsZTargetingWithHostileUpdate(this)) { func_8083C858(this, play); return; } Player_GetMovementSpeedAndYaw(this, &speedTarget, &yawTarget, SPEED_MODE_LINEAR, play); - if (func_80833B2C(this)) { + if (Player_FriendlyLockOnOrParallel(this)) { temp1 = func_8083FD78(this, &speedTarget, &yawTarget, play); } else { temp1 = func_8083FC68(this, speedTarget, yawTarget); @@ -8115,13 +8153,13 @@ void Player_Action_8084193C(Player* this, PlayState* play) { if (temp1 > 0) { func_8083C858(this, play); } else if (temp1 < 0) { - if (func_80833B2C(this)) { + if (Player_FriendlyLockOnOrParallel(this)) { func_8083CB2C(this, yawTarget, play); } else { func_8083CBF0(this, yawTarget, play); } } else if ((this->speedXZ < 3.6f) && (speedTarget < 4.0f)) { - if (!Player_CheckHostileLockOn(this) && func_80833B2C(this)) { + if (!Player_CheckHostileLockOn(this) && Player_FriendlyLockOnOrParallel(this)) { func_8083CB94(this, play); } else { func_80839F90(this, play); @@ -8282,7 +8320,7 @@ void Player_Action_80842180(Player* this, PlayState* play) { func_80841EE4(this, play); if (!Player_TryActionChangeList(play, this, sActionChangeList8, true)) { - if (func_80833C04(this)) { + if (Player_IsZTargetingWithHostileUpdate(this)) { func_8083C858(this, play); return; } @@ -8308,7 +8346,7 @@ void Player_Action_8084227C(Player* this, PlayState* play) { func_80841EE4(this, play); if (!Player_TryActionChangeList(play, this, sActionChangeList9, true)) { - if (!func_80833C04(this)) { + if (!Player_IsZTargetingWithHostileUpdate(this)) { func_8083C858(this, play); return; } @@ -8316,9 +8354,9 @@ void Player_Action_8084227C(Player* this, PlayState* play) { Player_GetMovementSpeedAndYaw(this, &speedTarget, &yawTarget, SPEED_MODE_LINEAR, play); if (!func_8083C484(this, &speedTarget, &yawTarget)) { - if ((func_80833B2C(this) && (speedTarget != 0.0f) && + if ((Player_FriendlyLockOnOrParallel(this) && (speedTarget != 0.0f) && (func_8083FD78(this, &speedTarget, &yawTarget, play) <= 0)) || - (!func_80833B2C(this) && (func_8083FC68(this, speedTarget, yawTarget) <= 0))) { + (!Player_FriendlyLockOnOrParallel(this) && (func_8083FC68(this, speedTarget, yawTarget) <= 0))) { func_80839F90(this, play); return; } @@ -8341,7 +8379,7 @@ void Player_Action_808423EC(Player* this, PlayState* play) { sp34 = LinkAnimation_Update(play, &this->skelAnime); if (!Player_TryActionChangeList(play, this, sActionChangeList5, true)) { - if (!func_80833C04(this)) { + if (!Player_IsZTargetingWithHostileUpdate(this)) { func_8083C858(this, play); return; } @@ -10389,18 +10427,19 @@ void Player_UpdateInterface(PlayState* play, Player* this) { doAction = sDiveNumberDoActions[sp24]; } else if (sp1C && !(this->stateFlags2 & PLAYER_STATE2_10)) { doAction = DO_ACTION_DIVE; - } else if (!sp1C && (!(this->stateFlags1 & PLAYER_STATE1_22) || func_80833BCC(this) || + } else if (!sp1C && (!(this->stateFlags1 & PLAYER_STATE1_22) || Player_IsZTargeting(this) || !Player_IsChildWithHylianShield(this))) { if ((!(this->stateFlags1 & PLAYER_STATE1_14) && (controlStickDirection <= PLAYER_STICK_DIR_FORWARD) && (Player_CheckHostileLockOn(this) || ((sFloorType != FLOOR_TYPE_7) && - (func_80833B2C(this) || ((play->roomCtx.curRoom.behaviorType1 != ROOM_BEHAVIOR_TYPE1_2) && - !(this->stateFlags1 & PLAYER_STATE1_22) && - (controlStickDirection == PLAYER_STICK_DIR_FORWARD))))))) { + (Player_FriendlyLockOnOrParallel(this) || + ((play->roomCtx.curRoom.behaviorType1 != ROOM_BEHAVIOR_TYPE1_2) && + !(this->stateFlags1 & PLAYER_STATE1_22) && + (controlStickDirection == PLAYER_STICK_DIR_FORWARD))))))) { doAction = DO_ACTION_ATTACK; - } else if ((play->roomCtx.curRoom.behaviorType1 != ROOM_BEHAVIOR_TYPE1_2) && func_80833BCC(this) && - (controlStickDirection >= PLAYER_STICK_DIR_LEFT)) { + } else if ((play->roomCtx.curRoom.behaviorType1 != ROOM_BEHAVIOR_TYPE1_2) && + Player_IsZTargeting(this) && (controlStickDirection >= PLAYER_STICK_DIR_LEFT)) { doAction = DO_ACTION_JUMP; } else if ((this->heldItemAction >= PLAYER_IA_SWORD_MASTER) || ((this->stateFlags2 & PLAYER_STATE2_20) && @@ -10793,7 +10832,7 @@ void Player_UpdateCamAndSeqModes(PlayState* play, Player* this) { } else if ((focusActor = this->focusActor) != NULL) { if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_TALK)) { camMode = CAM_MODE_TALK; - } else if (this->stateFlags1 & PLAYER_STATE1_16) { + } else if (this->stateFlags1 & PLAYER_STATE1_FRIENDLY_ACTOR_FOCUS) { if (this->stateFlags1 & PLAYER_STATE1_BOOMERANG_THROWN) { camMode = CAM_MODE_FOLLOW_BOOMERANG; } else { @@ -10809,7 +10848,7 @@ void Player_UpdateCamAndSeqModes(PlayState* play, Player* this) { camMode = CAM_MODE_FOLLOW_BOOMERANG; Camera_SetViewParam(Play_GetCamera(play, CAM_ID_MAIN), CAM_VIEW_TARGET, this->boomerangActor); } else if (this->stateFlags1 & (PLAYER_STATE1_13 | PLAYER_STATE1_14)) { - if (func_80833B2C(this)) { + if (Player_FriendlyLockOnOrParallel(this)) { camMode = CAM_MODE_Z_LEDGE_HANG; } else { camMode = CAM_MODE_LEDGE_HANG; @@ -11905,8 +11944,9 @@ void Player_Action_8084B1D8(Player* this, PlayState* play) { if ((this->csAction != PLAYER_CSACTION_NONE) || (this->unk_6AD == 0) || (this->unk_6AD >= 4) || Player_UpdateHostileLockOn(this) || (this->focusActor != NULL) || (func_8083AD4C(play, this) == CAM_MODE_NORMAL) || - (((this->unk_6AD == 2) && (CHECK_BTN_ANY(sControlInput->press.button, BTN_A | BTN_B | BTN_R) || - func_80833B2C(this) || (!func_8002DD78(this) && !func_808334B4(this)))) || + (((this->unk_6AD == 2) && + (CHECK_BTN_ANY(sControlInput->press.button, BTN_A | BTN_B | BTN_R) || Player_FriendlyLockOnOrParallel(this) || + (!func_8002DD78(this) && !func_808334B4(this)))) || ((this->unk_6AD == 1) && CHECK_BTN_ANY(sControlInput->press.button, BTN_A | BTN_B | BTN_R | BTN_CUP | BTN_CDOWN | BTN_CLEFT | BTN_CRIGHT)))) { @@ -12765,7 +12805,7 @@ void Player_Action_8084CC98(Player* this, PlayState* play) { if (this->stateFlags1 & PLAYER_STATE1_20) { if ((func_8083AD4C(play, this) == CAM_MODE_NORMAL) || CHECK_BTN_ANY(sControlInput->press.button, BTN_A) || - func_80833BCC(this)) { + Player_IsZTargeting(this)) { this->unk_6AD = 0; this->stateFlags1 &= ~PLAYER_STATE1_20; } else { @@ -12886,7 +12926,7 @@ void Player_Action_8084D610(Player* this, PlayState* play) { return; } - if (func_80833C04(this)) { + if (Player_IsZTargetingWithHostileUpdate(this)) { func_8084D5CC(play, this); } else { func_8084D574(play, this, yawTarget); @@ -12928,7 +12968,7 @@ void Player_Action_8084D84C(Player* this, PlayState* play) { temp = this->actor.shape.rot.y - yawTarget; if ((speedTarget == 0.0f) || (ABS(temp) > 0x6000) || (this->currentBoots == PLAYER_BOOTS_IRON)) { func_80838F18(play, this); - } else if (func_80833C04(this)) { + } else if (Player_IsZTargetingWithHostileUpdate(this)) { func_8084D5CC(play, this); } @@ -12987,7 +13027,7 @@ void Player_Action_8084DAB4(Player* this, PlayState* play) { if (speedTarget == 0.0f) { func_80838F18(play, this); - } else if (!func_80833C04(this)) { + } else if (!Player_IsZTargetingWithHostileUpdate(this)) { func_8084D574(play, this, yawTarget); } else { func_8084D980(play, this, &speedTarget, &yawTarget);