diff --git a/src/WeatherEditor/Weather/WeatherWidget.cpp b/src/WeatherEditor/Weather/WeatherWidget.cpp index 68b92f7dff..381cb85af6 100644 --- a/src/WeatherEditor/Weather/WeatherWidget.cpp +++ b/src/WeatherEditor/Weather/WeatherWidget.cpp @@ -464,7 +464,9 @@ void WeatherWidget::LoadSettings() settings = vanillaSettings; } InitializeInheritFlags(); - LoadFeatureSettings(); + if (!js.empty()) { + LoadFeatureSettings(); + } originalSettings = settings; ApplyChanges(); } @@ -603,32 +605,21 @@ void WeatherWidget::SetWeatherValues() } weather->cloudLayerDisabledBits = disabledBits; - // Save feature settings + // If this weather is currently active, immediately apply feature settings to game memory auto* weatherManager = WeatherManager::GetSingleton(); - for (const auto& [featureName, featureSettings] : settings.featureSettings) { - weatherManager->SaveSettingsToWeather(weather, featureName, featureSettings); - } - - // If this weather is currently active, immediately apply feature settings - auto currentWeathers = weatherManager->GetCurrentWeathers(); - if (currentWeathers.currentWeather == weather) { + if (weatherManager->GetCurrentWeathers().currentWeather == weather) { auto* globalRegistry = WeatherVariables::GlobalWeatherRegistry::GetSingleton(); - for (const auto& [featureName, featureSettings] : settings.featureSettings) { - // Check if overrides are enabled for this feature - bool enabled = featureSettings.value("__enabled", false); - if (enabled && globalRegistry->HasWeatherSupport(featureName)) { - // Filter out the __enabled flag before applying - json filteredSettings = json::object(); - for (auto it = featureSettings.begin(); it != featureSettings.end(); ++it) { - if (it.key() != "__enabled") { - filteredSettings[it.key()] = it.value(); - } - } + json emptyWeather; - // Apply the weather-specific settings immediately - json emptyWeather; // No previous weather during instant update - globalRegistry->UpdateFeatureFromWeathers(featureName, emptyWeather, filteredSettings, 1.0f); + for (const auto& [featureName, featureSettings] : settings.featureSettings) { + if (!featureSettings.value("__enabled", false) || !globalRegistry->HasWeatherSupport(featureName)) { + continue; } + + // Filter out __enabled flag and apply settings + json filteredSettings = featureSettings; + filteredSettings.erase("__enabled"); + globalRegistry->UpdateFeatureFromWeathers(featureName, emptyWeather, filteredSettings, 1.0f); } } } @@ -1462,9 +1453,22 @@ void WeatherWidget::SaveFeatureSettings() { auto* weatherManager = WeatherManager::GetSingleton(); - for (const auto& [featureName, featureJson] : settings.featureSettings) { - // Always call save so that empty objects are persisted as removals. - weatherManager->SaveSettingsToWeather(weather, featureName, featureJson); + // Collect all feature names from both current and original settings to detect deletions + std::set allFeatureNames; + for (const auto& [featureName, _] : settings.featureSettings) { + allFeatureNames.insert(featureName); + } + for (const auto& [featureName, _] : originalSettings.featureSettings) { + allFeatureNames.insert(featureName); + } + + // Save current settings or clear deleted features + for (const auto& featureName : allFeatureNames) { + auto it = settings.featureSettings.find(featureName); + weatherManager->SaveSettingsToWeather( + weather, + featureName, + it != settings.featureSettings.end() ? it->second : json::object()); } } @@ -1560,10 +1564,42 @@ void WeatherWidget::ApplyChanges() void WeatherWidget::RevertChanges() { + auto* weatherManager = WeatherManager::GetSingleton(); + + // If this weather is currently active, reset enabled feature overrides to user defaults + if (weather == weatherManager->GetCurrentWeathers().currentWeather) { + auto* globalRegistry = WeatherVariables::GlobalWeatherRegistry::GetSingleton(); + + for (const auto& [featureName, featureSettings] : settings.featureSettings) { + if (!featureSettings.value("__enabled", false) || !globalRegistry->HasWeatherSupport(featureName)) { + continue; + } + + globalRegistry->EndFeatureTransition(featureName); + + if (auto* featureRegistry = globalRegistry->GetFeatureRegistry(featureName)) { + for (const auto& var : featureRegistry->GetVariables()) { + var->SetToUserSettings(); + } + } + } + } + + weatherManager->ClearAllFeatureSettingsForWeather(weather); settings = vanillaSettings; ApplyChanges(); } +void WeatherWidget::Delete() +{ + // Clear cache and local settings before base Delete() to prevent reloading stale data + auto* weatherManager = WeatherManager::GetSingleton(); + weatherManager->ClearAllFeatureSettingsForWeather(weather); + settings.featureSettings.clear(); + + Widget::Delete(); +} + bool WeatherWidget::Settings::operator==(const Settings& o) const { return parent == o.parent && diff --git a/src/WeatherEditor/Weather/WeatherWidget.h b/src/WeatherEditor/Weather/WeatherWidget.h index 0f91c1caa1..defa843859 100644 --- a/src/WeatherEditor/Weather/WeatherWidget.h +++ b/src/WeatherEditor/Weather/WeatherWidget.h @@ -135,6 +135,7 @@ class WeatherWidget : public Widget void LoadWeatherValues(); void ApplyChanges() override; void RevertChanges() override; + void Delete() override; bool HasUnsavedChanges() const override; // New methods for per-feature settings diff --git a/src/WeatherEditor/Widget.h b/src/WeatherEditor/Widget.h index 3d47392b4d..9459eef518 100644 --- a/src/WeatherEditor/Widget.h +++ b/src/WeatherEditor/Widget.h @@ -123,9 +123,9 @@ class Widget void Save(); void Load(); - void Delete(); bool HasSavedFile() const; + virtual void Delete(); virtual void LoadSettings() = 0; virtual void SaveSettings() = 0; virtual void ApplyChanges() = 0; diff --git a/src/WeatherManager.cpp b/src/WeatherManager.cpp index 62de91bfaa..6c6bb0fed4 100644 --- a/src/WeatherManager.cpp +++ b/src/WeatherManager.cpp @@ -293,6 +293,16 @@ bool WeatherManager::HasWeatherSettings(RE::TESWeather* weather) const return perWeatherSettingsCache.find(weatherKey) != perWeatherSettingsCache.end(); } +void WeatherManager::ClearAllFeatureSettingsForWeather(RE::TESWeather* weather) +{ + if (!weather) { + return; + } + + std::string weatherKey = GetWeatherKey(weather); + perWeatherSettingsCache.erase(weatherKey); +} + void WeatherManager::ClearCache() { perWeatherSettingsCache.clear(); diff --git a/src/WeatherManager.h b/src/WeatherManager.h index 66dc042d5b..b930109f20 100644 --- a/src/WeatherManager.h +++ b/src/WeatherManager.h @@ -40,6 +40,9 @@ class WeatherManager // Get the weather key for caching static std::string GetWeatherKey(RE::TESWeather* weather); + // Clear all cached feature settings for a specific weather + void ClearAllFeatureSettingsForWeather(RE::TESWeather* weather); + // Check if settings exist for a weather bool HasWeatherSettings(RE::TESWeather* weather) const;