diff options
| author | Eblo <7004497+Eblo@users.noreply.github.com> | 2025-10-15 12:37:00 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-10-15 12:37:00 -0400 |
| commit | edb8cda56dc27caffac92c69e76dabe3a3728ea0 (patch) | |
| tree | e7a74bfbf7f36754f63501ba857a2beeb83df24c | |
| parent | 4569ead1ac673165b378fb65ba2cc17ccd46bd37 (diff) | |
Mask disable adjustments (#1268)
| -rw-r--r-- | mm/2s2h/Enhancements/Masks/FierceDeityAnywhere.cpp | 20 | ||||
| -rw-r--r-- | mm/2s2h/Enhancements/Player/UnderwaterOcarina.cpp | 8 | ||||
| -rw-r--r-- | mm/2s2h/GameInteractor/GameInteractor.h | 3 | ||||
| -rw-r--r-- | mm/2s2h/Rando/ActorBehavior/Souls.cpp | 13 | ||||
| -rw-r--r-- | mm/src/code/z_parameter.c | 18 | ||||
| -rw-r--r-- | mm/src/overlays/actors/ovl_player_actor/z_player.c | 2 |
6 files changed, 49 insertions, 15 deletions
diff --git a/mm/2s2h/Enhancements/Masks/FierceDeityAnywhere.cpp b/mm/2s2h/Enhancements/Masks/FierceDeityAnywhere.cpp index ba208b5ec..ac586ea0d 100644 --- a/mm/2s2h/Enhancements/Masks/FierceDeityAnywhere.cpp +++ b/mm/2s2h/Enhancements/Masks/FierceDeityAnywhere.cpp @@ -206,6 +206,26 @@ void RegisterFierceDeityAnywhere() { *should = true; } }); + + /* + * Allow the FD Mask to be usable in water. This requires two pieces: using VB_DISABLE_ITEM_UNDERWATER to make the + * assigned button itself enabled and using VB_USE_ITEM_CONSIDER_ITEM_ACTION to ensure the item action can be + * completed in water. This is how, normally, Zora Mask is the only usable item in water. + */ + COND_VB_SHOULD(VB_USE_ITEM_CONSIDER_ITEM_ACTION, CVAR, { + PlayerItemAction itemAction = *va_arg(args, PlayerItemAction*); + if (itemAction == PLAYER_IA_MASK_FIERCE_DEITY) { + *should = true; + } + }); + + COND_VB_SHOULD(VB_DISABLE_ITEM_UNDERWATER, CVAR, { + s32 item = va_arg(args, s32); + if (item == ITEM_MASK_FIERCE_DEITY && + Player_GetEnvironmentalHazard(gPlayState) > PLAYER_ENV_HAZARD_UNDERWATER_FLOOR) { + *should = false; + } + }); } static RegisterShipInitFunc initFunc(RegisterFierceDeityAnywhere, { CVAR_NAME }); diff --git a/mm/2s2h/Enhancements/Player/UnderwaterOcarina.cpp b/mm/2s2h/Enhancements/Player/UnderwaterOcarina.cpp index b6ff81fdc..9475e0ce3 100644 --- a/mm/2s2h/Enhancements/Player/UnderwaterOcarina.cpp +++ b/mm/2s2h/Enhancements/Player/UnderwaterOcarina.cpp @@ -3,16 +3,18 @@ #include "2s2h/ShipInit.hpp" extern "C" { -#include "z64item.h" +#include "variables.h" +#include "functions.h" } #define CVAR_NAME "gEnhancements.Player.UnderwaterOcarina" #define CVAR CVarGetInteger(CVAR_NAME, 0) void RegisterUnderwaterOcarina() { - COND_VB_SHOULD(VB_DISABLE_ITEM_UNDERWATER_FLOOR, CVAR, { + COND_VB_SHOULD(VB_DISABLE_ITEM_UNDERWATER, CVAR, { const auto item = va_arg(args, s32); - if (item == ITEM_OCARINA_OF_TIME) { + if (item == ITEM_OCARINA_OF_TIME && + Player_GetEnvironmentalHazard(gPlayState) == PLAYER_ENV_HAZARD_UNDERWATER_FLOOR) { *should = false; } }); diff --git a/mm/2s2h/GameInteractor/GameInteractor.h b/mm/2s2h/GameInteractor/GameInteractor.h index 83729fa6c..9bc8a868d 100644 --- a/mm/2s2h/GameInteractor/GameInteractor.h +++ b/mm/2s2h/GameInteractor/GameInteractor.h @@ -247,12 +247,13 @@ typedef enum { VB_BE_NEAR_DOOR, VB_LOAD_PLAYER_ANIMATION_FRAME, VB_PLAY_SCENE_SEQUENCE, - VB_DISABLE_ITEM_UNDERWATER_FLOOR, + VB_DISABLE_ITEM_UNDERWATER, VB_PLAY_SLOW_CHEST_CS, VB_BE_CLIMBABLE_SURFACE, VB_PLAYER_CUTSCENE_ACTION, VB_SET_CAMERA_AT_EYE, VB_SET_CAMERA_FOV, + VB_USE_ITEM_CONSIDER_ITEM_ACTION, } GIVanillaBehavior; typedef enum { diff --git a/mm/2s2h/Rando/ActorBehavior/Souls.cpp b/mm/2s2h/Rando/ActorBehavior/Souls.cpp index 156193b0d..ff2604bd1 100644 --- a/mm/2s2h/Rando/ActorBehavior/Souls.cpp +++ b/mm/2s2h/Rando/ActorBehavior/Souls.cpp @@ -69,4 +69,17 @@ void Rando::ActorBehavior::InitSoulsBehavior() { COND_ID_HOOK(ShouldActorUpdate, ACTOR_BOSS_02, shouldRegister, [](Actor* actor, bool* should) { ShouldActorUpdate(actor, should, RANDO_INF_OBTAINED_SOUL_OF_TWINMOLD); }); + + /* + * Giant's Mask functionality is handled by two pieces. The scene (Twinmold's Lair) determines whether the mask can + * be used, while the Twinmold actor itself handles the transformation. Boss Souls prevent Twinmold from updating + * unless its soul has been obtained, which results in a softlock. In this case, disable the item. + */ + COND_VB_SHOULD(VB_ITEM_BE_RESTRICTED, shouldRegister, { + ItemId itemId = *va_arg(args, ItemId*); + if (itemId == ITEM_MASK_GIANT && gPlayState->sceneId == SCENE_INISIE_BS && + !Flags_GetRandoInf(RANDO_INF_OBTAINED_SOUL_OF_TWINMOLD)) { + *should = true; + } + }); } diff --git a/mm/src/code/z_parameter.c b/mm/src/code/z_parameter.c index ffc4f824d..5c409fd46 100644 --- a/mm/src/code/z_parameter.c +++ b/mm/src/code/z_parameter.c @@ -3154,12 +3154,11 @@ void Interface_UpdateButtonsPart2(PlayState* play) { } for (i = EQUIP_SLOT_C_LEFT; i <= EQUIP_SLOT_C_RIGHT; i++) { - if (GET_CUR_FORM_BTN_ITEM(i) != ITEM_MASK_ZORA) { + if (GameInteractor_Should(VB_DISABLE_ITEM_UNDERWATER, GET_CUR_FORM_BTN_ITEM(i) != ITEM_MASK_ZORA, + (s32)GET_CUR_FORM_BTN_ITEM(i))) { if (Player_GetEnvironmentalHazard(play) == PLAYER_ENV_HAZARD_UNDERWATER_FLOOR) { - if (GameInteractor_Should(VB_DISABLE_ITEM_UNDERWATER_FLOOR, - !((GET_CUR_FORM_BTN_ITEM(i) >= ITEM_BOTTLE) && - (GET_CUR_FORM_BTN_ITEM(i) <= ITEM_OBABA_DRINK)), - (s32)GET_CUR_FORM_BTN_ITEM(i))) { + if (!((GET_CUR_FORM_BTN_ITEM(i) >= ITEM_BOTTLE) && + (GET_CUR_FORM_BTN_ITEM(i) <= ITEM_OBABA_DRINK))) { if (gSaveContext.buttonStatus[i] == BTN_ENABLED) { restoreHudVisibility = true; } @@ -3183,12 +3182,11 @@ void Interface_UpdateButtonsPart2(PlayState* play) { } // #region 2S2H [Dpad] for (s16 j = EQUIP_SLOT_D_RIGHT; j <= EQUIP_SLOT_D_UP; j++) { - if (DPAD_GET_CUR_FORM_BTN_ITEM(j) != ITEM_MASK_ZORA) { + if (GameInteractor_Should(VB_DISABLE_ITEM_UNDERWATER, DPAD_GET_CUR_FORM_BTN_ITEM(j) != ITEM_MASK_ZORA, + (s32)DPAD_GET_CUR_FORM_BTN_ITEM(j))) { if (Player_GetEnvironmentalHazard(play) == PLAYER_ENV_HAZARD_UNDERWATER_FLOOR) { - if (GameInteractor_Should(VB_DISABLE_ITEM_UNDERWATER_FLOOR, - !((DPAD_GET_CUR_FORM_BTN_ITEM(j) >= ITEM_BOTTLE) && - (DPAD_GET_CUR_FORM_BTN_ITEM(j) <= ITEM_OBABA_DRINK)), - (s32)DPAD_GET_CUR_FORM_BTN_ITEM(j))) { + if (!((DPAD_GET_CUR_FORM_BTN_ITEM(j) >= ITEM_BOTTLE) && + (DPAD_GET_CUR_FORM_BTN_ITEM(j) <= ITEM_OBABA_DRINK))) { if (gSaveContext.shipSaveContext.dpad.status[j] == BTN_ENABLED) { restoreHudVisibility = true; } diff --git a/mm/src/overlays/actors/ovl_player_actor/z_player.c b/mm/src/overlays/actors/ovl_player_actor/z_player.c index d4b1c832f..966115951 100644 --- a/mm/src/overlays/actors/ovl_player_actor/z_player.c +++ b/mm/src/overlays/actors/ovl_player_actor/z_player.c @@ -4629,7 +4629,7 @@ void Player_UseItem(PlayState* play, Player* this, ItemId item) { ((this->itemAction <= PLAYER_IA_MINUS1) && ((Player_MeleeWeaponFromIA(itemAction) != PLAYER_MELEEWEAPON_NONE) || (itemAction == PLAYER_IA_NONE)))) && ((itemAction == PLAYER_IA_NONE) || !(this->stateFlags1 & PLAYER_STATE1_8000000) || - (itemAction == PLAYER_IA_MASK_ZORA) || + (GameInteractor_Should(VB_USE_ITEM_CONSIDER_ITEM_ACTION, itemAction == PLAYER_IA_MASK_ZORA, &itemAction)) || ((this->currentBoots >= PLAYER_BOOTS_ZORA_UNDERWATER) && (this->actor.bgCheckFlags & BGCHECKFLAG_GROUND)))) { s32 var_v1 = ((itemAction >= PLAYER_IA_MASK_MIN) && (itemAction <= PLAYER_IA_MASK_MAX) && (!GameInteractor_Should(VB_USE_ITEM_CONSIDER_LINK_HUMAN, |
