Merge branch 'get-item-rework' into get-item-rework-rando-next

This commit is contained in:
Christopher Leggett 2022-08-21 17:04:53 -04:00
commit d8e7a247f4
No known key found for this signature in database
GPG Key ID: 7093AE5FF7037D79
6 changed files with 486 additions and 255 deletions

View File

@ -83,48 +83,6 @@ Randomizer::~Randomizer() {
this->itemLocations.clear(); this->itemLocations.clear();
} }
std::unordered_map<s16, s16> getItemIdToItemId = {
{ GI_BOW, ITEM_BOW },
{ GI_ARROW_FIRE, ITEM_ARROW_FIRE },
{ GI_DINS_FIRE, ITEM_DINS_FIRE },
{ GI_SLINGSHOT, ITEM_SLINGSHOT },
{ GI_OCARINA_FAIRY, ITEM_OCARINA_FAIRY },
{ GI_OCARINA_OOT, ITEM_OCARINA_TIME },
{ GI_HOOKSHOT, ITEM_HOOKSHOT },
{ GI_LONGSHOT, ITEM_LONGSHOT },
{ GI_ARROW_ICE, ITEM_ARROW_ICE },
{ GI_FARORES_WIND, ITEM_FARORES_WIND },
{ GI_BOOMERANG, ITEM_BOOMERANG },
{ GI_LENS, ITEM_LENS },
{ GI_HAMMER, ITEM_HAMMER },
{ GI_ARROW_LIGHT, ITEM_ARROW_LIGHT },
{ GI_NAYRUS_LOVE, ITEM_NAYRUS_LOVE },
{ GI_BOTTLE, ITEM_BOTTLE },
{ GI_POTION_RED, ITEM_POTION_RED },
{ GI_POTION_GREEN, ITEM_POTION_GREEN },
{ GI_POTION_BLUE, ITEM_POTION_BLUE },
{ GI_FAIRY, ITEM_FAIRY },
{ GI_FISH, ITEM_FISH },
{ GI_MILK_BOTTLE, ITEM_MILK_BOTTLE },
{ GI_LETTER_RUTO, ITEM_LETTER_RUTO },
{ GI_BLUE_FIRE, ITEM_BLUE_FIRE },
{ GI_BUGS, ITEM_BUG },
{ GI_BIG_POE, ITEM_BIG_POE },
{ GI_POE, ITEM_POE },
{ GI_WEIRD_EGG, ITEM_WEIRD_EGG },
{ GI_LETTER_ZELDA, ITEM_LETTER_ZELDA },
{ GI_POCKET_EGG, ITEM_POCKET_EGG },
{ GI_COJIRO, ITEM_COJIRO },
{ GI_ODD_MUSHROOM, ITEM_ODD_MUSHROOM },
{ GI_ODD_POTION, ITEM_ODD_POTION },
{ GI_SAW, ITEM_SAW },
{ GI_SWORD_BROKEN, ITEM_SWORD_BROKEN },
{ GI_PRESCRIPTION, ITEM_PRESCRIPTION },
{ GI_FROG, ITEM_FROG },
{ GI_EYEDROPS, ITEM_EYEDROPS },
{ GI_CLAIM_CHECK, ITEM_CLAIM_CHECK }
};
std::unordered_map<std::string, RandomizerGet> SpoilerfileGetNameToEnum = { std::unordered_map<std::string, RandomizerGet> SpoilerfileGetNameToEnum = {
{ "No Item", RG_NONE }, { "No Item", RG_NONE },
{ "Rien", RG_NONE }, { "Rien", RG_NONE },
@ -549,14 +507,6 @@ std::unordered_map<std::string, RandomizerSettingKey> SpoilerfileSettingNameToEn
{ "Timesaver Settings:Enable Glitch-Useful Cutscenes", RSK_ENABLE_GLITCH_CUTSCENES }, { "Timesaver Settings:Enable Glitch-Useful Cutscenes", RSK_ENABLE_GLITCH_CUTSCENES },
}; };
s32 Randomizer::GetItemIDFromGetItemID(s32 getItemId) {
if (getItemIdToItemId.count(getItemId) == 0) {
return -1;
}
return getItemIdToItemId[getItemId];
}
std::string sanitize(std::string stringValue) { std::string sanitize(std::string stringValue) {
// Add backslashes. // Add backslashes.
for (auto i = stringValue.begin();;) { for (auto i = stringValue.begin();;) {
@ -824,49 +774,13 @@ void Randomizer::ParseRandomizerSettingsFile(const char* spoilerFileName) {
gSaveContext.randoSettings[index].value = 3; gSaveContext.randoSettings[index].value = 3;
} }
break; break;
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") {
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: case RSK_GANONS_BOSS_KEY:
if(it.value() == "Vanilla") { if(it.value() == "Start With") {
gSaveContext.randoSettings[index].value = 0; gSaveContext.randoSettings[index].value = 0;
} else if(it.value() == "Own dungeon") { } else if(it.value() == "Vanilla") {
gSaveContext.randoSettings[index].value = 1; gSaveContext.randoSettings[index].value = 1;
} else if(it.value() == "Start with") { } else if(it.value() == "Own Dungeon") {
gSaveContext.randoSettings[index].value = 2; 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; break;
case RSK_SKIP_CHILD_ZELDA: case RSK_SKIP_CHILD_ZELDA:
@ -1336,6 +1250,51 @@ s16 Randomizer::GetItemFromGet(RandomizerGet randoGet, GetItemID ogItemId) {
return GI_BOTTLE; return GI_BOTTLE;
case RG_BOTTLE_WITH_MILK: case RG_BOTTLE_WITH_MILK:
return GI_MILK_BOTTLE; return GI_MILK_BOTTLE;
// todo implement dungeon-specific maps/compasses
case RG_DEKU_TREE_MAP:
case RG_DODONGOS_CAVERN_MAP:
case RG_JABU_JABUS_BELLY_MAP:
case RG_FOREST_TEMPLE_MAP:
case RG_FIRE_TEMPLE_MAP:
case RG_WATER_TEMPLE_MAP:
case RG_SPIRIT_TEMPLE_MAP:
case RG_SHADOW_TEMPLE_MAP:
case RG_BOTTOM_OF_THE_WELL_MAP:
case RG_ICE_CAVERN_MAP:
return GI_MAP;
case RG_DEKU_TREE_COMPASS:
case RG_DODONGOS_CAVERN_COMPASS:
case RG_JABU_JABUS_BELLY_COMPASS:
case RG_FOREST_TEMPLE_COMPASS:
case RG_FIRE_TEMPLE_COMPASS:
case RG_WATER_TEMPLE_COMPASS:
case RG_SPIRIT_TEMPLE_COMPASS:
case RG_SHADOW_TEMPLE_COMPASS:
case RG_BOTTOM_OF_THE_WELL_COMPASS:
case RG_ICE_CAVERN_COMPASS:
return GI_COMPASS;
// todo implement dungeon-specific keys/keyrings
case RG_FOREST_TEMPLE_BOSS_KEY:
case RG_FIRE_TEMPLE_BOSS_KEY:
case RG_WATER_TEMPLE_BOSS_KEY:
case RG_SPIRIT_TEMPLE_BOSS_KEY:
case RG_SHADOW_TEMPLE_BOSS_KEY:
case RG_GANONS_CASTLE_BOSS_KEY:
return GI_KEY_BOSS;
case RG_FOREST_TEMPLE_SMALL_KEY:
case RG_FIRE_TEMPLE_SMALL_KEY:
case RG_WATER_TEMPLE_SMALL_KEY:
case RG_SPIRIT_TEMPLE_SMALL_KEY:
case RG_SHADOW_TEMPLE_SMALL_KEY:
case RG_BOTTOM_OF_THE_WELL_SMALL_KEY:
case RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY:
case RG_GERUDO_FORTRESS_SMALL_KEY:
case RG_GANONS_CASTLE_SMALL_KEY:
return GI_KEY_SMALL;
// todo test this with keys in own dungeon // todo test this with keys in own dungeon
case RG_TREASURE_GAME_SMALL_KEY: case RG_TREASURE_GAME_SMALL_KEY:
@ -1431,8 +1390,8 @@ s16 Randomizer::GetItemFromGet(RandomizerGet randoGet, GetItemID ogItemId) {
return randoGet; return randoGet;
} }
return ogItemId; return ogItemId;
}
} }
}
bool Randomizer::IsItemVanilla(RandomizerGet randoGet) { bool Randomizer::IsItemVanilla(RandomizerGet randoGet) {
switch (randoGet) { switch (randoGet) {
@ -3078,10 +3037,134 @@ void DrawRandoEditor(bool& open) {
InsertHelpHoverText( InsertHelpHoverText(
"Sets whether or not Ganon's Castle Trials are required to enter Ganon's Tower."); "Sets whether or not Ganon's Castle Trials are required to enter Ganon's Tower.");
} }
ImGui::PopItemWidth();
// COLUMN 2 - Shuffle Settings
ImGui::TableNextColumn(); ImGui::TableNextColumn();
window->DC.CurrLineTextBaseOffset = 0.0f;
// COLUMN 2 - WORLD SETTINGS
// ImGui::NewLine();
// SohImGui::EnhancementCheckbox("Randomize All World Settings", "gRandomizeAllWorldSettings");
// InsertHelpHoverText("Randomize all World Settings");
// ImGui::Separator();
// if (CVar_GetS32("gRandomizeAllWorldSettings", 0) != 1) {
// todo implement starting age
// Starting Age
// ImGui::Text("Starting Age");
// InsertHelpHoverText(
// "Choose which age Link will start as.\nStarting as adult means you start with the "
// "Master Sword in your inventory.\nOnly the child option is compatible with "
// "Closed Forest.");
// SohImGui::EnhancementCombobox("gRandomizeStartingAge", randoStartingAge, 3, 0);
// ImGui::Separator();
// todo implement entrance shuffle
// Shuffle Entrances
// ImGui::Text("Shuffle Entrances");
// InsertHelpHoverText("Shuffle where the entrances between areas lead to.\n"
// "If turned on, select which kinds of entrances you "
// "want shuffled in the options below.\n Note that some "
// "types of entrances can have widly varying generation times.");
// SohImGui::EnhancementCombobox("gRandomizeShuffleEntrances", randoShuffleEntrances, 2, 0);
// if (CVar_GetS32("gRandomizeShuffleEntrances", 0) == 1) {
// ImGui::Indent();
// ImGui::Text("Shuffle Dungeons Entrances");
// InsertHelpHoverText(
// "Shuffle the pool of dungeon entrances, including Bottom of the Well, Ice Cavern and "
// "Gerudo Training Grounds\nGanon's Castle is not shuffled.\nAdditionally, the entrance "
// "of Deku Tree, Fire Temple and Bottom of the Well are open for both adult and child.");
// SohImGui::EnhancementCombobox("gRandomizeShuffleDungeonsEntrances",
// randoShuffleDungeonsEntrances, 2, 0);
// ImGui::Text("Shuffle Overworld Entrances");
// InsertHelpHoverText(
// "Shuffle the pool of Overworld entrances, which corresponds to almost all loading "
// "zones between Overworld areas.\nSome entrances are unshuffled to avoid issues:\n"
// "- Hyrule Castle Courtyard and Garden entrance\n"
// "- Both Market Back Alley entrances\n"
// "- Gerudo Valley to Lake Hylia (unless entrances are decoupled)");
// SohImGui::EnhancementCombobox("gRandomizeShuffleOverworldEntrances",
// randoShuffleOverworldEntrances, 2, 0);
// ImGui::Text("Shuffle Interiors Entrances");
// InsertHelpHoverText("Interior entrances will not be shuffled.");
// SohImGui::EnhancementCombobox("gRandomizeShuffleInteriorsEntrances",
// randoShuffleInteriorsEntrances, 2, 0);
// ImGui::Text("Shuffle Grottos Entrances");
// InsertHelpHoverText(
// "Shuffle the pool of grotto entrances, including all graves, small Fairy "
// "fountains and the Lost Woods Stage.");
// SohImGui::EnhancementCombobox("gRandomizeShuffleGrottosEntrances",
// randoShuffleGrottosEntrances, 2, 0);
// ImGui::Unindent();
// }
// ImGui::Separator();
// todo can't do this until bowling is unlocked by chus
// Bombchus in Logic
// ImGui::Text("Bombchus in Logic");
// InsertHelpHoverText(
// "Bombchus are properly considered in logic.\nThey can be replenished in shops or "
// "through bombchu drops, if those are enabled.\nBombchu Bowling is opened by bombchus.");
// SohImGui::EnhancementCombobox("gRandomizeBombchusInLogic", randoBombchusInLogic, 3, 0);
// ImGui::Separator();
// todo implement chu drops
// Ammo Drops
// ImGui::Text("Ammo Drops");
// switch (CVar_GetS32("gRandomizeAmmoDrops", 0)) {
// case 0:
// InsertHelpHoverText(
// "Bombs, arrows, seeds, nuts, sticks and magic jars appear as normal.\n"
// "Bombchus can sometimes replace bomb drops.");
// break;
// case 1:
// InsertHelpHoverText(
// "All ammo drops will be replaced by blue rupees, except for Deku Sticks.\n"
// "Ammo upgrades will only refill ammo by 10 units.");
// break;
// case 2:
// InsertHelpHoverText(
// "Bombs, arrow, seeds, nuts, sticks and magic jars appear as normal.");
// break;
// }
// SohImGui::EnhancementCombobox("gRandomizeAmmoDrops", randoAmmoDrops, 3, 0);
// ImGui::Separator();
// todo implement drop replacements
// Heart Drops and Refills
// ImGui::Text("Heart Drops and Refills");
// switch (CVar_GetS32("gRandomizeHeartDropsAndRefills", 0)) {
// case 0:
// InsertHelpHoverText(
// "Heart drops will appear as normal.\nHealth upgrades fully heal Link when "
// "picked up.\nFairies heal Link as normal.");
// break;
// case 1:
// InsertHelpHoverText(
// "Heart drops will be replaced by green rupees.\nHealth upgrades fully heal "
// "Link when picked up.\nFairies heal Link as normal.");
// break;
// case 2:
// InsertHelpHoverText(
// "Heart drops will appear as normal.\nHealth upgrades don't heal Link when "
// "picked up.\nFairies heal Link by only 3 hearts.");
// break;
// case 3:
// InsertHelpHoverText(
// "Heart drops will be replaced by green rupees.\nHealth upgrades don't heal "
// "Link when picked up.\nFairies heal Link by only 3 hearts.");
// break;
// }
// SohImGui::EnhancementCombobox("gRandomizeHeartDropsAndRefills", randoHeartDropsAndRefills, 4,
// 0);
// ImGui::Separator();
// }
// ImGui::TableNextColumn();
// COLUMN 3
// Randomize Settings
//ImGui::NewLine();
// SohImGui::EnhancementCheckbox("Randomize All Shuffle Settings", "gRandomizeAllShuffleSettings");
// InsertHelpHoverText("Randomize all Shuffle Settings");
// ImGui::Separator();
ImGui::PushItemWidth(-FLT_MIN); ImGui::PushItemWidth(-FLT_MIN);
if (CVar_GetS32("gRandomizeAllShuffleSettings", 0) != 1) { if (CVar_GetS32("gRandomizeAllShuffleSettings", 0) != 1) {
@ -3166,56 +3249,62 @@ void DrawRandoEditor(bool& open) {
PaddedSeparator(); PaddedSeparator();
} }
// Shuffle Weird Egg // hide this option if we're skipping child zelda
// Disabled when Skip Child Zelda is active if(CVar_GetS32("gRandomizeSkipChildZelda", 0) == 0) {
if (!disableEditingRandoSettings) { // Shuffle Weird Egg
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, CVar_GetS32("gRandomizeSkipChildZelda", 0)); ImGui::Text("Shuffle Weird Egg");
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, InsertHelpHoverText(
ImGui::GetStyle().Alpha * "Enabling this shuffles the Weird Egg from Malon into the item pool.\nThis "
(CVar_GetS32("gRandomizeSkipChildZelda", 0) ? 0.5f : 1.0f)); "will require finding the Weird Egg to talk to Zelda in Hyrule Castle which "
"in turn unlocks rewards from Impa, Saria, Malon and Talon as well as the "
"Happy Mask Sidequest.\nThe Weird egg is also required for Zelda's Letter to "
"unlock the Kakariko Gate as child which can lock some progression.");
SohImGui::EnhancementCombobox("gRandomizeShuffleWeirdEgg", randoShuffleWeirdEgg, 2, 0);
ImGui::Separator();
} }
SohImGui::EnhancementCheckbox(Settings::ShuffleWeirdEgg.GetName().c_str(), "gRandomizeShuffleWeirdEgg");
if (!disableEditingRandoSettings) {
ImGui::PopStyleVar();
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) &&
CVar_GetS32("gRandomizeSkipChildZelda", 0)) {
ImGui::SetTooltip("%s",
"This option is disabled because \"Skip Child Zelda\" is enabled");
}
ImGui::PopItemFlag();
}
InsertHelpHoverText(
"Shuffles the Weird Egg from Malon in to the item pool. Enabling "
"\"Skip Child Zelda\" disables this feature.\n"
"\n"
"The Weird Egg is required to unlock several events:\n"
" - Zelda's Lullaby from Impa\n"
" - Saria's song in Sacred Forest Meadow\n"
" - Epona's song and chicken minigame at Lon Lon Ranch\n"
" - Zelda's letter for Kakariko gate (if set to closed)\n"
" - Happy Mask Shop sidequest\n"
);
PaddedSeparator();
// Shuffle Gerudo Membership Card // Shuffle Gerudo Membership Card
SohImGui::EnhancementCheckbox(Settings::ShuffleGerudoToken.GetName().c_str(), "gRandomizeShuffleGerudoToken"); SohImGui::EnhancementCheckbox(Settings::ShuffleGerudoToken.GetName().c_str(), "gRandomizeShuffleGerudoToken");
InsertHelpHoverText( InsertHelpHoverText(
"Shuffles the Gerudo Membership Card into the item pool.\n" "Enabling this shuffles the Gerudo Membership Card into the item pool.\nThe Gerudo "
"\n" "Token is required to enter the Gerudo Training Ground.");
"The Gerudo Card is required to enter the Gerudo Training Grounds, opening " SohImGui::EnhancementCombobox("gRandomizeShuffleGerudoToken", randoShuffleGerudoToken, 2, 0);
"the gate to Haunted Wasteland and the Horseback Archery minigame." ImGui::Separator();
);
PaddedSeparator();
// Shuffle Frog Song Rupees // todo implement magic bean 10 pack
SohImGui::EnhancementCheckbox(Settings::ShuffleFrogSongRupees.GetName().c_str(), "gRandomizeShuffleFrogSongRupees"); // // Shuffle Magic Beans
InsertHelpHoverText( // ImGui::Text("Shuffle Magic Beans");
"Shuffles 5 Purple Rupees into to the item pool, and allows\n" // InsertHelpHoverText("Enabling this adds a pack of 10 beans to the item "
"you to earn items by playing songs at the Frog Choir.\n" // "pool and changes the Magic Bean Salesman to sell a "
"\n" // "random item at a price of 60 rupees.");
"This setting does not effect the item earned from playing\n" // SohImGui::EnhancementCombobox("gRandomizeShuffleMagicBeans", randoShuffleMagicBeans, 2, 0);
"the Song of Storms and the frog song minigame." // ImGui::Separator();
);
// todo implement shuffle merchants
// // Shuffle Merchants
// ImGui::Text("Shuffle Merchants");
// if (CVar_GetS32("gRandomizeShuffleMerchants", 0) == 0) {
// InsertHelpHoverText(
// "Enabling this adds a Giant's Knife and a pack of Bombchus to the item "
// "pool and changes both Mediagoron and the Haunted Wasteland "
// "Carpet Salesman to sell a random item once at the price of 200 rupees.");
// } else if (CVar_GetS32("gRandomizeShuffleMerchants", 0) <= 2) {
// InsertHelpHoverText(
// "These hints will make Medigoron and the Carpet salesman tell you which item they're "
// "selling.\nThe Clearer Hints setting will affect how they refer to the item.");
// }
// SohImGui::EnhancementCombobox("gRandomizeShuffleMerchants", randoShuffleMerchants, 3, 0);
// ImGui::Separator();
// todo implement adult trade item selection
// Shuffle Adult Trade
// ImGui::Text("Shuffle Adult Trade");
// InsertHelpHoverText(
// "Enabling this adds all of the adult trade quest items to the pool, each of which can be "
// "traded for a unique reward.\nYou will be able to choose which of your adult trade items "
// "are visible in the inventory by selecting the item and using the L and R buttons.\n"
// "If disabled only the Claim Check will be found in the pool.");
// SohImGui::EnhancementCombobox("gRandomizeShuffleAdultTrade", randoShuffleAdultTrade, 2, 0);
} }
ImGui::PopItemWidth(); ImGui::PopItemWidth();
@ -3224,109 +3313,227 @@ void DrawRandoEditor(bool& open) {
window->DC.CurrLineTextBaseOffset = 0.0f; window->DC.CurrLineTextBaseOffset = 0.0f;
ImGui::PushItemWidth(-FLT_MIN); ImGui::PushItemWidth(-FLT_MIN);
// Shuffle Dungeon Rewards // // COLUMN 4 - SHUFFLE DUNGEON ITEMS
ImGui::Text(Settings::ShuffleRewards.GetName().c_str()); // ImGui::NewLine();
InsertHelpHoverText( // SohImGui::EnhancementCheckbox("Randomize All Shuffle Dungeon Items Settings",
"Shuffles the location of spiritual stones and medallions.\n" // "gRandomizeAllShuffleDungeonItemsettings");
"\n" // InsertHelpHoverText("Randomize all Dungeon Shuffle Settings");
"End of dungeons - Spiritual stones and medallions will be given as rewards " // ImGui::Separator();
"for beating major dungeons. Link will always start with one stone or medallion.\n"
"\n"
"Any dungeon - Spiritual stones and medallions can be found inside any dungeon.\n"
"\n"
"Overworld - Spiritual stones and medallions can only be found outside of dungeons.\n"
"\n"
"Anywhere - Spiritual stones and medallions can appear anywhere."
);
SohImGui::EnhancementCombobox("gRandomizeShuffleDungeonReward", randoShuffleDungeonRewards, 4, 0);
PaddedSeparator();
// Maps & Compasses // if (CVar_GetS32("gRandomizeAllShuffleDungeonItemsettings", 0) != 1) {
ImGui::Text(Settings::MapsAndCompasses.GetName().c_str()); // todo implement maps/compasses outside of own dungeon
InsertHelpHoverText( // Maps / Compasses
"Start with - You will start with Maps & Compasses from all dungeons.\n" // ImGui::Text("Maps / Compasses");
"\n" // switch (CVar_GetS32("gRandomizeShuffleMapsAndCompasses", 0)) {
"Vanilla - Maps & Compasses will appear in their vanilla locations.\n" // case 0:
"\n" // InsertHelpHoverText("Maps and Compasses can only appear in their respective dungeon.");
"Own dungeon - Maps & Compasses can only appear in their respective dungeon.\n" // break;
"\n" // case 1:
"Any dungeon - Maps & Compasses can only appear inside of any dungon.\n" // InsertHelpHoverText(
"\n" // "Maps and Compasses can only appear in a dungeon but not necessarily the "
"Overworld - Maps & Compasses can only appear outside of dungeons.\n" // "dungeon they are for.");
"\n" // break;
"Anywhere - Maps & Compasses can appear anywhere in the world." // case 2:
); // InsertHelpHoverText("Maps and Compasses can only appear outside of dungeons.");
SohImGui::EnhancementCombobox("gRandomizeStartingMapsCompasses", randoShuffleMapsAndCompasses, 6, 2); // break;
PaddedSeparator(); // case 3:
// InsertHelpHoverText("Maps and Compasses can appear anywhere in the world.");
// break;
// case 4:
// InsertHelpHoverText(
// "Maps and Compasses are given to you from the start.\nThis will add a "
// "small amount of money and refill items to the pool.");
// break;
// case 5:
// InsertHelpHoverText("Maps and Compasses will appear in their vanilla locations.");
// break;
// }
// SohImGui::EnhancementCombobox("gRandomizeShuffleMapsAndCompasses", randoShuffleMapsAndCompasses,
// 6, 0);
// ImGui::Separator();
// Keysanity // todo implement small keys outside their own dungeons
ImGui::Text(Settings::Keysanity.GetName().c_str()); // // Small Keys
InsertHelpHoverText( // ImGui::Text("Small Keys");
"Start with - You will start with all Small Keys from all dungeons.\n" // switch (CVar_GetS32("gRandomizeShuffleSmallKeys", 0)) {
"\n" // case 0:
"Vanilla - Small Keys will appear in their vanilla locations.\n" // InsertHelpHoverText("Small Keys can only appear in their respective dungeon.");
"\n" // break;
"Own dungeon - Small Keys can only appear in their respective dungeon.\n" // case 1:
"\n" // InsertHelpHoverText(
"Any dungeon - Small Keys can only appear inside of any dungon.\n" // "Small Keys can only appear inside of any dungon, but won't necessarily "
"\n" // "be in the dungeon that the key is for.\nA difficult mode since it is "
"Overworld - Small Keys can only appear outside of dungeons.\n" // "more likely to need to enter a dungeon multiple times.");
"\n" // break;
"Anywhere - Small Keys can appear anywhere in the world." // case 2:
); // InsertHelpHoverText(
SohImGui::EnhancementCombobox("gRandomizeKeysanity", randoShuffleSmallKeys, 6, 2); // "Small Keys can only appear outside of dungeons.\nYou may need to enter a "
PaddedSeparator(); // "dungeon multiple times to gain items to access the overworld locations "
// "with the keys required to finish a dungeon.");
// break;
// case 3:
// InsertHelpHoverText(
// "Small Keys can appear anywhere in the world.\nA difficult mode since it "
// "is more likely to need to enter a dungeon multiple times.");
// break;
// case 4:
// InsertHelpHoverText(
// "Small Keys are given to you from the start so you won't have to worry "
// "about locked doors.\nAn easier mode.");
// break;
// case 5:
// InsertHelpHoverText("Small Keys will appear in their vanilla locations.");
// break;
// }
// SohImGui::EnhancementCombobox("gRandomizeShuffleSmallKeys", randoShuffleSmallKeys, 6, 0);
// ImGui::Separator();
// Gerudo Keys // todo implement gf keys outside of gf
ImGui::Text(Settings::GerudoKeys.GetName().c_str()); // // Gerudo Fortress Keys
InsertHelpHoverText( // ImGui::Text("Gerudo Fortress Keys");
"Vanilla - Thieve's Hideout Keys will appear in their vanilla locations.\n" // switch (CVar_GetS32("gRandomizeShuffleGerudoFortressKeys", 0)) {
"\n" // case 0:
"Any dungeon - Thieve's Hideout Keys can only appear inside of any dungon.\n" // InsertHelpHoverText(
"\n" // "Gerudo Fortress Keys will appear in their vanilla location dropping from "
"Overworld - Thieve's Hideout Keys can only appear outside of dungeons.\n" // "fighting Gerudo guards that attack when trying to free the jailed carpenters.");
"\n" // break;
"Anywhere - Thieve's Hideout Keys can appear anywhere in the world." // case 1:
); // InsertHelpHoverText("Gerudo Fortress Keys can only appear inside of dungeons.");
SohImGui::EnhancementCombobox("gRandomizeGerudoKeys", randoShuffleGerudoFortressKeys, 4, 0); // break;
PaddedSeparator(); // case 2:
// InsertHelpHoverText("Gerudo Fortress Keys can only appear outside of dungeons.");
// break;
// case 3:
// InsertHelpHoverText("Gerudo Fortress Keys can appear anywhere in the world.");
// break;
// }
// SohImGui::EnhancementCombobox("gRandomizeShuffleGerudoFortressKeys",
// randoShuffleGerudoFortressKeys, 4, 0);
// ImGui::Separator();
// Boss Keysanity // todo implement boss keys outside of own dungeon
ImGui::Text(Settings::BossKeysanity.GetName().c_str()); // // Boss Keys
InsertHelpHoverText( // ImGui::Text("Boss Keys");
"Start with - You will start with Boss keys from all dungeons.\n" // switch (CVar_GetS32("gRandomizeShuffleBossKeys", 0)) {
"\n" // case 0:
"Vanilla - Boss Keys will appear in their vanilla locations.\n" // InsertHelpHoverText("Boss Keys can only appear in their respective dungeons.");
"\n" // break;
"Own dungeon - Boss Keys can only appear in their respective dungeon.\n" // case 1:
"\n" // InsertHelpHoverText(
"Any dungeon - Boss Keys can only appear inside of any dungon.\n" // "Boss Keys can only appear inside of any dungeon, but won't necessarily "
"\n" // "be in the dungon that the key is for.\nA difficult mode since it is "
"Overworld - Boss Keys can only appear outside of dungeons.\n" // "more likely to need to enter a dungeon multiple times.");
"\n" // break;
"Anywhere - Boss Keys can appear anywhere in the world." // case 2:
); // InsertHelpHoverText(
SohImGui::EnhancementCombobox("gRandomizeBossKeysanity", randoShuffleBossKeys, 6, 2); // "Boss Keys can only appear outside of dungeons.\nYou may need to enter a dungeon "
PaddedSeparator(); // "without the boss key to get items required to find the key in the overworld.");
// break;
// case 3:
// InsertHelpHoverText(
// "Boss Keys can appear anywhere in the overworld.\nA difficult mode since it "
// "is more likely to need to enter a dungeon multiple times.");
// break;
// case 4:
// InsertHelpHoverText(
// "Boss Keys are given to you from the start so you won't have to worry "
// "about boss doors.\nAn easier mode.");
// break;
// case 5:
// InsertHelpHoverText("Boss Keys will appear in their vanilla locations.");
// break;
// }
// SohImGui::EnhancementCombobox("gRandomizeShuffleBossKeys", randoShuffleBossKeys, 6, 0);
// ImGui::Separator();
// Ganon's Boss Key // RANDOTODO implement ganon's boss key outside of ganon's castle
ImGui::Text(Settings::GanonsBossKey.GetName().c_str()); // Ganon's Boss Key
InsertHelpHoverText( ImGui::PushItemWidth(-FLT_MIN);
"Vanilla - Ganon's Boss Key will appear in the vanilla location.\n" ImGui::Text("Ganon's Boss Key");
"\n" SohImGui::EnhancementCombobox("gRandomizeShuffleGanonBossKey", randoShuffleGanonsBossKey, 3,
"Own dungeon - Ganon's Boss Key can appear anywhere inside Ganon's Castle.\n" 0);
"\n" switch (CVar_GetS32("gRandomizeShuffleGanonBossKey", 0)) {
"Start with - Places Ganon's Boss Key in your starting inventory." case 0:
"\n" SetLastItemHoverText(
"Any dungeon - Ganon's Boss Key Key can only appear inside of any dungon.\n" "Ganon's Boss Key is given to you from the start and you don't "
"\n" "have to worry about finding it.");
"Overworld - Ganon's Boss Key Key can only appear outside of dungeons.\n" break;
"\n" case 1:
"Anywhere - Ganon's Boss Key Key can appear anywhere in the world." SetLastItemHoverText("Ganon's Boss Key will appear in the vanilla location.");
); break;
SohImGui::EnhancementCombobox("gRandomizeShuffleGanonBossKey", randoShuffleGanonsBossKey, 6, 1); case 2:
SetLastItemHoverText("Ganon's Boss Key will appear somewhere inside Ganon's Castle.");
ImGui::PopItemWidth(); break;
// case 0:
// SetLastItemHoverText(
// "Ganon's Castle Boss Key can only appear inside of a dungeon, but not "
// "necessarily Ganon's Castle.");
// break;
// case 1:
// SetLastItemHoverText("Ganon's Castle Boss Key can only appear outside of dungeons.");
// break;
// case 2:
// SetLastItemHoverText("Ganon's Castle Boss Key can appear anywhere in the world.");
// break;
// case 3:
// SetLastItemHoverText(
// "These settings put the boss key on the Light Arrow Cutscene location, "
// "from Zelda in Temple of Time as adult, with differing requirements.");
// break;
// case 4:
// SetLastItemHoverText("Ganon's Castle Boss Key can appear anywhere in the world.");
// break;
// case 5:
// SetLastItemHoverText(
// "These settings put the boss key on the Light Arrow Cutscene location, "
// "from Zelda in Temple of Time as adult, with differing requirements.");
// SohImGui::EnhancementSliderInt("Medallion Count: %d", "##RandoGanonMedallionCount",
// "gRandomizeGanonMedallionCount", 0, 6, "");
// InsertHelpHoverText(
// "Set the number of Medallions required to trigger the Light Arrow Cutscene.");
// break;
// case 6:
// SetLastItemHoverText(
// "These settings put the boss key on the Light Arrow Cutscene location, "
// "from Zelda in Temple of Time as adult, with differing requirements.");
// SohImGui::EnhancementSliderInt("Stone Count: %d", "##RandoGanonStoneCount",
// "gRandomizeGanonStoneCount", 0, 3, "");
// InsertHelpHoverText("Set the number of Spiritual Stones required to trigger the Light "
// "Arrow Cutscene.");
// break;
// case 7:
// SetLastItemHoverText(
// "These settings put the boss key on the Light Arrow Cutscene location, "
// "from Zelda in Temple of Time as adult, with differing requirements.");
// SohImGui::EnhancementSliderInt("Reward Count: %d", "##RandoGanonRewardCount",
// "gRandomizeGanonRewardCount", 0, 9, "");
// InsertHelpHoverText(
// "Set the number of Dungeon Rewards (Spiritual Stones and Medallions) "
// "required to trigger the Light Arrow Cutscene.");
// break;
// case 8:
// SetLastItemHoverText(
// "These settings put the boss key on the Light Arrow Cutscene location, "
// "from Zelda in Temple of Time as adult, with differing requirements.");
// SohImGui::EnhancementSliderInt("MDungeon Count: %d", "##RandoGanonDungeonCount",
// "gRandomizeGanonDungeonCount", 0, 8, "");
// InsertHelpHoverText(
// "Set the number of completed dungeons required to trigger the Light Arrow "
// "Cutscene.\nDungeons are considered complete when Link steps into the "
// "blue warp at the end of them.");
// break;
// case 9:
// SetLastItemHoverText(
// "These settings put the boss key on the Light Arrow Cutscene location, "
// "from Zelda in Temple of Time as adult, with differing requirements.");
// SohImGui::EnhancementSliderInt("Token Count: %d", "##RandoGanonTokenCount",
// "gRandomizeGanonTokenCount", 0, 100, "");
// InsertHelpHoverText("Set the number of Gold Skulltula Tokens required to trigger the "
// "Light Arrow Cutscene.");
// break;
}
ImGui::Separator();
ImGui::PopItemWidth();
ImGui::EndTable(); ImGui::EndTable();
} }
ImGui::PopStyleVar(1); ImGui::PopStyleVar(1);
@ -3343,10 +3550,40 @@ void DrawRandoEditor(bool& open) {
ImGui::TableHeadersRow(); ImGui::TableHeadersRow();
ImGui::PopItemFlag(); ImGui::PopItemFlag();
ImGui::TableNextRow(); ImGui::TableNextRow();
// COLUMN 1 - TIME SAVERS
ImGui::TableNextColumn(); ImGui::TableNextColumn();
window->DC.CurrLineTextBaseOffset = 0.0f; // COLUMN 1 - TIME SAVERS
// ImGui::NewLine();
// todo implement minigame repeat skip
// // Skip Minigame repetition
// SohImGui::EnhancementCheckbox("Skip Minigame Repetition", "gRandomizeSkipMinigameRepetition");
// InsertHelpHoverText("Completing the second objective in the Dampe Race and Gerudo Archery on the "
// "first attempt will give both rewards at once for that minigame.");
// ImGui::Separator();
// todo implement free scarecrow (is this already in?)
// // Free scarecrow
// SohImGui::EnhancementCheckbox("Free Scarecrow", "gRandomizeFreeScarecrow");
// InsertHelpHoverText(
// "Pulling the Ocarina near a spot at which Pierre can spawn will do so, without "
// "needing the song.");
// ImGui::Separator();
// todo implement skip poes (did we already?)
// // Skip Four Poes cutscene
// SohImGui::EnhancementCheckbox("Skip Four Poes Cutscene", "gRandomizeSkipFourPoesCutscene");
// InsertHelpHoverText(
// "The cutscene with the 4 poes in Forest Temple will be skipped. If the cutscene "
// "is not skipped, it can be exploited to reach the basement early.");
// ImGui::Separator();
// todo implement skip lake hylia owl
// // Skip Lake Hylia owl
// SohImGui::EnhancementCheckbox("Skip Lake Hylia Owl Cutscene", "gRandomizeSkipLakeHyliaOwl");
// InsertHelpHoverText(
// "The owl flight cutscene in Lake Hylia will be skipped. This cutscene lets you "
// "see what item is on top of the laboratory roof.");
// ImGui::Separator();
// Cuccos to return // Cuccos to return
SohImGui::EnhancementSliderInt("Cuccos to return: %d", "##RandoCuccosToReturn", SohImGui::EnhancementSliderInt("Cuccos to return: %d", "##RandoCuccosToReturn",

View File

@ -1544,10 +1544,6 @@ extern "C" void* getN64WeirdFrame(s32 i) {
return &weirdFrameBytes[i + sizeof(n64WeirdFrames)]; return &weirdFrameBytes[i + sizeof(n64WeirdFrames)];
} }
extern "C" s32 Randomizer_GetItemIDFromGetItemID(s32 getItemId) {
return OTRGlobals::Instance->gRandomizer->GetItemIDFromGetItemID(getItemId);
}
extern "C" void Randomizer_LoadSettings(const char* spoilerFileName) { extern "C" void Randomizer_LoadSettings(const char* spoilerFileName) {
OTRGlobals::Instance->gRandomizer->LoadRandomizerSettings(spoilerFileName); OTRGlobals::Instance->gRandomizer->LoadRandomizerSettings(spoilerFileName);
} }

View File

@ -98,7 +98,6 @@ u8 Randomizer_GetSettingValue(RandomizerSettingKey randoSettingKey);
RandomizerCheck Randomizer_GetCheckFromActor(s16 actorId, s16 actorParams, s16 sceneNum); RandomizerCheck Randomizer_GetCheckFromActor(s16 actorId, s16 actorParams, s16 sceneNum);
void Randomizer_LoadHintLocations(const char* spoilerFileName); void Randomizer_LoadHintLocations(const char* spoilerFileName);
void Randomizer_LoadItemLocations(const char* spoilerFileName, bool silent); void Randomizer_LoadItemLocations(const char* spoilerFileName, bool silent);
s32 Randomizer_GetItemIDFromGetItemID(s32 getItemId); // TODO: Remove me
GetItemEntry Randomizer_GetRandomizedItem(GetItemID ogId, s16 actorId, s16 actorParams, s16 sceneNum); GetItemEntry Randomizer_GetRandomizedItem(GetItemID ogId, s16 actorId, s16 actorParams, s16 sceneNum);
GetItemEntry Randomizer_GetItemFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogId); GetItemEntry Randomizer_GetItemFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogId);
bool Randomizer_ObtainedFreestandingIceTrap(RandomizerCheck randomizerCheck, GetItemID ogId, Actor* actor); bool Randomizer_ObtainedFreestandingIceTrap(RandomizerCheck randomizerCheck, GetItemID ogId, Actor* actor);

