diff options
| author | OtherBlue <93625085+OtherBlue@users.noreply.github.com> | 2026-03-21 15:41:08 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-03-21 18:41:08 +0000 |
| commit | 2af5d2112543f88c4476d5cf082aeca9e601f5f2 (patch) | |
| tree | 9e76451628e6c810d5be841cdec5375b45e4eaab | |
| parent | b6bf97e2f199ae9c947e3b192b690c1d6257517b (diff) | |
[Enhancement] Reworked targetting (#6322)
Adds an enhancement that changes targeting behavior, allowing
Switching targets with the chosen button combo
(In Switch mode) Untargeting by just pressing Z
4 files changed, 87 insertions, 2 deletions
diff --git a/soh/soh/Enhancements/ReworkedTargeting.cpp b/soh/soh/Enhancements/ReworkedTargeting.cpp new file mode 100644 index 000000000..aa2b5f06c --- /dev/null +++ b/soh/soh/Enhancements/ReworkedTargeting.cpp @@ -0,0 +1,57 @@ +#include <libultraship/bridge.h> +#include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/ShipInit.hpp" +#include "soh/OTRGlobals.h" + +extern "C" { +#include "z64.h" +#include "macros.h" +#include "functions.h" +extern PlayState* gPlayState; +} + +#define CVAR_REWORKED_TARGETING_NAME CVAR_ENHANCEMENT("ReworkedTargeting.Enabled") +#define CVAR_REWORKED_TARGETING_VALUE CVarGetInteger(CVAR_REWORKED_TARGETING_NAME, 0) + +static bool sTriggeredByButtonCombo = false; + +void RegisterReworkedTargeting() { + + COND_VB_SHOULD(VB_TOGGLE_Z_TARGET_SWITCH_TARGETS, CVAR_REWORKED_TARGETING_VALUE, { + Player* player = GET_PLAYER(gPlayState); + if (player->focusActor != NULL && !sTriggeredByButtonCombo) { + *should = false; + } + sTriggeredByButtonCombo = false; + }); + + COND_VB_SHOULD(VB_TOGGLE_Z_TARGET_SWITCH_DIRECTION, CVAR_REWORKED_TARGETING_VALUE, { + if (*should) + return; + + Player* player = GET_PLAYER(gPlayState); + + if (player->focusActor != NULL) { + Input* input = &gPlayState->state.input[0]; + + static bool wasButtonComboActive = false; + + const s32 targetSwitchMask = CVarGetInteger(CVAR_ENHANCEMENT("ReworkedTargeting.Btn"), 0); + bool isButtonComboActive = CHECK_BTN_ANY(input->press.button, targetSwitchMask); + + if (isButtonComboActive && !wasButtonComboActive) { + Actor* nextTarget = gPlayState->actorCtx.targetCtx.unk_94; + if (nextTarget != NULL) { + sTriggeredByButtonCombo = true; + *should = true; + } else { + *should = false; + } + } + + wasButtonComboActive = isButtonComboActive; + } + }); +} + +static RegisterShipInitFunc initFunc(RegisterReworkedTargeting, { CVAR_REWORKED_TARGETING_NAME }); diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index 4959f7f23..2065c929d 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -2625,6 +2625,22 @@ typedef enum { // #### `result` // ```c + // false + // ``` + // #### `args` + // - None + VB_TOGGLE_Z_TARGET_SWITCH_DIRECTION, + + // #### `result` + // ```c + // !usingHoldTargeting + // ``` + // #### `args` + // - `int32_t` (usingHoldTargeting - promoted from `s32`) + VB_TOGGLE_Z_TARGET_SWITCH_TARGETS, + + // #### `result` + // ```c // (uint8_t)font->msgBuf[msgCtx->msgBufPos + 1] >= ITEM_CUSTOM // ``` // #### `args` diff --git a/soh/soh/SohGui/SohMenuEnhancements.cpp b/soh/soh/SohGui/SohMenuEnhancements.cpp index e0574ca53..aab8c4d04 100644 --- a/soh/soh/SohGui/SohMenuEnhancements.cpp +++ b/soh/soh/SohGui/SohMenuEnhancements.cpp @@ -268,6 +268,17 @@ void SohMenu::AddMenuEnhancements() { .DefaultValue(0) .Format("%d frames") .Tooltip("Buffers your inputs to be executed a specified amount of frames later.")); + AddWidget(path, "Reworked Targeting", WIDGET_CVAR_CHECKBOX) + .CVar(CVAR_ENHANCEMENT("ReworkedTargeting.Enabled")) + .Options(CheckboxOptions().Tooltip("Reworks targeting functionality\n" + "- Press Z while locked always untargets (in Toggle mode)\n" + "- Use the configured button combo to switch between targets")); + AddWidget(path, "Target Switch Button Combination:", WIDGET_CVAR_BTN_SELECTOR) + .PreFunc([](WidgetInfo& info) { + info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ReworkedTargeting.Enabled"), 0) == 0; + }) + .CVar(CVAR_ENHANCEMENT("ReworkedTargeting.Btn")) + .Options(BtnSelectorOptions().Tooltip("Buttons to activate target switching.")); AddWidget(path, "Item Count Messages", WIDGET_SEPARATOR_TEXT); AddWidget(path, "Gold Skulltula Tokens", WIDGET_CVAR_CHECKBOX) diff --git a/soh/src/overlays/actors/ovl_player_actor/z_player.c b/soh/src/overlays/actors/ovl_player_actor/z_player.c index 3c707383c..130644968 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -3829,7 +3829,8 @@ void Player_UpdateZTargeting(Player* this, PlayState* play) { if (!isTalking) { if (!(this->stateFlags1 & PLAYER_STATE1_BOOMERANG_THROWN) && ((this->heldItemAction != PLAYER_IA_FISHING_POLE) || (this->unk_860 == 0)) && - CHECK_BTN_ALL(sControlInput->press.button, BTN_Z)) { + GameInteractor_Should(VB_TOGGLE_Z_TARGET_SWITCH_DIRECTION, + CHECK_BTN_ALL(sControlInput->press.button, BTN_Z))) { if (this->actor.category == ACTORCAT_PLAYER) { // The next lock-on actor defaults to the actor Navi is hovering over. @@ -3855,7 +3856,7 @@ void Player_UpdateZTargeting(Player* this, PlayState* play) { nextLockOnActor = play->actorCtx.targetCtx.unk_94; } - if (nextLockOnActor != this->focusActor) { + if (GameInteractor_Should(VB_TOGGLE_Z_TARGET_SWITCH_TARGETS, nextLockOnActor != this->focusActor)) { // Set new lock-on if (!usingHoldTargeting) { |
