mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2024-11-26 03:12:18 -05:00
Pause Warp Enhancement (#3223)
* 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.
* Warp Song Check
-Now if you do not have a warp song you won't be able to select the empty slot and still teleport.
* Added Audio Fanfares and Changed stateFlag1 to PLAYER_STATE1_IN_CUTSCENE
-When selecting a warp song the audio for the applicable warp song will now play for a extra vanilla feel.
-Changed the stateFlag1 because previously it just disabled input allowing enemies to harm you. Now that won't happen because the game is put into a cutscene state.
* Feedback Update
-A new hook was created 'OnPauseMenu' so now PauseWarp_Main is only called when the pause menu is open
-Moved pauswarp.c to the Enhancements folder
-Removed from graph.c
PR Change:
Changing to the main branch instead of sulu
* Feedback Update #2
-Introduced new function 'PauseWarp_Idle' now that 'PauseWarp_Main' is no longer called every frame
-Added C wrapper to access 'GameInteractor::IsSaveLoaded' and scrapped the 'IsStateValid' function
-Added 'PauseWarp_Idle' to the the 'RegisterPauseWarp' function
-Refactored the code some
* Linux Compile Issue
-Added a missing header that was causing a compile issue for linux
-Hopefully, it won't crash
* Minor Bug Fix
-Now link won't get soft locked when warping to the same location twice
* Update libultraship
* Revert "Update libultraship"
This reverts commit 746fc23479
.
* Bug Fix
-Added more checks to ensure vanilla behavior when a Ocarina is not in the players inventory.
* WIP
* Done unless I'm missing headers
* now we done
* clean up, these arn't needed anymore
* Rename OnPauseMenu to OnKaleidoUpdate
This commit is contained in:
parent
c1eb0a8970
commit
3187564f5b
@ -2467,6 +2467,10 @@ void Message_DrawText(PlayState* play, Gfx** gfxP);
|
|||||||
void Interface_CreateQuadVertexGroup(Vtx* vtxList, s32 xStart, s32 yStart, s32 width, s32 height, u8 flippedH);
|
void Interface_CreateQuadVertexGroup(Vtx* vtxList, s32 xStart, s32 yStart, s32 width, s32 height, u8 flippedH);
|
||||||
void Interface_RandoRestoreSwordless(void);
|
void Interface_RandoRestoreSwordless(void);
|
||||||
|
|
||||||
|
//Pause Warp
|
||||||
|
void PauseWarp_HandleSelection();
|
||||||
|
void PauseWarp_Execute();
|
||||||
|
|
||||||
// #endregion
|
// #endregion
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -221,6 +221,7 @@ public:
|
|||||||
|
|
||||||
DEFINE_HOOK(OnFileDropped, void(std::string filePath));
|
DEFINE_HOOK(OnFileDropped, void(std::string filePath));
|
||||||
DEFINE_HOOK(OnAssetAltChange, void());
|
DEFINE_HOOK(OnAssetAltChange, void());
|
||||||
|
DEFINE_HOOK(OnKaleidoUpdate, void());
|
||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
static bool IsSaveLoaded();
|
static bool IsSaveLoaded();
|
||||||
|
@ -187,3 +187,9 @@ void GameInteractor_ExecuteOnSetGameLanguage() {
|
|||||||
void GameInteractor_RegisterOnAssetAltChange(void (*fn)(void)) {
|
void GameInteractor_RegisterOnAssetAltChange(void (*fn)(void)) {
|
||||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnAssetAltChange>(fn);
|
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnAssetAltChange>(fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//MARK: Pause Menu
|
||||||
|
|
||||||
|
void GameInteractor_ExecuteOnKaleidoUpdate() {
|
||||||
|
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnKaleidoUpdate>();
|
||||||
|
}
|
||||||
|
@ -60,6 +60,9 @@ void GameInteractor_ExecuteOnSetGameLanguage();
|
|||||||
// MARK: - System
|
// MARK: - System
|
||||||
void GameInteractor_RegisterOnAssetAltChange(void (*fn)(void));
|
void GameInteractor_RegisterOnAssetAltChange(void (*fn)(void));
|
||||||
|
|
||||||
|
//Mark: - Pause Menu
|
||||||
|
void GameInteractor_ExecuteOnKaleidoUpdate();
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1304,6 +1304,23 @@ void RegisterToTMedallions() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RegisterPauseMenuHooks() {
|
||||||
|
static bool pauseWarpHooksRegistered = false;
|
||||||
|
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnGameFrameUpdate>([&]() {
|
||||||
|
if (!GameInteractor::IsSaveLoaded() || !CVarGetInteger("gPauseWarp", 0)) {
|
||||||
|
pauseWarpHooksRegistered = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!pauseWarpHooksRegistered) {
|
||||||
|
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnKaleidoUpdate>([]() {PauseWarp_HandleSelection();});
|
||||||
|
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnGameFrameUpdate>([]() {
|
||||||
|
PauseWarp_Execute();
|
||||||
|
});
|
||||||
|
pauseWarpHooksRegistered = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void InitMods() {
|
void InitMods() {
|
||||||
RegisterTTS();
|
RegisterTTS();
|
||||||
RegisterInfiniteMoney();
|
RegisterInfiniteMoney();
|
||||||
@ -1340,4 +1357,5 @@ void InitMods() {
|
|||||||
NameTag_RegisterHooks();
|
NameTag_RegisterHooks();
|
||||||
RegisterPatchHandHandler();
|
RegisterPatchHandHandler();
|
||||||
RegisterHurtContainerModeHandler();
|
RegisterHurtContainerModeHandler();
|
||||||
|
RegisterPauseMenuHooks();
|
||||||
}
|
}
|
||||||
|
92
soh/soh/Enhancements/pausewarp.c
Normal file
92
soh/soh/Enhancements/pausewarp.c
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
#include "custom-message/CustomMessageTypes.h"
|
||||||
|
#include "global.h"
|
||||||
|
#include "z64.h"
|
||||||
|
#include "game-interactor/GameInteractor.h"
|
||||||
|
|
||||||
|
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
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int ocarinaSongMap[] = {
|
||||||
|
OCARINA_SONG_MINUET,
|
||||||
|
OCARINA_SONG_BOLERO,
|
||||||
|
OCARINA_SONG_SERENADE,
|
||||||
|
OCARINA_SONG_REQUIEM,
|
||||||
|
OCARINA_SONG_NOCTURNE,
|
||||||
|
OCARINA_SONG_PRELUDE
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int entranceIndexMap[] = {
|
||||||
|
ENTR_SACRED_FOREST_MEADOW_2, // Minuet
|
||||||
|
ENTR_DEATH_MOUNTAIN_CRATER_4, // Bolero
|
||||||
|
ENTR_LAKE_HYLIA_8, // Serenade
|
||||||
|
ENTR_DESERT_COLOSSUS_5, // Requiem
|
||||||
|
ENTR_GRAVEYARD_7, // Nocturne
|
||||||
|
ENTR_TEMPLE_OF_TIME_7 // Prelude
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int songAudioMap[] = {
|
||||||
|
NA_BGM_OCA_MINUET,
|
||||||
|
NA_BGM_OCA_BOLERO,
|
||||||
|
NA_BGM_OCA_SERENADE,
|
||||||
|
NA_BGM_OCA_REQUIEM,
|
||||||
|
NA_BGM_OCA_NOCTURNE,
|
||||||
|
NA_BGM_OCA_LIGHT
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool isWarpActive = false;
|
||||||
|
|
||||||
|
void PauseWarp_Execute() {
|
||||||
|
if (!isWarpActive || gPlayState->msgCtx.msgMode != MSGMODE_NONE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
isWarpActive = false;
|
||||||
|
GET_PLAYER(gPlayState)->stateFlags1 &= ~PLAYER_STATE1_IN_CUTSCENE;
|
||||||
|
if (gPlayState->msgCtx.choiceIndex != 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (IS_RANDO) {
|
||||||
|
Entrance_SetWarpSongEntrance();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gPlayState->transitionTrigger = TRANS_TRIGGER_START;
|
||||||
|
gPlayState->transitionType = TRANS_TYPE_FADE_WHITE_FAST;
|
||||||
|
for (int i = 0; i < ARRAY_COUNT(ocarinaSongMap); i++) {
|
||||||
|
if (gPlayState->msgCtx.lastPlayedSong == ocarinaSongMap[i]) {
|
||||||
|
gPlayState->nextEntranceIndex = entranceIndexMap[i];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gPlayState->transitionTrigger = TRANS_TRIGGER_OFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActivateWarp(PauseContext* pauseCtx, int song) {
|
||||||
|
Audio_OcaSetInstrument(0);
|
||||||
|
Interface_SetDoAction(gPlayState, DO_ACTION_NONE);
|
||||||
|
pauseCtx->state = 0x12;
|
||||||
|
WREG(2) = -6240;
|
||||||
|
func_800F64E0(0);
|
||||||
|
pauseCtx->unk_1E4 = 0;
|
||||||
|
int idx = song - QUEST_SONG_MINUET;
|
||||||
|
gPlayState->msgCtx.lastPlayedSong = ocarinaSongMap[idx];
|
||||||
|
Audio_SetSoundBanksMute(0x20);
|
||||||
|
Audio_PlayFanfare(songAudioMap[idx]);
|
||||||
|
Message_StartTextbox(gPlayState, songMessageMap[idx], NULL);
|
||||||
|
GET_PLAYER(gPlayState)->stateFlags1 |= PLAYER_STATE1_IN_CUTSCENE;
|
||||||
|
isWarpActive = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PauseWarp_HandleSelection() {
|
||||||
|
if (gSaveContext.inventory.items[SLOT_OCARINA] != ITEM_NONE) {
|
||||||
|
int aButtonPressed = CHECK_BTN_ALL(gPlayState->state.input->press.button, BTN_A);
|
||||||
|
int song = gPlayState->pauseCtx.cursorPoint[PAUSE_QUEST];
|
||||||
|
if (aButtonPressed && CHECK_QUEST_ITEM(song) && song >= QUEST_SONG_MINUET && song <= QUEST_SONG_PRELUDE) {
|
||||||
|
ActivateWarp(&gPlayState->pauseCtx, song);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -644,6 +644,8 @@ void DrawEnhancementsMenu() {
|
|||||||
"- Obtained the Master Sword\n"
|
"- Obtained the Master Sword\n"
|
||||||
"- Not within range of Time Block\n"
|
"- Not within range of Time Block\n"
|
||||||
"- Not within range of Ocarina playing spots");
|
"- Not within range of Ocarina playing spots");
|
||||||
|
UIWidgets::PaddedEnhancementCheckbox("Pause Warp", "gPauseWarp", true, false);
|
||||||
|
UIWidgets::Tooltip("Selection of warp song in pause menu initiates warp. Disables song playback.");
|
||||||
|
|
||||||
ImGui::EndTable();
|
ImGui::EndTable();
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "vt.h"
|
#include "vt.h"
|
||||||
|
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||||
|
|
||||||
void (*sKaleidoScopeUpdateFunc)(PlayState* play);
|
void (*sKaleidoScopeUpdateFunc)(PlayState* play);
|
||||||
void (*sKaleidoScopeDrawFunc)(PlayState* play);
|
void (*sKaleidoScopeDrawFunc)(PlayState* play);
|
||||||
@ -56,6 +57,8 @@ void KaleidoScopeCall_Update(PlayState* play) {
|
|||||||
KaleidoMgrOverlay* kaleidoScopeOvl = &gKaleidoMgrOverlayTable[KALEIDO_OVL_KALEIDO_SCOPE];
|
KaleidoMgrOverlay* kaleidoScopeOvl = &gKaleidoMgrOverlayTable[KALEIDO_OVL_KALEIDO_SCOPE];
|
||||||
PauseContext* pauseCtx = &play->pauseCtx;
|
PauseContext* pauseCtx = &play->pauseCtx;
|
||||||
|
|
||||||
|
GameInteractor_ExecuteOnKaleidoUpdate();
|
||||||
|
|
||||||
if (!gSaveContext.sohStats.gameComplete &&
|
if (!gSaveContext.sohStats.gameComplete &&
|
||||||
(!IS_BOSS_RUSH || !gSaveContext.isBossRushPaused)) {
|
(!IS_BOSS_RUSH || !gSaveContext.isBossRushPaused)) {
|
||||||
gSaveContext.sohStats.pauseTimer++;
|
gSaveContext.sohStats.pauseTimer++;
|
||||||
|
Loading…
Reference in New Issue
Block a user