Skip to content

Commit 8ec8ac3

Browse files
committed
feat(weather): allow disabling individual weather conditions
Add an Enabled checkbox per weather condition, shown as [Disabled] in the collapsed header when off. Disabled conditions are excluded from manual toggling, automatic weather rolls, and the /weather chat command. Fog now defaults to disabled since it's quite invasive to gameplay, which lets the Weather module itself default to enabled.
1 parent 8ae4225 commit 8ec8ac3

3 files changed

Lines changed: 18 additions & 9 deletions

File tree

GWToolboxdll/Modules/ToolboxSettings.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ namespace {
202202
{DistanceWidget::Instance(), false},
203203
Minimap::Instance(),
204204
GameWorldRenderer::Instance(),
205-
{WeatherModule::Instance(), false},
205+
WeatherModule::Instance(),
206206
{DangerRingsModule::Instance(), false},
207207
LootBeaconsModule::Instance(),
208208
{SkillRangeRingsModule::Instance(), false},

GWToolboxdll/Modules/WeatherModule.cpp

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ namespace weather_module {
8888
bool center_on_camera = false; // centre the volume on the camera itself, not its target (wraps tightly around the viewer)
8989
float column_height = 2500.f; // vertical extent of the falling-particle column above the focus, capped at column_height_max
9090
CloudCover cloud; // optional cloud-cover layer (overhead clouds / fog / sandstorm), composable with the falling particles
91+
bool enabled = true; // if false, excluded from manual toggling and automatic weather selection
9192
};
9293

9394
// A broad weather climate. Maps/regions are grouped into one of these (see ClimateForRegion), so weather is
@@ -195,7 +196,7 @@ namespace {
195196
// Ash: snow's drift (no floor decal) with a dark warm-grey tint and a heavier overcast.
196197
{"Ashfall", kTypeSnow, false, 10, 9.f, 350.f, 2500.f, 30.f, 55.f, 8.f, 0.f, {}, 12.f, 35.f, false, 0.45f, 0xFF42464Au, 0xFFA09078u, kDecalNone},
197198
// Cloud-cover-only conditions (low density = sparse/no falling particles); the look is mostly the cloud layer below.
198-
{"Fog", kTypeRain, true, 2, 10.f, 300.f, 1500.f, 0.f, 25.f, 0.f, 1.0f, {}, 10.f, 30.f, false, 0.0f, 0xFFFFFFFFu, 0xFFFFFFFFu},
199+
{"Fog", kTypeRain, false, 2, 10.f, 300.f, 1500.f, 0.f, 25.f, 0.f, 1.0f, {}, 10.f, 30.f, false, 0.0f, 0xFFFFFFFFu, 0xFFFFFFFFu},
199200
{"Sandstorm", kTypeRain, false, 10, 4.f, 500.f, 1000.f, 90.f, 90.f, 85.f, 0.f, {}, 10.f, 30.f, false, 0.0f, 0xFFC8B080u, 0xFFA09078u, kDecalNone},
200201
// Blizzard: heavy snow + a low white fog band.
201202
{"Blizzard", kTypeSnow, false, 85, 6.f, 700.f, 1500.f, 35.f, 60.f, 39.f, 0.f, {}, 10.f, 30.f, false, 0.55f, 0xFFFFFFFFu, 0xFFA09078u, kDecalAuto, 23.f},
@@ -211,6 +212,7 @@ namespace {
211212
v[4].cloud = {-500.f, 100.f, 0x11C8C8D0u, 10, 800.f, 10.f, 1500.f}; // Fog: white, low, slow, thin
212213
v[5].cloud = {-400.f, 60.f, 0x38C8B080u, 10, 500.f, 700.f, 600.f}; // Sandstorm: tan, ground-level, fast, tight (Wind sets the heading)
213214
v[6].cloud = {0.f, 1000.f, 0x2ED0D8E0u, 3, 800.f, 0.f, 1500.f}; // Blizzard: faint white fog under the snow
215+
v[4].enabled = false; // Fog: quite invasive to gameplay (obscures vision), so off by default
214216
return v;
215217
}
216218
std::vector<WeatherCondition> conditions = DefaultConditions();
@@ -526,9 +528,9 @@ namespace {
526528
for (const auto& e : prof->entries) {
527529
const float w = std::max(0.f, e.weight);
528530
if (w <= 0.f) continue;
529-
if (r < w) { // this entry won the roll; resolve its name to a live condition (clear if it's gone)
531+
if (r < w) { // this entry won the roll; resolve its name to a live, enabled condition (clear if it's gone/disabled)
530532
for (int i = 0; i < static_cast<int>(conditions.size()); i++)
531-
if (conditions[i].name == e.condition) { chosen = i; break; }
533+
if (conditions[i].name == e.condition && conditions[i].enabled) { chosen = i; break; }
532534
break;
533535
}
534536
r -= w;
@@ -1242,6 +1244,7 @@ namespace {
12421244
for (size_t i = 0; i < conditions.size(); i++) {
12431245
if (TextUtils::ToLower(conditions[i].name) != want) continue;
12441246
const bool on = state == 2 ? !conditions[i].active : state == 1;
1247+
if (on && !conditions[i].enabled) return Log::Error("%s is disabled; enable it in the weather settings first.", conditions[i].name.c_str());
12451248
// Only one condition at a time: activate this one and clear the rest (deactivating just turns it off).
12461249
for (auto& o : conditions)
12471250
o.active = false;
@@ -1404,6 +1407,7 @@ void WeatherModule::OnSettingsLoaded()
14041407
{
14051408
bool seen_active = false; // single-active: keep only the first active condition (older configs may have several)
14061409
for (auto& c : conditions) {
1410+
if (!c.enabled) c.active = false; // a disabled condition can't be the active one
14071411
if (c.active && std::exchange(seen_active, true)) c.active = false;
14081412
c.type = std::clamp(c.type, 0, kTypeCount - 1);
14091413
c.floor_decal = std::clamp(c.floor_decal, kDecalAuto, kDecalCount - 1);
@@ -1469,17 +1473,21 @@ void WeatherModule::DrawSettings()
14691473
for (int i = 0; i < static_cast<int>(conditions.size()); i++) {
14701474
auto& c = conditions[i];
14711475
ImGui::PushID(i);
1472-
ImGui::BeginDisabled(auto_weather); // automatic weather owns the active state; show it read-only
1476+
ImGui::BeginDisabled(auto_weather || !c.enabled); // automatic weather owns the active state; a disabled condition can't be activated
14731477
if (ImGui::Checkbox("##active", &c.active) && c.active) // only one condition at a time: turning one on turns the rest off
14741478
for (int j = 0; j < static_cast<int>(conditions.size()); j++)
14751479
if (j != i) conditions[j].active = false;
1476-
if (auto_weather && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) // explain the disabled state
1477-
ImGui::SetTooltip("Automatic weather is on and controls which condition is active.\nTurn off \"Automatic weather\" below to switch conditions manually.");
1480+
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) { // explain the disabled state
1481+
if (!c.enabled) ImGui::SetTooltip("This condition is disabled.\nTick \"Enabled\" in its settings below to allow it to be used.");
1482+
else if (auto_weather) ImGui::SetTooltip("Automatic weather is on and controls which condition is active.\nTurn off \"Automatic weather\" below to switch conditions manually.");
1483+
}
14781484
ImGui::EndDisabled();
14791485
ImGui::SameLine();
1480-
char header[64];
1481-
snprintf(header, sizeof(header), "%s###cond", c.name.empty() ? "(unnamed)" : c.name.c_str()); // stable id so editing the name doesn't collapse/unfocus the section
1486+
char header[80];
1487+
snprintf(header, sizeof(header), "%s%s###cond", c.name.empty() ? "(unnamed)" : c.name.c_str(), c.enabled ? "" : " [Disabled]"); // stable id so editing the name doesn't collapse/unfocus the section
14821488
if (ImGui::CollapsingHeader(header)) {
1489+
if (ImGui::Checkbox("Enabled", &c.enabled) && !c.enabled) c.active = false; // a disabled condition can't stay active
1490+
ImGui::ShowHelp("Untick to exclude this condition from manual selection and automatic weather rolls.");
14831491
ImGui::InputText("Name", c.name, 32);
14841492
ImGui::TextDisabled("Falling particles (set Density 0 for a cloud-cover-only condition like fog).");
14851493
const char* type_names[kTypeCount] = {"Rain", "Snow"};

site/src/content/docs/weather.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ The Weather module draws camera-anchored weather — rain, snow, ash and similar
1616

1717
Each condition is one weather effect. Only one runs at a time — turning a condition on (via its checkbox or [chat command](#chat-commands)) turns the others off. Expand a condition to edit it:
1818

19+
- **Enabled** — turn the condition off entirely: it's skipped by automatic weather and can't be turned on manually or via chat command until re-enabled. A disabled condition shows `[Disabled]` in its header. Fog is disabled by default, as it's quite invasive to gameplay (it obscures vision); enable it here if you want it in the rotation.
1920
- **Type** — Rain (streaked drops) or Snow (square flakes; also used for ash).
2021
- **Density** — how densely the volume is filled, 1–100%. The particle count is derived from this and the range, so it stays consistent if you change the radius. Higher = denser and heavier on FPS; the estimated particle count is shown below the slider.
2122
- **Range** — radius of the weather volume around the focus. A small range concentrates the effect close in; a large one fills out to compass range.

0 commit comments

Comments
 (0)