// Distant Lands 2024 // COZY: Stylized Weather 3 // All code included in this file is protected under the Unity Asset Store Eula using UnityEngine; using DistantLands.Cozy.Data; using System.Collections.Generic; namespace DistantLands.Cozy { [ExecuteAlways] public class CozyWeatherModule : CozyBiomeModuleBase, ICozyEcosystem { public float cumulus; public float cirrus; public float altocumulus; public float cirrostratus; public float chemtrails; public float nimbus; public float nimbusHeight; public float nimbusVariation; public float borderHeight; public float borderEffect; public float borderVariation; public float fogDensity; public float filterSaturation; public float filterValue; public Color filterColor = Color.white; public Color sunFilter = Color.white; public Color cloudFilter = Color.white; [CozySearchable(true)] public CozyEcosystem ecosystem; public CozyEcosystem Ecosystem { get => ecosystem; set => ecosystem = value; } public CozySystem LocalSystem { get => system; } [WeatherRelation] [CozySearchable] public List currentWeatherProfiles = new List(); public FilterFX defaultFilter; public CloudFX defaultClouds; public void Awake() { if (!enabled) return; RunChecks(); ecosystem.SetupEcosystem(); ResetFilter(); ResetClouds(); } public override void InitializeModule() { isBiomeModule = GetComponent(); if (isBiomeModule) { AddBiome(); return; } base.InitializeModule(); weatherSphere.weatherModule = this; AddBiome(); } private void RunChecks() { defaultClouds = (CloudFX)Resources.Load("Default Profiles/Default Clouds"); defaultFilter = (FilterFX)Resources.Load("Default Profiles/Default Filter"); ecosystem ??= new CozyEcosystem(); if (system == weatherSphere) weatherSphere.weatherModule = this; ecosystem.weatherSphere = weatherSphere; ecosystem.system = system; } public void Start() { foreach (WeatherProfile profile in ecosystem.forecastProfile.profilesToForecast) { foreach (FXProfile fx in profile.FX) fx?.InitializeEffect(weatherSphere); } } public override void UpdateWeatherWeights() { ecosystem.UpdateEcosystem(); ManageGlobalEcosystem(); UpdateWeatherByWeight(); } public override void UpdateFXWeights() { foreach (WeatherRelation weather in currentWeatherProfiles) { weather.profile.SetWeatherWeight(weather.weight); } } public override void FrameReset() { ResetClouds(); ResetFilter(); } /// /// Calculates the weather color filter based on the currently active Filter FX profiles. /// void ResetFilter() { if (ecosystem == null) return; filterSaturation = defaultFilter.filterSaturation; filterValue = defaultFilter.filterValue; filterColor = defaultFilter.filterColor; sunFilter = defaultFilter.sunFilter; cloudFilter = defaultFilter.cloudFilter; } /// /// Calculates the clouds based on the currently active Cloud FX profiles. /// void ResetClouds() { if (ecosystem == null) return; cumulus = defaultClouds.cumulusCoverage; cirrus = defaultClouds.cirrusCoverage; altocumulus = defaultClouds.altocumulusCoverage; cirrostratus = defaultClouds.cirrostratusCoverage; chemtrails = defaultClouds.chemtrailCoverage; nimbus = defaultClouds.nimbusCoverage; nimbusHeight = defaultClouds.nimbusHeightEffect; nimbusVariation = defaultClouds.nimbusVariation; borderHeight = defaultClouds.borderHeight; borderEffect = defaultClouds.borderEffect; borderVariation = defaultClouds.borderVariation; fogDensity = defaultClouds.fogDensity; } /// /// Send all weather information to the main COZY Weather Sphere for rendering. /// public override void PropogateVariables() { weatherSphere.cumulus = cumulus; weatherSphere.cirrus = cirrus; weatherSphere.altocumulus = altocumulus; weatherSphere.cirrostratus = cirrostratus; weatherSphere.chemtrails = chemtrails; weatherSphere.nimbus = nimbus; weatherSphere.nimbusHeightEffect = nimbusHeight; weatherSphere.nimbusVariation = nimbusVariation; weatherSphere.borderHeight = borderHeight; weatherSphere.borderEffect = borderEffect; weatherSphere.borderVariation = borderVariation; weatherSphere.fogDensity = fogDensity; weatherSphere.filterSaturation = filterSaturation; weatherSphere.filterValue = filterValue; weatherSphere.filterColor = filterColor; weatherSphere.sunFilter = sunFilter; weatherSphere.cloudFilter = cloudFilter; } void ManageGlobalEcosystem() { if (system == null) RunChecks(); currentWeatherProfiles.Clear(); if (weight > 0) foreach (WeatherRelation weatherRelation in ecosystem.weightedWeatherProfiles) { if (weatherRelation.weight == 0) { Debug.Log(weatherRelation); Debug.Log(weatherRelation.profile); weatherRelation.profile.SetWeatherWeight(0); continue; } if (currentWeatherProfiles.Find(x => x.profile == weatherRelation.profile) != null) { currentWeatherProfiles.Find(x => x.profile == weatherRelation.profile).weight += weatherRelation.weight * weight; continue; } WeatherRelation l = new WeatherRelation { profile = weatherRelation.profile, weight = weatherRelation.weight * weight }; currentWeatherProfiles.Add(l); } foreach (CozyWeatherModule biome in biomes) { if (biome == null) continue; CozyEcosystem localEcosystem = biome.Ecosystem; if (biome.weight > 0) { foreach (WeatherRelation weatherRelation in localEcosystem.weightedWeatherProfiles) { if (weatherRelation.weight == 0) { if (weatherRelation.profile) weatherRelation.profile.SetWeatherWeight(0); continue; } if (currentWeatherProfiles.Find(x => x.profile == weatherRelation.profile) != null) { currentWeatherProfiles.Find(x => x.profile == weatherRelation.profile).weight += weatherRelation.weight * biome.weight; continue; } WeatherRelation l = new WeatherRelation(); l.profile = weatherRelation.profile; l.weight = weatherRelation.weight * biome.weight; currentWeatherProfiles.Add(l); } } else { foreach (WeatherRelation i in localEcosystem.weightedWeatherProfiles) { i.profile.SetWeatherWeight(0); } } } } void UpdateWeatherByWeight() { ComputeBiomeWeights(); float weatherWeightAcrossSystems = 0; foreach (WeatherRelation i in currentWeatherProfiles) weatherWeightAcrossSystems += i.weight; if (weatherWeightAcrossSystems == 0) weatherWeightAcrossSystems = 1; foreach (WeatherRelation i in currentWeatherProfiles) { i.weight /= weatherWeightAcrossSystems; // i.profile.SetWeatherWeight(i.weight); } } } }