diff --git a/soh/include/z64cutscene.h b/soh/include/z64cutscene.h index 562561a08..3794547b4 100644 --- a/soh/include/z64cutscene.h +++ b/soh/include/z64cutscene.h @@ -38,8 +38,7 @@ typedef struct { } CsCmdBase; // size = 0x6 typedef struct { - /* 0x00 */ u8 unk_00; - /* 0x01 */ u8 setting; + /* 0x00 */ u16 setting; /* 0x02 */ u16 startFrame; /* 0x04 */ u16 endFrame; } CsCmdEnvLighting; // size = 0x6 diff --git a/soh/soh/Enhancements/debugger/debugSaveEditor.h b/soh/soh/Enhancements/debugger/debugSaveEditor.h index e51414f4c..488ec3ea6 100644 --- a/soh/soh/Enhancements/debugger/debugSaveEditor.h +++ b/soh/soh/Enhancements/debugger/debugSaveEditor.h @@ -241,7 +241,7 @@ const std::vector flagTables = { { 0xB7, "Spoke to Fado in Kokiri Forest as Child" }, { 0xB8, "Spoke to Malon After Saving Ranch" }, { 0xB9, "Spoke to Malon on Horseback" }, - { 0xBC, "Spoke to Carpenter Boss by Tent" }, + { 0xBC, "Fado requested Odd Potion" }, { 0xC0, "Spoke to Fat Woman by Market Potion Shop" }, { 0xC1, "Spoke to Fat Woman After Zelda's Escape" }, { 0xC2, "Spoke to Burly Man About Talon Search" }, diff --git a/soh/soh/GameMenuBar.cpp b/soh/soh/GameMenuBar.cpp index 65affde26..837568706 100644 --- a/soh/soh/GameMenuBar.cpp +++ b/soh/soh/GameMenuBar.cpp @@ -1118,12 +1118,7 @@ namespace GameMenuBar { ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0, 0)); ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f); ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.22f, 0.38f, 0.56f, 1.0f)); - #ifdef __WIIU__ - static ImVec2 buttonSize(200.0f * 2.0f, 0.0f); - #else - static ImVec2 buttonSize(200.0f, 0.0f); - #endif - if (ImGui::Button(GetWindowButtonText("Cosmetics Editor", CVar_GetS32("gCosmeticsEditorEnabled", 0)).c_str(), buttonSize)) + if (ImGui::Button(GetWindowButtonText("Cosmetics Editor", CVar_GetS32("gCosmeticsEditorEnabled", 0)).c_str(), ImVec2(-1.0f, 0.0f))) { bool currentValue = CVar_GetS32("gCosmeticsEditorEnabled", 0); CVar_SetS32("gCosmeticsEditorEnabled", !currentValue); @@ -1416,12 +1411,7 @@ namespace GameMenuBar { ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0,0)); ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f); ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.22f, 0.38f, 0.56f, 1.0f)); - #ifdef __WIIU__ - static ImVec2 buttonSize(160.0f * 2.0f, 0.0f); - #else - static ImVec2 buttonSize(160.0f, 0.0f); - #endif - if (ImGui::Button(GetWindowButtonText("Stats", CVar_GetS32("gStatsEnabled", 0)).c_str(), buttonSize)) + if (ImGui::Button(GetWindowButtonText("Stats", CVar_GetS32("gStatsEnabled", 0)).c_str(), ImVec2(-1.0f, 0.0f))) { bool currentValue = CVar_GetS32("gStatsEnabled", 0); CVar_SetS32("gStatsEnabled", !currentValue); @@ -1430,7 +1420,7 @@ namespace GameMenuBar { } UIWidgets::Tooltip("Shows the stats window, with your FPS and frametimes, and the OS you're playing on"); UIWidgets::Spacer(0); - if (ImGui::Button(GetWindowButtonText("Console", CVar_GetS32("gConsoleEnabled", 0)).c_str(), buttonSize)) + if (ImGui::Button(GetWindowButtonText("Console", CVar_GetS32("gConsoleEnabled", 0)).c_str(), ImVec2(-1.0f, 0.0f))) { bool currentValue = CVar_GetS32("gConsoleEnabled", 0); CVar_SetS32("gConsoleEnabled", !currentValue); @@ -1439,7 +1429,7 @@ namespace GameMenuBar { } UIWidgets::Tooltip("Enables the console window, allowing you to input commands, type help for some examples"); UIWidgets::Spacer(0); - if (ImGui::Button(GetWindowButtonText("Save Editor", CVar_GetS32("gSaveEditorEnabled", 0)).c_str(), buttonSize)) + if (ImGui::Button(GetWindowButtonText("Save Editor", CVar_GetS32("gSaveEditorEnabled", 0)).c_str(), ImVec2(-1.0f, 0.0f))) { bool currentValue = CVar_GetS32("gSaveEditorEnabled", 0); CVar_SetS32("gSaveEditorEnabled", !currentValue); @@ -1447,7 +1437,7 @@ namespace GameMenuBar { SohImGui::EnableWindow("Save Editor", CVar_GetS32("gSaveEditorEnabled", 0)); } UIWidgets::Spacer(0); - if (ImGui::Button(GetWindowButtonText("Collision Viewer", CVar_GetS32("gCollisionViewerEnabled", 0)).c_str(), buttonSize)) + if (ImGui::Button(GetWindowButtonText("Collision Viewer", CVar_GetS32("gCollisionViewerEnabled", 0)).c_str(), ImVec2(-1.0f, 0.0f))) { bool currentValue = CVar_GetS32("gCollisionViewerEnabled", 0); CVar_SetS32("gCollisionViewerEnabled", !currentValue); @@ -1455,7 +1445,7 @@ namespace GameMenuBar { SohImGui::EnableWindow("Collision Viewer", CVar_GetS32("gCollisionViewerEnabled", 0)); } UIWidgets::Spacer(0); - if (ImGui::Button(GetWindowButtonText("Actor Viewer", CVar_GetS32("gActorViewerEnabled", 0)).c_str(), buttonSize)) + if (ImGui::Button(GetWindowButtonText("Actor Viewer", CVar_GetS32("gActorViewerEnabled", 0)).c_str(), ImVec2(-1.0f, 0.0f))) { bool currentValue = CVar_GetS32("gActorViewerEnabled", 0); CVar_SetS32("gActorViewerEnabled", !currentValue); diff --git a/soh/soh/SaveManager.cpp b/soh/soh/SaveManager.cpp index cdf6be9c8..30bdc7fb5 100644 --- a/soh/soh/SaveManager.cpp +++ b/soh/soh/SaveManager.cpp @@ -106,6 +106,7 @@ void SaveManager::LoadRandomizerVersion1() { std::shared_ptr randomizer = OTRGlobals::Instance->gRandomizer; + randomizer->LoadRandomizerSettings(""); size_t merchantPricesSize = 0; if (randomizer->GetRandoSettingValue(RSK_SHUFFLE_SCRUBS) > 0) { merchantPricesSize += NUM_SCRUBS; diff --git a/soh/src/code/game.c b/soh/src/code/game.c index 9089606e6..712bc6f2a 100644 --- a/soh/src/code/game.c +++ b/soh/src/code/game.c @@ -370,7 +370,7 @@ void GameState_Update(GameState* gameState) { } // Bombchus (max: 50, no upgrades) - if (AMMO(ITEM_BOMBCHU) < 50) { + if (INV_CONTENT(ITEM_BOMBCHU) == ITEM_BOMBCHU && AMMO(ITEM_BOMBCHU) < 50) { AMMO(ITEM_BOMBCHU) = 50; } } diff --git a/soh/src/code/z_play.c b/soh/src/code/z_play.c index f25163c5e..47a6821da 100644 --- a/soh/src/code/z_play.c +++ b/soh/src/code/z_play.c @@ -2006,7 +2006,7 @@ s32 func_800C0DB4(GlobalContext* globalCtx, Vec3f* pos) { } void Gameplay_PerformSave(GlobalContext* globalCtx) { - if (globalCtx != NULL) { + if (globalCtx != NULL && gSaveContext.fileNum != 0xFF) { Gameplay_SaveSceneFlags(globalCtx); gSaveContext.savedSceneNum = globalCtx->sceneNum; if (gSaveContext.temporaryWeapon) { diff --git a/soh/src/code/z_skelanime.c b/soh/src/code/z_skelanime.c index 34e827b18..cc969be45 100644 --- a/soh/src/code/z_skelanime.c +++ b/soh/src/code/z_skelanime.c @@ -1242,8 +1242,12 @@ void LinkAnimation_Change(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAn if (ResourceMgr_OTRSigCheck(animation) != 0) animation = ResourceMgr_LoadAnimByName(animation); + AnimationHeader* currentAnimation = (AnimationHeader*)skelAnime->animation; + if (ResourceMgr_OTRSigCheck(currentAnimation) != 0) + currentAnimation = ResourceMgr_LoadAnimByName(currentAnimation); + skelAnime->mode = mode; - if ((morphFrames != 0.0f) && ((animation != skelAnime->animation) || (startFrame != skelAnime->curFrame))) { + if ((morphFrames != 0.0f) && ((animation != currentAnimation) || (startFrame != skelAnime->curFrame))) { if (morphFrames < 0) { LinkAnimation_SetUpdateFunction(skelAnime); SkelAnime_CopyFrameTable(skelAnime, skelAnime->morphTable, skelAnime->jointTable); @@ -1687,8 +1691,17 @@ s32 SkelAnime_Once(SkelAnime* skelAnime) { */ void Animation_ChangeImpl(SkelAnime* skelAnime, AnimationHeader* animation, f32 playSpeed, f32 startFrame, f32 endFrame, u8 mode, f32 morphFrames, s8 taper) { + LinkAnimationHeader* ogAnim = animation; + + if (ResourceMgr_OTRSigCheck(animation) != 0) + animation = ResourceMgr_LoadAnimByName(animation); + + AnimationHeader* currentAnimation = (AnimationHeader*)skelAnime->animation; + if (ResourceMgr_OTRSigCheck(currentAnimation) != 0) + currentAnimation = ResourceMgr_LoadAnimByName(currentAnimation); + skelAnime->mode = mode; - if ((morphFrames != 0.0f) && ((animation != skelAnime->animation) || (startFrame != skelAnime->curFrame))) { + if ((morphFrames != 0.0f) && ((animation != currentAnimation) || (startFrame != skelAnime->curFrame))) { if (morphFrames < 0) { SkelAnime_SetUpdate(skelAnime); SkelAnime_CopyFrameTable(skelAnime, skelAnime->morphTable, skelAnime->jointTable); @@ -1710,7 +1723,7 @@ void Animation_ChangeImpl(SkelAnime* skelAnime, AnimationHeader* animation, f32 skelAnime->morphWeight = 0.0f; } - skelAnime->animation = animation; + skelAnime->animation = ogAnim; skelAnime->startFrame = startFrame; skelAnime->endFrame = endFrame; skelAnime->animLength = Animation_GetLength(animation); diff --git a/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c b/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c index f10e8412a..781125cda 100644 --- a/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c +++ b/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c @@ -1349,6 +1349,11 @@ void EnGo2_RollingAnimation(EnGo2* this, GlobalContext* globalCtx) { } void EnGo2_WakeUp(EnGo2* this, GlobalContext* globalCtx) { + if (CVar_GetS32("gUnfixGoronSpin", 0)) { + // Trick SkelAnime into thinking the current animation is changing so that it morphs between the same position, + // making the goron do a spin + this->skelAnime.animation = NULL; + } if (this->skelAnime.playSpeed == 0.0f) { if ((this->actor.params & 0x1F) != GORON_DMT_BIGGORON) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOLON_WAKE_UP); diff --git a/soh/src/overlays/actors/ovl_player_actor/z_player.c b/soh/src/overlays/actors/ovl_player_actor/z_player.c index eb09b50db..28411dc11 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -10976,11 +10976,14 @@ void Player_DrawGameplay(GlobalContext* globalCtx, Player* this, s32 lod, Gfx* c this); if ((overrideLimbDraw == func_80090014) && (this->currentMask != PLAYER_MASK_NONE)) { + // Fixes a bug in vanilla where ice traps are rendered extremely large while wearing a bunny hood + if (CVar_GetS32("gFixIceTrapWithBunnyHood", 1)) Matrix_Push(); Mtx* sp70 = Graph_Alloc(globalCtx->state.gfxCtx, 2 * sizeof(Mtx)); if (this->currentMask == PLAYER_MASK_BUNNY) { Vec3s sp68; + FrameInterpolation_RecordActorPosRotMatrix(); gSPSegment(POLY_OPA_DISP++, 0x0B, sp70); sp68.x = D_80858AC8.unk_02 + 0x3E2; @@ -10997,6 +11000,7 @@ void Player_DrawGameplay(GlobalContext* globalCtx, Player* this, s32 lod, Gfx* c } gSPDisplayList(POLY_OPA_DISP++, sMaskDlists[this->currentMask - 1]); + if (CVar_GetS32("gFixIceTrapWithBunnyHood", 1)) Matrix_Pop(); } if ((this->currentBoots == PLAYER_BOOTS_HOVER) && !(this->actor.bgCheckFlags & 1) && diff --git a/soh/src/overlays/gamestates/ovl_opening/z_opening.c b/soh/src/overlays/gamestates/ovl_opening/z_opening.c index fa8ce9060..3b5beebd7 100644 --- a/soh/src/overlays/gamestates/ovl_opening/z_opening.c +++ b/soh/src/overlays/gamestates/ovl_opening/z_opening.c @@ -10,6 +10,7 @@ void Opening_SetupTitleScreen(OpeningContext* this) { gSaveContext.gameMode = 1; this->state.running = false; gSaveContext.linkAge = 0; + gSaveContext.fileNum = 0xFF; Sram_InitDebugSave(); gSaveContext.cutsceneIndex = 0xFFF3; gSaveContext.sceneSetupIndex = 7; diff --git a/soh/src/overlays/gamestates/ovl_title/z_title.c b/soh/src/overlays/gamestates/ovl_title/z_title.c index 10210a92c..99b05439d 100644 --- a/soh/src/overlays/gamestates/ovl_title/z_title.c +++ b/soh/src/overlays/gamestates/ovl_title/z_title.c @@ -307,6 +307,7 @@ void Title_Init(GameState* thisx) { Randomizer_LoadSettings(""); Randomizer_LoadHintLocations(""); Randomizer_LoadItemLocations("", true); + Randomizer_LoadMerchantMessages(""); gSaveContext.gameMode = 0; gSaveContext.magic = gSaveContext.magic; SET_NEXT_GAMESTATE(&this->state, Gameplay_Init, GlobalContext); diff --git a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_item.c b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_item.c index fc5e9dff2..0e5ea0bef 100644 --- a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_item.c +++ b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_item.c @@ -381,7 +381,8 @@ void KaleidoScope_DrawItemSelect(GlobalContext* globalCtx) { --INV_CONTENT(ITEM_TRADE_CHILD); } else if ((pauseCtx->stickRelX < -30 || pauseCtx->stickRelX > 30 || pauseCtx->stickRelY < -30 || pauseCtx->stickRelY > 30) || dpad && CHECK_BTN_ANY(input->press.button, BTN_DUP | BTN_DDOWN | BTN_DLEFT | BTN_DRIGHT)) { - if (INV_CONTENT(ITEM_TRADE_CHILD) == ITEM_LETTER_ZELDA) { + // Change to keaton mask if no mask is in child trade slot. Catches Zelda's letter and bottle duping over this slot. + if (INV_CONTENT(ITEM_TRADE_CHILD) < ITEM_MASK_KEATON || INV_CONTENT(ITEM_TRADE_CHILD) > ITEM_MASK_TRUTH) { INV_CONTENT(ITEM_TRADE_CHILD) = ITEM_MASK_KEATON; } else { INV_CONTENT(ITEM_TRADE_CHILD) ^= ITEM_MASK_KEATON ^ ITEM_MASK_TRUTH; diff --git a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c index ee0b5c179..cf145b474 100644 --- a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c +++ b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c @@ -1134,6 +1134,7 @@ void KaleidoScope_DrawPages(GlobalContext* globalCtx, GraphicsContext* gfxCtx) { static s16 D_8082AD48 = 0; static s16 D_8082AD4C = 0; static s16 D_8082AD50 = 0; + const Color_RGB8 A_cursor = CVar_GetRGB("gCCABtnPrim", A_BTN_ori); PauseContext* pauseCtx = &globalCtx->pauseCtx; Input* input = &globalCtx->state.input[0]; s16 stepR; @@ -1508,7 +1509,7 @@ void KaleidoScope_DrawPages(GlobalContext* globalCtx, GraphicsContext* gfxCtx) { } else if (CVar_GetS32("gHudColors", 1) == 1) { gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 100, 255, 100, VREG(61)); } else if (CVar_GetS32("gHudColors", 1) == 2) { - gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, CVar_GetRGB("gCCABtnPrim", A_BTN_ori).r, CVar_GetRGB("gCCABtnPrim", A_BTN_ori).g, CVar_GetRGB("gCCABtnPrim", A_BTN_ori).b, VREG(61)); //Save prompt cursor colour + gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, A_cursor.r, A_cursor.g, A_cursor.b, VREG(61)); //Save prompt cursor colour } if (pauseCtx->promptChoice == 0) { @@ -1533,7 +1534,13 @@ void KaleidoScope_DrawPages(GlobalContext* globalCtx, GraphicsContext* gfxCtx) { gDPSetCombineLERP(POLY_KAL_DISP++, 1, 0, PRIMITIVE, 0, TEXEL0, 0, PRIMITIVE, 0, 1, 0, PRIMITIVE, 0, TEXEL0, 0, PRIMITIVE, 0); - gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 100, 255, 100, VREG(61)); + if (CVar_GetS32("gHudColors", 1) == 0) { //Continue prompt cursor colour + gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 100, 100, 255, VREG(61)); + } else if (CVar_GetS32("gHudColors", 1) == 1) { + gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 100, 255, 100, VREG(61)); + } else if (CVar_GetS32("gHudColors", 1) == 2) { + gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, A_cursor.r, A_cursor.g, A_cursor.b, VREG(61)); //Continue prompt cursor colour + } if (pauseCtx->promptChoice == 0) { gSPDisplayList(POLY_KAL_DISP++, gPromptCursorLeftDL);