Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions mm/2s2h/BenGui/BenMenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -962,6 +962,10 @@ void BenMenu::AddEnhancements() {
AddWidget(path, "Dpad Equips", WIDGET_CVAR_CHECKBOX)
.CVar("gEnhancements.Dpad.DpadEquips")
.Options(CheckboxOptions().Tooltip("Allows you to equip items to your D-pad."));
AddWidget(path, "Unequip Items", WIDGET_CVAR_CHECKBOX)
.CVar("gEnhancements.Equipment.ItemUnequip")
.Options(CheckboxOptions().Tooltip("In the pause menu, press the same C-button or D-pad button an item is "
"equipped to in order to unequip it."));
AddWidget(path, "Fast Magic Arrow Equip Animation", WIDGET_CVAR_CHECKBOX)
.CVar("gEnhancements.Equipment.MagicArrowEquipSpeed")
.Options(CheckboxOptions().Tooltip("Removes the animation for equipping Magic Arrows."));
Expand Down
138 changes: 138 additions & 0 deletions mm/2s2h/Enhancements/Equipment/ItemUnequip.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
#include <libultraship/bridge.h>
#include "2s2h/GameInteractor/GameInteractor.h"
#include "2s2h/ShipInit.hpp"
#include "2s2h_assets.h"

extern "C" {
#include "z64.h"
#include "functions.h"
#include "macros.h"
#include "variables.h"
#include "overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope.h"
}

#define CVAR_DPAD_NAME "gEnhancements.Dpad.DpadEquips"
#define CVAR_DPAD CVarGetInteger(CVAR_DPAD_NAME, 0)
#define CVAR_NAME "gEnhancements.Equipment.ItemUnequip"
#define CVAR CVarGetInteger(CVAR_NAME, 0)

void RegisterDpadPageSwitchPrevention() {
COND_VB_SHOULD(VB_KALEIDO_SWITCH_PAGE_WITH_DPAD, CVAR_DPAD, {
u16 button = va_arg(args, int);
Input* input = &gPlayState->state.input[0];

if (CHECK_BTN_ALL(input->cur.button, button)) {
PauseContext* pauseCtx = &gPlayState->pauseCtx;

// Prevent page switching with D-pad when on item or mask page
if ((pauseCtx->pageIndex == PAUSE_ITEM || pauseCtx->pageIndex == PAUSE_MASK) &&
pauseCtx->mainState <= PAUSE_MAIN_STATE_IDLE_CURSOR_ON_SONG) {
*should = false;
}
}
});
}

void RegisterItemUnequip() {
COND_VB_SHOULD(VB_KALEIDO_EQUIP_ITEM_TO_BUTTON, CVAR, {
u16 cursorSlot = va_arg(args, int);
u16 cursorItem = va_arg(args, int);

PauseContext* pauseCtx = &gPlayState->pauseCtx;
s32 targetSlot = -1;
bool isDpad = false;

// Determine which button was pressed based on equipTargetCBtn
switch (pauseCtx->equipTargetCBtn) {
case PAUSE_EQUIP_C_LEFT:
targetSlot = EQUIP_SLOT_C_LEFT;
break;
case PAUSE_EQUIP_C_DOWN:
targetSlot = EQUIP_SLOT_C_DOWN;
break;
case PAUSE_EQUIP_C_RIGHT:
targetSlot = EQUIP_SLOT_C_RIGHT;
break;
case PAUSE_EQUIP_D_RIGHT:
targetSlot = EQUIP_SLOT_D_RIGHT;
isDpad = true;
break;
case PAUSE_EQUIP_D_LEFT:
targetSlot = EQUIP_SLOT_D_LEFT;
isDpad = true;
break;
case PAUSE_EQUIP_D_DOWN:
targetSlot = EQUIP_SLOT_D_DOWN;
isDpad = true;
break;
case PAUSE_EQUIP_D_UP:
targetSlot = EQUIP_SLOT_D_UP;
isDpad = true;
break;
default:
return;
}

u8 equippedItem;
u8 equippedSlot;
bool shouldUnequip = false;
bool isMask = cursorSlot >= ITEM_NUM_SLOTS;

// C-buttons vs D-pad
if (!isDpad) {
equippedItem = BUTTON_ITEM_EQUIP(0, targetSlot);
equippedSlot = C_SLOT_EQUIP(0, targetSlot);
} else {
equippedItem = DPAD_BUTTON_ITEM_EQUIP(0, targetSlot);
equippedSlot = DPAD_SLOT_EQUIP(0, targetSlot);
}

// Check if we should unequip
if (equippedItem == cursorItem) {
if (isMask) {
// For masks, check the slot matches (cursorSlot is already offset by ITEM_NUM_SLOTS)
if (equippedSlot == cursorSlot) {
shouldUnequip = true;
}
}
// For bottles, we need to check the slot too (since there are multiple bottle items)
else if (cursorItem >= ITEM_BOTTLE && cursorItem <= ITEM_OBABA_DRINK) {
if (equippedSlot == cursorSlot) {
shouldUnequip = true;
}
} else {
shouldUnequip = true;
}
}
// Handle magic arrows (bow variants)
else if (cursorItem == ITEM_ARROW_FIRE && equippedItem == ITEM_BOW_FIRE) {
shouldUnequip = true;
} else if (cursorItem == ITEM_ARROW_ICE && equippedItem == ITEM_BOW_ICE) {
shouldUnequip = true;
} else if (cursorItem == ITEM_ARROW_LIGHT && equippedItem == ITEM_BOW_LIGHT) {
shouldUnequip = true;
}

if (shouldUnequip) {
if (!isDpad) {
// C-buttons
BUTTON_ITEM_EQUIP(0, targetSlot) = ITEM_NONE;
C_SLOT_EQUIP(0, targetSlot) = SLOT_NONE;
Interface_LoadItemIconImpl(gPlayState, targetSlot);
} else {
// D-pad
DPAD_BUTTON_ITEM_EQUIP(0, targetSlot) = ITEM_NONE;
DPAD_SLOT_EQUIP(0, targetSlot) = SLOT_NONE;
// Manually clear D-pad icon
gPlayState->interfaceCtx.iconItemSegment[DPAD_BUTTON(targetSlot) + EQUIP_SLOT_MAX] =
(char*)gEmptyTexture;
}

Audio_PlaySfx(NA_SE_SY_DECIDE);
*should = false;
}
});
}

static RegisterShipInitFunc initFunc(RegisterItemUnequip, { CVAR_NAME });
static RegisterShipInitFunc initDpadPageSwitch(RegisterDpadPageSwitchPrevention, { CVAR_DPAD_NAME });
17 changes: 17 additions & 0 deletions mm/2s2h/GameInteractor/GameInteractor_VanillaBehavior.h
Original file line number Diff line number Diff line change
Expand Up @@ -1101,6 +1101,23 @@ typedef enum {
// - `u16` (item under cursor)
VB_KALEIDO_DISPLAY_ITEM_TEXT,

// #### `result`
// ```c
// true
// ```
// #### `args`
// - `u16` (cursor slot)
// - `u16` (cursor item)
VB_KALEIDO_EQUIP_ITEM_TO_BUTTON,

// #### `result`
// ```c
// true
// ```
// #### `args`
// - `u16` (button - BTN_DLEFT or BTN_DRIGHT)
VB_KALEIDO_SWITCH_PAGE_WITH_DPAD,

// #### `result`
// ```c
// true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -733,6 +733,9 @@ void KaleidoScope_UpdateItemCursor(PlayState* play) {
}
}
// #endregion
if (!GameInteractor_Should(VB_KALEIDO_EQUIP_ITEM_TO_BUTTON, true, cursorSlot, cursorItem)) {
return;
}

