mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-02-15 14:50:20 -05:00
Pause Warp Enhancement
This commit introduces the PauseWarp mod, a feature that allows players to warp to different locations in the game directly from the pause menu. - Add PauseWarpState structure to manage flags and cooldowns for the pause warp feature. - Implement IsStateValid function for state validation. - Implement ResetStateFlags function to reset all state flags to default values. - Add InitiateWarp function to handle the initiation of warp sequences. - Implement HandleWarpConfirmation function to confirm and execute warp actions. - Implement HandleCooldowns function to manage various cooldown timers. - Add PauseWarp_Main function as the main logic, called every frame to handle pause warp functionality. - Map warp song messages to in-game text messages.
This commit is contained in:
parent
bb643661f6
commit
ee0d0b0929
97
soh/soh/Enhancements/randomizer/pausewarp.c
Normal file
97
soh/soh/Enhancements/randomizer/pausewarp.c
Normal file
@ -0,0 +1,97 @@
|
||||
// Importing necessary libraries and headers
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "soh/Enhancements/gameconsole.h"
|
||||
#include "global.h"
|
||||
#include "../custom-message/CustomMessageTypes.h"
|
||||
|
||||
// Defining the structure for the pause warp state, which holds different flags and cooldowns
|
||||
typedef struct {
|
||||
bool warpInitiated, textboxInitiated, inChoosingState, textboxIsOpen, isTextboxClosing;
|
||||
int aButtonCooldown, textboxCheckCooldown, textboxOpenCooldown;
|
||||
} PauseWarpState;
|
||||
|
||||
// Mapping the song messages. Each song corresponds to a specific text message.
|
||||
static const int songMessageMap[] = { TEXT_WARP_MINUET_OF_FOREST, TEXT_WARP_BOLERO_OF_FIRE, TEXT_WARP_SERENADE_OF_WATER, TEXT_WARP_REQUIEM_OF_SPIRIT, TEXT_WARP_NOCTURNE_OF_SHADOW, TEXT_WARP_PRELUDE_OF_LIGHT };
|
||||
|
||||
// Forward declaring the functions used in this file
|
||||
bool IsStateValid(PlayState* play, Player* player, PauseWarpState* state);
|
||||
void ResetStateFlags(PauseWarpState* state);
|
||||
void InitiateWarp(PlayState* play, Player* player, int song, PauseWarpState* state);
|
||||
void HandleWarpConfirmation(PlayState* play, Player* player, PauseWarpState* state);
|
||||
void HandleCooldowns(PauseWarpState* state);
|
||||
|
||||
// Checking if the state is valid. This is a sanity check to ensure we're not operating on null pointers.
|
||||
bool IsStateValid(PlayState* play, Player* player, PauseWarpState* state) {
|
||||
return play && player && state;
|
||||
}
|
||||
|
||||
// Resetting all the flags in the state to their default values (which is mostly 'false' for booleans and '0' for integers)
|
||||
void ResetStateFlags(PauseWarpState* state) {
|
||||
*state = (PauseWarpState){0};
|
||||
}
|
||||
|
||||
// Initiating the warp process. Here we set all the required flags and disable player input.
|
||||
void InitiateWarp(PlayState* play, Player* player, int song, PauseWarpState* state) {
|
||||
int idx = song - QUEST_SONG_MINUET; // Calculating the song index
|
||||
play->msgCtx.lastPlayedSong = idx; // Storing the last played song
|
||||
play->pauseCtx.state = 0x12; // Setting the pause state
|
||||
Message_StartTextbox(play, songMessageMap[idx], NULL); // Starting the textbox with the appropriate message
|
||||
player->stateFlags1 |= PLAYER_STATE1_INPUT_DISABLED; // Disabling player input
|
||||
*state = (PauseWarpState){.warpInitiated = true, .textboxOpenCooldown = 10, .aButtonCooldown = 10, .textboxCheckCooldown = 5, .textboxIsOpen = true}; // Setting the flags for warp
|
||||
play->msgCtx.choiceIndex = 0; // Resetting the choice index
|
||||
}
|
||||
|
||||
// Handling the warp confirmation. This is the part where the player actually gets teleported if they confirmed.
|
||||
void HandleWarpConfirmation(PlayState* play, Player* player, PauseWarpState* state) {
|
||||
if (play->msgCtx.choiceIndex == 0) Entrance_SetWarpSongEntrance(); // Teleporting the player if 'ok' was selected
|
||||
player->stateFlags1 &= ~PLAYER_STATE1_INPUT_DISABLED; // Re-enabling player input
|
||||
ResetStateFlags(state); // Resetting the state flags
|
||||
}
|
||||
|
||||
// Managing the cooldowns for different actions and transitions
|
||||
void HandleCooldowns(PauseWarpState* state) {
|
||||
// Decreasing the cooldowns if they're greater than zero
|
||||
if (state->aButtonCooldown > 0) state->aButtonCooldown--;
|
||||
if (state->textboxCheckCooldown > 0) state->textboxCheckCooldown--;
|
||||
if (state->textboxOpenCooldown > 0) state->textboxOpenCooldown--;
|
||||
|
||||
// If the textbox is closing, reset the flag
|
||||
if (state->isTextboxClosing) *state = (PauseWarpState){.isTextboxClosing = false};
|
||||
}
|
||||
|
||||
// The main function that gets called every frame
|
||||
void PauseWarp_Main() {
|
||||
static PauseWarpState state; // The state is static so it retains its value between function calls
|
||||
|
||||
// Checking if the pause warp feature is enabled
|
||||
int pauseWarpEnabled = CVarGetInteger("gPauseWarpEnabled", 0);
|
||||
PlayState* play = gPlayState;
|
||||
Player* player = play ? GET_PLAYER(play) : NULL;
|
||||
|
||||
// If pause warp is not enabled or the state is invalid, reset the state and exit
|
||||
if (!pauseWarpEnabled || !IsStateValid(play, player, &state)) return ResetStateFlags(&state);
|
||||
|
||||
// Check if a Ocarina in the Ocarina slot
|
||||
if (gSaveContext.inventory.items[SLOT_OCARINA] == ITEM_NONE) return ResetStateFlags(&state);
|
||||
|
||||
// Checking if the 'A' button is pressed
|
||||
int aButtonPressed = CHECK_BTN_ALL(play->state.input->press.button, BTN_A);
|
||||
|
||||
// If 'A' is pressed and the cooldowns are zero, and we're not already warping, initiate the warp
|
||||
if (aButtonPressed && !state.aButtonCooldown && !(state.warpInitiated || state.textboxInitiated || state.inChoosingState)) {
|
||||
int song = play->pauseCtx.cursorPoint[PAUSE_QUEST];
|
||||
if (song >= QUEST_SONG_MINUET && song <= QUEST_SONG_PRELUDE) InitiateWarp(play, player, song, &state);
|
||||
}
|
||||
|
||||
// Depending on the message mode, update the state flags
|
||||
switch (play->msgCtx.msgMode) {
|
||||
case 6: if (state.warpInitiated) state.textboxInitiated = true; break;
|
||||
case 53: if (state.warpInitiated && state.textboxInitiated) state.inChoosingState = true; break;
|
||||
case 54: if (state.warpInitiated && state.textboxInitiated && state.inChoosingState) HandleWarpConfirmation(play, player, &state); break;
|
||||
case 0: ResetStateFlags(&state); break;
|
||||
}
|
||||
|
||||
// Finally, handle any cooldowns for the next frame
|
||||
HandleCooldowns(&state);
|
||||
}
|
@ -560,11 +560,13 @@ void DrawEnhancementsMenu() {
|
||||
"- Obtained the Master Sword\n"
|
||||
"- Not within range of Time Block\n"
|
||||
"- Not within range of Ocarina playing spots");
|
||||
UIWidgets::PaddedEnhancementCheckbox("Pause Warp", "gPauseWarpEnabled", false);
|
||||
UIWidgets::Tooltip("Warp by selecing warp song in pause menu.");
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
UIWidgets::Spacer(0);
|
||||
|
||||
|
||||
if (ImGui::BeginMenu("Items"))
|
||||
{
|
||||
UIWidgets::PaddedEnhancementCheckbox("Instant Putaway", "gInstantPutaway", true, false);
|
||||
|
Loading…
Reference in New Issue
Block a user