Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 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
133 changes: 133 additions & 0 deletions mm/2s2h/Enhancements/Equipment/ItemUnequip.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
#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_NAME "gEnhancements.Equipment.ItemUnequip"
#define CVAR CVarGetInteger(CVAR_NAME, 0)

void RegisterDpadPageSwitchPrevention() {
COND_VB_SHOULD(VB_KALEIDO_SWITCH_PAGE_WITH_DPAD, CVarGetInteger("gEnhancements.Dpad.DpadEquips", 0), {
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you go ahead and follow the same pattern you did with ItemUnequip? Just so we're not repeating one name and not the other. CVAR_DPAD_EQUIPS is probably as good a name as any.

PlayState* play = va_arg(args, PlayState*);
Copy link
Contributor

Choose a reason for hiding this comment

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

The globally available gPlayState should give you what you need instead of having to pass a PlayState* arg, or is there a reason you had to do it this way?

u16 button = va_arg(args, int);
PauseContext* pauseCtx = &play->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, {
PlayState* play = va_arg(args, PlayState*);
Copy link
Contributor

Choose a reason for hiding this comment

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

Ditto

u16 cursorSlot = va_arg(args, int);
u16 cursorItem = va_arg(args, int);

PauseContext* pauseCtx = &play->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(play, targetSlot);
} else {
// D-pad
DPAD_BUTTON_ITEM_EQUIP(0, targetSlot) = ITEM_NONE;
DPAD_SLOT_EQUIP(0, targetSlot) = SLOT_NONE;
// Manually clear D-pad icon
play->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, { "gEnhancements.Dpad.DpadEquips" });
19 changes: 19 additions & 0 deletions mm/2s2h/GameInteractor/GameInteractor_VanillaBehavior.h
Original file line number Diff line number Diff line change
Expand Up @@ -1101,6 +1101,25 @@ typedef enum {
// - `u16` (item under cursor)
VB_KALEIDO_DISPLAY_ITEM_TEXT,

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

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

// #### `result`
// ```c
// true
Expand Down
80 changes: 47 additions & 33 deletions mm/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_item.c
Original file line number Diff line number Diff line change
Expand Up @@ -701,36 +701,45 @@ void KaleidoScope_UpdateItemCursor(PlayState* play) {
pauseCtx->equipTargetCBtn = PAUSE_EQUIP_C_RIGHT;
}
// #region 2S2H [Dpad]
else if (CVarGetInteger("gEnhancements.Dpad.DpadEquips", 0)) {
if (CHECK_BTN_ALL(CONTROLLER1(&play->state)->press.button, BTN_DRIGHT)) {
if ((Player_GetCurMaskItemId(play) != ITEM_NONE) &&
(Player_GetCurMaskItemId(play) == DPAD_BUTTON_ITEM_EQUIP(0, EQUIP_SLOT_D_RIGHT))) {
Audio_PlaySfx(NA_SE_SY_ERROR);
return;
}
pauseCtx->equipTargetCBtn = PAUSE_EQUIP_D_RIGHT;
} else if (CHECK_BTN_ALL(CONTROLLER1(&play->state)->press.button, BTN_DLEFT)) {
if ((Player_GetCurMaskItemId(play) != ITEM_NONE) &&
(Player_GetCurMaskItemId(play) == DPAD_BUTTON_ITEM_EQUIP(0, EQUIP_SLOT_D_LEFT))) {
Audio_PlaySfx(NA_SE_SY_ERROR);
return;
}
pauseCtx->equipTargetCBtn = PAUSE_EQUIP_D_LEFT;
} else if (CHECK_BTN_ALL(CONTROLLER1(&play->state)->press.button, BTN_DDOWN)) {
if ((Player_GetCurMaskItemId(play) != ITEM_NONE) &&
(Player_GetCurMaskItemId(play) == DPAD_BUTTON_ITEM_EQUIP(0, EQUIP_SLOT_D_DOWN))) {
Audio_PlaySfx(NA_SE_SY_ERROR);
return;
}
pauseCtx->equipTargetCBtn = PAUSE_EQUIP_D_DOWN;
} else if (CHECK_BTN_ALL(CONTROLLER1(&play->state)->press.button, BTN_DUP)) {
if ((Player_GetCurMaskItemId(play) != ITEM_NONE) &&
(Player_GetCurMaskItemId(play) == DPAD_BUTTON_ITEM_EQUIP(0, EQUIP_SLOT_D_UP))) {
Audio_PlaySfx(NA_SE_SY_ERROR);
return;
}
pauseCtx->equipTargetCBtn = PAUSE_EQUIP_D_UP;
else if (CVarGetInteger("gEnhancements.Dpad.DpadEquips", 0) &&
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm having trouble understanding why if (CVarGetInteger("gEnhancements.Dpad.DpadEquips", 0) was moved from being one overarching condition with further nested conditions, to being an AND condition for every case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

this is from when I was troubleshooting to try and understand why the enhancement didn't wanna work with the dpad and I thought I removed it but ig not????

CHECK_BTN_ALL(CONTROLLER1(&play->state)->press.button, BTN_DRIGHT)) {
if ((Player_GetCurMaskItemId(play) != ITEM_NONE) &&
(Player_GetCurMaskItemId(play) == DPAD_BUTTON_ITEM_EQUIP(0, EQUIP_SLOT_D_RIGHT))) {
Audio_PlaySfx(NA_SE_SY_ERROR);
return;
}
pauseCtx->equipTargetCBtn = PAUSE_EQUIP_D_RIGHT;
} else if (CVarGetInteger("gEnhancements.Dpad.DpadEquips", 0) &&
CHECK_BTN_ALL(CONTROLLER1(&play->state)->press.button, BTN_DLEFT)) {
if ((Player_GetCurMaskItemId(play) != ITEM_NONE) &&
(Player_GetCurMaskItemId(play) == DPAD_BUTTON_ITEM_EQUIP(0, EQUIP_SLOT_D_LEFT))) {
Audio_PlaySfx(NA_SE_SY_ERROR);
return;
}
pauseCtx->equipTargetCBtn = PAUSE_EQUIP_D_LEFT;
} else if (CVarGetInteger("gEnhancements.Dpad.DpadEquips", 0) &&
CHECK_BTN_ALL(CONTROLLER1(&play->state)->press.button, BTN_DDOWN)) {
if ((Player_GetCurMaskItemId(play) != ITEM_NONE) &&
(Player_GetCurMaskItemId(play) == DPAD_BUTTON_ITEM_EQUIP(0, EQUIP_SLOT_D_DOWN))) {
Audio_PlaySfx(NA_SE_SY_ERROR);
return;
}
pauseCtx->equipTargetCBtn = PAUSE_EQUIP_D_DOWN;
} else if (CVarGetInteger("gEnhancements.Dpad.DpadEquips", 0) &&
CHECK_BTN_ALL(CONTROLLER1(&play->state)->press.button, BTN_DUP)) {
if ((Player_GetCurMaskItemId(play) != ITEM_NONE) &&
(Player_GetCurMaskItemId(play) == DPAD_BUTTON_ITEM_EQUIP(0, EQUIP_SLOT_D_UP))) {
Audio_PlaySfx(NA_SE_SY_ERROR);
return;
}
pauseCtx->equipTargetCBtn = PAUSE_EQUIP_D_UP;
}
// #endregion

// #region 2S2H [Enhancement]
// 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.

This comment tag is mostly for inline changes to source code. VB names are self-explanatory, plus this entire DPad input region already labeled as such.

Suggested change
// #endregion
// #region 2S2H [Enhancement]
// Item unequip enhancement

if (!GameInteractor_Should(VB_KALEIDO_EQUIP_ITEM_TO_BUTTON, true, play, cursorSlot, cursorItem)) {
return;
}
// #endregion

Expand Down Expand Up @@ -1168,11 +1177,15 @@ void KaleidoScope_UpdateDpadItemEquip(PlayState* play) {
}
}

// Equip item on DLeft
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);
if (GameInteractor_Should(VB_KALEIDO_EQUIP_ITEM_TO_BUTTON, true, play, pauseCtx->cursorSlot[PAUSE_ITEM],
pauseCtx->cursorItem[PAUSE_ITEM])) {
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) {

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

// Swap if item is already equipped on other Item Buttons.
if (pauseCtx->equipTargetSlot == C_SLOT_EQUIP(0, EQUIP_SLOT_C_LEFT)) {
if ((DPAD_BUTTON_ITEM_EQUIP(0, EQUIP_SLOT_D_DOWN) & 0xFF) != ITEM_NONE) {
Expand Down Expand Up @@ -1319,6 +1332,7 @@ void KaleidoScope_UpdateDpadItemEquip(PlayState* play) {
DPAD_SLOT_EQUIP(0, EQUIP_SLOT_D_DOWN) = pauseCtx->equipTargetSlot;
Interface_Dpad_LoadItemIconImpl(play, EQUIP_SLOT_D_DOWN);
} else if (pauseCtx->equipTargetCBtn == PAUSE_EQUIP_D_UP) {

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

// Swap if item is already equipped on other Item Buttons.
if (pauseCtx->equipTargetSlot == C_SLOT_EQUIP(0, EQUIP_SLOT_C_LEFT)) {
if ((DPAD_BUTTON_ITEM_EQUIP(0, EQUIP_SLOT_D_UP) & 0xFF) != ITEM_NONE) {
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, play, 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,10 @@ 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 (CHECK_BTN_ALL(input->cur.button, BTN_DRIGHT) &&
!GameInteractor_Should(VB_KALEIDO_SWITCH_PAGE_WITH_DPAD, true, play, 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 +558,10 @@ 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 (CHECK_BTN_ALL(input->cur.button, BTN_DLEFT) &&
!GameInteractor_Should(VB_KALEIDO_SWITCH_PAGE_WITH_DPAD, true, play, 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