diff --git a/soh/include/z64item.h b/soh/include/z64item.h index 9e78487dba..5b3844da1d 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 7f6c85de8f..75c883605b 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 364e63956a..6e33cdd92a 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 34a94c67b3..68893ac002 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),