View File

@ -509,12 +509,11 @@ void EnItem00_Init(Actor* thisx, GlobalContext* globalCtx) {
break; break;
} }
if ((gSaveContext.n64ddFlag || getItemId != GI_NONE) && !Actor_HasParent(&this->actor, globalCtx)) { if (!Actor_HasParent(&this->actor, globalCtx)) {
getItem = Randomizer_GetRandomizedItem(getItemId, this->actor.id, this->ogParams, globalCtx->sceneNum); if (!gSaveContext.n64ddFlag && getItemId != GI_NONE) {
getItemId = getItem.getItemId;
if (!gSaveContext.n64ddFlag) {
func_8002F554(&this->actor, globalCtx, getItemId); func_8002F554(&this->actor, globalCtx, getItemId);
} else { } else {
getItem = Randomizer_GetRandomizedItem(getItemId, this->actor.id, this->ogParams, globalCtx->sceneNum);
GiveItemEntryFromActorWithFixedRange(&this->actor, globalCtx, getItem); GiveItemEntryFromActorWithFixedRange(&this->actor, globalCtx, getItem);
} }
} }
@ -672,13 +671,13 @@ void func_8001E304(EnItem00* this, GlobalContext* globalCtx) {
void func_8001E5C8(EnItem00* this, GlobalContext* globalCtx) { void func_8001E5C8(EnItem00* this, GlobalContext* globalCtx) {
Player* player = GET_PLAYER(globalCtx); Player* player = GET_PLAYER(globalCtx);
GetItemEntry getItemEntry = Randomizer_GetRandomizedItem(this->getItemId, this->actor.id, this->ogParams, globalCtx->sceneNum);
if (this->getItemId != GI_NONE) { if (this->getItemId != GI_NONE) {
if (!Actor_HasParent(&this->actor, globalCtx)) { if (!Actor_HasParent(&this->actor, globalCtx)) {
if (!gSaveContext.n64ddFlag || getItemEntry.getItemId == GI_NONE) { if (!gSaveContext.n64ddFlag) {
func_8002F434(&this->actor, globalCtx, getItemEntry.getItemId, 50.0f, 80.0f); func_8002F434(&this->actor, globalCtx, this->getItemId, 50.0f, 80.0f);
} else { } else {
GetItemEntry getItemEntry =
Randomizer_GetRandomizedItem(this->getItemId, this->actor.id, this->ogParams, globalCtx->sceneNum);
GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, 50.0f, 80.0f); GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, 50.0f, 80.0f);
} }
this->unk_15A++; this->unk_15A++;

View File

@ -858,7 +858,7 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) {
} else if (giid == GI_NUT_UPGRADE_30 || giid == GI_NUT_UPGRADE_40) { } else if (giid == GI_NUT_UPGRADE_30 || giid == GI_NUT_UPGRADE_40) {
GiveLinkDekuNutUpgrade(giid); GiveLinkDekuNutUpgrade(giid);
} else { } else {
s32 iid = Randomizer_GetItemIDFromGetItemID(giid); s32 iid = getItem.itemId;
if (iid != -1) INV_CONTENT(iid) = iid; if (iid != -1) INV_CONTENT(iid) = iid;
} }
} else if (getItem.modIndex == MOD_RANDOMIZER) { } else if (getItem.modIndex == MOD_RANDOMIZER) {

View File

@ -546,7 +546,7 @@ void EnGe1_WaitTillItemGiven_Archery(EnGe1* this, GlobalContext* globalCtx) {
} }
} }
if (!gSaveContext.n64ddFlag || getItemEntry.getItemId != GI_NONE) { if (!gSaveContext.n64ddFlag || getItemEntry.getItemId == GI_NONE) {
func_8002F434(&this->actor, globalCtx, getItemId, 10000.0f, 50.0f); func_8002F434(&this->actor, globalCtx, getItemId, 10000.0f, 50.0f);
} else { } else {
GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, 10000.0f, 50.0f); GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, 10000.0f, 50.0f);
@ -587,7 +587,7 @@ void EnGe1_BeginGiveItem_Archery(EnGe1* this, GlobalContext* globalCtx) {
} }
} }
if (!gSaveContext.n64ddFlag || getItemEntry.getItemId != GI_NONE) { if (!gSaveContext.n64ddFlag || getItemEntry.getItemId == GI_NONE) {
func_8002F434(&this->actor, globalCtx, getItemId, 10000.0f, 50.0f); func_8002F434(&this->actor, globalCtx, getItemId, 10000.0f, 50.0f);
} else { } else {
GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, 10000.0f, 50.0f); GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, 10000.0f, 50.0f);