diff --git a/mm/2s2h/BenGui/BenMenu.cpp b/mm/2s2h/BenGui/BenMenu.cpp index ef420124f9..655416fd47 100644 --- a/mm/2s2h/BenGui/BenMenu.cpp +++ b/mm/2s2h/BenGui/BenMenu.cpp @@ -1399,6 +1399,9 @@ void BenMenu::AddEnhancements() { AddWidget(path, "Skip Enemy Cutscenes", WIDGET_CVAR_CHECKBOX) .CVar("gEnhancements.Cutscenes.SkipEnemyCutscenes") .Options(CheckboxOptions().Tooltip("Skips cutscenes specific to enemies and boss battles.")); + AddWidget(path, "Skip Bottle Pickup Messages", WIDGET_CVAR_CHECKBOX) + .CVar("gEnhancements.Timesavers.SkipBottlePickupMessages") + .Options(CheckboxOptions().Tooltip("Skip pickup messages for bottle swipes.")); AddWidget(path, "Skip Item Get Cutscene", WIDGET_CVAR_COMBOBOX) .CVar("gEnhancements.Cutscenes.SkipGetItemCutscenes") .Options(ComboboxOptions() @@ -1457,6 +1460,9 @@ void BenMenu::AddEnhancements() { "Automatically deposits excess Rupees into your bank account when your wallet is full. " "Deposits stop when the bank reaches maximum capacity. " "Bank rewards are granted automatically. Notifications display deposit amount and new balance.")); + AddWidget(path, "Empty Bottles Faster", WIDGET_CVAR_CHECKBOX) + .CVar("gEnhancements.Timesavers.FasterBottleEmpty") + .Options(CheckboxOptions().Tooltip("Speeds up emptying animation when dumping out the contents of a bottle.")); // Fixes path = { "Enhancements", "Fixes", SECTION_COLUMN_1 }; diff --git a/mm/2s2h/Enhancements/Timesavers/FasterBottleEmpty.cpp b/mm/2s2h/Enhancements/Timesavers/FasterBottleEmpty.cpp new file mode 100644 index 0000000000..cb6fcc14cf --- /dev/null +++ b/mm/2s2h/Enhancements/Timesavers/FasterBottleEmpty.cpp @@ -0,0 +1,22 @@ +#include "2s2h/GameInteractor/GameInteractor.h" +#include "2s2h/ShipInit.hpp" + +extern "C" { +#include "z64save.h" +} + +#define CVAR_NAME "gEnhancements.Timesavers.FasterBottleEmpty" +#define CVAR CVarGetInteger(CVAR_NAME, 0) + +void RegisterFasterEmptyBottle() { + COND_VB_SHOULD(VB_EMPTYING_BOTTLE, CVAR, { + Player* player = va_arg(args, Player*); + if (player->skelAnime.curFrame <= 60.0f) { + player->skelAnime.playSpeed = 3.0f; + } else { + player->skelAnime.playSpeed = 1.0f; + } + }); +} + +static RegisterShipInitFunc initFunc(RegisterFasterEmptyBottle, { CVAR_NAME }); diff --git a/mm/2s2h/GameInteractor/GameInteractor_VanillaBehavior.h b/mm/2s2h/GameInteractor/GameInteractor_VanillaBehavior.h index 9f8bd8bb16..774f30e1a5 100644 --- a/mm/2s2h/GameInteractor/GameInteractor_VanillaBehavior.h +++ b/mm/2s2h/GameInteractor/GameInteractor_VanillaBehavior.h @@ -646,6 +646,14 @@ typedef enum { // - None VB_FLASH_SCREEN_FOR_ENEMY_KILL, + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - Player* + VB_EMPTYING_BOTTLE, + // #### `result` // ```c // false 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 2404ce0ad6..83ee153ba2 100644 --- a/mm/src/overlays/actors/ovl_player_actor/z_player.c +++ b/mm/src/overlays/actors/ovl_player_actor/z_player.c @@ -18210,6 +18210,12 @@ void Player_Action_68(Player* this, PlayState* play) { if (PlayerAnimation_Update(play, &this->skelAnime)) { if (this->av1.actionVar1 != 0) { + if (CVarGetInteger("gEnhancements.Timesavers.SkipBottlePickupMessages", 0)) { + this->av1.actionVar1 = 0; + Camera_SetFinishedFlag(Play_GetCamera(play, CAM_ID_MAIN)); + Audio_PlayFanfare(NA_BGM_GET_ITEM); + return; + } func_808323C0(this, play->playerCsIds[PLAYER_CS_ID_ITEM_SHOW]); if (this->av2.actionVar2 == 0) { @@ -18260,10 +18266,14 @@ void Player_Action_68(Player* this, PlayState* play) { if (i < ARRAY_COUNT(D_8085D798)) { this->av1.actionVar1 = i + 1; this->av2.actionVar2 = 0; - this->stateFlags1 |= PLAYER_STATE1_10000000 | PLAYER_STATE1_20000000; + if (!CVarGetInteger("gEnhancements.Timesavers.SkipBottlePickupMessages", 0)) { + this->stateFlags1 |= PLAYER_STATE1_10000000 | PLAYER_STATE1_20000000; + } interactRangeActor->parent = &this->actor; Player_UpdateBottleHeld(play, this, entry->itemId, entry->itemAction); - Player_Anim_PlayOnceAdjusted(play, this, sp24->unk_4); + if (!CVarGetInteger("gEnhancements.Timesavers.SkipBottlePickupMessages", 0)) { + Player_Anim_PlayOnceAdjusted(play, this, sp24->unk_4); + } } } } @@ -18289,10 +18299,14 @@ void Player_Action_68(Player* this, PlayState* play) { if (i < ARRAY_COUNT(D_8085D798)) { this->av1.actionVar1 = i + 1; this->av2.actionVar2 = 0; - this->stateFlags1 |= PLAYER_STATE1_10000000 | PLAYER_STATE1_20000000; + if (!CVarGetInteger("gEnhancements.Timesavers.SkipBottlePickupMessages", 0)) { + this->stateFlags1 |= PLAYER_STATE1_10000000 | PLAYER_STATE1_20000000; + } interactRangeActor->parent = &this->actor; Player_UpdateBottleHeld(play, this, entry->itemId, entry->itemAction); - Player_Anim_PlayOnceAdjusted(play, this, sp24->unk_4); + if (!CVarGetInteger("gEnhancements.Timesavers.SkipBottlePickupMessages", 0)) { + Player_Anim_PlayOnceAdjusted(play, this, sp24->unk_4); + } } } } @@ -18380,6 +18394,9 @@ void Player_Action_70(Player* this, PlayState* play) { } Player_DecelerateToZero(this); + + GameInteractor_Should(VB_EMPTYING_BOTTLE, true, this); + func_8083249C(this); if (PlayerAnimation_Update(play, &this->skelAnime)) {