[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
This commit is contained in:
OtherBlue
2026-03-21 15:41:08 -03:00
committed by GitHub
parent b6bf97e2f1
commit 2af5d21125
4 changed files with 87 additions and 2 deletions

View File

@@ -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 });

View File

@@ -2623,6 +2623,22 @@ typedef enum {
// - `double` (temp - promoted from `f32`)
VB_RUMBLE_FOR_SECRET,
// #### `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

View File

@@ -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)

View File

@@ -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) {