// Equip item to the C buttons
pauseCtx->equipTargetItem = cursorItem;
Expand Down Expand Up @@ -1172,6 +1175,7 @@ void KaleidoScope_UpdateDpadItemEquip(PlayState* play) {
DPAD_BUTTON_ITEM_EQUIP(0, EQUIP_SLOT_D_LEFT) = pauseCtx->equipTargetItem;
DPAD_SLOT_EQUIP(0, EQUIP_SLOT_D_LEFT) = pauseCtx->equipTargetSlot;
Interface_Dpad_LoadItemIconImpl(play, EQUIP_SLOT_D_LEFT);

} else if (pauseCtx->equipTargetCBtn == PAUSE_EQUIP_D_DOWN) {
// Swap if item is already equipped on other Item Buttons.
if (pauseCtx->equipTargetSlot == C_SLOT_EQUIP(0, EQUIP_SLOT_C_LEFT)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -661,6 +661,12 @@ void KaleidoScope_UpdateMaskCursor(PlayState* play) {
}
// #endregion

// Item unequip enhancement
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Item unequip enhancement

if (!GameInteractor_Should(VB_KALEIDO_EQUIP_ITEM_TO_BUTTON, true, cursorSlot + ITEM_NUM_SLOTS,
cursorItem)) {
return;
}

// Equip item to the C buttons
pauseCtx->equipTargetItem = cursorItem;
pauseCtx->equipTargetSlot = cursorSlot + ITEM_NUM_SLOTS;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,9 @@ void KaleidoScope_HandlePageToggles(PlayState* play, Input* input) {
}

if (CHECK_BTN_ALL(input->cur.button, BTN_DRIGHT) || CHECK_BTN_ALL(input->press.button, BTN_R)) {
if (!GameInteractor_Should(VB_KALEIDO_SWITCH_PAGE_WITH_DPAD, true, BTN_DRIGHT)) {
return;
}
// Switch the page to the right regardless of where the cursor is
if (interfaceCtx->aButtonDoActionDelayed == DO_ACTION_DECIDE) {
Interface_SetAButtonDoAction(play, DO_ACTION_INFO);
Expand All @@ -554,6 +557,9 @@ void KaleidoScope_HandlePageToggles(PlayState* play, Input* input) {
}

if (CHECK_BTN_ALL(input->cur.button, BTN_DLEFT) || CHECK_BTN_ALL(input->press.button, BTN_Z)) {
if (!GameInteractor_Should(VB_KALEIDO_SWITCH_PAGE_WITH_DPAD, true, BTN_DLEFT)) {
return;
}
// Switch the page to the left regardless of where the cursor is
if (interfaceCtx->aButtonDoActionDelayed == DO_ACTION_DECIDE) {
Interface_SetAButtonDoAction(play, DO_ACTION_INFO);
Expand Down
Loading