diff --git a/soh/soh/Enhancements/ExtraTraps.cpp b/soh/soh/Enhancements/ExtraTraps.cpp index b506582df80..ca1f4787d14 100644 --- a/soh/soh/Enhancements/ExtraTraps.cpp +++ b/soh/soh/Enhancements/ExtraTraps.cpp @@ -29,11 +29,6 @@ typedef enum { ADD_TRAP_MAX } AltTrapType; -static AltTrapType roll = ADD_TRAP_MAX; -static int statusTimer = -1; -static int eventTimer = -1; -static EntranceIndex teleportRoll = ENTR_MAX; - const char* altTrapTypeCvars[] = { CVAR_ENHANCEMENT("ExtraTraps.Ice"), CVAR_ENHANCEMENT("ExtraTraps.Burn"), CVAR_ENHANCEMENT("ExtraTraps.Shock"), CVAR_ENHANCEMENT("ExtraTraps.Knockback"), @@ -48,69 +43,137 @@ const std::array teleportDestinations = { ENTR_TEMPLE_OF_TIME_WARP_PAD, }; -std::vector getEnabledAddTraps() { - std::vector enabledAddTraps; +typedef struct { + AltTrapType trap; + uint16_t ticks; + void (*execute)(Player*, uint32_t); + uint32_t state; +} EventTimer; + +static std::vector timers = std::vector(); + +static void queueTimer(AltTrapType trap, uint16_t ticks, void (*execute)(Player*, uint32_t), uint32_t state = 0) { + + EventTimer m = { .trap = trap, .ticks = ticks, .execute = execute, .state = state }; + timers.push_back(m); +} + +static AltTrapType selectWeightedTrap(uint64_t* state) { + float weights[ADD_TRAP_MAX] = { 0.0f }; + float totalWeight = 0.0f; + + bool weighted = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.WeightedTraps"), 0); + for (int i = 0; i < ADD_TRAP_MAX; i++) { - if (CVarGetInteger(altTrapTypeCvars[i], 0)) { - if (gSaveContext.equips.buttonItems[0] == ITEM_FISHING_POLE && - (i == ADD_VOID_TRAP || i == ADD_TELEPORT_TRAP)) { - continue; // don't add void or teleport if you're holding the fishing pole, as this causes issues - } - enabledAddTraps.push_back(static_cast(i)); + float weight = weighted ? CVarGetInteger(altTrapTypeCvars[i], 0) : 1; + if (gSaveContext.equips.buttonItems[0] == ITEM_FISHING_POLE && (i == ADD_VOID_TRAP || i == ADD_TELEPORT_TRAP)) { + weight = 0; // don't add void or teleport if you're holding the fishing pole, as this causes issues } + + totalWeight += weight; + weights[i] = totalWeight; + SPDLOG_TRACE("TRAP trap:{0} weight:{1} position:{2}", altTrapTypeCvars[i], weight, totalWeight); } - if (enabledAddTraps.size() == 0) { - enabledAddTraps.push_back(ADD_ICE_TRAP); + + if (totalWeight == 0.0f) // No weights? Just return an invalid value. + return ADD_TRAP_MAX; + + double target = ShipUtils::RandomDouble(state) * totalWeight; + + for (int i = 0; i < ADD_TRAP_MAX; i++) { + if (weights[i] >= target) { + SPDLOG_TRACE("SELECTED {0} {1} {2}", target, i, altTrapTypeCvars[i]); + return (AltTrapType)i; + } } - return enabledAddTraps; -}; + + return ADD_TRAP_MAX; +} static void RollRandomTrap(uint64_t seed) { uint64_t finalSeed = seed + (IS_RANDO ? static_cast(Rando::Context::GetInstance()->GetSeed()) : gSaveContext.ship.stats.fileCreatedAt); uint64_t state; ShipUtils::RandInit(finalSeed, &state); + AltTrapType roll = selectWeightedTrap(&state); + if (roll == ADD_TRAP_MAX) // If it failed to pick a trap, fallback to a basic ice trap. + { + roll = ADD_ICE_TRAP; + } - roll = ShipUtils::RandomElement(getEnabledAddTraps(), &state); switch (roll) { - case ADD_ICE_TRAP: + case ADD_ICE_TRAP: { GameInteractor::RawAction::FreezePlayer(); break; - case ADD_BURN_TRAP: + } + case ADD_BURN_TRAP: { GameInteractor::RawAction::BurnPlayer(); break; - case ADD_SHOCK_TRAP: + } + case ADD_SHOCK_TRAP: { GameInteractor::RawAction::ElectrocutePlayer(); break; - case ADD_KNOCK_TRAP: - eventTimer = 3; + } + case ADD_KNOCK_TRAP: { + queueTimer(ADD_KNOCK_TRAP, 3, + [](Player* player, uint32_t state) { GameInteractor::RawAction::KnockbackPlayer(1); }); break; - case ADD_SPEED_TRAP: + } + case ADD_SPEED_TRAP: { Audio_PlaySoundGeneral(NA_SE_VO_KZ_MOVE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + + for (int i = 0; i < timers.size(); i++) { + if (timers[i].trap == ADD_SPEED_TRAP) { + timers[i].ticks += 200; + return; + } + } GameInteractor::State::MovementSpeedMultiplier = 0.5f; - statusTimer = 200; Notification::Emit({ .message = "Speed Decreased!" }); + queueTimer(ADD_SPEED_TRAP, 200, [](Player* player, uint32_t state) { + GameInteractor::State::MovementSpeedMultiplier = 1.0f; + Notification::Emit({ .message = "Speed Restored!" }); + }); break; - case ADD_BOMB_TRAP: - eventTimer = 3; + } + case ADD_BOMB_TRAP: { + queueTimer(ADD_BOMB_TRAP, 3, + [](Player* player, uint32_t state) { GameInteractor::RawAction::SpawnActor(ACTOR_EN_BOM, 1); }); break; - case ADD_VOID_TRAP: + } + case ADD_VOID_TRAP: { Audio_PlaySoundGeneral(NA_SE_EN_GANON_LAUGH, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); - eventTimer = 3; + queueTimer(ADD_VOID_TRAP, 3, [](Player* player, uint32_t state) { Play_TriggerRespawn(gPlayState); }); break; - case ADD_AMMO_TRAP: - eventTimer = 3; + } + case ADD_AMMO_TRAP: { Notification::Emit({ .message = "Ammo Halved!" }); + queueTimer(ADD_AMMO_TRAP, 3, [](Player* player, uint32_t state) { + AMMO(ITEM_STICK) = static_cast(floor(AMMO(ITEM_STICK) * 0.5f)); + AMMO(ITEM_NUT) = static_cast(floor(AMMO(ITEM_NUT) * 0.5f)); + AMMO(ITEM_SLINGSHOT) = static_cast(floor(AMMO(ITEM_SLINGSHOT) * 0.5f)); + AMMO(ITEM_BOW) = static_cast(floor(AMMO(ITEM_BOW) * 0.5f)); + AMMO(ITEM_BOMB) = static_cast(floor(AMMO(ITEM_BOMB) * 0.5f)); + AMMO(ITEM_BOMBCHU) = static_cast(floor(AMMO(ITEM_BOMBCHU) * 0.5f)); + Audio_PlaySoundGeneral(NA_SE_VO_FR_SMILE_0, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + }); break; - case ADD_KILL_TRAP: + } + case ADD_KILL_TRAP: { GameInteractor::RawAction::SetPlayerHealth(0); break; - case ADD_TELEPORT_TRAP: - eventTimer = 3; - teleportRoll = ShipUtils::RandomElement(teleportDestinations, &state); + } + case ADD_TELEPORT_TRAP: { + EntranceIndex teleportRoll = ShipUtils::RandomElement(teleportDestinations, &state); + + queueTimer( + ADD_TELEPORT_TRAP, 3, + [](Player* player, uint32_t state) { GameInteractor::RawAction::TeleportPlayer(state); }, teleportRoll); break; + } default: break; } @@ -118,47 +181,16 @@ static void RollRandomTrap(uint64_t seed) { static void OnPlayerUpdate() { Player* player = GET_PLAYER(gPlayState); - if (statusTimer == 0) { - GameInteractor::State::MovementSpeedMultiplier = 1.0f; - } - if (eventTimer == 0) { - switch (roll) { - case ADD_KNOCK_TRAP: - GameInteractor::RawAction::KnockbackPlayer(1); - break; - case ADD_BOMB_TRAP: - GameInteractor::RawAction::SpawnActor(ACTOR_EN_BOM, 1); - break; - case ADD_VOID_TRAP: - Play_TriggerRespawn(gPlayState); - break; - case ADD_AMMO_TRAP: - AMMO(ITEM_STICK) = static_cast(floor(AMMO(ITEM_STICK) * 0.5f)); - AMMO(ITEM_NUT) = static_cast(floor(AMMO(ITEM_NUT) * 0.5f)); - AMMO(ITEM_SLINGSHOT) = static_cast(floor(AMMO(ITEM_SLINGSHOT) * 0.5f)); - AMMO(ITEM_BOW) = static_cast(floor(AMMO(ITEM_BOW) * 0.5f)); - AMMO(ITEM_BOMB) = static_cast(floor(AMMO(ITEM_BOMB) * 0.5f)); - AMMO(ITEM_BOMBCHU) = static_cast(floor(AMMO(ITEM_BOMBCHU) * 0.5f)); - Audio_PlaySoundGeneral(NA_SE_VO_FR_SMILE_0, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, - &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); - break; - case ADD_TELEPORT_TRAP: { - GameInteractor::RawAction::TeleportPlayer(teleportRoll); - break; - } - default: - break; + for (int i = timers.size() - 1; i >= 0; i--) { + auto& n = timers[i]; + if (--n.ticks == 0) { + n.execute(player, n.state); + timers.erase(timers.begin() + i); } } - if (statusTimer >= 0) { - statusTimer--; - } - if (eventTimer >= 0) { - eventTimer--; - } } -void RegisterExtraTraps() { +static void RegisterExtraTraps() { COND_HOOK(OnPlayerUpdate, CVAR_EXTRA_TRAPS_VALUE, OnPlayerUpdate); COND_VB_SHOULD(VB_SHORT_CIRCUIT_GIVE_ITEM_PROCESS, true, { diff --git a/soh/soh/SohGui/SohMenuEnhancements.cpp b/soh/soh/SohGui/SohMenuEnhancements.cpp index c17a622e78a..675cf6a43db 100644 --- a/soh/soh/SohGui/SohMenuEnhancements.cpp +++ b/soh/soh/SohGui/SohMenuEnhancements.cpp @@ -1659,58 +1659,176 @@ void SohMenu::AddMenuEnhancements() { AddWidget(path, "Additional Traps", WIDGET_CVAR_CHECKBOX) .CVar(CVAR_ENHANCEMENT("ExtraTraps.Enabled")) .Options(CheckboxOptions().Tooltip("Enables additional Trap variants.")); + AddWidget(path, "Trap Options", WIDGET_SEPARATOR_TEXT).PreFunc([](WidgetInfo& info) { info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0; }); + + AddWidget(path, "Weighted Traps", WIDGET_CVAR_CHECKBOX) + .CVar(CVAR_ENHANCEMENT("ExtraTraps.WeightedTraps")) + .PreFunc( + [](WidgetInfo& info) { info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0; }); + AddWidget(path, "Tier 1 Traps:", WIDGET_TEXT).PreFunc([](WidgetInfo& info) { info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0; }); AddWidget(path, "Freeze Traps", WIDGET_CVAR_CHECKBOX) .CVar(CVAR_ENHANCEMENT("ExtraTraps.Ice")) - .PreFunc( - [](WidgetInfo& info) { info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0; }); + .PreFunc([](WidgetInfo& info) { + info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0 || + CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.WeightedTraps"), 0) != 0; + }); + + AddWidget(path, "Freeze Traps Weight", WIDGET_CVAR_SLIDER_INT) + .CVar(CVAR_ENHANCEMENT("ExtraTraps.Ice")) + .PreFunc([](WidgetInfo& info) { + info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0 || + CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.WeightedTraps"), 0) == 0; + }) + .Options(IntSliderOptions().DefaultValue(0).Min(0).Max(100).Tooltip("Set to zero (0) to disable.")); + AddWidget(path, "Burn Traps", WIDGET_CVAR_CHECKBOX) .CVar(CVAR_ENHANCEMENT("ExtraTraps.Burn")) - .PreFunc( - [](WidgetInfo& info) { info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0; }); + .PreFunc([](WidgetInfo& info) { + info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0 || + CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.WeightedTraps"), 0) != 0; + }); + + AddWidget(path, "Burn Traps Weight", WIDGET_CVAR_SLIDER_INT) + .CVar(CVAR_ENHANCEMENT("ExtraTraps.Burn")) + .PreFunc([](WidgetInfo& info) { + info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0 || + CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.WeightedTraps"), 0) == 0; + }) + .Options(IntSliderOptions().DefaultValue(0).Min(0).Max(100).Tooltip("Set to zero (0) to disable.")); + AddWidget(path, "Shock Traps", WIDGET_CVAR_CHECKBOX) .CVar(CVAR_ENHANCEMENT("ExtraTraps.Shock")) - .PreFunc( - [](WidgetInfo& info) { info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0; }); + .PreFunc([](WidgetInfo& info) { + info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0 || + CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.WeightedTraps"), 0) != 0; + }); + + AddWidget(path, "Shock Traps Weight", WIDGET_CVAR_SLIDER_INT) + .CVar(CVAR_ENHANCEMENT("ExtraTraps.Shock")) + .PreFunc([](WidgetInfo& info) { + info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0 || + CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.WeightedTraps"), 0) == 0; + }) + .Options(IntSliderOptions().DefaultValue(0).Min(0).Max(100).Tooltip("Set to zero (0) to disable.")); + AddWidget(path, "Tier 2 Traps:", WIDGET_TEXT).PreFunc([](WidgetInfo& info) { info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0; }); + AddWidget(path, "Knockback Traps", WIDGET_CVAR_CHECKBOX) .CVar(CVAR_ENHANCEMENT("ExtraTraps.Knockback")) - .PreFunc( - [](WidgetInfo& info) { info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0; }); + .PreFunc([](WidgetInfo& info) { + info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0 || + CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.WeightedTraps"), 0) != 0; + }); + + AddWidget(path, "Knockback Traps Weight", WIDGET_CVAR_SLIDER_INT) + .CVar(CVAR_ENHANCEMENT("ExtraTraps.Knockback")) + .PreFunc([](WidgetInfo& info) { + info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0 || + CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.WeightedTraps"), 0) == 0; + }) + .Options(IntSliderOptions().DefaultValue(0).Min(0).Max(100).Tooltip("Set to zero (0) to disable.")); + AddWidget(path, "Speed Traps", WIDGET_CVAR_CHECKBOX) .CVar(CVAR_ENHANCEMENT("ExtraTraps.Speed")) - .PreFunc( - [](WidgetInfo& info) { info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0; }); + .PreFunc([](WidgetInfo& info) { + info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0 || + CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.WeightedTraps"), 0) != 0; + }); + + AddWidget(path, "Speed Traps Weight", WIDGET_CVAR_SLIDER_INT) + .CVar(CVAR_ENHANCEMENT("ExtraTraps.Speed")) + .PreFunc([](WidgetInfo& info) { + info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0 || + CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.WeightedTraps"), 0) == 0; + }) + .Options(IntSliderOptions().DefaultValue(0).Min(0).Max(100).Tooltip("Set to zero (0) to disable.")); + AddWidget(path, "Bomb Traps", WIDGET_CVAR_CHECKBOX) .CVar(CVAR_ENHANCEMENT("ExtraTraps.Bomb")) - .PreFunc( - [](WidgetInfo& info) { info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0; }); + .PreFunc([](WidgetInfo& info) { + info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0 || + CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.WeightedTraps"), 0) != 0; + }); + + AddWidget(path, "Bomb Traps Weight", WIDGET_CVAR_SLIDER_INT) + .CVar(CVAR_ENHANCEMENT("ExtraTraps.Bomb")) + .PreFunc([](WidgetInfo& info) { + info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0 || + CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.WeightedTraps"), 0) == 0; + }) + .Options(IntSliderOptions().DefaultValue(0).Min(0).Max(100).Tooltip("Set to zero (0) to disable.")); + AddWidget(path, "Tier 3 Traps:", WIDGET_TEXT).PreFunc([](WidgetInfo& info) { info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0; }); + AddWidget(path, "Void Traps", WIDGET_CVAR_CHECKBOX) .CVar(CVAR_ENHANCEMENT("ExtraTraps.Void")) - .PreFunc( - [](WidgetInfo& info) { info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0; }); + .PreFunc([](WidgetInfo& info) { + info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0 || + CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.WeightedTraps"), 0) != 0; + }); + + AddWidget(path, "Void Traps Weight", WIDGET_CVAR_SLIDER_INT) + .CVar(CVAR_ENHANCEMENT("ExtraTraps.Void")) + .PreFunc([](WidgetInfo& info) { + info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0 || + CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.WeightedTraps"), 0) == 0; + }) + .Options(IntSliderOptions().DefaultValue(0).Min(0).Max(100).Tooltip("Set to zero (0) to disable.")); + AddWidget(path, "Ammo Traps", WIDGET_CVAR_CHECKBOX) .CVar(CVAR_ENHANCEMENT("ExtraTraps.Ammo")) - .PreFunc( - [](WidgetInfo& info) { info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0; }); + .PreFunc([](WidgetInfo& info) { + info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0 || + CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.WeightedTraps"), 0) != 0; + }); + + AddWidget(path, "Ammo Traps Weight", WIDGET_CVAR_SLIDER_INT) + .CVar(CVAR_ENHANCEMENT("ExtraTraps.Ammo")) + .PreFunc([](WidgetInfo& info) { + info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0 || + CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.WeightedTraps"), 0) == 0; + }) + .Options(IntSliderOptions().DefaultValue(0).Min(0).Max(100).Tooltip("Set to zero (0) to disable.")); + AddWidget(path, "Death Traps", WIDGET_CVAR_CHECKBOX) .CVar(CVAR_ENHANCEMENT("ExtraTraps.Kill")) - .PreFunc( - [](WidgetInfo& info) { info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0; }); + .PreFunc([](WidgetInfo& info) { + info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0 || + CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.WeightedTraps"), 0) != 0; + }); + + AddWidget(path, "Death Traps Weight", WIDGET_CVAR_SLIDER_INT) + .CVar(CVAR_ENHANCEMENT("ExtraTraps.Kill")) + .PreFunc([](WidgetInfo& info) { + info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0 || + CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.WeightedTraps"), 0) == 0; + }) + .Options(IntSliderOptions().DefaultValue(0).Min(0).Max(100).Tooltip("Set to zero (0) to disable.")); + AddWidget(path, "Teleport Traps", WIDGET_CVAR_CHECKBOX) .CVar(CVAR_ENHANCEMENT("ExtraTraps.Teleport")) - .PreFunc( - [](WidgetInfo& info) { info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0; }); + .PreFunc([](WidgetInfo& info) { + info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0 || + CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.WeightedTraps"), 0) != 0; + }); + + AddWidget(path, "Teleport Traps Weight", WIDGET_CVAR_SLIDER_INT) + .CVar(CVAR_ENHANCEMENT("ExtraTraps.Teleport")) + .PreFunc([](WidgetInfo& info) { + info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0 || + CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.WeightedTraps"), 0) == 0; + }) + .Options(IntSliderOptions().DefaultValue(0).Min(0).Max(100).Tooltip("Set to zero (0) to disable.")); // Cheats path.sidebarName = "Cheats";