Add advanced option for teleport trap (#6986)

This commit is contained in:
Garrett Cox
2026-08-14 15:42:43 -05:00
committed by GitHub
parent e048afd10a
commit fa5172a58b
3 changed files with 223 additions and 4 deletions
+203 -2
View File
@@ -1,5 +1,6 @@
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/ShipInit.hpp"
#include "soh/Enhancements/enhancementTypes.h"
#include "soh/Enhancements/randomizer/SeedContext.h"
#include "soh/Notification/Notification.h"
@@ -42,12 +43,209 @@ const char* altTrapTypeCvars[] = {
CVAR_ENHANCEMENT("ExtraTraps.Kill"), CVAR_ENHANCEMENT("ExtraTraps.Teleport"),
};
const std::array<EntranceIndex, 7> teleportDestinations = {
const std::vector<EntranceIndex> simpleTeleportDestinations = {
ENTR_LINKS_HOUSE_CHILD_SPAWN, ENTR_SACRED_FOREST_MEADOW_WARP_PAD, ENTR_DEATH_MOUNTAIN_CRATER_WARP_PAD,
ENTR_LAKE_HYLIA_WARP_PAD, ENTR_DESERT_COLOSSUS_WARP_PAD, ENTR_GRAVEYARD_WARP_PAD,
ENTR_TEMPLE_OF_TIME_WARP_PAD,
};
// Mirrors the entrances available in rando
const std::vector<EntranceIndex> advancedTeleportDestinations = {
ENTR_DEKU_TREE_ENTRANCE,
ENTR_KOKIRI_FOREST_OUTSIDE_DEKU_TREE,
ENTR_DODONGOS_CAVERN_ENTRANCE,
ENTR_DEATH_MOUNTAIN_TRAIL_OUTSIDE_DODONGOS_CAVERN,
ENTR_JABU_JABU_ENTRANCE,
ENTR_ZORAS_FOUNTAIN_OUTSIDE_JABU_JABU,
ENTR_FOREST_TEMPLE_ENTRANCE,
ENTR_SACRED_FOREST_MEADOW_OUTSIDE_TEMPLE,
ENTR_FIRE_TEMPLE_ENTRANCE,
ENTR_DEATH_MOUNTAIN_CRATER_OUTSIDE_TEMPLE,
ENTR_WATER_TEMPLE_ENTRANCE,
ENTR_LAKE_HYLIA_OUTSIDE_TEMPLE,
ENTR_SPIRIT_TEMPLE_ENTRANCE,
ENTR_DESERT_COLOSSUS_OUTSIDE_TEMPLE,
ENTR_SHADOW_TEMPLE_ENTRANCE,
ENTR_GRAVEYARD_OUTSIDE_TEMPLE,
ENTR_BOTTOM_OF_THE_WELL_ENTRANCE,
ENTR_KAKARIKO_VILLAGE_OUTSIDE_BOTTOM_OF_THE_WELL,
ENTR_ICE_CAVERN_ENTRANCE,
ENTR_ZORAS_FOUNTAIN_OUTSIDE_ICE_CAVERN,
ENTR_GERUDO_TRAINING_GROUND_ENTRANCE,
ENTR_GERUDOS_FORTRESS_OUTSIDE_GERUDO_TRAINING_GROUND,
ENTR_INSIDE_GANONS_CASTLE_ENTRANCE,
ENTR_CASTLE_GROUNDS_RAINBOW_BRIDGE_EXIT,
ENTR_MIDOS_HOUSE_0,
ENTR_KOKIRI_FOREST_OUTSIDE_MIDOS_HOUSE,
ENTR_SARIAS_HOUSE_0,
ENTR_KOKIRI_FOREST_OUTSIDE_SARIAS_HOUSE,
ENTR_TWINS_HOUSE_0,
ENTR_KOKIRI_FOREST_OUTSIDE_TWINS_HOUSE,
ENTR_KNOW_IT_ALL_BROS_HOUSE_0,
ENTR_KOKIRI_FOREST_OUTSIDE_KNOW_IT_ALL_HOUSE,
ENTR_KOKIRI_SHOP_0,
ENTR_KOKIRI_FOREST_OUTSIDE_SHOP,
ENTR_LAKESIDE_LABORATORY_0,
ENTR_LAKE_HYLIA_OUTSIDE_LAB,
ENTR_FISHING_POND_0,
ENTR_LAKE_HYLIA_OUTSIDE_FISHING_POND,
ENTR_CARPENTERS_TENT_0,
ENTR_GERUDO_VALLEY_OUTSIDE_TENT,
ENTR_MARKET_GUARD_HOUSE_0,
ENTR_MARKET_ENTRANCE_OUTSIDE_GUARD_HOUSE,
ENTR_HAPPY_MASK_SHOP_0,
ENTR_MARKET_DAY_OUTSIDE_HAPPY_MASK_SHOP,
ENTR_BOMBCHU_BOWLING_ALLEY_0,
ENTR_MARKET_DAY_OUTSIDE_BOMBCHU_BOWLING,
ENTR_POTION_SHOP_MARKET_0,
ENTR_MARKET_DAY_OUTSIDE_POTION_SHOP,
ENTR_TREASURE_BOX_SHOP_0,
ENTR_MARKET_DAY_OUTSIDE_TREASURE_BOX_SHOP,
ENTR_BOMBCHU_SHOP_1,
ENTR_BACK_ALLEY_DAY_OUTSIDE_BOMBCHU_SHOP,
ENTR_BACK_ALLEY_MAN_IN_GREEN_HOUSE,
ENTR_BACK_ALLEY_DAY_OUTSIDE_MAN_IN_GREEN_HOUSE,
ENTR_KAKARIKO_CENTER_GUEST_HOUSE_0,
ENTR_KAKARIKO_VILLAGE_OUTSIDE_CENTER_GUEST_HOUSE,
ENTR_HOUSE_OF_SKULLTULA_0,
ENTR_KAKARIKO_VILLAGE_OUTSIDE_SKULKLTULA_HOUSE,
ENTR_IMPAS_HOUSE_FRONT,
ENTR_KAKARIKO_VILLAGE_OUTSIDE_IMPAS_HOUSE_FRONT,
ENTR_IMPAS_HOUSE_BACK,
ENTR_KAKARIKO_VILLAGE_OUTSIDE_IMPAS_HOUSE_BACK,
ENTR_POTION_SHOP_GRANNY_0,
ENTR_KAKARIKO_VILLAGE_OUTSIDE_SHOP_GRANNY,
ENTR_GRAVEKEEPERS_HUT_0,
ENTR_GRAVEYARD_OUTSIDE_DAMPES_HUT,
ENTR_GORON_SHOP_0,
ENTR_GORON_CITY_OUTSIDE_SHOP,
ENTR_ZORA_SHOP_0,
ENTR_ZORAS_DOMAIN_OUTSIDE_SHOP,
ENTR_LON_LON_BUILDINGS_TALONS_HOUSE,
ENTR_LON_LON_RANCH_OUTSIDE_TALONS_HOUSE,
ENTR_STABLE_0,
ENTR_LON_LON_RANCH_OUTSIDE_STABLES,
ENTR_LON_LON_BUILDINGS_TOWER,
ENTR_LON_LON_RANCH_OUTSIDE_TOWER,
ENTR_BAZAAR_1,
ENTR_MARKET_DAY_OUTSIDE_BAZAAR,
ENTR_SHOOTING_GALLERY_1,
ENTR_MARKET_DAY_OUTSIDE_SHOOTING_GALLERY,
ENTR_BAZAAR_0,
ENTR_KAKARIKO_VILLAGE_OUTSIDE_BAZAAR,
ENTR_SHOOTING_GALLERY_0,
ENTR_KAKARIKO_VILLAGE_OUTSIDE_SHOOTING_GALLERY,
ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_NAYRUS_COLOSSUS,
ENTR_DESERT_COLOSSUS_GREAT_FAIRY_EXIT,
ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_DINS_HC,
ENTR_CASTLE_GROUNDS_GREAT_FAIRY_EXIT,
ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_OGC_DD,
ENTR_POTION_SHOP_KAKARIKO_1,
ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_DMC,
ENTR_DEATH_MOUNTAIN_CRATER_GREAT_FAIRY_EXIT,
ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_DMT,
ENTR_DEATH_MOUNTAIN_TRAIL_GREAT_FAIRY_EXIT,
ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_FARORES_ZF,
ENTR_ZORAS_FOUNTAIN_OUTSIDE_GREAT_FAIRY,
ENTR_LINKS_HOUSE_1,
ENTR_KOKIRI_FOREST_OUTSIDE_LINKS_HOUSE,
ENTR_TEMPLE_OF_TIME_ENTRANCE,
ENTR_TEMPLE_OF_TIME_EXTERIOR_DAY_OUTSIDE_TEMPLE,
ENTR_WINDMILL_AND_DAMPES_GRAVE_WINDMILL,
ENTR_KAKARIKO_VILLAGE_OUTSIDE_WINDMILL,
ENTR_POTION_SHOP_KAKARIKO_FRONT,
ENTR_KAKARIKO_VILLAGE_OUTSIDE_POTION_SHOP_FRONT,
ENTR_POTION_SHOP_KAKARIKO_BACK,
ENTR_KAKARIKO_VILLAGE_OUTSIDE_POTION_SHOP_BACK,
ENTR_GRAVE_WITH_FAIRYS_FOUNTAIN_0,
ENTR_GRAVEYARD_SHIELD_GRAVE_EXIT,
ENTR_REDEAD_GRAVE_0,
ENTR_GRAVEYARD_HEART_PIECE_GRAVE_EXIT,
ENTR_ROYAL_FAMILYS_TOMB_0,
ENTR_GRAVEYARD_ROYAL_TOMB_EXIT,
ENTR_WINDMILL_AND_DAMPES_GRAVE_GRAVE,
ENTR_GRAVEYARD_DAMPES_GRAVE_EXIT,
ENTR_LOST_WOODS_BRIDGE_EAST_EXIT,
ENTR_KOKIRI_FOREST_LOWER_EXIT,
ENTR_LOST_WOODS_SOUTH_EXIT,
ENTR_KOKIRI_FOREST_UPPER_EXIT,
ENTR_GORON_CITY_TUNNEL_SHORTCUT,
ENTR_LOST_WOODS_TUNNEL_SHORTCUT,
ENTR_ZORAS_RIVER_UNDERWATER_SHORTCUT,
ENTR_LOST_WOODS_UNDERWATER_SHORTCUT,
ENTR_SACRED_FOREST_MEADOW_SOUTH_EXIT,
ENTR_LOST_WOODS_NORTH_EXIT,
ENTR_HYRULE_FIELD_WOODED_EXIT,
ENTR_LOST_WOODS_BRIDGE_WEST_EXIT,
ENTR_LAKE_HYLIA_NORTH_EXIT,
ENTR_HYRULE_FIELD_FENCE_EXIT,
ENTR_GERUDO_VALLEY_EAST_EXIT,
ENTR_HYRULE_FIELD_ROCKY_PATH,
ENTR_MARKET_ENTRANCE_NEAR_GUARD_EXIT,
ENTR_HYRULE_FIELD_ON_BRIDGE_SPAWN,
ENTR_KAKARIKO_VILLAGE_FRONT_GATE,
ENTR_HYRULE_FIELD_STAIRS_EXIT,
ENTR_ZORAS_RIVER_WEST_EXIT,
ENTR_HYRULE_FIELD_RIVER_EXIT,
ENTR_LON_LON_RANCH_ENTRANCE,
ENTR_HYRULE_FIELD_CENTER_EXIT,
ENTR_ZORAS_DOMAIN_UNDERWATER_SHORTCUT,
ENTR_LAKE_HYLIA_UNDERWATER_SHORTCUT,
ENTR_GERUDOS_FORTRESS_EAST_EXIT,
ENTR_GERUDO_VALLEY_WEST_EXIT,
ENTR_HAUNTED_WASTELAND_EAST_EXIT,
ENTR_GERUDOS_FORTRESS_GATE_EXIT,
ENTR_DESERT_COLOSSUS_EAST_EXIT,
ENTR_HAUNTED_WASTELAND_WEST_EXIT,
ENTR_MARKET_SOUTH_EXIT,
ENTR_MARKET_ENTRANCE_NORTH_EXIT,
ENTR_CASTLE_GROUNDS_SOUTH_EXIT,
ENTR_MARKET_DAY_CASTLE_EXIT,
ENTR_TEMPLE_OF_TIME_EXTERIOR_DAY_GOSSIP_STONE_EXIT,
ENTR_MARKET_DAY_TEMPLE_EXIT,
ENTR_GRAVEYARD_ENTRANCE,
ENTR_KAKARIKO_VILLAGE_SOUTHEAST_EXIT,
ENTR_DEATH_MOUNTAIN_TRAIL_BOTTOM_EXIT,
ENTR_KAKARIKO_VILLAGE_GUARD_GATE,
ENTR_GORON_CITY_UPPER_EXIT,
ENTR_DEATH_MOUNTAIN_TRAIL_GC_EXIT,
ENTR_DEATH_MOUNTAIN_CRATER_GC_EXIT,
ENTR_GORON_CITY_DARUNIA_ROOM_EXIT,
ENTR_DEATH_MOUNTAIN_CRATER_UPPER_EXIT,
ENTR_DEATH_MOUNTAIN_TRAIL_SUMMIT_EXIT,
ENTR_ZORAS_DOMAIN_ENTRANCE,
ENTR_ZORAS_RIVER_WATERFALL_EXIT,
ENTR_ZORAS_FOUNTAIN_TUNNEL_EXIT,
ENTR_ZORAS_DOMAIN_KING_ZORA_EXIT,
ENTR_LAKE_HYLIA_RIVER_EXIT,
ENTR_HYRULE_FIELD_OWL_DROP,
ENTR_KAKARIKO_VILLAGE_OWL_DROP,
ENTR_LINKS_HOUSE_CHILD_SPAWN,
ENTR_HYRULE_FIELD_10,
ENTR_SACRED_FOREST_MEADOW_WARP_PAD,
ENTR_DEATH_MOUNTAIN_CRATER_WARP_PAD,
ENTR_LAKE_HYLIA_WARP_PAD,
ENTR_DESERT_COLOSSUS_WARP_PAD,
ENTR_GRAVEYARD_WARP_PAD,
ENTR_TEMPLE_OF_TIME_WARP_PAD,
ENTR_DEKU_TREE_BOSS_ENTRANCE,
ENTR_DEKU_TREE_BOSS_DOOR,
ENTR_DODONGOS_CAVERN_BOSS_ENTRANCE,
ENTR_DODONGOS_CAVERN_BOSS_DOOR,
ENTR_JABU_JABU_BOSS_ENTRANCE,
ENTR_JABU_JABU_BOSS_DOOR,
ENTR_FOREST_TEMPLE_BOSS_ENTRANCE,
ENTR_FOREST_TEMPLE_BOSS_DOOR,
ENTR_FIRE_TEMPLE_BOSS_ENTRANCE,
ENTR_FIRE_TEMPLE_BOSS_DOOR,
ENTR_WATER_TEMPLE_BOSS_ENTRANCE,
ENTR_WATER_TEMPLE_BOSS_DOOR,
ENTR_SPIRIT_TEMPLE_BOSS_ENTRANCE,
ENTR_SPIRIT_TEMPLE_BOSS_DOOR,
ENTR_SHADOW_TEMPLE_BOSS_ENTRANCE,
ENTR_SHADOW_TEMPLE_BOSS_DOOR,
};
std::vector<AltTrapType> getEnabledAddTraps() {
std::vector<AltTrapType> enabledAddTraps;
for (int i = 0; i < ADD_TRAP_MAX; i++) {
@@ -109,7 +307,10 @@ static void RollRandomTrap(uint64_t seed) {
break;
case ADD_TELEPORT_TRAP:
eventTimer = 3;
teleportRoll = ShipUtils::RandomElement(teleportDestinations, &state);
teleportRoll =
CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Teleport"), TELEPORT_TRAP_OFF) == TELEPORT_TRAP_ADVANCED
? ShipUtils::RandomElement(advancedTeleportDestinations, &state)
: ShipUtils::RandomElement(simpleTeleportDestinations, &state);
break;
default:
break;
+6
View File
@@ -132,4 +132,10 @@ typedef enum {
RANDOMIZE_ON_FILE_LOAD_SEEDED,
} RandomizeOnMode;
typedef enum {
TELEPORT_TRAP_OFF,
TELEPORT_TRAP_SIMPLE,
TELEPORT_TRAP_ADVANCED,
} TeleportTrapMode;
#endif
+14 -2
View File
@@ -138,6 +138,12 @@ static const std::map<int32_t, const char*> zFightingOptions = {
{ ZFIGHT_FIX_NO_VANISH, "No Vanish" },
};
static const std::map<int32_t, const char*> teleportTrapModes = {
{ TELEPORT_TRAP_OFF, "Off" },
{ TELEPORT_TRAP_SIMPLE, "Simple" },
{ TELEPORT_TRAP_ADVANCED, "Advanced" },
};
static const std::map<int32_t, const char*> swordToggleModes = {
{ SWORD_TOGGLE_NONE, "None" },
{ SWORD_TOGGLE_CHILD, "Child Toggle" },
@@ -1823,10 +1829,16 @@ void SohMenu::AddMenuEnhancements() {
.CVar(CVAR_ENHANCEMENT("ExtraTraps.Kill"))
.PreFunc(
[](WidgetInfo& info) { info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0; });
AddWidget(path, "Teleport Traps", WIDGET_CVAR_CHECKBOX)
AddWidget(path, "Teleport Traps", WIDGET_CVAR_COMBOBOX)
.CVar(CVAR_ENHANCEMENT("ExtraTraps.Teleport"))
.PreFunc(
[](WidgetInfo& info) { info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0; });
[](WidgetInfo& info) { info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0; })
.Options(ComboboxOptions()
.ComboMap(teleportTrapModes)
.DefaultIndex(TELEPORT_TRAP_OFF)
.Tooltip("Where a Teleport Trap can send you. Off keeps them out of the trap pool.\n\n"
"Simple: Link's House and the six warp song pads.\n"
"Advanced: The same pool the randomizer uses when it shuffles spawns and warp songs."));
// Cheats
path.sidebarName = "Cheats";