From e9d1bf2d56ebaa0c12233f5d2250d6b8f9e11225 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Thu, 4 Aug 2022 22:28:21 -0500 Subject: [PATCH 01/21] Initial work for keysanity --- .../randomizer/3drando/settings.cpp | 3 ++ .../Enhancements/randomizer/randomizer.cpp | 49 +++++++++++++++++-- .../Enhancements/randomizer/randomizerTypes.h | 3 ++ 3 files changed, 51 insertions(+), 4 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/3drando/settings.cpp b/soh/soh/Enhancements/randomizer/3drando/settings.cpp index 6bf207069..d5f7a58ac 100644 --- a/soh/soh/Enhancements/randomizer/3drando/settings.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/settings.cpp @@ -2542,6 +2542,9 @@ namespace Settings { ItemPoolValue.SetSelectedIndex(cvarSettings[RSK_ITEM_POOL]); IceTrapValue.SetSelectedIndex(cvarSettings[RSK_ICE_TRAPS]); + Keysanity.SetSelectedIndex(cvarSettings[RSK_KEYSANITY]); + GerudoKeys.SetSelectedIndex(cvarSettings[RSK_GERUDO_KEYS]); + BossKeysanity.SetSelectedIndex(cvarSettings[RSK_BOSS_KEYSANITY]); GanonsBossKey.SetSelectedIndex(cvarSettings[RSK_GANONS_BOSS_KEY]); NumRequiredCuccos.SetSelectedIndex(cvarSettings[RSK_CUCCO_COUNT]); diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 3a6b23bb7..7f6c85de8 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -3450,6 +3450,9 @@ void GenerateRandomizerImgui() { cvarSettings[RSK_GOSSIP_STONE_HINTS] = CVar_GetS32("gRandomizeGossipStoneHints", 1); cvarSettings[RSK_HINT_CLARITY] = CVar_GetS32("gRandomizeHintClarity", 2); cvarSettings[RSK_HINT_DISTRIBUTION] = CVar_GetS32("gRandomizeHintDistribution", 1); + cvarSettings[RSK_KEYSANITY] = CVar_GetS32("gRandomizeKeysanity", 0); + cvarSettings[RSK_GERUDO_KEYS] = CVar_GetS32("gRandomizeGerudoKeys", 0); + cvarSettings[RSK_BOSS_KEYSANITY] = CVar_GetS32("gRandomizeBossKeysanity", 0); cvarSettings[RSK_GANONS_BOSS_KEY] = CVar_GetS32("gRandomizeShuffleGanonBossKey", 0); cvarSettings[RSK_STARTING_CONSUMABLES] = CVar_GetS32("gRandomizeStartingConsumables", 0); cvarSettings[RSK_FULL_WALLETS] = CVar_GetS32("gRandomizeFullWallets", 0); @@ -3540,11 +3543,9 @@ void DrawRandoEditor(bool& open) { // Shuffle Dungeon Items Settings const char* randoShuffleMapsAndCompasses[6] = { "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere", "Start with", "Vanilla" }; - const char* randoShuffleSmallKeys[6] = { "Own Dungeon", "Any Dungeon", "Overworld", - "Anywhere", "Start with", "Vanilla" }; + const char* randoShuffleSmallKeys[6] = { "Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere" }; const char* randoShuffleGerudoFortressKeys[4] = { "Vanilla", "Any Dungeon", "Overworld", "Anywhere" }; - const char* randoShuffleBossKeys[6] = { "Own Dungeon", "Any Dungeon", "Overworld", - "Anywhere", "Start with", "Vanilla" }; + const char* randoShuffleBossKeys[6] = { "Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere" }; // const char* randoShuffleGanonsBossKey[12] = { "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere", // "LACS Vanilla", "LACS Medallions", "LACS Stones", "LACS Rewards", // "LACS Dungeons", "LACS Tokens", "Start with", "Vanilla" }; @@ -4042,6 +4043,46 @@ void DrawRandoEditor(bool& open) { SohImGui::EnhancementCombobox("gRandomizeShuffleDungeonReward", randoShuffleDungeonRewards, 4, 0); PaddedSeparator(); + // Keysanity + ImGui::Text(Settings::Keysanity.GetName().c_str()); + InsertHelpHoverText( + "Own dungeon - Small Keys can only appear in their respective dungeon.\n" + "\n" + "Any dungeon - Small Keys can only appear inside of any dungon.\n" + "\n" + "Overworld - Small Keys can only appear outside of dungeons.\n" + "\n" + "Anywhere - Small Keys can appear anywhere in the world." + ); + SohImGui::EnhancementCombobox("gRandomizeKeysanity", randoShuffleSmallKeys, 6, 0); + PaddedSeparator(); + + // Gerudo Keys + ImGui::Text(Settings::GerudoKeys.GetName().c_str()); + InsertHelpHoverText( + "Any dungeon - Small Keys can only appear inside of any dungon.\n" + "\n" + "Overworld - Small Keys can only appear outside of dungeons.\n" + "\n" + "Anywhere - Small Keys can appear anywhere in the world." + ); + SohImGui::EnhancementCombobox("gRandomizeGerudoKeys", randoShuffleGerudoFortressKeys, 4, 0); + PaddedSeparator(); + + // Boss Keysanity + ImGui::Text(Settings::BossKeysanity.GetName().c_str()); + InsertHelpHoverText( + "Own dungeon - Boss Keys can only appear in their respective dungeon.\n" + "\n" + "Any dungeon - Boss Keys can only appear inside of any dungon.\n" + "\n" + "Overworld - Boss Keys can only appear outside of dungeons.\n" + "\n" + "Anywhere - Boss Keys can appear anywhere in the world." + ); + SohImGui::EnhancementCombobox("gRandomizeBossKeysanity", randoShuffleBossKeys, 6, 0); + PaddedSeparator(); + // RANDOTODO implement ganon's boss key outside of ganon's castle // Ganon's Boss Key ImGui::Text(Settings::GanonsBossKey.GetName().c_str()); diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 04e647783..4261af545 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -982,6 +982,9 @@ typedef enum { RSK_GOSSIP_STONE_HINTS, RSK_HINT_CLARITY, RSK_HINT_DISTRIBUTION, + RSK_KEYSANITY, + RSK_GERUDO_KEYS, + RSK_BOSS_KEYSANITY, RSK_GANONS_BOSS_KEY, RSK_SKIP_CHILD_STEALTH, RSK_SKIP_CHILD_ZELDA, From 4a78375c8fa2060d7adcc865d7587d7b4911241b Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Fri, 5 Aug 2022 23:08:46 -0500 Subject: [PATCH 02/21] And like magic, keysanity working :D --- soh/include/z64item.h | 62 ++++++++++---- .../Enhancements/randomizer/randomizer.cpp | 33 ++++++- soh/src/code/z_parameter.c | 85 ++++++++++++++----- .../actors/ovl_player_actor/z_player.c | 17 ++++ 4 files changed, 156 insertions(+), 41 deletions(-) diff --git a/soh/include/z64item.h b/soh/include/z64item.h index 9e78487db..5b3844da1 100644 --- a/soh/include/z64item.h +++ b/soh/include/z64item.h @@ -253,6 +253,21 @@ typedef enum { /* 0xA2 */ ITEM_BOTTLE_WITH_BUGS, /* 0xA3 */ ITEM_BOTTLE_WITH_POE, /* 0xA4 */ ITEM_BOTTLE_WITH_BIG_POE, + /* 0xA5 */ ITEM_GERUDO_FORTRESS_SMALL_KEY, + /* 0xA6 */ ITEM_FOREST_TEMPLE_SMALL_KEY, + /* 0xA7 */ ITEM_FIRE_TEMPLE_SMALL_KEY, + /* 0xA8 */ ITEM_WATER_TEMPLE_SMALL_KEY, + /* 0xA9 */ ITEM_SPIRIT_TEMPLE_SMALL_KEY, + /* 0xAA */ ITEM_SHADOW_TEMPLE_SMALL_KEY, + /* 0xAB */ ITEM_BOTTOM_OF_THE_WELL_SMALL_KEY, + /* 0xAC */ ITEM_GERUDO_TRAINING_GROUNDS_SMALL_KEY, + /* 0xAD */ ITEM_GANONS_CASTLE_SMALL_KEY, + /* 0xAE */ ITEM_FOREST_TEMPLE_BOSS_KEY, + /* 0xAF */ ITEM_FIRE_TEMPLE_BOSS_KEY, + /* 0xB0 */ ITEM_WATER_TEMPLE_BOSS_KEY, + /* 0xB1 */ ITEM_SPIRIT_TEMPLE_BOSS_KEY, + /* 0xB2 */ ITEM_SHADOW_TEMPLE_BOSS_KEY, + /* 0xB3 */ ITEM_GANONS_CASTLE_BOSS_KEY, /* 0xFC */ ITEM_LAST_USED = 0xFC, /* 0xFE */ ITEM_NONE_FE = 0xFE, /* 0xFF */ ITEM_NONE = 0xFF @@ -397,23 +412,40 @@ typedef enum { /* 0x82 */ GI_MEDALLION_SHADOW, /* 0x83 */ GI_MEDALLION_SPIRIT, - /* 0x81 */ GI_STONE_KOKIRI, - /* 0x82 */ GI_STONE_GORON, - /* 0x83 */ GI_STONE_ZORA, + /* 0x84 */ GI_STONE_KOKIRI, + /* 0x85 */ GI_STONE_GORON, + /* 0x86 */ GI_STONE_ZORA, - /* 0x81 */ GI_ZELDAS_LULLABY, - /* 0x82 */ GI_SUNS_SONG, - /* 0x83 */ GI_EPONAS_SONG, - /* 0x81 */ GI_SONG_OF_STORMS, - /* 0x82 */ GI_SONG_OF_TIME, - /* 0x83 */ GI_SARIAS_SONG, + /* 0x87 */ GI_ZELDAS_LULLABY, + /* 0x88 */ GI_SUNS_SONG, + /* 0x89 */ GI_EPONAS_SONG, + /* 0x8A */ GI_SONG_OF_STORMS, + /* 0x8B */ GI_SONG_OF_TIME, + /* 0x8C */ GI_SARIAS_SONG, - /* 0x81 */ GI_MINUET_OF_FOREST, - /* 0x82 */ GI_BOLERO_OF_FIRE, - /* 0x83 */ GI_SERENADE_OF_WATER, - /* 0x81 */ GI_NOCTURNE_OF_SHADOW, - /* 0x82 */ GI_REQUIEM_OF_SPIRIT, - /* 0x83 */ GI_PRELUDE_OF_LIGHT, + /* 0x8D */ GI_MINUET_OF_FOREST, + /* 0x8E */ GI_BOLERO_OF_FIRE, + /* 0x8F */ GI_SERENADE_OF_WATER, + /* 0x90 */ GI_NOCTURNE_OF_SHADOW, + /* 0x91 */ GI_REQUIEM_OF_SPIRIT, + /* 0x92 */ GI_PRELUDE_OF_LIGHT, + + /* 0x93 */ GI_GERUDO_FORTRESS_SMALL_KEY, + /* 0x94 */ GI_FOREST_TEMPLE_SMALL_KEY, + /* 0x95 */ GI_FIRE_TEMPLE_SMALL_KEY, + /* 0x96 */ GI_WATER_TEMPLE_SMALL_KEY, + /* 0x97 */ GI_SPIRIT_TEMPLE_SMALL_KEY, + /* 0x98 */ GI_SHADOW_TEMPLE_SMALL_KEY, + /* 0x99 */ GI_BOTTOM_OF_THE_WELL_SMALL_KEY, + /* 0x9A */ GI_GERUDO_TRAINING_GROUNDS_SMALL_KEY, + /* 0x9B */ GI_GANONS_CASTLE_SMALL_KEY, + + /* 0x9C */ GI_FOREST_TEMPLE_BOSS_KEY, + /* 0x9D */ GI_FIRE_TEMPLE_BOSS_KEY, + /* 0x9E */ GI_WATER_TEMPLE_BOSS_KEY, + /* 0x9F */ GI_SPIRIT_TEMPLE_BOSS_KEY, + /* 0xA0 */ GI_SHADOW_TEMPLE_BOSS_KEY, + /* 0xA1 */ GI_GANONS_CASTLE_BOSS_KEY, GI_SINGLE_MAGIC, GI_DOUBLE_MAGIC, diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 7f6c85de8..75c883605 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -981,6 +981,21 @@ std::unordered_map itemIdToModel = { { GI_NONE, GID_MAXIMUM }, { GI_REQUIEM_OF_SPIRIT, GID_SONG_REQUIEM }, { GI_NOCTURNE_OF_SHADOW, GID_SONG_NOCTURNE }, { GI_PRELUDE_OF_LIGHT, GID_SONG_PRELUDE }, + { GI_GERUDO_FORTRESS_SMALL_KEY, GID_KEY_SMALL }, + { GI_FOREST_TEMPLE_SMALL_KEY, GID_KEY_SMALL }, + { GI_FIRE_TEMPLE_SMALL_KEY, GID_KEY_SMALL }, + { GI_WATER_TEMPLE_SMALL_KEY, GID_KEY_SMALL }, + { GI_SPIRIT_TEMPLE_SMALL_KEY, GID_KEY_SMALL }, + { GI_SHADOW_TEMPLE_SMALL_KEY, GID_KEY_SMALL }, + { GI_BOTTOM_OF_THE_WELL_SMALL_KEY, GID_KEY_SMALL }, + { GI_GERUDO_TRAINING_GROUNDS_SMALL_KEY, GID_KEY_SMALL }, + { GI_GANONS_CASTLE_SMALL_KEY, GID_KEY_SMALL }, + { GI_FOREST_TEMPLE_BOSS_KEY, GID_KEY_BOSS }, + { GI_FIRE_TEMPLE_BOSS_KEY, GID_KEY_BOSS }, + { GI_WATER_TEMPLE_BOSS_KEY, GID_KEY_BOSS }, + { GI_SPIRIT_TEMPLE_BOSS_KEY, GID_KEY_BOSS }, + { GI_SHADOW_TEMPLE_BOSS_KEY, GID_KEY_BOSS }, + { GI_GANONS_CASTLE_BOSS_KEY, GID_KEY_BOSS }, { GI_DOUBLE_DEFENSE, GID_HEART_CONTAINER }, { GI_STONE_KOKIRI, GID_KOKIRI_EMERALD }, { GI_STONE_GORON, GID_GORON_RUBY }, @@ -2253,25 +2268,37 @@ GetItemID Randomizer::GetItemFromGet(RandomizerGet randoGet, GetItemID ogItemId) case RG_ICE_CAVERN_COMPASS: return GI_COMPASS; - // todo implement dungeon-specific keys/keyrings case RG_FOREST_TEMPLE_BOSS_KEY: + return GI_FIRE_TEMPLE_BOSS_KEY; case RG_FIRE_TEMPLE_BOSS_KEY: + return GI_FOREST_TEMPLE_BOSS_KEY; case RG_WATER_TEMPLE_BOSS_KEY: + return GI_WATER_TEMPLE_BOSS_KEY; case RG_SPIRIT_TEMPLE_BOSS_KEY: + return GI_SPIRIT_TEMPLE_BOSS_KEY; case RG_SHADOW_TEMPLE_BOSS_KEY: + return GI_SHADOW_TEMPLE_BOSS_KEY; case RG_GANONS_CASTLE_BOSS_KEY: - return GI_KEY_BOSS; + return GI_GANONS_CASTLE_BOSS_KEY; case RG_FOREST_TEMPLE_SMALL_KEY: + return GI_FOREST_TEMPLE_SMALL_KEY; case RG_FIRE_TEMPLE_SMALL_KEY: + return GI_FIRE_TEMPLE_SMALL_KEY; case RG_WATER_TEMPLE_SMALL_KEY: + return GI_WATER_TEMPLE_SMALL_KEY; case RG_SPIRIT_TEMPLE_SMALL_KEY: + return GI_SPIRIT_TEMPLE_SMALL_KEY; case RG_SHADOW_TEMPLE_SMALL_KEY: + return GI_SHADOW_TEMPLE_SMALL_KEY; case RG_BOTTOM_OF_THE_WELL_SMALL_KEY: + return GI_BOTTOM_OF_THE_WELL_SMALL_KEY; case RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY: + return GI_GERUDO_TRAINING_GROUNDS_SMALL_KEY; case RG_GERUDO_FORTRESS_SMALL_KEY: + return GI_GERUDO_FORTRESS_SMALL_KEY; case RG_GANONS_CASTLE_SMALL_KEY: - return GI_KEY_SMALL; + return GI_GANONS_CASTLE_SMALL_KEY; // todo test this with keys in own dungeon case RG_TREASURE_GAME_SMALL_KEY: diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index 364e63956..6e33cdd92 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -1749,30 +1749,69 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { gSaveContext.inventory.dungeonItems[gSaveContext.mapIndex] |= gBitFlags[item - ITEM_KEY_BOSS]; } return ITEM_NONE; - } else if (item == ITEM_KEY_SMALL) { - // Small key exceptions for rando. - if (gSaveContext.n64ddFlag) { - if (globalCtx->sceneNum == 10) { // ganon's tower -> ganon's castle - if (gSaveContext.inventory.dungeonKeys[13] < 0) { - gSaveContext.inventory.dungeonKeys[13] = 1; - return ITEM_NONE; - } else { - gSaveContext.inventory.dungeonKeys[13]++; - return ITEM_NONE; - } - } - - if (globalCtx->sceneNum == 92) { // Desert Colossus -> Spirit Temple. - if (gSaveContext.inventory.dungeonKeys[6] < 0) { - gSaveContext.inventory.dungeonKeys[6] = 1; - return ITEM_NONE; - } else { - gSaveContext.inventory.dungeonKeys[6]++; - return ITEM_NONE; - } - } + } else if ((item >= ITEM_FOREST_TEMPLE_BOSS_KEY) && (item <= ITEM_GANONS_CASTLE_BOSS_KEY)) { + int mapIndex = gSaveContext.mapIndex; + switch (item) { + case ITEM_FOREST_TEMPLE_BOSS_KEY: + mapIndex = 3; + break; + case ITEM_FIRE_TEMPLE_BOSS_KEY: + mapIndex = 4; + break; + case ITEM_WATER_TEMPLE_BOSS_KEY: + mapIndex = 5; + break; + case ITEM_SPIRIT_TEMPLE_BOSS_KEY: + mapIndex = 6; + break; + case ITEM_SHADOW_TEMPLE_BOSS_KEY: + mapIndex = 7; + break; + case ITEM_GANONS_CASTLE_BOSS_KEY: + mapIndex = 13; + break; } - + + gSaveContext.inventory.dungeonItems[gSaveContext.mapIndex] |= gBitFlags[item - ITEM_KEY_BOSS]; + } else if (item == ITEM_GERUDO_FORTRESS_SMALL_KEY) { + // todo + } else if ((item >= ITEM_FOREST_TEMPLE_SMALL_KEY) && (item <= ITEM_GANONS_CASTLE_SMALL_KEY)) { + int mapIndex = gSaveContext.mapIndex; + switch (item) { + case ITEM_FOREST_TEMPLE_SMALL_KEY: + mapIndex = 3; + break; + case ITEM_FIRE_TEMPLE_SMALL_KEY: + mapIndex = 4; + break; + case ITEM_WATER_TEMPLE_SMALL_KEY: + mapIndex = 5; + break; + case ITEM_SPIRIT_TEMPLE_SMALL_KEY: + mapIndex = 6; + break; + case ITEM_SHADOW_TEMPLE_SMALL_KEY: + mapIndex = 7; + break; + case ITEM_BOTTOM_OF_THE_WELL_SMALL_KEY: + mapIndex = 8; + break; + case ITEM_GERUDO_TRAINING_GROUNDS_SMALL_KEY: + mapIndex = 11; + break; + case ITEM_GANONS_CASTLE_SMALL_KEY: + mapIndex = 13; + break; + } + + if (gSaveContext.inventory.dungeonKeys[mapIndex] < 0) { + gSaveContext.inventory.dungeonKeys[mapIndex] = 1; + return ITEM_NONE; + } else { + gSaveContext.inventory.dungeonKeys[mapIndex]++; + return ITEM_NONE; + } + } else if (item == ITEM_KEY_SMALL) { if (gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex] < 0) { gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex] = 1; return ITEM_NONE; 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 34a94c67b..68893ac00 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -641,6 +641,23 @@ GetItemEntry sGetItemTable[] = { GET_ITEM(ITEM_SONG_REQUIEM, OBJECT_GI_MELODY, GID_SONG_REQUIEM, 0x76, 0x80, CHEST_ANIM_LONG), GET_ITEM(ITEM_SONG_PRELUDE, OBJECT_GI_MELODY, GID_SONG_PRELUDE, 0x78, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_GERUDO_FORTRESS_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, 0x60, 0x80, CHEST_ANIM_SHORT), + GET_ITEM(ITEM_FOREST_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, 0x60, 0x80, CHEST_ANIM_SHORT), + GET_ITEM(ITEM_FIRE_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, 0x60, 0x80, CHEST_ANIM_SHORT), + GET_ITEM(ITEM_WATER_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, 0x60, 0x80, CHEST_ANIM_SHORT), + GET_ITEM(ITEM_SPIRIT_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, 0x60, 0x80, CHEST_ANIM_SHORT), + GET_ITEM(ITEM_SHADOW_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, 0x60, 0x80, CHEST_ANIM_SHORT), + GET_ITEM(ITEM_BOTTOM_OF_THE_WELL_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, 0x60, 0x80, CHEST_ANIM_SHORT), + GET_ITEM(ITEM_GERUDO_TRAINING_GROUNDS_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, 0x60, 0x80, CHEST_ANIM_SHORT), + GET_ITEM(ITEM_GANONS_CASTLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, 0x60, 0x80, CHEST_ANIM_SHORT), + + GET_ITEM(ITEM_FOREST_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, 0xC7, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_FIRE_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, 0xC7, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_WATER_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, 0xC7, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_SPIRIT_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, 0xC7, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_SHADOW_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, 0xC7, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_GANONS_CASTLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, 0xC7, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_SINGLE_MAGIC, OBJECT_GI_MAGICPOT, GID_MAGIC_SMALL, 0xE4, 0x80, CHEST_ANIM_LONG), GET_ITEM(ITEM_DOUBLE_MAGIC, OBJECT_GI_MAGICPOT, GID_MAGIC_LARGE, 0xE8, 0x80, CHEST_ANIM_LONG), GET_ITEM(ITEM_DOUBLE_DEFENSE, OBJECT_GI_HEARTS, GID_HEART_CONTAINER, 0xE9, 0x80, CHEST_ANIM_LONG), From 733ce5d28f5bb6d7c920061005800165115159bc Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Fri, 5 Aug 2022 23:26:50 -0500 Subject: [PATCH 03/21] Use scene enum, handle thieves hideout keys --- soh/src/code/z_parameter.c | 42 ++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index 6e33cdd92..a07aee654 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -1753,54 +1753,52 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { int mapIndex = gSaveContext.mapIndex; switch (item) { case ITEM_FOREST_TEMPLE_BOSS_KEY: - mapIndex = 3; + mapIndex = SCENE_BMORI1; break; case ITEM_FIRE_TEMPLE_BOSS_KEY: - mapIndex = 4; + mapIndex = SCENE_HIDAN; break; case ITEM_WATER_TEMPLE_BOSS_KEY: - mapIndex = 5; + mapIndex = SCENE_MIZUSIN; break; case ITEM_SPIRIT_TEMPLE_BOSS_KEY: - mapIndex = 6; + mapIndex = SCENE_JYASINZOU; break; case ITEM_SHADOW_TEMPLE_BOSS_KEY: - mapIndex = 7; + mapIndex = SCENE_HAKADAN; break; case ITEM_GANONS_CASTLE_BOSS_KEY: - mapIndex = 13; + mapIndex = SCENE_GANON; break; } gSaveContext.inventory.dungeonItems[gSaveContext.mapIndex] |= gBitFlags[item - ITEM_KEY_BOSS]; - } else if (item == ITEM_GERUDO_FORTRESS_SMALL_KEY) { - // todo - } else if ((item >= ITEM_FOREST_TEMPLE_SMALL_KEY) && (item <= ITEM_GANONS_CASTLE_SMALL_KEY)) { + } else if ((item >= ITEM_GERUDO_FORTRESS_SMALL_KEY) && (item <= ITEM_GANONS_CASTLE_SMALL_KEY)) { int mapIndex = gSaveContext.mapIndex; switch (item) { - case ITEM_FOREST_TEMPLE_SMALL_KEY: - mapIndex = 3; + case ITEM_FOREST_TEMPLE_BOSS_KEY: + mapIndex = SCENE_BMORI1; break; - case ITEM_FIRE_TEMPLE_SMALL_KEY: - mapIndex = 4; + case ITEM_FIRE_TEMPLE_BOSS_KEY: + mapIndex = SCENE_HIDAN; break; - case ITEM_WATER_TEMPLE_SMALL_KEY: - mapIndex = 5; + case ITEM_WATER_TEMPLE_BOSS_KEY: + mapIndex = SCENE_MIZUSIN; break; - case ITEM_SPIRIT_TEMPLE_SMALL_KEY: - mapIndex = 6; + case ITEM_SPIRIT_TEMPLE_BOSS_KEY: + mapIndex = SCENE_JYASINZOU; break; - case ITEM_SHADOW_TEMPLE_SMALL_KEY: - mapIndex = 7; + case ITEM_SHADOW_TEMPLE_BOSS_KEY: + mapIndex = SCENE_HAKADAN; break; case ITEM_BOTTOM_OF_THE_WELL_SMALL_KEY: - mapIndex = 8; + mapIndex = SCENE_HAKADANCH; break; case ITEM_GERUDO_TRAINING_GROUNDS_SMALL_KEY: - mapIndex = 11; + mapIndex = SCENE_MEN; break; case ITEM_GANONS_CASTLE_SMALL_KEY: - mapIndex = 13; + mapIndex = SCENE_GANONTIKA; break; } From cc4300ef8b171acddc5b96853a880af2f7fd7377 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Fri, 5 Aug 2022 23:40:43 -0500 Subject: [PATCH 04/21] Revert accidental changes --- soh/src/code/z_parameter.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index a07aee654..64cfed212 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -1776,19 +1776,19 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { } else if ((item >= ITEM_GERUDO_FORTRESS_SMALL_KEY) && (item <= ITEM_GANONS_CASTLE_SMALL_KEY)) { int mapIndex = gSaveContext.mapIndex; switch (item) { - case ITEM_FOREST_TEMPLE_BOSS_KEY: + case ITEM_FOREST_TEMPLE_SMALL_KEY: mapIndex = SCENE_BMORI1; break; - case ITEM_FIRE_TEMPLE_BOSS_KEY: + case ITEM_FIRE_TEMPLE_SMALL_KEY: mapIndex = SCENE_HIDAN; break; - case ITEM_WATER_TEMPLE_BOSS_KEY: + case ITEM_WATER_TEMPLE_SMALL_KEY: mapIndex = SCENE_MIZUSIN; break; - case ITEM_SPIRIT_TEMPLE_BOSS_KEY: + case ITEM_SPIRIT_TEMPLE_SMALL_KEY: mapIndex = SCENE_JYASINZOU; break; - case ITEM_SHADOW_TEMPLE_BOSS_KEY: + case ITEM_SHADOW_TEMPLE_SMALL_KEY: mapIndex = SCENE_HAKADAN; break; case ITEM_BOTTOM_OF_THE_WELL_SMALL_KEY: From 2d9d67bbd056ff52e9637c5603fb4d220d284dbe Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Fri, 5 Aug 2022 23:44:53 -0500 Subject: [PATCH 05/21] Add missing case --- soh/src/code/z_parameter.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index 64cfed212..668637cf1 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -1797,6 +1797,9 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { case ITEM_GERUDO_TRAINING_GROUNDS_SMALL_KEY: mapIndex = SCENE_MEN; break; + case ITEM_GERUDO_FORTRESS_SMALL_KEY: + mapIndex = SCENE_GERUDOWAY; + break; case ITEM_GANONS_CASTLE_SMALL_KEY: mapIndex = SCENE_GANONTIKA; break; From 5346217af36ddf510f37289e95722336f97ec8dd Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Sat, 6 Aug 2022 00:29:05 -0500 Subject: [PATCH 06/21] Misc fixes --- soh/soh/Enhancements/randomizer/randomizer.cpp | 4 ++-- soh/src/code/z_parameter.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 75c883605..d47b8cf66 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -2269,9 +2269,9 @@ GetItemID Randomizer::GetItemFromGet(RandomizerGet randoGet, GetItemID ogItemId) return GI_COMPASS; case RG_FOREST_TEMPLE_BOSS_KEY: - return GI_FIRE_TEMPLE_BOSS_KEY; - case RG_FIRE_TEMPLE_BOSS_KEY: return GI_FOREST_TEMPLE_BOSS_KEY; + case RG_FIRE_TEMPLE_BOSS_KEY: + return GI_FIRE_TEMPLE_BOSS_KEY; case RG_WATER_TEMPLE_BOSS_KEY: return GI_WATER_TEMPLE_BOSS_KEY; case RG_SPIRIT_TEMPLE_BOSS_KEY: diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index 668637cf1..eb02c14f2 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -1772,7 +1772,7 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { break; } - gSaveContext.inventory.dungeonItems[gSaveContext.mapIndex] |= gBitFlags[item - ITEM_KEY_BOSS]; + gSaveContext.inventory.dungeonItems[mapIndex] |= gBitFlags[ITEM_KEY_BOSS - ITEM_KEY_BOSS]; } else if ((item >= ITEM_GERUDO_FORTRESS_SMALL_KEY) && (item <= ITEM_GANONS_CASTLE_SMALL_KEY)) { int mapIndex = gSaveContext.mapIndex; switch (item) { From 5574442fdc28e5391be4a3113e0fcf630aadfb9c Mon Sep 17 00:00:00 2001 From: briaguya Date: Sat, 6 Aug 2022 04:30:03 -0400 Subject: [PATCH 07/21] fix ganon's boss key --- soh/include/z64item.h | 8 ++++---- soh/include/z64player.h | 2 +- soh/src/overlays/actors/ovl_player_actor/z_player.c | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/soh/include/z64item.h b/soh/include/z64item.h index 5b3844da1..ec2bf1457 100644 --- a/soh/include/z64item.h +++ b/soh/include/z64item.h @@ -430,6 +430,10 @@ typedef enum { /* 0x91 */ GI_REQUIEM_OF_SPIRIT, /* 0x92 */ GI_PRELUDE_OF_LIGHT, + GI_SINGLE_MAGIC, + GI_DOUBLE_MAGIC, + GI_DOUBLE_DEFENSE, + /* 0x93 */ GI_GERUDO_FORTRESS_SMALL_KEY, /* 0x94 */ GI_FOREST_TEMPLE_SMALL_KEY, /* 0x95 */ GI_FIRE_TEMPLE_SMALL_KEY, @@ -447,10 +451,6 @@ typedef enum { /* 0xA0 */ GI_SHADOW_TEMPLE_BOSS_KEY, /* 0xA1 */ GI_GANONS_CASTLE_BOSS_KEY, - GI_SINGLE_MAGIC, - GI_DOUBLE_MAGIC, - GI_DOUBLE_DEFENSE, - GI_BOTTLE_WITH_RED_POTION, GI_BOTTLE_WITH_GREEN_POTION, GI_BOTTLE_WITH_BLUE_POTION, diff --git a/soh/include/z64player.h b/soh/include/z64player.h index 0425c8eae..08618e3d1 100644 --- a/soh/include/z64player.h +++ b/soh/include/z64player.h @@ -13,7 +13,7 @@ typedef struct { /* 0x04 */ u16 objectId; } GetItemEntry; // size = 0x06 -extern GetItemEntry sGetItemTable[160]; +extern GetItemEntry sGetItemTable[175]; typedef enum { /* 0 */ PLAYER_SWORD_NONE, 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 68893ac00..c6a584dcb 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -641,6 +641,10 @@ GetItemEntry sGetItemTable[] = { GET_ITEM(ITEM_SONG_REQUIEM, OBJECT_GI_MELODY, GID_SONG_REQUIEM, 0x76, 0x80, CHEST_ANIM_LONG), GET_ITEM(ITEM_SONG_PRELUDE, OBJECT_GI_MELODY, GID_SONG_PRELUDE, 0x78, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_SINGLE_MAGIC, OBJECT_GI_MAGICPOT, GID_MAGIC_SMALL, 0xE4, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_DOUBLE_MAGIC, OBJECT_GI_MAGICPOT, GID_MAGIC_LARGE, 0xE8, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_DOUBLE_DEFENSE, OBJECT_GI_HEARTS, GID_HEART_CONTAINER, 0xE9, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_GERUDO_FORTRESS_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, 0x60, 0x80, CHEST_ANIM_SHORT), GET_ITEM(ITEM_FOREST_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, 0x60, 0x80, CHEST_ANIM_SHORT), GET_ITEM(ITEM_FIRE_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, 0x60, 0x80, CHEST_ANIM_SHORT), @@ -658,10 +662,6 @@ GetItemEntry sGetItemTable[] = { GET_ITEM(ITEM_SHADOW_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, 0xC7, 0x80, CHEST_ANIM_LONG), GET_ITEM(ITEM_GANONS_CASTLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, 0xC7, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_SINGLE_MAGIC, OBJECT_GI_MAGICPOT, GID_MAGIC_SMALL, 0xE4, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_DOUBLE_MAGIC, OBJECT_GI_MAGICPOT, GID_MAGIC_LARGE, 0xE8, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_DOUBLE_DEFENSE, OBJECT_GI_HEARTS, GID_HEART_CONTAINER, 0xE9, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_BOTTLE_WITH_RED_POTION, OBJECT_GI_LIQUID, GID_POTION_RED, 0x43, 0x80, CHEST_ANIM_LONG), GET_ITEM(ITEM_BOTTLE_WITH_GREEN_POTION, OBJECT_GI_LIQUID, GID_POTION_GREEN, 0x44, 0x80, CHEST_ANIM_LONG), GET_ITEM(ITEM_BOTTLE_WITH_BLUE_POTION, OBJECT_GI_LIQUID, GID_POTION_BLUE, 0x45, 0x80, CHEST_ANIM_LONG), From 77f2e56039033756ace1ed0899d61e52a2b48608 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Sat, 6 Aug 2022 14:07:46 -0500 Subject: [PATCH 08/21] Support starts with and more options on ganons boss key --- .../Enhancements/randomizer/randomizer.cpp | 74 +++++++++++++++---- soh/src/code/z_sram.c | 25 ++++++- 2 files changed, 82 insertions(+), 17 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index c65f144a5..d51f71d0b 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -1684,13 +1684,61 @@ void Randomizer::ParseRandomizerSettingsFile(const char* spoilerFileName) { gSaveContext.randoSettings[index].value = 3; } break; - case RSK_GANONS_BOSS_KEY: - if(it.value() == "Start with") { + case RSK_KEYSANITY: + if(it.value() == "Start With") { gSaveContext.randoSettings[index].value = 0; } else if(it.value() == "Vanilla") { gSaveContext.randoSettings[index].value = 1; - } else if(it.value() == "Own dungeon") { + } else if(it.value() == "Own Dungeon") { gSaveContext.randoSettings[index].value = 2; + } else if(it.value() == "Any Dungeon") { + gSaveContext.randoSettings[index].value = 3; + } else if(it.value() == "Overworld") { + gSaveContext.randoSettings[index].value = 4; + } else if(it.value() == "Anywhere") { + gSaveContext.randoSettings[index].value = 5; + } + break; + case RSK_BOSS_KEYSANITY: + if(it.value() == "Start With") { + gSaveContext.randoSettings[index].value = 0; + } else if(it.value() == "Vanilla") { + gSaveContext.randoSettings[index].value = 1; + } else if(it.value() == "Own Dungeon") { + gSaveContext.randoSettings[index].value = 2; + } else if(it.value() == "Any Dungeon") { + gSaveContext.randoSettings[index].value = 3; + } else if(it.value() == "Overworld") { + gSaveContext.randoSettings[index].value = 4; + } else if(it.value() == "Anywhere") { + gSaveContext.randoSettings[index].value = 5; + } + break; + case RSK_GANONS_BOSS_KEY: + if(it.value() == "Vanilla") { + gSaveContext.randoSettings[index].value = 0; + } else if(it.value() == "Own dungeon") { + gSaveContext.randoSettings[index].value = 1; + } else if(it.value() == "Start with") { + gSaveContext.randoSettings[index].value = 2; + } else if(it.value() == "Any Dungeon") { + gSaveContext.randoSettings[index].value = 3; + } else if(it.value() == "Overworld") { + gSaveContext.randoSettings[index].value = 4; + } else if(it.value() == "Anywhere") { + gSaveContext.randoSettings[index].value = 5; + } else if(it.value() == "LACS-Vanilla") { + gSaveContext.randoSettings[index].value = 6; + } else if(it.value() == "LACS-Medallions") { + gSaveContext.randoSettings[index].value = 7; + } else if(it.value() == "LACS-Stones") { + gSaveContext.randoSettings[index].value = 8; + } else if(it.value() == "LACS-Rewards") { + gSaveContext.randoSettings[index].value = 9; + } else if(it.value() == "LACS-Dungeons") { + gSaveContext.randoSettings[index].value = 10; + } else if(it.value() == "LACS-Tokens") { + gSaveContext.randoSettings[index].value = 11; } break; case RSK_SKIP_CHILD_ZELDA: @@ -3479,9 +3527,9 @@ void GenerateRandomizerImgui() { cvarSettings[RSK_GOSSIP_STONE_HINTS] = CVar_GetS32("gRandomizeGossipStoneHints", 1); cvarSettings[RSK_HINT_CLARITY] = CVar_GetS32("gRandomizeHintClarity", 2); cvarSettings[RSK_HINT_DISTRIBUTION] = CVar_GetS32("gRandomizeHintDistribution", 1); - cvarSettings[RSK_KEYSANITY] = CVar_GetS32("gRandomizeKeysanity", 0); + cvarSettings[RSK_KEYSANITY] = CVar_GetS32("gRandomizeKeysanity", 1); cvarSettings[RSK_GERUDO_KEYS] = CVar_GetS32("gRandomizeGerudoKeys", 0); - cvarSettings[RSK_BOSS_KEYSANITY] = CVar_GetS32("gRandomizeBossKeysanity", 0); + cvarSettings[RSK_BOSS_KEYSANITY] = CVar_GetS32("gRandomizeBossKeysanity", 1); cvarSettings[RSK_GANONS_BOSS_KEY] = CVar_GetS32("gRandomizeShuffleGanonBossKey", 0); cvarSettings[RSK_STARTING_CONSUMABLES] = CVar_GetS32("gRandomizeStartingConsumables", 0); cvarSettings[RSK_FULL_WALLETS] = CVar_GetS32("gRandomizeFullWallets", 0); @@ -3570,14 +3618,13 @@ void DrawRandoEditor(bool& open) { // Shuffle Dungeon Items Settings const char* randoShuffleMapsAndCompasses[6] = { "Own Dungeon", "Any Dungeon", "Overworld", - "Anywhere", "Start with", "Vanilla" }; + "Anywhere", "Start With", "Vanilla" }; const char* randoShuffleSmallKeys[6] = { "Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere" }; const char* randoShuffleGerudoFortressKeys[4] = { "Vanilla", "Any Dungeon", "Overworld", "Anywhere" }; const char* randoShuffleBossKeys[6] = { "Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere" }; - // const char* randoShuffleGanonsBossKey[12] = { "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere", - // "LACS Vanilla", "LACS Medallions", "LACS Stones", "LACS Rewards", - // "LACS Dungeons", "LACS Tokens", "Start with", "Vanilla" }; - const char* randoShuffleGanonsBossKey[3] = {"Vanilla", "Own dungeon", "Start with"}; + const char* randoShuffleGanonsBossKey[12] = { "Vanilla", "Own dungeon", "Start with", "Any Dungeon", + "Overworld", "Anywhere", "LACS-Vanilla", "LACS-Medallions", + "LACS-Stones", "LACS-Rewards", "LACS-Dungeons", "LACS-Tokens" }; // Timesaver Settings const char* randoSkipSongReplays[3] = { "Don't skip", "Skip (no SFX)", "Skip (Keep SFX)" }; @@ -4088,7 +4135,7 @@ void DrawRandoEditor(bool& open) { "\n" "Anywhere - Small Keys can appear anywhere in the world." ); - SohImGui::EnhancementCombobox("gRandomizeKeysanity", randoShuffleSmallKeys, 6, 0); + SohImGui::EnhancementCombobox("gRandomizeKeysanity", randoShuffleSmallKeys, 6, 1); PaddedSeparator(); // Gerudo Keys @@ -4114,7 +4161,7 @@ void DrawRandoEditor(bool& open) { "\n" "Anywhere - Boss Keys can appear anywhere in the world." ); - SohImGui::EnhancementCombobox("gRandomizeBossKeysanity", randoShuffleBossKeys, 6, 0); + SohImGui::EnhancementCombobox("gRandomizeBossKeysanity", randoShuffleBossKeys, 6, 1); PaddedSeparator(); // RANDOTODO implement ganon's boss key outside of ganon's castle @@ -4127,8 +4174,7 @@ void DrawRandoEditor(bool& open) { "\n" "Start with - Places Ganon's Boss Key in your starting inventory." ); - SohImGui::EnhancementCombobox("gRandomizeShuffleGanonBossKey", randoShuffleGanonsBossKey, 3, - 0); + SohImGui::EnhancementCombobox("gRandomizeShuffleGanonBossKey", randoShuffleGanonsBossKey, 12, 0); PaddedSeparator(); // Start with Maps & Compasses diff --git a/soh/src/code/z_sram.c b/soh/src/code/z_sram.c index ddc28450f..2a494cf9b 100644 --- a/soh/src/code/z_sram.c +++ b/soh/src/code/z_sram.c @@ -814,9 +814,28 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) { GiveLinkRupees(9001); } - // For Ganon's boss key "Start With" is 0 - if(Randomizer_GetSettingValue(RSK_GANONS_BOSS_KEY) == 0) { - gSaveContext.inventory.dungeonItems[10] |= 1; + if(Randomizer_GetSettingValue(RSK_KEYSANITY) == 0) { + // TODO: If master quest there are different key counts + gSaveContext.inventory.dungeonKeys[SCENE_BMORI1] = 5; // Forest + gSaveContext.inventory.dungeonKeys[SCENE_HIDAN] = 8; // Fire + gSaveContext.inventory.dungeonKeys[SCENE_MIZUSIN] = 6; // Water + gSaveContext.inventory.dungeonKeys[SCENE_JYASINZOU] = 5; // Spirit + gSaveContext.inventory.dungeonKeys[SCENE_HAKADAN] = 5; // Shadow + gSaveContext.inventory.dungeonKeys[SCENE_HAKADANCH] = 2; // BotW + gSaveContext.inventory.dungeonKeys[SCENE_MEN] = 9; // GTG + gSaveContext.inventory.dungeonKeys[SCENE_GANONTIKA] = 2; // Ganon + } + + if(Randomizer_GetSettingValue(RSK_BOSS_KEYSANITY) == 0) { + gSaveContext.inventory.dungeonItems[SCENE_BMORI1] |= 1; // Forest + gSaveContext.inventory.dungeonItems[SCENE_HIDAN] |= 1; // Fire + gSaveContext.inventory.dungeonItems[SCENE_MIZUSIN] |= 1; // Water + gSaveContext.inventory.dungeonItems[SCENE_JYASINZOU] |= 1; // Spirit + gSaveContext.inventory.dungeonItems[SCENE_HAKADAN] |= 1; // Shadow + } + + if(Randomizer_GetSettingValue(RSK_GANONS_BOSS_KEY) == 2) { + gSaveContext.inventory.dungeonItems[SCENE_GANON] |= 1; } HIGH_SCORE(HS_POE_POINTS) = 1000 - (100 * Randomizer_GetSettingValue(RSK_BIG_POE_COUNT)); From ea909b748eed77228f10b6aa4927837b78be0fa9 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Sat, 6 Aug 2022 16:51:58 -0500 Subject: [PATCH 09/21] Add super basic custom messages for keysanity, not pretty... --- soh/src/code/z_message_PAL.c | 65 ++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/soh/src/code/z_message_PAL.c b/soh/src/code/z_message_PAL.c index 72058206f..b5444faac 100644 --- a/soh/src/code/z_message_PAL.c +++ b/soh/src/code/z_message_PAL.c @@ -1736,6 +1736,71 @@ void Message_OpenText(GlobalContext* globalCtx, u16 textId) { } else { msgCtx->msgLength = font->msgLength = Randomizer_CopyGanonHintText(font->msgBuf, sizeof(font->msgBuf)); } + } else if (gSaveContext.n64ddFlag && textId == 0x60 && GET_PLAYER(globalCtx)->getItemId >= GI_GERUDO_FORTRESS_SMALL_KEY && GET_PLAYER(globalCtx)->getItemId <= GI_GANONS_CASTLE_SMALL_KEY) { + char* keyMsg; + switch (gSaveContext.language) { + case LANGUAGE_ENG: default: + switch (GET_PLAYER(globalCtx)->getItemId) { + case GI_GERUDO_FORTRESS_SMALL_KEY: + keyMsg = "\x08You got a \x05\x46\Thieves Hideout\x01\Small Key\x05\x40!\x09\x02"; + break; + case GI_FOREST_TEMPLE_SMALL_KEY: + keyMsg = "\x08You got a \x05\x42\Forest Temple\x01\Small Key\x05\x40!\x09\x02"; + break; + case GI_FIRE_TEMPLE_SMALL_KEY: + keyMsg = "\x08You got a \x05\x41\Fire Temple\x01\Small Key\x05\x40!\x09\x02"; + break; + case GI_WATER_TEMPLE_SMALL_KEY: + keyMsg = "\x08You got a \x05\x43\Water Temple\x01\Small Key\x05\x40!\x09\x02"; + break; + case GI_SPIRIT_TEMPLE_SMALL_KEY: + keyMsg = "\x08You got a \x05\x46\Spirit Temple\x01\Small Key\x05\x40!\x09\x02"; + break; + case GI_SHADOW_TEMPLE_SMALL_KEY: + keyMsg = "\x08You got a \x05\x45\Shadow Temple\x01\Small Key\x05\x40!\x09\x02"; + break; + case GI_BOTTOM_OF_THE_WELL_SMALL_KEY: + keyMsg = "\x08You got a \x05\x45\Bottom of the Well\x01\Small Key\x05\x40!\x09\x02"; + break; + case GI_GERUDO_TRAINING_GROUNDS_SMALL_KEY: + keyMsg = "\x08You got a \x05\x46\Gerudo Training Grounds\x01\Small Key\x05\x40!\x09\x02"; + break; + case GI_GANONS_CASTLE_SMALL_KEY: + keyMsg = "\x08You got a \x05\x41\Ganon's Castle\x01\Small Key\x05\x40!\x09\x02"; + break; + } + strcpy(font->msgBuf, keyMsg); + break; + } + msgCtx->msgLength = font->msgLength = strlen(font->msgBuf); + } else if (gSaveContext.n64ddFlag && textId == 0xC7 && GET_PLAYER(globalCtx)->getItemId >= GI_FOREST_TEMPLE_BOSS_KEY && GET_PLAYER(globalCtx)->getItemId <= GI_GANONS_CASTLE_BOSS_KEY) { + char* keyMsg; + switch (gSaveContext.language) { + case LANGUAGE_ENG: default: + switch (GET_PLAYER(globalCtx)->getItemId) { + case GI_FOREST_TEMPLE_BOSS_KEY: + keyMsg = "\x08You got a \x05\x42\Forest Temple\x01\Boss Key\x05\x40!\x09\x02"; + break; + case GI_FIRE_TEMPLE_BOSS_KEY: + keyMsg = "\x08You got a \x05\x41\Fire Temple\x01\Boss Key\x05\x40!\x09\x02"; + break; + case GI_WATER_TEMPLE_BOSS_KEY: + keyMsg = "\x08You got a \x05\x43\Water Temple\x01\Boss Key\x05\x40!\x09\x02"; + break; + case GI_SPIRIT_TEMPLE_BOSS_KEY: + keyMsg = "\x08You got a \x05\x46\Spirit Temple\x01\Boss Key\x05\x40!\x09\x02"; + break; + case GI_SHADOW_TEMPLE_BOSS_KEY: + keyMsg = "\x08You got a \x05\x45\Shadow Temple\x01\Boss Key\x05\x40!\x09\x02"; + break; + case GI_GANONS_CASTLE_BOSS_KEY: + keyMsg = "\x08You got a \x05\x41\Ganon's Castle\x01\Boss Key\x05\x40!\x09\x02"; + break; + } + strcpy(font->msgBuf, keyMsg); + break; + } + msgCtx->msgLength = font->msgLength = strlen(font->msgBuf); } else if (textId == 0xF8 && GET_PLAYER(globalCtx)->getItemId == GI_ICE_TRAP) { switch (gSaveContext.language) { case LANGUAGE_FRA: From ea9d76621c364a9f553c037f4862f438a6c02719 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Sat, 6 Aug 2022 22:01:55 -0500 Subject: [PATCH 10/21] Fix issue with keysanity values not loading from spoiler file --- soh/soh/Enhancements/randomizer/randomizer.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index d51f71d0b..8e1a7336e 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -1413,6 +1413,9 @@ std::unordered_map SpoilerfileSettingNameToEn { "Start with Kokiri Sword", RSK_STARTING_KOKIRI_SWORD }, { "Start with Fairy Ocarina", RSK_STARTING_OCARINA }, { "Shuffle Dungeon Items:Start with Maps/Compasses", RSK_STARTING_MAPS_COMPASSES }, + { "Shuffle Dungeon Items:Small Keys", RSK_KEYSANITY }, + { "Shuffle Dungeon Items:Gerudo Fortress Keys", RSK_GERUDO_KEYS }, + { "Shuffle Dungeon Items:Boss Keys", RSK_BOSS_KEYSANITY }, { "Shuffle Dungeon Items:Ganon's Boss Key", RSK_GANONS_BOSS_KEY }, { "Misc Settings:Gossip Stone Hints", RSK_GOSSIP_STONE_HINTS }, { "Misc Settings:Hint Clarity", RSK_HINT_CLARITY}, From ec801530b7e2ee1f3cca1303197168be20150fdb Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Sun, 7 Aug 2022 14:32:54 -0500 Subject: [PATCH 11/21] Move some more items around, boss keys still broken --- soh/include/z64item.h | 56 +++++++++---------- .../Enhancements/randomizer/3drando/item.hpp | 4 +- .../actors/ovl_player_actor/z_player.c | 20 +++---- 3 files changed, 40 insertions(+), 40 deletions(-) diff --git a/soh/include/z64item.h b/soh/include/z64item.h index ec2bf1457..8883eb8ca 100644 --- a/soh/include/z64item.h +++ b/soh/include/z64item.h @@ -430,38 +430,38 @@ typedef enum { /* 0x91 */ GI_REQUIEM_OF_SPIRIT, /* 0x92 */ GI_PRELUDE_OF_LIGHT, - GI_SINGLE_MAGIC, - GI_DOUBLE_MAGIC, - GI_DOUBLE_DEFENSE, + /* 0x93 */ GI_SINGLE_MAGIC, + /* 0x94 */ GI_DOUBLE_MAGIC, + /* 0x95 */ GI_DOUBLE_DEFENSE, - /* 0x93 */ GI_GERUDO_FORTRESS_SMALL_KEY, - /* 0x94 */ GI_FOREST_TEMPLE_SMALL_KEY, - /* 0x95 */ GI_FIRE_TEMPLE_SMALL_KEY, - /* 0x96 */ GI_WATER_TEMPLE_SMALL_KEY, - /* 0x97 */ GI_SPIRIT_TEMPLE_SMALL_KEY, - /* 0x98 */ GI_SHADOW_TEMPLE_SMALL_KEY, - /* 0x99 */ GI_BOTTOM_OF_THE_WELL_SMALL_KEY, - /* 0x9A */ GI_GERUDO_TRAINING_GROUNDS_SMALL_KEY, - /* 0x9B */ GI_GANONS_CASTLE_SMALL_KEY, + /* 0x96 */ GI_BOTTLE_WITH_RED_POTION, + /* 0x97 */ GI_BOTTLE_WITH_GREEN_POTION, + /* 0x98 */ GI_BOTTLE_WITH_BLUE_POTION, + /* 0x99 */ GI_BOTTLE_WITH_FAIRY, + /* 0x9A */ GI_BOTTLE_WITH_FISH, + /* 0x9B */ GI_BOTTLE_WITH_BLUE_FIRE, + /* 0x9C */ GI_BOTTLE_WITH_BUGS, + /* 0x9D */ GI_BOTTLE_WITH_POE, + /* 0x9E */ GI_BOTTLE_WITH_BIG_POE, - /* 0x9C */ GI_FOREST_TEMPLE_BOSS_KEY, - /* 0x9D */ GI_FIRE_TEMPLE_BOSS_KEY, - /* 0x9E */ GI_WATER_TEMPLE_BOSS_KEY, - /* 0x9F */ GI_SPIRIT_TEMPLE_BOSS_KEY, - /* 0xA0 */ GI_SHADOW_TEMPLE_BOSS_KEY, - /* 0xA1 */ GI_GANONS_CASTLE_BOSS_KEY, + /* 0x9F */ GI_GERUDO_FORTRESS_SMALL_KEY, + /* 0xA0 */ GI_FOREST_TEMPLE_SMALL_KEY, + /* 0xA1 */ GI_FIRE_TEMPLE_SMALL_KEY, + /* 0xA2 */ GI_WATER_TEMPLE_SMALL_KEY, + /* 0xA3 */ GI_SPIRIT_TEMPLE_SMALL_KEY, + /* 0xA4 */ GI_SHADOW_TEMPLE_SMALL_KEY, + /* 0xA5 */ GI_BOTTOM_OF_THE_WELL_SMALL_KEY, + /* 0xA6 */ GI_GERUDO_TRAINING_GROUNDS_SMALL_KEY, + /* 0xA7 */ GI_GANONS_CASTLE_SMALL_KEY, - GI_BOTTLE_WITH_RED_POTION, - GI_BOTTLE_WITH_GREEN_POTION, - GI_BOTTLE_WITH_BLUE_POTION, - GI_BOTTLE_WITH_FAIRY, - GI_BOTTLE_WITH_FISH, - GI_BOTTLE_WITH_BLUE_FIRE, - GI_BOTTLE_WITH_BUGS, - GI_BOTTLE_WITH_POE, - GI_BOTTLE_WITH_BIG_POE, + /* 0xA8 */ GI_FOREST_TEMPLE_BOSS_KEY, + /* 0xA9 */ GI_FIRE_TEMPLE_BOSS_KEY, + /* 0xAA */ GI_WATER_TEMPLE_BOSS_KEY, + /* 0xAB */ GI_SPIRIT_TEMPLE_BOSS_KEY, + /* 0xAC */ GI_SHADOW_TEMPLE_BOSS_KEY, + /* 0xAD */ GI_GANONS_CASTLE_BOSS_KEY, - /* 0x84 */ GI_MAX + /* 0xAE */ GI_MAX } GetItemID; typedef enum { diff --git a/soh/soh/Enhancements/randomizer/3drando/item.hpp b/soh/soh/Enhancements/randomizer/3drando/item.hpp index a424dbf2b..dbfb695b1 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/item.hpp @@ -103,11 +103,11 @@ public: return false; } - if ((type == ITEMTYPE_BOSSKEY && getItemId != 0x9A) && (BossKeysanity.Is(BOSSKEYSANITY_VANILLA) || BossKeysanity.Is(BOSSKEYSANITY_OWN_DUNGEON))) { + if ((type == ITEMTYPE_BOSSKEY && getItemId != 0xAD) && (BossKeysanity.Is(BOSSKEYSANITY_VANILLA) || BossKeysanity.Is(BOSSKEYSANITY_OWN_DUNGEON))) { return false; } //Ganons Castle Boss Key - if (getItemId == 0x9A && (GanonsBossKey.Is(GANONSBOSSKEY_VANILLA) || GanonsBossKey.Is(GANONSBOSSKEY_OWN_DUNGEON))) { + if (getItemId == 0xAD && (GanonsBossKey.Is(GANONSBOSSKEY_VANILLA) || GanonsBossKey.Is(GANONSBOSSKEY_OWN_DUNGEON))) { return false; } 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 c6a584dcb..8fefef0a5 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -645,6 +645,16 @@ GetItemEntry sGetItemTable[] = { GET_ITEM(ITEM_DOUBLE_MAGIC, OBJECT_GI_MAGICPOT, GID_MAGIC_LARGE, 0xE8, 0x80, CHEST_ANIM_LONG), GET_ITEM(ITEM_DOUBLE_DEFENSE, OBJECT_GI_HEARTS, GID_HEART_CONTAINER, 0xE9, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_BOTTLE_WITH_RED_POTION, OBJECT_GI_LIQUID, GID_POTION_RED, 0x43, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_BOTTLE_WITH_GREEN_POTION, OBJECT_GI_LIQUID, GID_POTION_GREEN, 0x44, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_BOTTLE_WITH_BLUE_POTION, OBJECT_GI_LIQUID, GID_POTION_BLUE, 0x45, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_BOTTLE_WITH_FAIRY, OBJECT_GI_BOTTLE, GID_BOTTLE, 0x46, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_BOTTLE_WITH_FISH, OBJECT_GI_FISH, GID_FISH, 0x47, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_BOTTLE_WITH_BLUE_FIRE, OBJECT_GI_FIRE, GID_BLUE_FIRE, 0x5D, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_BOTTLE_WITH_BUGS, OBJECT_GI_INSECT, GID_BUG, 0x7A, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_BOTTLE_WITH_POE, OBJECT_GI_GHOST, GID_POE, 0x97, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_BOTTLE_WITH_BIG_POE, OBJECT_GI_GHOST, GID_BIG_POE, 0xF9, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_GERUDO_FORTRESS_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, 0x60, 0x80, CHEST_ANIM_SHORT), GET_ITEM(ITEM_FOREST_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, 0x60, 0x80, CHEST_ANIM_SHORT), GET_ITEM(ITEM_FIRE_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, 0x60, 0x80, CHEST_ANIM_SHORT), @@ -662,16 +672,6 @@ GetItemEntry sGetItemTable[] = { GET_ITEM(ITEM_SHADOW_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, 0xC7, 0x80, CHEST_ANIM_LONG), GET_ITEM(ITEM_GANONS_CASTLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, 0xC7, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_BOTTLE_WITH_RED_POTION, OBJECT_GI_LIQUID, GID_POTION_RED, 0x43, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_BOTTLE_WITH_GREEN_POTION, OBJECT_GI_LIQUID, GID_POTION_GREEN, 0x44, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_BOTTLE_WITH_BLUE_POTION, OBJECT_GI_LIQUID, GID_POTION_BLUE, 0x45, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_BOTTLE_WITH_FAIRY, OBJECT_GI_BOTTLE, GID_BOTTLE, 0x46, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_BOTTLE_WITH_FISH, OBJECT_GI_FISH, GID_FISH, 0x47, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_BOTTLE_WITH_BLUE_FIRE, OBJECT_GI_FIRE, GID_BLUE_FIRE, 0x5D, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_BOTTLE_WITH_BUGS, OBJECT_GI_INSECT, GID_BUG, 0x7A, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_BOTTLE_WITH_POE, OBJECT_GI_GHOST, GID_POE, 0x97, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_BOTTLE_WITH_BIG_POE, OBJECT_GI_GHOST, GID_BIG_POE, 0xF9, 0x80, CHEST_ANIM_LONG), - GET_ITEM_NONE, GET_ITEM_NONE, }; From 01a36f525efc414aa6c0261afef5519f260720de Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Sun, 7 Aug 2022 15:41:30 -0500 Subject: [PATCH 12/21] Handle keys in checkObtainability --- soh/src/code/z_parameter.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index f0a421800..f1d138e70 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -2329,6 +2329,8 @@ u8 Item_CheckObtainability(u8 item) { } else { return ITEM_NONE; } + } else if ((item >= ITEM_GERUDO_FORTRESS_SMALL_KEY) && (item <= ITEM_GANONS_CASTLE_BOSS_KEY)) { + return ITEM_NONE; } else if ((item == ITEM_KEY_BOSS) || (item == ITEM_COMPASS) || (item == ITEM_DUNGEON_MAP)) { return ITEM_NONE; } else if (item == ITEM_KEY_SMALL) { From c8ac2d7c7e65cf67a9c09b1a67d0ce2926e40075 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Sun, 7 Aug 2022 16:41:57 -0500 Subject: [PATCH 13/21] Finally found fix for boss keys... --- soh/src/code/z_parameter.c | 1 + 1 file changed, 1 insertion(+) diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index f1d138e70..a71c8a52c 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -1773,6 +1773,7 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { } gSaveContext.inventory.dungeonItems[mapIndex] |= gBitFlags[ITEM_KEY_BOSS - ITEM_KEY_BOSS]; + return ITEM_NONE; } else if ((item >= ITEM_GERUDO_FORTRESS_SMALL_KEY) && (item <= ITEM_GANONS_CASTLE_SMALL_KEY)) { int mapIndex = gSaveContext.mapIndex; switch (item) { From 34b8d7d5f8cb37b2196d897cc70f87c959961c9e Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Mon, 8 Aug 2022 11:09:06 -0500 Subject: [PATCH 14/21] Handle impa giving a key if skip zelda is on --- soh/src/code/z_sram.c | 71 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/soh/src/code/z_sram.c b/soh/src/code/z_sram.c index 2a494cf9b..b91da8918 100644 --- a/soh/src/code/z_sram.c +++ b/soh/src/code/z_sram.c @@ -416,6 +416,73 @@ void GiveLinkDungeonReward(GetItemID getItemId) { } } +void GiveLinkSmallKey(GetItemID getItemId) { + int mapIndex; + + switch (getItemId) { + case GI_FOREST_TEMPLE_SMALL_KEY: + mapIndex = SCENE_BMORI1; + break; + case GI_FIRE_TEMPLE_SMALL_KEY: + mapIndex = SCENE_HIDAN; + break; + case GI_WATER_TEMPLE_SMALL_KEY: + mapIndex = SCENE_MIZUSIN; + break; + case GI_SPIRIT_TEMPLE_SMALL_KEY: + mapIndex = SCENE_JYASINZOU; + break; + case GI_SHADOW_TEMPLE_SMALL_KEY: + mapIndex = SCENE_HAKADAN; + break; + case GI_BOTTOM_OF_THE_WELL_SMALL_KEY: + mapIndex = SCENE_HAKADANCH; + break; + case GI_GERUDO_TRAINING_GROUNDS_SMALL_KEY: + mapIndex = SCENE_MEN; + break; + case GI_GERUDO_FORTRESS_SMALL_KEY: + mapIndex = SCENE_GERUDOWAY; + break; + case GI_GANONS_CASTLE_SMALL_KEY: + mapIndex = SCENE_GANONTIKA; + break; + } + + if (gSaveContext.inventory.dungeonKeys[mapIndex] < 0) { + gSaveContext.inventory.dungeonKeys[mapIndex] = 1; + } else { + gSaveContext.inventory.dungeonKeys[mapIndex]++; + } +} + +void GiveLinkBossKey(GetItemID getItemId) { + int mapIndex; + + switch (getItemId) { + case GI_FOREST_TEMPLE_BOSS_KEY: + mapIndex = SCENE_BMORI1; + break; + case GI_FIRE_TEMPLE_BOSS_KEY: + mapIndex = SCENE_HIDAN; + break; + case GI_WATER_TEMPLE_BOSS_KEY: + mapIndex = SCENE_MIZUSIN; + break; + case GI_SPIRIT_TEMPLE_BOSS_KEY: + mapIndex = SCENE_JYASINZOU; + break; + case GI_SHADOW_TEMPLE_BOSS_KEY: + mapIndex = SCENE_HAKADAN; + break; + case GI_GANONS_CASTLE_BOSS_KEY: + mapIndex = SCENE_GANON; + break; + } + + gSaveContext.inventory.dungeonItems[mapIndex] |= 1; +} + void GiveLinksPocketMedallion() { GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(RC_LINKS_POCKET, RG_NONE); @@ -788,6 +855,10 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) { GiveLinkMagic(giid); } else if (giid == GI_DOUBLE_DEFENSE) { GiveLinkDoubleDefense(); + } else if (giid >= GI_GERUDO_FORTRESS_SMALL_KEY && giid <= GI_GANONS_CASTLE_SMALL_KEY) { + GiveLinkSmallKey(giid); + } else if (giid >= GI_FOREST_TEMPLE_BOSS_KEY && giid <= GI_GANONS_CASTLE_BOSS_KEY) { + GiveLinkBossKey(giid); } else { s32 iid = Randomizer_GetItemIDFromGetItemID(giid); if (iid != -1) INV_CONTENT(iid) = iid; From 8f55dd0624b35c14a38a1a202acaa22b132fa71d Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Mon, 8 Aug 2022 14:07:02 -0500 Subject: [PATCH 15/21] Add support for shuffling maps and compasses --- soh/include/z64item.h | 42 +++++++ soh/include/z64player.h | 2 +- .../randomizer/3drando/settings.cpp | 9 +- .../Enhancements/randomizer/randomizer.cpp | 100 +++++++++++---- .../Enhancements/randomizer/randomizerTypes.h | 2 +- soh/src/code/z_message_PAL.c | 80 ++++++++++++ soh/src/code/z_parameter.c | 115 ++++++++++++------ soh/src/code/z_sram.c | 96 +++++++++------ .../actors/ovl_player_actor/z_player.c | 22 ++++ 9 files changed, 359 insertions(+), 109 deletions(-) diff --git a/soh/include/z64item.h b/soh/include/z64item.h index 8883eb8ca..3a409a705 100644 --- a/soh/include/z64item.h +++ b/soh/include/z64item.h @@ -268,6 +268,26 @@ typedef enum { /* 0xB1 */ ITEM_SPIRIT_TEMPLE_BOSS_KEY, /* 0xB2 */ ITEM_SHADOW_TEMPLE_BOSS_KEY, /* 0xB3 */ ITEM_GANONS_CASTLE_BOSS_KEY, + /* 0xB4 */ ITEM_DEKU_TREE_MAP, + /* 0xB5 */ ITEM_DODONGOS_CAVERN_MAP, + /* 0xB6 */ ITEM_JABU_JABUS_BELLY_MAP, + /* 0xB7 */ ITEM_FOREST_TEMPLE_MAP, + /* 0xB8 */ ITEM_FIRE_TEMPLE_MAP, + /* 0xB9 */ ITEM_WATER_TEMPLE_MAP, + /* 0xBA */ ITEM_SPIRIT_TEMPLE_MAP, + /* 0xBB */ ITEM_SHADOW_TEMPLE_MAP, + /* 0xBC */ ITEM_BOTTOM_OF_THE_WELL_MAP, + /* 0xBD */ ITEM_ICE_CAVERN_MAP, + /* 0xBE */ ITEM_DEKU_TREE_COMPASS, + /* 0xBF */ ITEM_DODONGOS_CAVERN_COMPASS, + /* 0xC0 */ ITEM_JABU_JABUS_BELLY_COMPASS, + /* 0xC1 */ ITEM_FOREST_TEMPLE_COMPASS, + /* 0xC2 */ ITEM_FIRE_TEMPLE_COMPASS, + /* 0xC3 */ ITEM_WATER_TEMPLE_COMPASS, + /* 0xC4 */ ITEM_SPIRIT_TEMPLE_COMPASS, + /* 0xC5 */ ITEM_SHADOW_TEMPLE_COMPASS, + /* 0xC6 */ ITEM_BOTTOM_OF_THE_WELL_COMPASS, + /* 0xC7 */ ITEM_ICE_CAVERN_COMPASS, /* 0xFC */ ITEM_LAST_USED = 0xFC, /* 0xFE */ ITEM_NONE_FE = 0xFE, /* 0xFF */ ITEM_NONE = 0xFF @@ -461,6 +481,28 @@ typedef enum { /* 0xAC */ GI_SHADOW_TEMPLE_BOSS_KEY, /* 0xAD */ GI_GANONS_CASTLE_BOSS_KEY, + /* 0xAE */ GI_DEKU_TREE_MAP, + /* 0xAF */ GI_DODONGOS_CAVERN_MAP, + /* 0xB0 */ GI_JABU_JABUS_BELLY_MAP, + /* 0xB1 */ GI_FOREST_TEMPLE_MAP, + /* 0xB2 */ GI_FIRE_TEMPLE_MAP, + /* 0xB3 */ GI_WATER_TEMPLE_MAP, + /* 0xB4 */ GI_SPIRIT_TEMPLE_MAP, + /* 0xB5 */ GI_SHADOW_TEMPLE_MAP, + /* 0xB6 */ GI_BOTTOM_OF_THE_WELL_MAP, + /* 0xB7 */ GI_ICE_CAVERN_MAP, + + /* 0xB8 */ GI_DEKU_TREE_COMPASS, + /* 0xB9 */ GI_DODONGOS_CAVERN_COMPASS, + /* 0xBA */ GI_JABU_JABUS_BELLY_COMPASS, + /* 0xBB */ GI_FOREST_TEMPLE_COMPASS, + /* 0xBC */ GI_FIRE_TEMPLE_COMPASS, + /* 0xBD */ GI_WATER_TEMPLE_COMPASS, + /* 0xBE */ GI_SPIRIT_TEMPLE_COMPASS, + /* 0xBF */ GI_SHADOW_TEMPLE_COMPASS, + /* 0xC0 */ GI_BOTTOM_OF_THE_WELL_COMPASS, + /* 0xC1 */ GI_ICE_CAVERN_COMPASS, + /* 0xAE */ GI_MAX } GetItemID; diff --git a/soh/include/z64player.h b/soh/include/z64player.h index 8be705674..08c77a0ee 100644 --- a/soh/include/z64player.h +++ b/soh/include/z64player.h @@ -13,7 +13,7 @@ typedef struct { /* 0x04 */ u16 objectId; } GetItemEntry; // size = 0x06 -extern GetItemEntry sGetItemTable[175]; +extern GetItemEntry sGetItemTable[195]; typedef enum { /* 0 */ PLAYER_SWORD_NONE, diff --git a/soh/soh/Enhancements/randomizer/3drando/settings.cpp b/soh/soh/Enhancements/randomizer/3drando/settings.cpp index e6a4f1385..d310717db 100644 --- a/soh/soh/Enhancements/randomizer/3drando/settings.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/settings.cpp @@ -2544,14 +2544,7 @@ namespace Settings { StartingDekuShield.SetSelectedIndex(cvarSettings[RSK_STARTING_DEKU_SHIELD]); StartingKokiriSword.SetSelectedIndex(cvarSettings[RSK_STARTING_KOKIRI_SWORD]); - if(cvarSettings[RSK_STARTING_MAPS_COMPASSES]) { - // "Start With" is index 0 - MapsAndCompasses.SetSelectedIndex(0); - } else { - // We don't support maps/compasses outside of their own dungeon yet - // "Own Dungeon" is index 2 - MapsAndCompasses.SetSelectedIndex(2); - } + MapsAndCompasses.SetSelectedIndex(cvarSettings[RSK_STARTING_MAPS_COMPASSES]); StartingConsumables.SetSelectedIndex(cvarSettings[RSK_STARTING_CONSUMABLES]); StartingMaxRupees.SetSelectedIndex(cvarSettings[RSK_FULL_WALLETS]); diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index b3ab45028..d4b2874c6 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -985,6 +985,18 @@ std::unordered_map itemIdToModel = { { GI_NONE, GID_MAXIMUM }, { GI_REQUIEM_OF_SPIRIT, GID_SONG_REQUIEM }, { GI_NOCTURNE_OF_SHADOW, GID_SONG_NOCTURNE }, { GI_PRELUDE_OF_LIGHT, GID_SONG_PRELUDE }, + { GI_DOUBLE_DEFENSE, GID_HEART_CONTAINER }, + { GI_STONE_KOKIRI, GID_KOKIRI_EMERALD }, + { GI_STONE_GORON, GID_GORON_RUBY }, + { GI_STONE_ZORA, GID_ZORA_SAPPHIRE }, + { GI_MEDALLION_FOREST, GID_MEDALLION_FOREST }, + { GI_MEDALLION_FIRE, GID_MEDALLION_FIRE }, + { GI_MEDALLION_WATER, GID_MEDALLION_WATER }, + { GI_MEDALLION_SPIRIT, GID_MEDALLION_SPIRIT }, + { GI_MEDALLION_SHADOW, GID_MEDALLION_SHADOW }, + { GI_MEDALLION_LIGHT, GID_MEDALLION_LIGHT }, + { GI_SINGLE_MAGIC, GID_MAGIC_SMALL }, + { GI_DOUBLE_MAGIC, GID_MAGIC_LARGE }, { GI_GERUDO_FORTRESS_SMALL_KEY, GID_KEY_SMALL }, { GI_FOREST_TEMPLE_SMALL_KEY, GID_KEY_SMALL }, { GI_FIRE_TEMPLE_SMALL_KEY, GID_KEY_SMALL }, @@ -1000,18 +1012,26 @@ std::unordered_map itemIdToModel = { { GI_NONE, GID_MAXIMUM }, { GI_SPIRIT_TEMPLE_BOSS_KEY, GID_KEY_BOSS }, { GI_SHADOW_TEMPLE_BOSS_KEY, GID_KEY_BOSS }, { GI_GANONS_CASTLE_BOSS_KEY, GID_KEY_BOSS }, - { GI_DOUBLE_DEFENSE, GID_HEART_CONTAINER }, - { GI_STONE_KOKIRI, GID_KOKIRI_EMERALD }, - { GI_STONE_GORON, GID_GORON_RUBY }, - { GI_STONE_ZORA, GID_ZORA_SAPPHIRE }, - { GI_MEDALLION_FOREST, GID_MEDALLION_FOREST }, - { GI_MEDALLION_FIRE, GID_MEDALLION_FIRE }, - { GI_MEDALLION_WATER, GID_MEDALLION_WATER }, - { GI_MEDALLION_SPIRIT, GID_MEDALLION_SPIRIT }, - { GI_MEDALLION_SHADOW, GID_MEDALLION_SHADOW }, - { GI_MEDALLION_LIGHT, GID_MEDALLION_LIGHT }, - { GI_SINGLE_MAGIC, GID_MAGIC_SMALL }, - { GI_DOUBLE_MAGIC, GID_MAGIC_LARGE }, + { GI_DEKU_TREE_MAP, GID_DUNGEON_MAP }, + { GI_DODONGOS_CAVERN_MAP, GID_DUNGEON_MAP }, + { GI_JABU_JABUS_BELLY_MAP, GID_DUNGEON_MAP }, + { GI_FOREST_TEMPLE_MAP, GID_DUNGEON_MAP }, + { GI_FIRE_TEMPLE_MAP, GID_DUNGEON_MAP }, + { GI_WATER_TEMPLE_MAP, GID_DUNGEON_MAP }, + { GI_SPIRIT_TEMPLE_MAP, GID_DUNGEON_MAP }, + { GI_SHADOW_TEMPLE_MAP, GID_DUNGEON_MAP }, + { GI_BOTTOM_OF_THE_WELL_MAP, GID_DUNGEON_MAP }, + { GI_ICE_CAVERN_MAP, GID_DUNGEON_MAP }, + { GI_DEKU_TREE_COMPASS, GID_COMPASS }, + { GI_DODONGOS_CAVERN_COMPASS, GID_COMPASS }, + { GI_JABU_JABUS_BELLY_COMPASS, GID_COMPASS }, + { GI_FOREST_TEMPLE_COMPASS, GID_COMPASS }, + { GI_FIRE_TEMPLE_COMPASS, GID_COMPASS }, + { GI_WATER_TEMPLE_COMPASS, GID_COMPASS }, + { GI_SPIRIT_TEMPLE_COMPASS, GID_COMPASS }, + { GI_SHADOW_TEMPLE_COMPASS, GID_COMPASS }, + { GI_BOTTOM_OF_THE_WELL_COMPASS, GID_COMPASS }, + { GI_ICE_CAVERN_COMPASS, GID_COMPASS }, { GI_ICE_TRAP, GID_RUPEE_GOLD }, { GI_ICE_TRAP, GID_MAXIMUM }, { GI_TEXT_0, GID_MAXIMUM } }; @@ -1634,10 +1654,18 @@ void Randomizer::ParseRandomizerSettingsFile(const char* spoilerFileName) { } break; case RSK_STARTING_MAPS_COMPASSES: - if(it.value() == "Own Dungeon") { - gSaveContext.randoSettings[index].value = 0; - } else if (it.value() == "Start With") { - gSaveContext.randoSettings[index].value = 1; + if(it.value() == "Start With") { + gSaveContext.randoSettings[index].value = 0; + } else if(it.value() == "Vanilla") { + gSaveContext.randoSettings[index].value = 1; + } else if(it.value() == "Own Dungeon") { + gSaveContext.randoSettings[index].value = 2; + } else if(it.value() == "Any Dungeon") { + gSaveContext.randoSettings[index].value = 3; + } else if(it.value() == "Overworld") { + gSaveContext.randoSettings[index].value = 4; + } else if(it.value() == "Anywhere") { + gSaveContext.randoSettings[index].value = 5; } break; case RSK_STARTING_DEKU_SHIELD: @@ -2300,30 +2328,47 @@ GetItemID Randomizer::GetItemFromGet(RandomizerGet randoGet, GetItemID ogItemId) case RG_PRELUDE_OF_LIGHT: return GI_PRELUDE_OF_LIGHT; - // todo implement dungeon-specific maps/compasses case RG_DEKU_TREE_MAP: + return GI_DEKU_TREE_MAP; case RG_DODONGOS_CAVERN_MAP: + return GI_DODONGOS_CAVERN_MAP; case RG_JABU_JABUS_BELLY_MAP: + return GI_JABU_JABUS_BELLY_MAP; case RG_FOREST_TEMPLE_MAP: + return GI_FOREST_TEMPLE_MAP; case RG_FIRE_TEMPLE_MAP: + return GI_FIRE_TEMPLE_MAP; case RG_WATER_TEMPLE_MAP: + return GI_WATER_TEMPLE_MAP; case RG_SPIRIT_TEMPLE_MAP: + return GI_SPIRIT_TEMPLE_MAP; case RG_SHADOW_TEMPLE_MAP: + return GI_SHADOW_TEMPLE_MAP; case RG_BOTTOM_OF_THE_WELL_MAP: + return GI_BOTTOM_OF_THE_WELL_MAP; case RG_ICE_CAVERN_MAP: - return GI_MAP; + return GI_ICE_CAVERN_MAP; case RG_DEKU_TREE_COMPASS: + return GI_DEKU_TREE_COMPASS; case RG_DODONGOS_CAVERN_COMPASS: + return GI_DODONGOS_CAVERN_COMPASS; case RG_JABU_JABUS_BELLY_COMPASS: + return GI_JABU_JABUS_BELLY_COMPASS; case RG_FOREST_TEMPLE_COMPASS: + return GI_FOREST_TEMPLE_COMPASS; case RG_FIRE_TEMPLE_COMPASS: + return GI_FIRE_TEMPLE_COMPASS; case RG_WATER_TEMPLE_COMPASS: + return GI_WATER_TEMPLE_COMPASS; case RG_SPIRIT_TEMPLE_COMPASS: + return GI_SPIRIT_TEMPLE_COMPASS; case RG_SHADOW_TEMPLE_COMPASS: + return GI_SHADOW_TEMPLE_COMPASS; case RG_BOTTOM_OF_THE_WELL_COMPASS: + return GI_BOTTOM_OF_THE_WELL_COMPASS; case RG_ICE_CAVERN_COMPASS: - return GI_COMPASS; + return GI_ICE_CAVERN_COMPASS; case RG_FOREST_TEMPLE_BOSS_KEY: return GI_FOREST_TEMPLE_BOSS_KEY; @@ -3518,7 +3563,7 @@ void GenerateRandomizerImgui() { cvarSettings[RSK_SHUFFLE_KOKIRI_SWORD] = CVar_GetS32("gRandomizeShuffleKokiriSword", 0) || CVar_GetS32("gRandomizeStartingKokiriSword", 0); cvarSettings[RSK_STARTING_DEKU_SHIELD] = CVar_GetS32("gRandomizeStartingDekuShield", 0); - cvarSettings[RSK_STARTING_MAPS_COMPASSES] = CVar_GetS32("gRandomizeStartingMapsCompasses", 0); + cvarSettings[RSK_STARTING_MAPS_COMPASSES] = CVar_GetS32("gRandomizeStartingMapsCompasses", 1); cvarSettings[RSK_SHUFFLE_DUNGEON_REWARDS] = CVar_GetS32("gRandomizeShuffleDungeonReward", 0); cvarSettings[RSK_SHUFFLE_SONGS] = CVar_GetS32("gRandomizeShuffleSongs", 0); cvarSettings[RSK_SHUFFLE_TOKENS] = CVar_GetS32("gRandomizeShuffleTokens", 0); @@ -3627,8 +3672,7 @@ void DrawRandoEditor(bool& open) { const char* randoShuffleAdultTrade[2] = { "Off", "On" }; // Shuffle Dungeon Items Settings - const char* randoShuffleMapsAndCompasses[6] = { "Own Dungeon", "Any Dungeon", "Overworld", - "Anywhere", "Start With", "Vanilla" }; + const char* randoShuffleMapsAndCompasses[6] = { "Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere" }; const char* randoShuffleSmallKeys[6] = { "Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere" }; const char* randoShuffleGerudoFortressKeys[4] = { "Vanilla", "Any Dungeon", "Overworld", "Anywhere" }; const char* randoShuffleBossKeys[6] = { "Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere" }; @@ -4198,7 +4242,17 @@ void DrawRandoEditor(bool& open) { PaddedSeparator(); // Start with Maps & Compasses - SohImGui::EnhancementCheckbox(Settings::MapsAndCompasses.GetName().c_str(), "gRandomizeStartingMapsCompasses"); + ImGui::Text(Settings::MapsAndCompasses.GetName().c_str()); + InsertHelpHoverText( + "Own dungeon - Boss Keys can only appear in their respective dungeon.\n" + "\n" + "Any dungeon - Boss Keys can only appear inside of any dungon.\n" + "\n" + "Overworld - Boss Keys can only appear outside of dungeons.\n" + "\n" + "Anywhere - Boss Keys can appear anywhere in the world." + ); + SohImGui::EnhancementCombobox("gRandomizeStartingMapsCompasses", randoShuffleMapsAndCompasses, 6, 1); ImGui::PopItemWidth(); ImGui::EndTable(); diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 28a159bfe..1f663123a 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -971,7 +971,7 @@ typedef enum { RSK_STARTING_DEKU_SHIELD, RSK_STARTING_KOKIRI_SWORD, RSK_SHUFFLE_KOKIRI_SWORD, - RSK_STARTING_MAPS_COMPASSES, //RANDOTODO more options for this, rn it's just start with or own dungeon + RSK_STARTING_MAPS_COMPASSES, RSK_SHUFFLE_DUNGEON_REWARDS, RSK_SHUFFLE_SONGS, RSK_SHUFFLE_TOKENS, diff --git a/soh/src/code/z_message_PAL.c b/soh/src/code/z_message_PAL.c index b5444faac..5c7bccac0 100644 --- a/soh/src/code/z_message_PAL.c +++ b/soh/src/code/z_message_PAL.c @@ -1801,6 +1801,86 @@ void Message_OpenText(GlobalContext* globalCtx, u16 textId) { break; } msgCtx->msgLength = font->msgLength = strlen(font->msgBuf); + } else if (gSaveContext.n64ddFlag && textId == 0x66 && GET_PLAYER(globalCtx)->getItemId >= GI_DEKU_TREE_MAP && GET_PLAYER(globalCtx)->getItemId <= GI_ICE_CAVERN_MAP) { + char* keyMsg; + switch (gSaveContext.language) { + case LANGUAGE_ENG: default: + switch (GET_PLAYER(globalCtx)->getItemId) { + case GI_DEKU_TREE_MAP: + keyMsg = "\x08You got the \x05\x42\Deku Tree Map\x05\x40!\x09\x02"; + break; + case GI_DODONGOS_CAVERN_MAP: + keyMsg = "\x08You got the \x05\x41\Dodongo's Cavern Map\x05\x40!\x09\x02"; + break; + case GI_JABU_JABUS_BELLY_MAP: + keyMsg = "\x08You got the \x05\x43\Jabu Jabu's Belly Map\x05\x40!\x09\x02"; + break; + case GI_FOREST_TEMPLE_MAP: + keyMsg = "\x08You got the \x05\x42\Forest Temple Map\x05\x40!\x09\x02"; + break; + case GI_FIRE_TEMPLE_MAP: + keyMsg = "\x08You got the \x05\x41\Fire Temple Map\x05\x40!\x09\x02"; + break; + case GI_WATER_TEMPLE_MAP: + keyMsg = "\x08You got the \x05\x43\Water Temple Map\x05\x40!\x09\x02"; + break; + case GI_SPIRIT_TEMPLE_MAP: + keyMsg = "\x08You got the \x05\x46\Spirit Temple Map\x05\x40!\x09\x02"; + break; + case GI_SHADOW_TEMPLE_MAP: + keyMsg = "\x08You got the \x05\x45\Shadow Temple Map\x05\x40!\x09\x02"; + break; + case GI_BOTTOM_OF_THE_WELL_MAP: + keyMsg = "\x08You got the \x05\x45\Bottom of the Well Map\x05\x40!\x09\x02"; + break; + case GI_ICE_CAVERN_MAP: + keyMsg = "\x08You got the \x05\x43\Ice Cavern Map\x05\x40!\x09\x02"; + break; + } + strcpy(font->msgBuf, keyMsg); + break; + } + msgCtx->msgLength = font->msgLength = strlen(font->msgBuf); + } else if (gSaveContext.n64ddFlag && textId == 0x67 && GET_PLAYER(globalCtx)->getItemId >= GI_DEKU_TREE_COMPASS && GET_PLAYER(globalCtx)->getItemId <= GI_ICE_CAVERN_COMPASS) { + char* keyMsg; + switch (gSaveContext.language) { + case LANGUAGE_ENG: default: + switch (GET_PLAYER(globalCtx)->getItemId) { + case GI_DEKU_TREE_COMPASS: + keyMsg = "\x08You got the \x05\x42\Deku Tree Compass\x05\x40!\x09\x02"; + break; + case GI_DODONGOS_CAVERN_COMPASS: + keyMsg = "\x08You got the \x05\x41\Dodongo's Cavern Compass\x05\x40!\x09\x02"; + break; + case GI_JABU_JABUS_BELLY_COMPASS: + keyMsg = "\x08You got the \x05\x43\Jabu Jabu's Belly Compass\x05\x40!\x09\x02"; + break; + case GI_FOREST_TEMPLE_COMPASS: + keyMsg = "\x08You got the \x05\x42\Forest Temple Compass\x05\x40!\x09\x02"; + break; + case GI_FIRE_TEMPLE_COMPASS: + keyMsg = "\x08You got the \x05\x41\Fire Temple Compass\x05\x40!\x09\x02"; + break; + case GI_WATER_TEMPLE_COMPASS: + keyMsg = "\x08You got the \x05\x43\Water Temple Compass\x05\x40!\x09\x02"; + break; + case GI_SPIRIT_TEMPLE_COMPASS: + keyMsg = "\x08You got the \x05\x46\Spirit Temple Compass\x05\x40!\x09\x02"; + break; + case GI_SHADOW_TEMPLE_COMPASS: + keyMsg = "\x08You got the \x05\x45\Shadow Temple Compass\x05\x40!\x09\x02"; + break; + case GI_BOTTOM_OF_THE_WELL_COMPASS: + keyMsg = "\x08You got the \x05\x45\Bottom of the Well Compass\x05\x40!\x09\x02"; + break; + case GI_ICE_CAVERN_COMPASS: + keyMsg = "\x08You got the \x05\x43\Ice Cavern Compass\x05\x40!\x09\x02"; + break; + } + strcpy(font->msgBuf, keyMsg); + break; + } + msgCtx->msgLength = font->msgLength = strlen(font->msgBuf); } else if (textId == 0xF8 && GET_PLAYER(globalCtx)->getItemId == GI_ICE_TRAP) { switch (gSaveContext.language) { case LANGUAGE_FRA: diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index a71c8a52c..b121c97d3 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -1749,52 +1749,76 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { gSaveContext.inventory.dungeonItems[gSaveContext.mapIndex] |= gBitFlags[item - ITEM_KEY_BOSS]; } return ITEM_NONE; - } else if ((item >= ITEM_FOREST_TEMPLE_BOSS_KEY) && (item <= ITEM_GANONS_CASTLE_BOSS_KEY)) { + } else if (item == ITEM_KEY_SMALL) { + if (gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex] < 0) { + gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex] = 1; + return ITEM_NONE; + } else { + gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex]++; + return ITEM_NONE; + } + } else if ( + (item >= ITEM_GERUDO_FORTRESS_SMALL_KEY) && (item <= ITEM_GANONS_CASTLE_SMALL_KEY) || + (item >= ITEM_FOREST_TEMPLE_BOSS_KEY) && (item <= ITEM_GANONS_CASTLE_BOSS_KEY) || + (item >= ITEM_DEKU_TREE_MAP) && (item <= ITEM_ICE_CAVERN_MAP) || + (item >= ITEM_DEKU_TREE_COMPASS) && (item <= ITEM_ICE_CAVERN_COMPASS) + ) { int mapIndex = gSaveContext.mapIndex; switch (item) { + case ITEM_DEKU_TREE_MAP: + case ITEM_DEKU_TREE_COMPASS: + mapIndex = SCENE_YDAN; + break; + case ITEM_DODONGOS_CAVERN_MAP: + case ITEM_DODONGOS_CAVERN_COMPASS: + mapIndex = SCENE_DDAN; + break; + case ITEM_JABU_JABUS_BELLY_MAP: + case ITEM_JABU_JABUS_BELLY_COMPASS: + mapIndex = SCENE_BDAN; + break; + case ITEM_FOREST_TEMPLE_MAP: + case ITEM_FOREST_TEMPLE_COMPASS: + case ITEM_FOREST_TEMPLE_SMALL_KEY: case ITEM_FOREST_TEMPLE_BOSS_KEY: mapIndex = SCENE_BMORI1; break; + case ITEM_FIRE_TEMPLE_MAP: + case ITEM_FIRE_TEMPLE_COMPASS: + case ITEM_FIRE_TEMPLE_SMALL_KEY: case ITEM_FIRE_TEMPLE_BOSS_KEY: mapIndex = SCENE_HIDAN; break; + case ITEM_WATER_TEMPLE_MAP: + case ITEM_WATER_TEMPLE_COMPASS: + case ITEM_WATER_TEMPLE_SMALL_KEY: case ITEM_WATER_TEMPLE_BOSS_KEY: mapIndex = SCENE_MIZUSIN; break; + case ITEM_SPIRIT_TEMPLE_MAP: + case ITEM_SPIRIT_TEMPLE_COMPASS: + case ITEM_SPIRIT_TEMPLE_SMALL_KEY: case ITEM_SPIRIT_TEMPLE_BOSS_KEY: mapIndex = SCENE_JYASINZOU; break; + case ITEM_SHADOW_TEMPLE_MAP: + case ITEM_SHADOW_TEMPLE_COMPASS: + case ITEM_SHADOW_TEMPLE_SMALL_KEY: case ITEM_SHADOW_TEMPLE_BOSS_KEY: mapIndex = SCENE_HAKADAN; break; - case ITEM_GANONS_CASTLE_BOSS_KEY: - mapIndex = SCENE_GANON; - break; - } - - gSaveContext.inventory.dungeonItems[mapIndex] |= gBitFlags[ITEM_KEY_BOSS - ITEM_KEY_BOSS]; - return ITEM_NONE; - } else if ((item >= ITEM_GERUDO_FORTRESS_SMALL_KEY) && (item <= ITEM_GANONS_CASTLE_SMALL_KEY)) { - int mapIndex = gSaveContext.mapIndex; - switch (item) { - case ITEM_FOREST_TEMPLE_SMALL_KEY: - mapIndex = SCENE_BMORI1; - break; - case ITEM_FIRE_TEMPLE_SMALL_KEY: - mapIndex = SCENE_HIDAN; - break; - case ITEM_WATER_TEMPLE_SMALL_KEY: - mapIndex = SCENE_MIZUSIN; - break; - case ITEM_SPIRIT_TEMPLE_SMALL_KEY: - mapIndex = SCENE_JYASINZOU; - break; - case ITEM_SHADOW_TEMPLE_SMALL_KEY: - mapIndex = SCENE_HAKADAN; - break; + case ITEM_BOTTOM_OF_THE_WELL_MAP: + case ITEM_BOTTOM_OF_THE_WELL_COMPASS: case ITEM_BOTTOM_OF_THE_WELL_SMALL_KEY: mapIndex = SCENE_HAKADANCH; break; + case ITEM_ICE_CAVERN_MAP: + case ITEM_ICE_CAVERN_COMPASS: + mapIndex = SCENE_ICE_DOUKUTO; + break; + case ITEM_GANONS_CASTLE_BOSS_KEY: + mapIndex = SCENE_GANON; + break; case ITEM_GERUDO_TRAINING_GROUNDS_SMALL_KEY: mapIndex = SCENE_MEN; break; @@ -1805,20 +1829,26 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { mapIndex = SCENE_GANONTIKA; break; } - - if (gSaveContext.inventory.dungeonKeys[mapIndex] < 0) { - gSaveContext.inventory.dungeonKeys[mapIndex] = 1; - return ITEM_NONE; + + if ((item >= ITEM_GERUDO_FORTRESS_SMALL_KEY) && (item <= ITEM_GANONS_CASTLE_SMALL_KEY)) { + if (gSaveContext.inventory.dungeonKeys[mapIndex] < 0) { + gSaveContext.inventory.dungeonKeys[mapIndex] = 1; + return ITEM_NONE; + } else { + gSaveContext.inventory.dungeonKeys[mapIndex]++; + return ITEM_NONE; + } } else { - gSaveContext.inventory.dungeonKeys[mapIndex]++; - return ITEM_NONE; - } - } else if (item == ITEM_KEY_SMALL) { - if (gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex] < 0) { - gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex] = 1; - return ITEM_NONE; - } else { - gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex]++; + int bitmask; + if ((item >= ITEM_DEKU_TREE_MAP) && (item <= ITEM_ICE_CAVERN_MAP)) { + bitmask = gBitFlags[2]; + } else if ((item >= ITEM_DEKU_TREE_COMPASS) && (item <= ITEM_ICE_CAVERN_COMPASS)) { + bitmask = gBitFlags[1]; + } else { + bitmask = gBitFlags[0]; + } + + gSaveContext.inventory.dungeonItems[mapIndex] |= bitmask; return ITEM_NONE; } } else if ((item == ITEM_QUIVER_30) || (item == ITEM_BOW)) { @@ -2330,7 +2360,12 @@ u8 Item_CheckObtainability(u8 item) { } else { return ITEM_NONE; } - } else if ((item >= ITEM_GERUDO_FORTRESS_SMALL_KEY) && (item <= ITEM_GANONS_CASTLE_BOSS_KEY)) { + } else if ( + (item >= ITEM_GERUDO_FORTRESS_SMALL_KEY) && (item <= ITEM_GANONS_CASTLE_SMALL_KEY) || + (item >= ITEM_FOREST_TEMPLE_BOSS_KEY) && (item <= ITEM_GANONS_CASTLE_BOSS_KEY) || + (item >= ITEM_DEKU_TREE_MAP) && (item <= ITEM_ICE_CAVERN_MAP) || + (item >= ITEM_DEKU_TREE_COMPASS) && (item <= ITEM_ICE_CAVERN_COMPASS) + ) { return ITEM_NONE; } else if ((item == ITEM_KEY_BOSS) || (item == ITEM_COMPASS) || (item == ITEM_DUNGEON_MAP)) { return ITEM_NONE; diff --git a/soh/src/code/z_sram.c b/soh/src/code/z_sram.c index b91da8918..18f732717 100644 --- a/soh/src/code/z_sram.c +++ b/soh/src/code/z_sram.c @@ -416,28 +416,64 @@ void GiveLinkDungeonReward(GetItemID getItemId) { } } -void GiveLinkSmallKey(GetItemID getItemId) { +void GiveLinkDungeonItem(GetItemID getItemId, GetItemID type) { int mapIndex; switch (getItemId) { + case GI_DEKU_TREE_MAP: + case GI_DEKU_TREE_COMPASS: + mapIndex = SCENE_YDAN; + break; + case GI_DODONGOS_CAVERN_MAP: + case GI_DODONGOS_CAVERN_COMPASS: + mapIndex = SCENE_DDAN; + break; + case GI_JABU_JABUS_BELLY_MAP: + case GI_JABU_JABUS_BELLY_COMPASS: + mapIndex = SCENE_BDAN; + break; + case GI_FOREST_TEMPLE_MAP: + case GI_FOREST_TEMPLE_COMPASS: case GI_FOREST_TEMPLE_SMALL_KEY: + case GI_FOREST_TEMPLE_BOSS_KEY: mapIndex = SCENE_BMORI1; break; + case GI_FIRE_TEMPLE_MAP: + case GI_FIRE_TEMPLE_COMPASS: case GI_FIRE_TEMPLE_SMALL_KEY: + case GI_FIRE_TEMPLE_BOSS_KEY: mapIndex = SCENE_HIDAN; break; + case GI_WATER_TEMPLE_MAP: + case GI_WATER_TEMPLE_COMPASS: case GI_WATER_TEMPLE_SMALL_KEY: + case GI_WATER_TEMPLE_BOSS_KEY: mapIndex = SCENE_MIZUSIN; break; + case GI_SPIRIT_TEMPLE_MAP: + case GI_SPIRIT_TEMPLE_COMPASS: case GI_SPIRIT_TEMPLE_SMALL_KEY: + case GI_SPIRIT_TEMPLE_BOSS_KEY: mapIndex = SCENE_JYASINZOU; break; + case GI_SHADOW_TEMPLE_MAP: + case GI_SHADOW_TEMPLE_COMPASS: case GI_SHADOW_TEMPLE_SMALL_KEY: + case GI_SHADOW_TEMPLE_BOSS_KEY: mapIndex = SCENE_HAKADAN; break; + case GI_BOTTOM_OF_THE_WELL_MAP: + case GI_BOTTOM_OF_THE_WELL_COMPASS: case GI_BOTTOM_OF_THE_WELL_SMALL_KEY: mapIndex = SCENE_HAKADANCH; break; + case GI_ICE_CAVERN_MAP: + case GI_ICE_CAVERN_COMPASS: + mapIndex = SCENE_ICE_DOUKUTO; + break; + case GI_GANONS_CASTLE_BOSS_KEY: + mapIndex = SCENE_GANON; + break; case GI_GERUDO_TRAINING_GROUNDS_SMALL_KEY: mapIndex = SCENE_MEN; break; @@ -449,40 +485,24 @@ void GiveLinkSmallKey(GetItemID getItemId) { break; } - if (gSaveContext.inventory.dungeonKeys[mapIndex] < 0) { - gSaveContext.inventory.dungeonKeys[mapIndex] = 1; - } else { - gSaveContext.inventory.dungeonKeys[mapIndex]++; + if (type == GI_MAP) { + uint32_t mapBitMask = 1 << 1; + gSaveContext.inventory.dungeonItems[mapIndex] |= mapBitMask; + } else if (type == GI_COMPASS) { + uint32_t compassBitMask = 1 << 2; + gSaveContext.inventory.dungeonItems[mapIndex] |= compassBitMask; + } else if (type == GI_KEY_SMALL) { + if (gSaveContext.inventory.dungeonKeys[mapIndex] < 0) { + gSaveContext.inventory.dungeonKeys[mapIndex] = 1; + } else { + gSaveContext.inventory.dungeonKeys[mapIndex]++; + } + } else if (type == GI_KEY_BOSS) { + uint32_t bossKeyBitMask = 1 << 0; + gSaveContext.inventory.dungeonItems[mapIndex] |= bossKeyBitMask; } } -void GiveLinkBossKey(GetItemID getItemId) { - int mapIndex; - - switch (getItemId) { - case GI_FOREST_TEMPLE_BOSS_KEY: - mapIndex = SCENE_BMORI1; - break; - case GI_FIRE_TEMPLE_BOSS_KEY: - mapIndex = SCENE_HIDAN; - break; - case GI_WATER_TEMPLE_BOSS_KEY: - mapIndex = SCENE_MIZUSIN; - break; - case GI_SPIRIT_TEMPLE_BOSS_KEY: - mapIndex = SCENE_JYASINZOU; - break; - case GI_SHADOW_TEMPLE_BOSS_KEY: - mapIndex = SCENE_HAKADAN; - break; - case GI_GANONS_CASTLE_BOSS_KEY: - mapIndex = SCENE_GANON; - break; - } - - gSaveContext.inventory.dungeonItems[mapIndex] |= 1; -} - void GiveLinksPocketMedallion() { GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(RC_LINKS_POCKET, RG_NONE); @@ -754,11 +774,11 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) { INV_CONTENT(ITEM_OCARINA_FAIRY) = ITEM_OCARINA_FAIRY; } - if(Randomizer_GetSettingValue(RSK_STARTING_MAPS_COMPASSES)) { + if(Randomizer_GetSettingValue(RSK_STARTING_MAPS_COMPASSES) == 0) { uint32_t mapBitMask = 1 << 1; uint32_t compassBitMask = 1 << 2; uint32_t startingDungeonItemsBitMask = mapBitMask | compassBitMask; - for(int scene = 0; scene <= 9; scene++) { + for(int scene = SCENE_YDAN; scene <= SCENE_ICE_DOUKUTO; scene++) { gSaveContext.inventory.dungeonItems[scene] |= startingDungeonItemsBitMask; } } @@ -856,9 +876,13 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) { } else if (giid == GI_DOUBLE_DEFENSE) { GiveLinkDoubleDefense(); } else if (giid >= GI_GERUDO_FORTRESS_SMALL_KEY && giid <= GI_GANONS_CASTLE_SMALL_KEY) { - GiveLinkSmallKey(giid); + GiveLinkDungeonItem(giid, GI_KEY_SMALL); } else if (giid >= GI_FOREST_TEMPLE_BOSS_KEY && giid <= GI_GANONS_CASTLE_BOSS_KEY) { - GiveLinkBossKey(giid); + GiveLinkDungeonItem(giid, GI_KEY_BOSS); + } else if (giid >= GI_DEKU_TREE_MAP && giid <= GI_ICE_CAVERN_MAP) { + GiveLinkDungeonItem(giid, GI_MAP); + } else if (giid >= GI_DEKU_TREE_COMPASS && giid <= GI_ICE_CAVERN_COMPASS) { + GiveLinkDungeonItem(giid, GI_COMPASS); } else { s32 iid = Randomizer_GetItemIDFromGetItemID(giid); if (iid != -1) INV_CONTENT(iid) = iid; 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 dcb0a2929..8c5914cca 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -671,6 +671,28 @@ GetItemEntry sGetItemTable[] = { GET_ITEM(ITEM_SPIRIT_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, 0xC7, 0x80, CHEST_ANIM_LONG), GET_ITEM(ITEM_SHADOW_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, 0xC7, 0x80, CHEST_ANIM_LONG), GET_ITEM(ITEM_GANONS_CASTLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, 0xC7, 0x80, CHEST_ANIM_LONG), + + GET_ITEM(ITEM_DEKU_TREE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, 0x66, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_DODONGOS_CAVERN_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, 0x66, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_JABU_JABUS_BELLY_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, 0x66, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_FOREST_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, 0x66, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_FIRE_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, 0x66, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_WATER_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, 0x66, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_SPIRIT_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, 0x66, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_SHADOW_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, 0x66, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_BOTTOM_OF_THE_WELL_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, 0x66, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_ICE_CAVERN_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, 0x66, 0x80, CHEST_ANIM_LONG), + + GET_ITEM(ITEM_DEKU_TREE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, 0x67, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_DODONGOS_CAVERN_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, 0x67, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_JABU_JABUS_BELLY_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, 0x67, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_FOREST_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, 0x67, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_FIRE_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, 0x67, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_WATER_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, 0x67, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_SPIRIT_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, 0x67, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_SHADOW_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, 0x67, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_BOTTOM_OF_THE_WELL_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, 0x67, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_ICE_CAVERN_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, 0x67, 0x80, CHEST_ANIM_LONG), GET_ITEM_NONE, GET_ITEM_NONE, From a0ac945b4eaaedc88a14971446aae387352715f7 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Mon, 8 Aug 2022 14:18:15 -0500 Subject: [PATCH 16/21] Make logic consistent across z_parameter & z_sram --- soh/src/code/z_parameter.c | 8 ++++---- soh/src/code/z_sram.c | 39 +++++++++++++++++++------------------- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index b121c97d3..d07c4b33e 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -1758,10 +1758,10 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { return ITEM_NONE; } } else if ( - (item >= ITEM_GERUDO_FORTRESS_SMALL_KEY) && (item <= ITEM_GANONS_CASTLE_SMALL_KEY) || - (item >= ITEM_FOREST_TEMPLE_BOSS_KEY) && (item <= ITEM_GANONS_CASTLE_BOSS_KEY) || - (item >= ITEM_DEKU_TREE_MAP) && (item <= ITEM_ICE_CAVERN_MAP) || - (item >= ITEM_DEKU_TREE_COMPASS) && (item <= ITEM_ICE_CAVERN_COMPASS) + (item >= ITEM_GERUDO_FORTRESS_SMALL_KEY && item <= ITEM_GANONS_CASTLE_SMALL_KEY) || + (item >= ITEM_FOREST_TEMPLE_BOSS_KEY && item <= ITEM_GANONS_CASTLE_BOSS_KEY) || + (item >= ITEM_DEKU_TREE_MAP && item <= ITEM_ICE_CAVERN_MAP) || + (item >= ITEM_DEKU_TREE_COMPASS && item <= ITEM_ICE_CAVERN_COMPASS) ) { int mapIndex = gSaveContext.mapIndex; switch (item) { diff --git a/soh/src/code/z_sram.c b/soh/src/code/z_sram.c index 18f732717..24dfd2b1e 100644 --- a/soh/src/code/z_sram.c +++ b/soh/src/code/z_sram.c @@ -416,7 +416,7 @@ void GiveLinkDungeonReward(GetItemID getItemId) { } } -void GiveLinkDungeonItem(GetItemID getItemId, GetItemID type) { +void GiveLinkDungeonItem(GetItemID getItemId) { int mapIndex; switch (getItemId) { @@ -485,21 +485,23 @@ void GiveLinkDungeonItem(GetItemID getItemId, GetItemID type) { break; } - if (type == GI_MAP) { - uint32_t mapBitMask = 1 << 1; - gSaveContext.inventory.dungeonItems[mapIndex] |= mapBitMask; - } else if (type == GI_COMPASS) { - uint32_t compassBitMask = 1 << 2; - gSaveContext.inventory.dungeonItems[mapIndex] |= compassBitMask; - } else if (type == GI_KEY_SMALL) { + if ((getItemId >= GI_GERUDO_FORTRESS_SMALL_KEY) && (getItemId <= GI_GANONS_CASTLE_SMALL_KEY)) { if (gSaveContext.inventory.dungeonKeys[mapIndex] < 0) { gSaveContext.inventory.dungeonKeys[mapIndex] = 1; } else { gSaveContext.inventory.dungeonKeys[mapIndex]++; } - } else if (type == GI_KEY_BOSS) { - uint32_t bossKeyBitMask = 1 << 0; - gSaveContext.inventory.dungeonItems[mapIndex] |= bossKeyBitMask; + } else { + int bitmask; + if ((getItemId >= GI_DEKU_TREE_MAP) && (getItemId <= GI_ICE_CAVERN_MAP)) { + bitmask = gBitFlags[2]; + } else if ((getItemId >= GI_DEKU_TREE_COMPASS) && (getItemId <= GI_ICE_CAVERN_COMPASS)) { + bitmask = gBitFlags[1]; + } else { + bitmask = gBitFlags[0]; + } + + gSaveContext.inventory.dungeonItems[mapIndex] |= bitmask; } } @@ -875,14 +877,13 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) { GiveLinkMagic(giid); } else if (giid == GI_DOUBLE_DEFENSE) { GiveLinkDoubleDefense(); - } else if (giid >= GI_GERUDO_FORTRESS_SMALL_KEY && giid <= GI_GANONS_CASTLE_SMALL_KEY) { - GiveLinkDungeonItem(giid, GI_KEY_SMALL); - } else if (giid >= GI_FOREST_TEMPLE_BOSS_KEY && giid <= GI_GANONS_CASTLE_BOSS_KEY) { - GiveLinkDungeonItem(giid, GI_KEY_BOSS); - } else if (giid >= GI_DEKU_TREE_MAP && giid <= GI_ICE_CAVERN_MAP) { - GiveLinkDungeonItem(giid, GI_MAP); - } else if (giid >= GI_DEKU_TREE_COMPASS && giid <= GI_ICE_CAVERN_COMPASS) { - GiveLinkDungeonItem(giid, GI_COMPASS); + } else if ( + (giid >= GI_GERUDO_FORTRESS_SMALL_KEY && giid <= GI_GANONS_CASTLE_SMALL_KEY) || + (giid >= GI_FOREST_TEMPLE_BOSS_KEY && giid <= GI_GANONS_CASTLE_BOSS_KEY) || + (giid >= GI_DEKU_TREE_MAP && giid <= GI_ICE_CAVERN_MAP) || + (giid >= GI_DEKU_TREE_COMPASS && giid <= GI_ICE_CAVERN_COMPASS) + ) { + GiveLinkDungeonItem(giid); } else { s32 iid = Randomizer_GetItemIDFromGetItemID(giid); if (iid != -1) INV_CONTENT(iid) = iid; From 3472e832506ddfc3f0f5d149bd63af8aa0469d2e Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Tue, 9 Aug 2022 00:00:30 -0500 Subject: [PATCH 17/21] Use new custom message system, skulltula drops still broken text --- .../Enhancements/randomizer/randomizer.cpp | 39 +++++++++++ .../actors/ovl_player_actor/z_player.c | 70 +++++++++---------- 2 files changed, 74 insertions(+), 35 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index fd85d10bc..e376e22c4 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -4591,6 +4591,45 @@ void Randomizer::CreateCustomMessages() { "You got a %rBottle of Green Potion%w!&Drink it to replenish your&%bmagic%w!"), GIMESSAGE_UNTRANSLATED(GI_BOTTLE_WITH_POE, ITEM_POE, "You got a %rPoe in a Bottle%w!&That creepy Ghost Shop might&be interested in this..."), + + GIMESSAGE_UNTRANSLATED(GI_GERUDO_FORTRESS_SMALL_KEY, ITEM_KEY_SMALL, "You found a %yThieves Hideout &%wSmall Key!"), + GIMESSAGE_UNTRANSLATED(GI_FOREST_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %gForest Temple &%wSmall Key!"), + GIMESSAGE_UNTRANSLATED(GI_FIRE_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %rFire Temple &%wSmall Key!"), + GIMESSAGE_UNTRANSLATED(GI_WATER_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %bWater Temple &%wSmall Key!"), + GIMESSAGE_UNTRANSLATED(GI_SPIRIT_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %ySpirit Temple &%wSmall Key!"), + GIMESSAGE_UNTRANSLATED(GI_SHADOW_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %pShadow Temple &%wSmall Key!"), + GIMESSAGE_UNTRANSLATED(GI_BOTTOM_OF_THE_WELL_SMALL_KEY, ITEM_KEY_SMALL, "You found a %pBottom of the &Well %wSmall Key!"), + GIMESSAGE_UNTRANSLATED(GI_GERUDO_TRAINING_GROUNDS_SMALL_KEY, ITEM_KEY_SMALL, "You found a %yGerudo Training Grounds &%wSmall Key!"), + GIMESSAGE_UNTRANSLATED(GI_GANONS_CASTLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %rGanon's Castle &%wSmall Key!"), + + GIMESSAGE_UNTRANSLATED(GI_FOREST_TEMPLE_BOSS_KEY, ITEM_KEY_BOSS, "You found the %gForest Temple &%wBoss Key!"), + GIMESSAGE_UNTRANSLATED(GI_FIRE_TEMPLE_BOSS_KEY, ITEM_KEY_BOSS, "You found the %rFire Temple &%wBoss Key!"), + GIMESSAGE_UNTRANSLATED(GI_WATER_TEMPLE_BOSS_KEY, ITEM_KEY_BOSS, "You found the %bWater Temple &%wBoss Key!"), + GIMESSAGE_UNTRANSLATED(GI_SPIRIT_TEMPLE_BOSS_KEY, ITEM_KEY_BOSS, "You found the %ySpirit Temple &%wBoss Key!"), + GIMESSAGE_UNTRANSLATED(GI_SHADOW_TEMPLE_BOSS_KEY, ITEM_KEY_BOSS, "You found the %pShadow Temple &%wBoss Key!"), + GIMESSAGE_UNTRANSLATED(GI_GANONS_CASTLE_BOSS_KEY, ITEM_KEY_BOSS, "You found the %rGanon's Castle &%wBoss Key!"), + + GIMESSAGE_UNTRANSLATED(GI_DEKU_TREE_MAP, ITEM_DUNGEON_MAP, "You found the %gDeku Tree &%wMap!"), + GIMESSAGE_UNTRANSLATED(GI_DODONGOS_CAVERN_MAP, ITEM_DUNGEON_MAP, "You found the %rDodongo's Cavern &%wMap!"), + GIMESSAGE_UNTRANSLATED(GI_JABU_JABUS_BELLY_MAP, ITEM_DUNGEON_MAP, "You found the %bJabu Jabu's Belly &%wMap!"), + GIMESSAGE_UNTRANSLATED(GI_FOREST_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %gForest Temple &%wMap!"), + GIMESSAGE_UNTRANSLATED(GI_FIRE_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %rFire Temple &%wMap!"), + GIMESSAGE_UNTRANSLATED(GI_WATER_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %bWater Temple &%wMap!"), + GIMESSAGE_UNTRANSLATED(GI_SPIRIT_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %ySpirit Temple &%wMap!"), + GIMESSAGE_UNTRANSLATED(GI_SHADOW_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %pShadow Temple &%wMap!"), + GIMESSAGE_UNTRANSLATED(GI_BOTTOM_OF_THE_WELL_MAP, ITEM_DUNGEON_MAP, "You found the %pBottom of the &Well %wMap!"), + GIMESSAGE_UNTRANSLATED(GI_ICE_CAVERN_MAP, ITEM_DUNGEON_MAP, "You found the %cIce Cavern &%wMap!"), + + GIMESSAGE_UNTRANSLATED(GI_DEKU_TREE_COMPASS, ITEM_COMPASS, "You found the %gDeku Tree &%wCompass!"), + GIMESSAGE_UNTRANSLATED(GI_DODONGOS_CAVERN_COMPASS, ITEM_COMPASS, "You found the %rDodongo's Cavern &%wCompass!"), + GIMESSAGE_UNTRANSLATED(GI_JABU_JABUS_BELLY_COMPASS, ITEM_COMPASS, "You found the %bJabu Jabu's Belly &%wCompass!"), + GIMESSAGE_UNTRANSLATED(GI_FOREST_TEMPLE_COMPASS, ITEM_COMPASS, "You found the %gForest Temple &%wCompass!"), + GIMESSAGE_UNTRANSLATED(GI_FIRE_TEMPLE_COMPASS, ITEM_COMPASS, "You found the %rFire Temple &%wCompass!"), + GIMESSAGE_UNTRANSLATED(GI_WATER_TEMPLE_COMPASS, ITEM_COMPASS, "You found the %bWater Temple &%wCompass!"), + GIMESSAGE_UNTRANSLATED(GI_SPIRIT_TEMPLE_COMPASS, ITEM_COMPASS, "You found the %ySpirit Temple &%wCompass!"), + GIMESSAGE_UNTRANSLATED(GI_SHADOW_TEMPLE_COMPASS, ITEM_COMPASS, "You found the %pShadow Temple &%wCompass!"), + GIMESSAGE_UNTRANSLATED(GI_BOTTOM_OF_THE_WELL_COMPASS, ITEM_COMPASS, "You found the %pBottom of the &Well %wCompass!"), + GIMESSAGE_UNTRANSLATED(GI_ICE_CAVERN_COMPASS, ITEM_COMPASS, "You found the %cIce Cavern &%wCompass!"), }; CreateGetItemMessages(getItemMessages); CreateScrubMessages(); 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 db5ad2dd1..cf682a45c 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -656,44 +656,44 @@ GetItemEntry sGetItemTable[] = { GET_ITEM(ITEM_BOTTLE_WITH_POE, OBJECT_GI_GHOST, GID_POE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), GET_ITEM(ITEM_BOTTLE_WITH_BIG_POE, OBJECT_GI_GHOST, GID_BIG_POE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_GERUDO_FORTRESS_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, 0x60, 0x80, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_FOREST_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, 0x60, 0x80, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_FIRE_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, 0x60, 0x80, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_WATER_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, 0x60, 0x80, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_SPIRIT_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, 0x60, 0x80, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_SHADOW_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, 0x60, 0x80, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_BOTTOM_OF_THE_WELL_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, 0x60, 0x80, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_GERUDO_TRAINING_GROUNDS_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, 0x60, 0x80, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_GANONS_CASTLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, 0x60, 0x80, CHEST_ANIM_SHORT), + GET_ITEM(ITEM_GERUDO_FORTRESS_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT), + GET_ITEM(ITEM_FOREST_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT), + GET_ITEM(ITEM_FIRE_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT), + GET_ITEM(ITEM_WATER_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT), + GET_ITEM(ITEM_SPIRIT_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT), + GET_ITEM(ITEM_SHADOW_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT), + GET_ITEM(ITEM_BOTTOM_OF_THE_WELL_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT), + GET_ITEM(ITEM_GERUDO_TRAINING_GROUNDS_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT), + GET_ITEM(ITEM_GANONS_CASTLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_FOREST_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, 0xC7, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_FIRE_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, 0xC7, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_WATER_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, 0xC7, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_SPIRIT_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, 0xC7, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_SHADOW_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, 0xC7, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_GANONS_CASTLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, 0xC7, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_FOREST_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_FIRE_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_WATER_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_SPIRIT_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_SHADOW_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_GANONS_CASTLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_DEKU_TREE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, 0x66, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_DODONGOS_CAVERN_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, 0x66, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_JABU_JABUS_BELLY_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, 0x66, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_FOREST_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, 0x66, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_FIRE_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, 0x66, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_WATER_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, 0x66, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_SPIRIT_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, 0x66, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_SHADOW_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, 0x66, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_BOTTOM_OF_THE_WELL_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, 0x66, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_ICE_CAVERN_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, 0x66, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_DEKU_TREE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_DODONGOS_CAVERN_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_JABU_JABUS_BELLY_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_FOREST_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_FIRE_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_WATER_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_SPIRIT_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_SHADOW_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_BOTTOM_OF_THE_WELL_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_ICE_CAVERN_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_DEKU_TREE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, 0x67, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_DODONGOS_CAVERN_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, 0x67, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_JABU_JABUS_BELLY_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, 0x67, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_FOREST_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, 0x67, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_FIRE_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, 0x67, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_WATER_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, 0x67, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_SPIRIT_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, 0x67, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_SHADOW_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, 0x67, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_BOTTOM_OF_THE_WELL_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, 0x67, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_ICE_CAVERN_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, 0x67, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_DEKU_TREE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_DODONGOS_CAVERN_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_JABU_JABUS_BELLY_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_FOREST_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_FIRE_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_WATER_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_SPIRIT_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_SHADOW_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_BOTTOM_OF_THE_WELL_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), + GET_ITEM(ITEM_ICE_CAVERN_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), GET_ITEM_NONE, GET_ITEM_NONE, From 608f493c5be103ed0e512b48bb7e8e26a15cb22b Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Tue, 9 Aug 2022 07:53:15 -0500 Subject: [PATCH 18/21] Update descriptions and defaults --- .../Enhancements/randomizer/randomizer.cpp | 55 +++++++++++++------ soh/src/code/z_sram.c | 4 ++ 2 files changed, 41 insertions(+), 18 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 2529bd364..62a0eeec9 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -3552,7 +3552,7 @@ void GenerateRandomizerImgui() { cvarSettings[RSK_SHUFFLE_KOKIRI_SWORD] = CVar_GetS32("gRandomizeShuffleKokiriSword", 0) || CVar_GetS32("gRandomizeStartingKokiriSword", 0); cvarSettings[RSK_STARTING_DEKU_SHIELD] = CVar_GetS32("gRandomizeStartingDekuShield", 0); - cvarSettings[RSK_STARTING_MAPS_COMPASSES] = CVar_GetS32("gRandomizeStartingMapsCompasses", 1); + cvarSettings[RSK_STARTING_MAPS_COMPASSES] = CVar_GetS32("gRandomizeStartingMapsCompasses", 2); cvarSettings[RSK_SHUFFLE_DUNGEON_REWARDS] = CVar_GetS32("gRandomizeShuffleDungeonReward", 0); cvarSettings[RSK_SHUFFLE_SONGS] = CVar_GetS32("gRandomizeShuffleSongs", 0); cvarSettings[RSK_SHUFFLE_TOKENS] = CVar_GetS32("gRandomizeShuffleTokens", 0); @@ -3571,10 +3571,10 @@ void GenerateRandomizerImgui() { cvarSettings[RSK_GOSSIP_STONE_HINTS] = CVar_GetS32("gRandomizeGossipStoneHints", 1); cvarSettings[RSK_HINT_CLARITY] = CVar_GetS32("gRandomizeHintClarity", 2); cvarSettings[RSK_HINT_DISTRIBUTION] = CVar_GetS32("gRandomizeHintDistribution", 1); - cvarSettings[RSK_KEYSANITY] = CVar_GetS32("gRandomizeKeysanity", 1); + cvarSettings[RSK_KEYSANITY] = CVar_GetS32("gRandomizeKeysanity", 2); cvarSettings[RSK_GERUDO_KEYS] = CVar_GetS32("gRandomizeGerudoKeys", 0); - cvarSettings[RSK_BOSS_KEYSANITY] = CVar_GetS32("gRandomizeBossKeysanity", 1); - cvarSettings[RSK_GANONS_BOSS_KEY] = CVar_GetS32("gRandomizeShuffleGanonBossKey", 0); + cvarSettings[RSK_BOSS_KEYSANITY] = CVar_GetS32("gRandomizeBossKeysanity", 2); + cvarSettings[RSK_GANONS_BOSS_KEY] = CVar_GetS32("gRandomizeShuffleGanonBossKey", 1); cvarSettings[RSK_STARTING_CONSUMABLES] = CVar_GetS32("gRandomizeStartingConsumables", 0); cvarSettings[RSK_FULL_WALLETS] = CVar_GetS32("gRandomizeFullWallets", 0); @@ -4184,6 +4184,10 @@ void DrawRandoEditor(bool& open) { // Keysanity ImGui::Text(Settings::Keysanity.GetName().c_str()); InsertHelpHoverText( + "Start with - You will start with all Small Keys from all dungeons.\n" + "\n" + "Vanilla - Small Keys will appear in their vanilla locations.\n" + "\n" "Own dungeon - Small Keys can only appear in their respective dungeon.\n" "\n" "Any dungeon - Small Keys can only appear inside of any dungon.\n" @@ -4192,17 +4196,19 @@ void DrawRandoEditor(bool& open) { "\n" "Anywhere - Small Keys can appear anywhere in the world." ); - SohImGui::EnhancementCombobox("gRandomizeKeysanity", randoShuffleSmallKeys, 6, 1); + SohImGui::EnhancementCombobox("gRandomizeKeysanity", randoShuffleSmallKeys, 6, 2); PaddedSeparator(); // Gerudo Keys ImGui::Text(Settings::GerudoKeys.GetName().c_str()); InsertHelpHoverText( - "Any dungeon - Small Keys can only appear inside of any dungon.\n" + "Vanilla - Thieve's Hideout Keys will appear in their vanilla locations.\n" "\n" - "Overworld - Small Keys can only appear outside of dungeons.\n" + "Any dungeon - Thieve's Hideout Keys can only appear inside of any dungon.\n" "\n" - "Anywhere - Small Keys can appear anywhere in the world." + "Overworld - Thieve's Hideout Keys can only appear outside of dungeons.\n" + "\n" + "Anywhere - Thieve's Hideout Keys can appear anywhere in the world." ); SohImGui::EnhancementCombobox("gRandomizeGerudoKeys", randoShuffleGerudoFortressKeys, 4, 0); PaddedSeparator(); @@ -4210,6 +4216,10 @@ void DrawRandoEditor(bool& open) { // Boss Keysanity ImGui::Text(Settings::BossKeysanity.GetName().c_str()); InsertHelpHoverText( + "Start with - You will start with Boss keys from all dungeons.\n" + "\n" + "Vanilla - Boss Keys will appear in their vanilla locations.\n" + "\n" "Own dungeon - Boss Keys can only appear in their respective dungeon.\n" "\n" "Any dungeon - Boss Keys can only appear inside of any dungon.\n" @@ -4218,34 +4228,43 @@ void DrawRandoEditor(bool& open) { "\n" "Anywhere - Boss Keys can appear anywhere in the world." ); - SohImGui::EnhancementCombobox("gRandomizeBossKeysanity", randoShuffleBossKeys, 6, 1); + SohImGui::EnhancementCombobox("gRandomizeBossKeysanity", randoShuffleBossKeys, 6, 2); PaddedSeparator(); - // RANDOTODO implement ganon's boss key outside of ganon's castle // Ganon's Boss Key ImGui::Text(Settings::GanonsBossKey.GetName().c_str()); InsertHelpHoverText( - "Vanilla - Key will appear in the vanilla location.\n" + "Vanilla - Ganon's Boss Key will appear in the vanilla location.\n" "\n" - "Own dungeon - Key can appear anywhere inside Ganon's Castle.\n" + "Own dungeon - Ganon's Boss Key can appear anywhere inside Ganon's Castle.\n" "\n" "Start with - Places Ganon's Boss Key in your starting inventory." + "\n" + "Any dungeon - Ganon's Boss Key Key can only appear inside of any dungon.\n" + "\n" + "Overworld - Ganon's Boss Key Key can only appear outside of dungeons.\n" + "\n" + "Anywhere - Ganon's Boss Key Key can appear anywhere in the world." ); - SohImGui::EnhancementCombobox("gRandomizeShuffleGanonBossKey", randoShuffleGanonsBossKey, 12, 0); + SohImGui::EnhancementCombobox("gRandomizeShuffleGanonBossKey", randoShuffleGanonsBossKey, 12, 1); PaddedSeparator(); // Start with Maps & Compasses ImGui::Text(Settings::MapsAndCompasses.GetName().c_str()); InsertHelpHoverText( - "Own dungeon - Boss Keys can only appear in their respective dungeon.\n" + "Start with - You will start with Maps & Compasses from all dungeons.\n" "\n" - "Any dungeon - Boss Keys can only appear inside of any dungon.\n" + "Vanilla - Maps & Compasses will appear in their vanilla locations.\n" "\n" - "Overworld - Boss Keys can only appear outside of dungeons.\n" + "Own dungeon - Maps & Compasses can only appear in their respective dungeon.\n" "\n" - "Anywhere - Boss Keys can appear anywhere in the world." + "Any dungeon - Maps & Compasses can only appear inside of any dungon.\n" + "\n" + "Overworld - Maps & Compasses can only appear outside of dungeons.\n" + "\n" + "Anywhere - Maps & Compasses can appear anywhere in the world." ); - SohImGui::EnhancementCombobox("gRandomizeStartingMapsCompasses", randoShuffleMapsAndCompasses, 6, 1); + SohImGui::EnhancementCombobox("gRandomizeStartingMapsCompasses", randoShuffleMapsAndCompasses, 6, 2); ImGui::PopItemWidth(); ImGui::EndTable(); diff --git a/soh/src/code/z_sram.c b/soh/src/code/z_sram.c index c211d93ec..1b160b944 100644 --- a/soh/src/code/z_sram.c +++ b/soh/src/code/z_sram.c @@ -776,6 +776,7 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) { INV_CONTENT(ITEM_OCARINA_FAIRY) = ITEM_OCARINA_FAIRY; } + // "Start with" == 0 for Maps and Compasses if(Randomizer_GetSettingValue(RSK_STARTING_MAPS_COMPASSES) == 0) { uint32_t mapBitMask = 1 << 1; uint32_t compassBitMask = 1 << 2; @@ -910,6 +911,7 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) { GiveLinkRupees(9001); } + // "Start with" == 0 for Keysanity if(Randomizer_GetSettingValue(RSK_KEYSANITY) == 0) { // TODO: If master quest there are different key counts gSaveContext.inventory.dungeonKeys[SCENE_BMORI1] = 5; // Forest @@ -922,6 +924,7 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) { gSaveContext.inventory.dungeonKeys[SCENE_GANONTIKA] = 2; // Ganon } + // "Start with" == 0 for Boss Kesanity if(Randomizer_GetSettingValue(RSK_BOSS_KEYSANITY) == 0) { gSaveContext.inventory.dungeonItems[SCENE_BMORI1] |= 1; // Forest gSaveContext.inventory.dungeonItems[SCENE_HIDAN] |= 1; // Fire @@ -930,6 +933,7 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) { gSaveContext.inventory.dungeonItems[SCENE_HAKADAN] |= 1; // Shadow } + // "Start with" == 2 for Ganon's Boss Key if(Randomizer_GetSettingValue(RSK_GANONS_BOSS_KEY) == 2) { gSaveContext.inventory.dungeonItems[SCENE_GANON] |= 1; } From ec7e3d350aabfb57d6b398066d52ab2b8d1af1a8 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Wed, 10 Aug 2022 01:15:00 -0500 Subject: [PATCH 19/21] Remove LACS settings for ganons key for now --- soh/soh/Enhancements/randomizer/randomizer.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 62a0eeec9..f3b8ef857 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -3669,9 +3669,7 @@ void DrawRandoEditor(bool& open) { const char* randoShuffleSmallKeys[6] = { "Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere" }; const char* randoShuffleGerudoFortressKeys[4] = { "Vanilla", "Any Dungeon", "Overworld", "Anywhere" }; const char* randoShuffleBossKeys[6] = { "Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere" }; - const char* randoShuffleGanonsBossKey[12] = { "Vanilla", "Own dungeon", "Start with", "Any Dungeon", - "Overworld", "Anywhere", "LACS-Vanilla", "LACS-Medallions", - "LACS-Stones", "LACS-Rewards", "LACS-Dungeons", "LACS-Tokens" }; + const char* randoShuffleGanonsBossKey[6] = { "Vanilla", "Own dungeon", "Start with", "Any Dungeon", "Overworld", "Anywhere" }; // Timesaver Settings const char* randoSkipSongReplays[3] = { "Don't skip", "Skip (no SFX)", "Skip (Keep SFX)" }; From 8abfa4821f0af2a5f4b6ec4a9aa3f05591ecb421 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Wed, 10 Aug 2022 01:17:19 -0500 Subject: [PATCH 20/21] Anotha one (removing LACS stuff) --- soh/soh/Enhancements/randomizer/randomizer.cpp | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index f3b8ef857..932027af7 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -1793,18 +1793,6 @@ void Randomizer::ParseRandomizerSettingsFile(const char* spoilerFileName) { gSaveContext.randoSettings[index].value = 4; } else if(it.value() == "Anywhere") { gSaveContext.randoSettings[index].value = 5; - } else if(it.value() == "LACS-Vanilla") { - gSaveContext.randoSettings[index].value = 6; - } else if(it.value() == "LACS-Medallions") { - gSaveContext.randoSettings[index].value = 7; - } else if(it.value() == "LACS-Stones") { - gSaveContext.randoSettings[index].value = 8; - } else if(it.value() == "LACS-Rewards") { - gSaveContext.randoSettings[index].value = 9; - } else if(it.value() == "LACS-Dungeons") { - gSaveContext.randoSettings[index].value = 10; - } else if(it.value() == "LACS-Tokens") { - gSaveContext.randoSettings[index].value = 11; } break; case RSK_SKIP_CHILD_ZELDA: From 7f62802aef2457dec03ddc54cb059b2475f96402 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Wed, 10 Aug 2022 01:19:21 -0500 Subject: [PATCH 21/21] Man I really had to split that up into three commits.. Fix from removing LACS setting --- soh/soh/Enhancements/randomizer/randomizer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 932027af7..1c9fdbb70 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -4232,7 +4232,7 @@ void DrawRandoEditor(bool& open) { "\n" "Anywhere - Ganon's Boss Key Key can appear anywhere in the world." ); - SohImGui::EnhancementCombobox("gRandomizeShuffleGanonBossKey", randoShuffleGanonsBossKey, 12, 1); + SohImGui::EnhancementCombobox("gRandomizeShuffleGanonBossKey", randoShuffleGanonsBossKey, 6, 1); PaddedSeparator(); // Start with Maps & Compasses