mirror of
https://github.com/izzy2lost/2ship2harkinian-Android.git
synced 2026-06-19 01:20:08 -07:00
[Enhancement] Pause Owl Warp (#620)
* Add Pause Owl Warp Enhancement - **mm/2s2h/BenGui/BenMenuBar.cpp**: Updated menu to include new enhancement options. - **mm/2s2h/Enhancements/Enhancements.cpp**: Registered the new Pause Owl Warp enhancement. - **mm/2s2h/Enhancements/Enhancements.h**: Declared functions for the new enhancement. - **mm/2s2h/Enhancements/Songs/PauseOwlWarp.cpp**: Implemented the Pause Owl Warp functionality. - **mm/2s2h/Enhancements/Songs/PauseOwlWarp.h**: Header file for the Pause Owl Warp implementation. - **mm/include/functions.h**: Added function declarations related to the new enhancement. - **mm/src/overlays/kaleido_scope/ovl_kaleido_map.c**: Modified to support the new enhancement. - **mm/src/overlays/kaleido_scope/ovl_kaleido_scope_NES.c**: Modified to support the new enhancement. * ran clang-format script * Additional logic and bug fixes * Fix PauseOwlWarp cursor logic triggering on dungeon map -Added a check to ensure PauseOwlWarp's cursor logic is only triggered when not in a dungeon. * Add Song of Soaring check - To make it more in line with vanilla, you are now required to have the Song of Soaring to use this enhancement. * bug fix and ran clang-format script -My previous commit had a extra condition that wasn't needed that caused a bug where the world map points locations pointed to activated owl statues. * added more checks * Simplified complex conditional statements * possibly fix macos build issue? * index warping logic added * implement feedback from Archez * shot in the dark macos build fix? * how bout now? * revert back to previous commit * if this fixed the macos build issue it'll be thanks to cclark25... let's pray * add debugeditor check - thanks archez! * Moved debugEditor check to prevent triggering ALL pauseOwlWarp logic. wtf was I thinking earlier
This commit is contained in:
@@ -653,6 +653,9 @@ void DrawEnhancementsMenu() {
|
||||
{ .tooltip = "Enables using the Dpad for Ocarina playback." });
|
||||
UIWidgets::CVarCheckbox("Prevent Dropped Ocarina Inputs", "gEnhancements.Playback.NoDropOcarinaInput",
|
||||
{ .tooltip = "Prevent dropping inputs when playing the ocarina quickly" });
|
||||
UIWidgets::CVarCheckbox("Pause Owl Warp", "gEnhancements.Songs.PauseOwlWarp",
|
||||
{ .tooltip = "Allows the player to use the pause menu map to owl warp instead of "
|
||||
"having to play the Song of Soaring." });
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ void InitEnhancements() {
|
||||
|
||||
// Songs
|
||||
RegisterEnableSunsSong();
|
||||
RegisterPauseOwlWarp();
|
||||
|
||||
// Restorations
|
||||
RegisterPowerCrouchStab();
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "Graphics/PlayAsKafei.h"
|
||||
#include "Player/Player.h"
|
||||
#include "Songs/EnableSunsSong.h"
|
||||
#include "Songs/PauseOwlWarp.h"
|
||||
#include "Saving/SavingEnhancements.h"
|
||||
#include "Graphics/DisableBlackBars.h"
|
||||
#include "Modes/TimeMovesWhenYouMove.h"
|
||||
|
||||
@@ -0,0 +1,222 @@
|
||||
#include "PauseOwlWarp.h"
|
||||
#include <libultraship/libultraship.h>
|
||||
#include "Enhancements/GameInteractor/GameInteractor.h"
|
||||
|
||||
extern "C" {
|
||||
#include "overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope.h"
|
||||
|
||||
extern f32 sPauseMenuVerticalOffset;
|
||||
extern u16 sCursorPointsToOcarinaModes[];
|
||||
extern u16 sOwlWarpPauseItems[];
|
||||
extern u16 D_80AF343C[];
|
||||
extern s16 sInDungeonScene;
|
||||
}
|
||||
|
||||
extern "C" bool PauseOwlWarp_IsOwlWarpEnabled() {
|
||||
return CVarGetInteger("gEnhancements.Songs.PauseOwlWarp", 0) && CHECK_QUEST_ITEM(QUEST_SONG_SOARING) &&
|
||||
gSaveContext.save.saveInfo.playerData.owlActivationFlags != 0 &&
|
||||
gPlayState->pauseCtx.debugEditor == DEBUG_EDITOR_NONE;
|
||||
}
|
||||
|
||||
static bool sIsConfirming = false;
|
||||
static u16 sStickAdjTimer = 0;
|
||||
|
||||
void ResetMessageContext() {
|
||||
gPlayState->msgCtx.msgLength = 0;
|
||||
gPlayState->msgCtx.msgMode = MSGMODE_NONE;
|
||||
}
|
||||
|
||||
void ClosePauseMenu(PauseContext* pauseCtx) {
|
||||
Interface_SetAButtonDoAction(gPlayState, DO_ACTION_NONE);
|
||||
Audio_PlaySfx_PauseMenuOpenOrClose(SFX_PAUSE_MENU_CLOSE);
|
||||
gPlayState->msgCtx.ocarinaMode = OCARINA_MODE_END;
|
||||
gSaveContext.prevHudVisibility = HUD_VISIBILITY_ALL;
|
||||
sIsConfirming = false;
|
||||
Message_CloseTextbox(gPlayState);
|
||||
pauseCtx->state = PAUSE_STATE_UNPAUSE_SETUP;
|
||||
}
|
||||
|
||||
void HandleConfirmingState(PauseContext* pauseCtx, Input* input) {
|
||||
if (Message_ShouldAdvance(gPlayState)) {
|
||||
ResetMessageContext();
|
||||
sIsConfirming = false;
|
||||
if (gPlayState->msgCtx.choiceIndex == 0) { // Yes
|
||||
Interface_SetAButtonDoAction(gPlayState, DO_ACTION_NONE);
|
||||
Audio_PlaySfx_PauseMenuOpenOrClose(SFX_PAUSE_MENU_CLOSE);
|
||||
gPlayState->msgCtx.ocarinaMode = sCursorPointsToOcarinaModes[pauseCtx->cursorPoint[PAUSE_WORLD_MAP]];
|
||||
Audio_PlaySfx(NA_SE_SY_DECIDE);
|
||||
Message_CloseTextbox(gPlayState);
|
||||
sPauseMenuVerticalOffset = -6240.0f;
|
||||
pauseCtx->state = PAUSE_STATE_UNPAUSE_SETUP;
|
||||
gPlayState->nextEntrance = D_80AF343C[pauseCtx->cursorPoint[PAUSE_WORLD_MAP]];
|
||||
gPlayState->transitionTrigger = TRANS_TRIGGER_START;
|
||||
gPlayState->transitionType = TRANS_TYPE_FADE_WHITE;
|
||||
} else { // No
|
||||
Interface_SetAButtonDoAction(gPlayState, DO_ACTION_WARP);
|
||||
Audio_PlaySfx(NA_SE_SY_MESSAGE_PASS);
|
||||
Message_CloseTextbox(gPlayState);
|
||||
}
|
||||
} else if (CHECK_BTN_ALL(input->press.button, BTN_B)) {
|
||||
ResetMessageContext();
|
||||
sIsConfirming = false;
|
||||
Audio_PlaySfx(NA_SE_SY_MESSAGE_PASS);
|
||||
Message_CloseTextbox(gPlayState);
|
||||
} else if (CHECK_BTN_ALL(input->press.button, BTN_START)) {
|
||||
ClosePauseMenu(pauseCtx);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateCursorForOwlWarpPoints(PauseContext* pauseCtx) {
|
||||
if (pauseCtx->cursorSpecialPos == 0) {
|
||||
if (pauseCtx->stickAdjX > 30) {
|
||||
pauseCtx->cursorShrinkRate = 4.0f;
|
||||
sStickAdjTimer = 0;
|
||||
do {
|
||||
pauseCtx->cursorPoint[PAUSE_WORLD_MAP]++;
|
||||
if (pauseCtx->cursorPoint[PAUSE_WORLD_MAP] > OWL_WARP_STONE_TOWER) {
|
||||
KaleidoScope_MoveCursorToSpecialPos(gPlayState, PAUSE_CURSOR_PAGE_RIGHT);
|
||||
return;
|
||||
}
|
||||
} while (!pauseCtx->worldMapPoints[pauseCtx->cursorPoint[PAUSE_WORLD_MAP]]);
|
||||
if (pauseCtx->worldMapPoints[pauseCtx->cursorPoint[PAUSE_WORLD_MAP]]) {
|
||||
pauseCtx->cursorItem[PAUSE_MAP] =
|
||||
sOwlWarpPauseItems[pauseCtx->cursorPoint[PAUSE_WORLD_MAP]] - ITEM_MAP_POINT_GREAT_BAY;
|
||||
pauseCtx->cursorSlot[PAUSE_MAP] = 31 + pauseCtx->cursorPoint[PAUSE_WORLD_MAP];
|
||||
Audio_PlaySfx(NA_SE_SY_CURSOR);
|
||||
}
|
||||
} else if (pauseCtx->stickAdjX < -30) {
|
||||
pauseCtx->cursorShrinkRate = 4.0f;
|
||||
sStickAdjTimer = 0;
|
||||
do {
|
||||
pauseCtx->cursorPoint[PAUSE_WORLD_MAP]--;
|
||||
if (pauseCtx->cursorPoint[PAUSE_WORLD_MAP] < OWL_WARP_GREAT_BAY_COAST) {
|
||||
KaleidoScope_MoveCursorToSpecialPos(gPlayState, PAUSE_CURSOR_PAGE_LEFT);
|
||||
return;
|
||||
}
|
||||
} while (!pauseCtx->worldMapPoints[pauseCtx->cursorPoint[PAUSE_WORLD_MAP]]);
|
||||
if (pauseCtx->worldMapPoints[pauseCtx->cursorPoint[PAUSE_WORLD_MAP]]) {
|
||||
pauseCtx->cursorItem[PAUSE_MAP] =
|
||||
sOwlWarpPauseItems[pauseCtx->cursorPoint[PAUSE_WORLD_MAP]] - ITEM_MAP_POINT_GREAT_BAY;
|
||||
pauseCtx->cursorSlot[PAUSE_MAP] = 31 + pauseCtx->cursorPoint[PAUSE_WORLD_MAP];
|
||||
Audio_PlaySfx(NA_SE_SY_CURSOR);
|
||||
}
|
||||
} else {
|
||||
sStickAdjTimer++;
|
||||
}
|
||||
} else if (pauseCtx->cursorSpecialPos == PAUSE_CURSOR_PAGE_LEFT && pauseCtx->stickAdjX > 30) {
|
||||
KaleidoScope_MoveCursorFromSpecialPos(gPlayState);
|
||||
for (int i = OWL_WARP_GREAT_BAY_COAST; i <= OWL_WARP_STONE_TOWER; i++) {
|
||||
if (pauseCtx->worldMapPoints[i]) {
|
||||
pauseCtx->cursorPoint[PAUSE_WORLD_MAP] = i;
|
||||
pauseCtx->cursorItem[PAUSE_MAP] =
|
||||
sOwlWarpPauseItems[pauseCtx->cursorPoint[PAUSE_WORLD_MAP]] - ITEM_MAP_POINT_GREAT_BAY;
|
||||
pauseCtx->cursorSlot[PAUSE_MAP] = 31 + pauseCtx->cursorPoint[PAUSE_WORLD_MAP];
|
||||
KaleidoScope_UpdateWorldMapCursor(gPlayState);
|
||||
KaleidoScope_UpdateNamePanel(gPlayState);
|
||||
return;
|
||||
}
|
||||
}
|
||||
KaleidoScope_MoveCursorToSpecialPos(gPlayState, PAUSE_CURSOR_PAGE_RIGHT);
|
||||
} else if (pauseCtx->cursorSpecialPos == PAUSE_CURSOR_PAGE_RIGHT && pauseCtx->stickAdjX < -30) {
|
||||
KaleidoScope_MoveCursorFromSpecialPos(gPlayState);
|
||||
for (int i = OWL_WARP_STONE_TOWER; i >= OWL_WARP_GREAT_BAY_COAST; i--) {
|
||||
if (pauseCtx->worldMapPoints[i]) {
|
||||
pauseCtx->cursorPoint[PAUSE_WORLD_MAP] = i;
|
||||
pauseCtx->cursorItem[PAUSE_MAP] =
|
||||
sOwlWarpPauseItems[pauseCtx->cursorPoint[PAUSE_WORLD_MAP]] - ITEM_MAP_POINT_GREAT_BAY;
|
||||
pauseCtx->cursorSlot[PAUSE_MAP] = 31 + pauseCtx->cursorPoint[PAUSE_WORLD_MAP];
|
||||
KaleidoScope_UpdateWorldMapCursor(gPlayState);
|
||||
KaleidoScope_UpdateNamePanel(gPlayState);
|
||||
return;
|
||||
}
|
||||
}
|
||||
KaleidoScope_MoveCursorToSpecialPos(gPlayState, PAUSE_CURSOR_PAGE_LEFT);
|
||||
}
|
||||
}
|
||||
|
||||
void HandlePauseOwlWarp(PauseContext* pauseCtx) {
|
||||
// Initialize worldMapPoints based on owl activation flags
|
||||
for (int i = OWL_WARP_STONE_TOWER; i >= OWL_WARP_GREAT_BAY_COAST; i--) {
|
||||
pauseCtx->worldMapPoints[i] = (gSaveContext.save.saveInfo.playerData.owlActivationFlags >> i) & 1;
|
||||
}
|
||||
|
||||
// Special condition for when only the 15th owl statue is activated
|
||||
if (gSaveContext.save.saveInfo.playerData.owlActivationFlags == (1 << 15)) {
|
||||
for (int i = REGION_GREAT_BAY; i < REGION_MAX; i++) {
|
||||
if ((gSaveContext.save.saveInfo.regionsVisited >> i) & 1) {
|
||||
switch (i) {
|
||||
case REGION_GREAT_BAY:
|
||||
pauseCtx->worldMapPoints[OWL_WARP_GREAT_BAY_COAST] = true;
|
||||
break;
|
||||
case REGION_ZORA_HALL:
|
||||
pauseCtx->worldMapPoints[OWL_WARP_ZORA_CAPE] = true;
|
||||
break;
|
||||
case REGION_ROMANI_RANCH:
|
||||
pauseCtx->worldMapPoints[OWL_WARP_SNOWHEAD] = true;
|
||||
break;
|
||||
case REGION_DEKU_PALACE:
|
||||
pauseCtx->worldMapPoints[OWL_WARP_MOUNTAIN_VILLAGE] = true;
|
||||
break;
|
||||
case REGION_WOODFALL:
|
||||
pauseCtx->worldMapPoints[OWL_WARP_CLOCK_TOWN] = true;
|
||||
break;
|
||||
case REGION_CLOCK_TOWN:
|
||||
pauseCtx->worldMapPoints[OWL_WARP_MILK_ROAD] = true;
|
||||
break;
|
||||
case REGION_SNOWHEAD:
|
||||
pauseCtx->worldMapPoints[OWL_WARP_WOODFALL] = true;
|
||||
break;
|
||||
case REGION_IKANA_GRAVEYARD:
|
||||
pauseCtx->worldMapPoints[OWL_WARP_SOUTHERN_SWAMP] = true;
|
||||
break;
|
||||
case REGION_IKANA_CANYON:
|
||||
pauseCtx->worldMapPoints[OWL_WARP_IKANA_CANYON] = true;
|
||||
break;
|
||||
case REGION_GORON_VILLAGE:
|
||||
pauseCtx->worldMapPoints[OWL_WARP_STONE_TOWER] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure cursor starts at an activated point
|
||||
if (!pauseCtx->worldMapPoints[pauseCtx->cursorPoint[PAUSE_WORLD_MAP]]) {
|
||||
for (int i = OWL_WARP_GREAT_BAY_COAST; i <= OWL_WARP_STONE_TOWER; i++) {
|
||||
if (pauseCtx->worldMapPoints[i]) {
|
||||
pauseCtx->cursorPoint[PAUSE_WORLD_MAP] = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Player* player = GET_PLAYER(gPlayState);
|
||||
Input* input = &gPlayState->state.input[0];
|
||||
|
||||
if ((pauseCtx->state == PAUSE_STATE_MAIN && pauseCtx->pageIndex == PAUSE_MAP && pauseCtx->mapPageRoll == 0) ||
|
||||
sIsConfirming) {
|
||||
if (CHECK_BTN_ALL(input->press.button, BTN_START) || CHECK_BTN_ALL(input->press.button, BTN_B)) {
|
||||
ClosePauseMenu(pauseCtx);
|
||||
} else if (CHECK_BTN_ALL(input->press.button, BTN_A) && !sIsConfirming) {
|
||||
if (pauseCtx->cursorSpecialPos == 0 && pauseCtx->worldMapPoints[pauseCtx->cursorPoint[PAUSE_WORLD_MAP]]) {
|
||||
Audio_PlaySfx(NA_SE_SY_DECIDE);
|
||||
Message_StartTextbox(gPlayState, 0x1B93, NULL);
|
||||
sIsConfirming = true;
|
||||
}
|
||||
} else if (sIsConfirming) {
|
||||
HandleConfirmingState(pauseCtx, input);
|
||||
} else {
|
||||
KaleidoScope_UpdateOwlWarpNamePanel(gPlayState);
|
||||
}
|
||||
|
||||
UpdateCursorForOwlWarpPoints(pauseCtx);
|
||||
}
|
||||
}
|
||||
|
||||
void RegisterPauseOwlWarp() {
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnKaleidoUpdate>([](PauseContext* pauseCtx) {
|
||||
if (!sInDungeonScene && PauseOwlWarp_IsOwlWarpEnabled() && CHECK_QUEST_ITEM(QUEST_SONG_SOARING)) {
|
||||
HandlePauseOwlWarp(pauseCtx);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#ifndef PAUSE_OWL_WARP_H
|
||||
#define PAUSE_OWL_WARP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void RegisterPauseOwlWarp(void);
|
||||
bool PauseOwlWarp_IsOwlWarpEnabled(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // PAUSE_OWL_WARP_H
|
||||
@@ -523,6 +523,7 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|AppleClang")
|
||||
$<$<COMPILE_LANGUAGE:C>:
|
||||
#-Werror-implicit-function-declaration
|
||||
-Wno-incompatible-pointer-types
|
||||
-Wno-int-conversion
|
||||
>
|
||||
$<$<COMPILE_LANGUAGE:CXX>:-fpermissive>
|
||||
$<$<COMPILE_LANGUAGE:CXX>:
|
||||
|
||||
@@ -1328,6 +1328,8 @@ void osContGetReadData(OSContPad* pad);
|
||||
// #region 2S2H [Port] Previously unavailable functions, made available for porting
|
||||
void PadMgr_ThreadEntry();
|
||||
void Heaps_Alloc(void);
|
||||
void KaleidoScope_UpdateOwlWarpNamePanel(PlayState* play);
|
||||
void KaleidoScope_UpdateNamePanel(PlayState* play);
|
||||
// #endregion
|
||||
// #region 2S2H [Port] New methods added for porting
|
||||
void AudioSeq_SetPortVolumeScale(u8 seqPlayerIndex, f32 volume);
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
|
||||
#include "BenPort.h"
|
||||
|
||||
#include "2s2h/Enhancements/Songs/PauseOwlWarp.h"
|
||||
|
||||
// 2S2H [Port] (and line 26) don't do pointer math and access the list of digits directly.
|
||||
extern const char* sCounterTextures[];
|
||||
|
||||
@@ -675,7 +677,7 @@ void KaleidoScope_DrawWorldMap(PlayState* play) {
|
||||
|
||||
Gfx_SetupDL42_Opa(play->state.gfxCtx);
|
||||
|
||||
if (!IS_PAUSE_STATE_OWLWARP) {
|
||||
if (!IS_PAUSE_STATE_OWLWARP && !PauseOwlWarp_IsOwlWarpEnabled()) {
|
||||
// Browsing the world map regions on the pause menu
|
||||
gDPLoadTextureBlock(POLY_OPA_DISP++, gWorldMapDotTex, G_IM_FMT_IA, G_IM_SIZ_8b, 8, 8, 0,
|
||||
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD,
|
||||
@@ -846,7 +848,7 @@ void KaleidoScope_UpdateWorldMapCursor(PlayState* play) {
|
||||
s16 oldCursorPoint;
|
||||
|
||||
if ((pauseCtx->state == PAUSE_STATE_MAIN) && (pauseCtx->mainState == PAUSE_MAIN_STATE_IDLE) &&
|
||||
(pauseCtx->pageIndex == PAUSE_MAP)) {
|
||||
(pauseCtx->pageIndex == PAUSE_MAP) && !PauseOwlWarp_IsOwlWarpEnabled()) {
|
||||
pauseCtx->cursorColorSet = PAUSE_CURSOR_COLOR_SET_WHITE;
|
||||
oldCursorPoint = pauseCtx->cursorPoint[PAUSE_WORLD_MAP];
|
||||
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
|
||||
#include "2s2h/Enhancements/GameInteractor/GameInteractor.h"
|
||||
|
||||
#include "2s2h/Enhancements/Songs/PauseOwlWarp.h"
|
||||
|
||||
// Page Textures (Background of Page):
|
||||
// Broken up into multiple textures.
|
||||
// Numbered by column/row.
|
||||
@@ -2901,7 +2903,7 @@ void KaleidoScope_UpdateCursorSize(PlayState* play) {
|
||||
|
||||
case PAUSE_MAP:
|
||||
if (!sInDungeonScene) {
|
||||
if (IS_PAUSE_STATE_OWLWARP) {
|
||||
if (IS_PAUSE_STATE_OWLWARP || PauseOwlWarp_IsOwlWarpEnabled()) {
|
||||
pauseCtx->cursorX = sOwlWarpWorldMapCursorsX[pauseCtx->cursorPoint[PAUSE_WORLD_MAP]];
|
||||
pauseCtx->cursorY = sOwlWarpWorldMapCursorsY[pauseCtx->cursorPoint[PAUSE_WORLD_MAP]];
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user