Merge pull request #1051 from garrettjoecox/keysanity

Keysanity + Shuffle Compasses & Maps
This commit is contained in:
briaguya 2022-08-10 02:28:14 -04:00 committed by GitHub
commit 65356b6ced
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 623 additions and 99 deletions

View File

@ -253,6 +253,41 @@ 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,
/* 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
@ -397,39 +432,78 @@ 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,
GI_SINGLE_MAGIC,
GI_DOUBLE_MAGIC,
GI_DOUBLE_DEFENSE,
/* 0x93 */ GI_SINGLE_MAGIC,
/* 0x94 */ GI_DOUBLE_MAGIC,
/* 0x95 */ GI_DOUBLE_DEFENSE,
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,
/* 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,
/* 0x84 */ GI_MAX
/* 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,
/* 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,
/* 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;
typedef enum {

View File

@ -13,7 +13,7 @@ typedef struct {
/* 0x04 */ u16 objectId;
} GetItemEntry; // size = 0x06
extern GetItemEntry sGetItemTable[160];
extern GetItemEntry sGetItemTable[195];
typedef enum {
/* 0 */ PLAYER_SWORD_NONE,

View File

@ -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;
}

View File

@ -2546,14 +2546,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]);
@ -2565,6 +2558,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]);

View File

@ -1004,6 +1004,41 @@ std::unordered_map<s16, s16> itemIdToModel = { { GI_NONE, GID_MAXIMUM },
{ 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 },
{ 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_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 } };
@ -1412,6 +1447,9 @@ std::unordered_map<std::string, RandomizerSettingKey> 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 },
@ -1648,10 +1686,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:
@ -1706,13 +1752,49 @@ 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;
}
break;
case RSK_SKIP_CHILD_ZELDA:
@ -2229,50 +2311,79 @@ 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;
// todo implement dungeon-specific keys/keyrings
case RG_FOREST_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:
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:
@ -3431,7 +3542,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", 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);
@ -3451,7 +3562,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_GANONS_BOSS_KEY] = CVar_GetS32("gRandomizeShuffleGanonBossKey", 0);
cvarSettings[RSK_KEYSANITY] = CVar_GetS32("gRandomizeKeysanity", 2);
cvarSettings[RSK_GERUDO_KEYS] = CVar_GetS32("gRandomizeGerudoKeys", 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);
@ -3542,17 +3656,11 @@ 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* randoShuffleSmallKeys[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] = { "Own Dungeon", "Any Dungeon", "Overworld",
"Anywhere", "Start with", "Vanilla" };
// 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* randoShuffleBossKeys[6] = { "Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere" };
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)" };
@ -4076,22 +4184,90 @@ void DrawRandoEditor(bool& open) {
SohImGui::EnhancementCombobox("gRandomizeShuffleDungeonReward", randoShuffleDungeonRewards, 4, 0);
PaddedSeparator();
// RANDOTODO implement ganon's boss key outside of ganon's castle
// 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"
"\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, 2);
PaddedSeparator();
// Gerudo Keys
ImGui::Text(Settings::GerudoKeys.GetName().c_str());
InsertHelpHoverText(
"Vanilla - Thieve's Hideout Keys will appear in their vanilla locations.\n"
"\n"
"Any dungeon - Thieve's Hideout Keys can only appear inside of any dungon.\n"
"\n"
"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();
// 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"
"\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, 2);
PaddedSeparator();
// 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, 3,
0);
SohImGui::EnhancementCombobox("gRandomizeShuffleGanonBossKey", randoShuffleGanonsBossKey, 6, 1);
PaddedSeparator();
// Start with Maps & Compasses
SohImGui::EnhancementCheckbox(Settings::MapsAndCompasses.GetName().c_str(), "gRandomizeStartingMapsCompasses");
ImGui::Text(Settings::MapsAndCompasses.GetName().c_str());
InsertHelpHoverText(
"Start with - You will start with Maps & Compasses from all dungeons.\n"
"\n"
"Vanilla - Maps & Compasses will appear in their vanilla locations.\n"
"\n"
"Own dungeon - Maps & Compasses can only appear in their respective dungeon.\n"
"\n"
"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, 2);
ImGui::PopItemWidth();
ImGui::EndTable();
@ -4460,6 +4636,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();

View File

@ -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,
@ -984,6 +984,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,

View File

@ -1751,29 +1751,6 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) {
}
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;
}
}
}
if (gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex] < 0) {
gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex] = 1;
return ITEM_NONE;
@ -1781,6 +1758,100 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) {
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_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;
case ITEM_GERUDO_FORTRESS_SMALL_KEY:
mapIndex = SCENE_GERUDOWAY;
break;
case ITEM_GANONS_CASTLE_SMALL_KEY:
mapIndex = SCENE_GANONTIKA;
break;
}
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 {
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)) {
if (CUR_UPG_VALUE(UPG_QUIVER) == 0) {
Inventory_ChangeUpgrade(UPG_QUIVER, 1);
@ -2294,6 +2365,13 @@ u8 Item_CheckObtainability(u8 item) {
} else {
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)
) {
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) {

View File

@ -416,6 +416,95 @@ void GiveLinkDungeonReward(GetItemID getItemId) {
}
}
void GiveLinkDungeonItem(GetItemID getItemId) {
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;
case GI_GERUDO_FORTRESS_SMALL_KEY:
mapIndex = SCENE_GERUDOWAY;
break;
case GI_GANONS_CASTLE_SMALL_KEY:
mapIndex = SCENE_GANONTIKA;
break;
}
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 {
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;
}
}
void GiveLinksPocketMedallion() {
GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(RC_LINKS_POCKET, RG_NONE);
@ -689,11 +778,12 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) {
INV_CONTENT(ITEM_OCARINA_FAIRY) = ITEM_OCARINA_FAIRY;
}
if(Randomizer_GetSettingValue(RSK_STARTING_MAPS_COMPASSES)) {
// "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;
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;
}
}
@ -790,6 +880,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) ||
(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;
@ -816,9 +913,31 @@ 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;
// "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
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
}
// "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
gSaveContext.inventory.dungeonItems[SCENE_MIZUSIN] |= 1; // Water
gSaveContext.inventory.dungeonItems[SCENE_JYASINZOU] |= 1; // Spirit
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;
}
HIGH_SCORE(HS_POE_POINTS) = 1000 - (100 * Randomizer_GetSettingValue(RSK_BIG_POE_COUNT));

View File

@ -656,6 +656,45 @@ 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, 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, 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, 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, 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,
};