summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOtherBlue <93625085+OtherBlue@users.noreply.github.com>2026-03-21 15:41:08 -0300
committerGitHub <noreply@github.com>2026-03-21 18:41:08 +0000
commit2af5d2112543f88c4476d5cf082aeca9e601f5f2 (patch)
tree9e76451628e6c810d5be841cdec5375b45e4eaab
parentb6bf97e2f199ae9c947e3b192b690c1d6257517b (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
-rw-r--r--soh/soh/Enhancements/ReworkedTargeting.cpp57
-rw-r--r--soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h16
-rw-r--r--soh/soh/SohGui/SohMenuEnhancements.cpp11
-rw-r--r--soh/src/overlays/actors/ovl_player_actor/z_player.c5
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) {