Decompiled source of BetterStorm v1.1.6
BepInEx/plugins/BetterStorm/BetterStorm.dll
Decompiled a month ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: InternalsVisibleTo("BetterStorm.Tests")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("BetterStorm")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.1.6.0")] [assembly: AssemblyInformationalVersion("1.1.6")] [assembly: AssemblyProduct("BetterStorm")] [assembly: AssemblyTitle("BetterStorm")] [assembly: AssemblyVersion("1.1.6.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace BetterStorm { [Flags] internal enum ClimateSeasonMask { None = 0, Winter = 1, Spring = 2, Summer = 4, Autumn = 8, All = 0xF } internal static class ClimateSeasonCompatibility { private const int DefaultYearLength = 92; internal static bool Allows(StormDefinition definition) { if (definition == null || definition.AllowedClimateSeasons == ClimateSeasonMask.All) { return true; } BetterStormPlugin instance = BetterStormPlugin.Instance; if ((Object)(object)instance == (Object)null || instance.DisableSeasonLimits.Value || !TryGetActiveClimateYear(out var yearLength)) { return true; } ClimateSeasonMask season = GetSeason(GameState.day, yearLength); return (definition.AllowedClimateSeasons & season) != 0; } internal static ClimateSeasonMask GetSeason(int day, int yearLength) { int num = Math.Max(4, yearLength); int num2 = day % num; if (num2 < 0) { num2 += num; } int num3 = num / 4; if (num2 < num3) { return ClimateSeasonMask.Winter; } if (num2 < num3 * 2) { return ClimateSeasonMask.Spring; } if (num2 < num3 * 3) { return ClimateSeasonMask.Summer; } return ClimateSeasonMask.Autumn; } private static bool TryGetActiveClimateYear(out int yearLength) { yearLength = 92; ConfigEntry<bool> val = default(ConfigEntry<bool>); if (!Chainloader.PluginInfos.TryGetValue("com.raddude.climate", out var value) || value == null || (Object)(object)value.Instance == (Object)null || !value.Instance.Config.TryGetEntry<bool>("Settings", "Enable Custom Winds", ref val) || !val.Value) { return false; } ConfigEntry<int> val2 = default(ConfigEntry<int>); if (value.Instance.Config.TryGetEntry<int>("Settings", "Days In A Year", ref val2)) { yearLength = val2.Value; } return yearLength >= 4; } } internal sealed class ConfigurationManagerAttributes { public bool? ShowRangeAsPercent; public Action<ConfigEntryBase> CustomDrawer; public bool? HideDefaultButton; public bool? HideSettingName; public string DispName; public int? Order; } internal sealed class SteppedAcceptableValueRange : AcceptableValueRange<float> { private readonly float step; internal SteppedAcceptableValueRange(float minimum, float maximum, float step) : base(minimum, maximum) { this.step = step; } public override object Clamp(object value) { float num = (float)base.Clamp(value); return Mathf.Clamp(((AcceptableValueRange<float>)this).MinValue + Mathf.Floor((num - ((AcceptableValueRange<float>)this).MinValue) / step + 0.5f) * step, ((AcceptableValueRange<float>)this).MinValue, ((AcceptableValueRange<float>)this).MaxValue); } public override bool IsValid(object value) { if (!(value is float num)) { return false; } return Mathf.Approximately(num, (float)((AcceptableValueBase)this).Clamp((object)num)); } } internal sealed class SteppedAcceptableIntRange : AcceptableValueRange<int> { private readonly int step; internal SteppedAcceptableIntRange(int minimum, int maximum, int step) : base(minimum, maximum) { this.step = step; } public override object Clamp(object value) { int num = (int)base.Clamp(value); return Mathf.Clamp(((AcceptableValueRange<int>)this).MinValue + (int)Mathf.Floor((float)(num - ((AcceptableValueRange<int>)this).MinValue) / (float)step + 0.5f) * step, ((AcceptableValueRange<int>)this).MinValue, ((AcceptableValueRange<int>)this).MaxValue); } public override bool IsValid(object value) { if (value is int num) { return num == (int)((AcceptableValueBase)this).Clamp((object)num); } return false; } } internal static class DebugStormControls { private const float DrawerWidth = 230f; private static bool expanded; internal static void DrawButtons(ConfigEntryBase unused) { if (GUILayout.Button(expanded ? "[-] Storm Debug Controls" : "[+] Storm Debug Controls", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(230f) })) { expanded = !expanded; } if (expanded) { GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(230f) }); DrawVanillaControls(); for (int i = 0; i < StormCatalog.Custom.Length; i++) { StormDefinition stormDefinition = StormCatalog.Custom[i]; DrawControls(stormDefinition.Name, stormDefinition.Id); } GUILayout.EndVertical(); } } private static void DrawVanillaControls() { bool enabled = GUI.enabled; GUI.enabled = enabled && TryGetVanillaContext(out var _, out var _, out var _); GUILayout.Space(4f); GUILayout.Label("Vanilla Storm (priority 1)", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(230f) }); if (GUILayout.Button("Summon", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(230f) })) { MoveVanillaStorm(summon: true); } if (GUILayout.Button("Push to outer edge", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(230f) })) { MoveVanillaStorm(summon: false); } GUI.enabled = enabled; } internal static bool MoveVanillaStorm(bool summon) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) if (!TryGetVanillaContext(out var storm, out var weatherStorms, out var player)) { return false; } float num = storm.GetRadius() + StormInfluenceService.GetWeatherRange(weatherStorms, null); Vector3 val = ((Component)storm).transform.position - player.position; val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { val = player.forward; val.y = 0f; } val = ((((Vector3)(ref val)).sqrMagnitude < 0.0001f) ? Vector3.forward : ((Vector3)(ref val)).normalized); Vector3 val2 = (summon ? player.position : (player.position + val * num)); val2.y = ((Component)storm).transform.position.y; ((Component)storm).transform.position = val2; storm.active = true; ParticleSystem val3 = StormAccess.BottomParticles.Invoke(storm); if ((Object)(object)val3 != (Object)null) { EmissionModule emission = val3.emission; ((EmissionModule)(ref emission)).enabled = Vector3.Distance(val2, player.position) <= StormAccess.ParticleDistance.Invoke(storm); } if (summon) { WindOverrideState.NotifyDebugSummon(StormKind.Vanilla); StormAccess.CurrentStorm.Invoke(weatherStorms) = storm; WeatherStorms.currentStormDistance = Vector3.Distance(val2, player.position); WanderingStormLightning component = ((Component)storm).GetComponent<WanderingStormLightning>(); if ((Object)(object)component != (Object)null) { StormAccess.LightningCooldown.Invoke(component) = 0f; } } Refresh(weatherStorms); BetterStormPlugin.Instance.LogFeatureInfo(summon ? "Debug summoned vanilla priority-1 storm." : ("Debug pushed vanilla priority-1 storm to outer edge " + num.ToString("0.0") + ".")); return true; } private static bool TryGetVanillaContext(out WanderingStorm storm, out WeatherStorms weatherStorms, out Transform player) { storm = null; weatherStorms = WeatherStorms.instance; Camera main = Camera.main; player = (((Object)(object)main != (Object)null) ? ((Component)main).transform : null); Region currentRegion = GameplayRegionResolver.GetCurrentRegion(); if ((Object)(object)BetterStormPlugin.Instance == (Object)null || !GameState.playing || (Object)(object)weatherStorms == (Object)null || (Object)(object)player == (Object)null || (Object)(object)currentRegion == (Object)null || currentRegion.stormCount < 1) { return false; } WanderingStorm[] array = StormAccess.Storms.Invoke(weatherStorms); if (array == null) { return false; } foreach (WanderingStorm val in array) { if ((Object)(object)val != (Object)null && ((Behaviour)val).isActiveAndEnabled && StormAccess.Priority.Invoke(val) == 1 && (Object)(object)((Component)val).GetComponent<ModStormController>() == (Object)null) { storm = val; return true; } } return false; } internal static bool Summon(CustomStormId id) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (!TryGetContext(id, out var controller, out var weatherStorms, out var player)) { return false; } ThunderPoolRegistry.Reset(controller); Vector3 position = player.position; controller.SetDebugPosition(position); controller.PrepareDebugMove(resetLightningCooldown: true); WindOverrideState.NotifyDebugSummon(controller.Definition.Kind); StormAccess.CurrentStorm.Invoke(weatherStorms) = controller.Storm; WeatherStorms.currentStormDistance = 0f; Refresh(weatherStorms); BetterStormPlugin.Instance.LogFeatureInfo("Debug summoned " + controller.Definition.Name + "."); return true; } internal static bool PushToOuterEdge(CustomStormId id) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) if (!TryGetContext(id, out var controller, out var weatherStorms, out var player)) { return false; } float weatherRange = StormInfluenceService.GetWeatherRange(weatherStorms, controller); float num = controller.Definition.Radius + weatherRange; Vector3 val = ((Component)controller).transform.position - player.position; val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { val = player.forward; val.y = 0f; } if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { val = Vector3.forward; } else { ((Vector3)(ref val)).Normalize(); } ThunderPoolRegistry.Reset(controller); Vector3 debugPosition = player.position + val * num; controller.SetDebugPosition(debugPosition); controller.PrepareDebugMove(resetLightningCooldown: false); Refresh(weatherStorms); BetterStormPlugin.Instance.LogFeatureInfo("Debug pushed " + controller.Definition.Name + " to outer edge " + num.ToString("0.0") + "."); return true; } private static void DrawControls(string label, CustomStormId id) { bool enabled = GUI.enabled; GUI.enabled = enabled && CanOperate(id); GUILayout.Space(4f); GUILayout.Label(label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(230f) }); if (GUILayout.Button("Summon", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(230f) })) { Summon(id); } if (GUILayout.Button("Push to outer edge", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(230f) })) { PushToOuterEdge(id); } GUI.enabled = enabled; } private static bool CanOperate(CustomStormId id) { BetterStormPlugin instance = BetterStormPlugin.Instance; ModStormController modStormController = ModStormFactory.Find(id); if ((Object)(object)instance != (Object)null && instance.IsEnabled(id) && GameState.playing && (Object)(object)modStormController != (Object)null && modStormController.ShouldBeActive() && (Object)(object)WeatherStorms.instance != (Object)null) { return (Object)(object)Camera.main != (Object)null; } return false; } private static bool TryGetContext(CustomStormId id, out ModStormController controller, out WeatherStorms weatherStorms, out Transform player) { controller = ModStormFactory.Find(id); weatherStorms = WeatherStorms.instance; player = (((Object)(object)Camera.main != (Object)null) ? ((Component)Camera.main).transform : null); if (!CanOperate(id) || (Object)(object)controller == (Object)null || (Object)(object)weatherStorms == (Object)null || (Object)(object)player == (Object)null) { BetterStormPlugin.Instance?.LogFeatureWarning("Debug storm action is unavailable for " + id.ToString() + "."); return false; } return true; } private static void Refresh(WeatherStorms weatherStorms) { weatherStorms.FindClosestStorm(); if ((Object)(object)weatherStorms.GetCurrentStorm() != (Object)null) { weatherStorms.ApplyStorm(); } WindOverrideState.Tick(); } } internal sealed class IndoorPrecipitationExclusion : MonoBehaviour { private sealed class Interior { internal Transform BoatModel; internal InteriorEffectsTrigger Volume; internal Collider Collider; internal bool IsActive { get { if ((Object)(object)BoatModel != (Object)null && (Object)(object)Volume != (Object)null && ((Behaviour)Volume).isActiveAndEnabled && (Object)(object)Collider != (Object)null && Collider.enabled && Collider.isTrigger && ((Component)Collider).gameObject.activeInHierarchy) { return ((Component)Collider).transform.IsChildOf(BoatModel); } return false; } } } private static readonly List<Interior> interiors = new List<Interior>(); private static float nextDiscovery; private ParticleSystem particles; private Interior[] selected; private Interior[] candidates; private float[] distances; private float nextSelection; private int lastReportedCount = -1; internal static void Attach(ParticleSystem target) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)target == (Object)null) && !((Object)(object)((Component)target).GetComponent<IndoorPrecipitationExclusion>() != (Object)null)) { IndoorPrecipitationExclusion indoorPrecipitationExclusion = ((Component)target).gameObject.AddComponent<IndoorPrecipitationExclusion>(); indoorPrecipitationExclusion.particles = target; TriggerModule trigger = target.trigger; indoorPrecipitationExclusion.selected = new Interior[((TriggerModule)(ref trigger)).maxColliderCount]; indoorPrecipitationExclusion.candidates = new Interior[((TriggerModule)(ref trigger)).maxColliderCount]; indoorPrecipitationExclusion.distances = new float[((TriggerModule)(ref trigger)).maxColliderCount]; ((TriggerModule)(ref trigger)).enabled = false; ((TriggerModule)(ref trigger)).inside = (ParticleSystemOverlapAction)1; ((TriggerModule)(ref trigger)).enter = (ParticleSystemOverlapAction)1; ((TriggerModule)(ref trigger)).outside = (ParticleSystemOverlapAction)0; ((TriggerModule)(ref trigger)).exit = (ParticleSystemOverlapAction)0; ((TriggerModule)(ref trigger)).radiusScale = 1f; for (int i = 0; i < ((TriggerModule)(ref trigger)).maxColliderCount; i++) { ((TriggerModule)(ref trigger)).SetCollider(i, (Component)null); } CollisionModule collision = target.collision; ((CollisionModule)(ref collision)).enabled = false; nextDiscovery = 0f; } } internal static void ResetCaches() { interiors.Clear(); nextDiscovery = 0f; } private static void DiscoverInteriors() { if (Time.unscaledTime < nextDiscovery) { return; } nextDiscovery = Time.unscaledTime + 1f; interiors.Clear(); BoatRefs[] array = Object.FindObjectsOfType<BoatRefs>(); foreach (BoatRefs val in array) { if ((Object)(object)val.boatModel == (Object)null) { continue; } InteriorEffectsTrigger[] componentsInChildren = ((Component)val.boatModel).GetComponentsInChildren<InteriorEffectsTrigger>(true); foreach (InteriorEffectsTrigger val2 in componentsInChildren) { Collider[] components = ((Component)val2).GetComponents<Collider>(); foreach (Collider collider in components) { interiors.Add(new Interior { BoatModel = val.boatModel, Volume = val2, Collider = collider }); } } } } private void Update() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)particles == (Object)null || selected == null) { return; } TriggerModule trigger = particles.trigger; bool flag = false; for (int i = 0; i < selected.Length; i++) { if (selected[i] != null && !selected[i].IsActive) { selected[i] = null; ((TriggerModule)(ref trigger)).SetCollider(i, (Component)null); flag = true; } } if (!GameState.playing) { ClearSlots(); } else { if (particles.particleCount == 0 || (!flag && Time.unscaledTime < nextSelection)) { return; } nextSelection = Time.unscaledTime + 0.25f; DiscoverInteriors(); Camera main = Camera.main; Vector3 val = (((Object)(object)main != (Object)null) ? ((Component)main).transform.position : ((Component)this).transform.position); for (int j = 0; j < candidates.Length; j++) { candidates[j] = null; distances[j] = float.PositiveInfinity; } foreach (Interior interior in interiors) { if (!interior.IsActive) { continue; } Bounds bounds = interior.Collider.bounds; float num = ((Bounds)(ref bounds)).SqrDistance(val); if (num > 40000f) { continue; } for (int k = 0; k < candidates.Length; k++) { if (!(num >= distances[k])) { for (int num2 = candidates.Length - 1; num2 > k; num2--) { candidates[num2] = candidates[num2 - 1]; distances[num2] = distances[num2 - 1]; } candidates[k] = interior; distances[k] = num; break; } } } int num3 = 0; for (int l = 0; l < selected.Length; l++) { Collider obj = selected[l]?.Collider; selected[l] = candidates[l]; Collider val2 = selected[l]?.Collider; if ((Object)(object)obj != (Object)(object)val2) { ((TriggerModule)(ref trigger)).SetCollider(l, (Component)(object)val2); } if ((Object)(object)val2 != (Object)null) { num3++; } } ((TriggerModule)(ref trigger)).enabled = num3 > 0; if (lastReportedCount != num3) { lastReportedCount = num3; BetterStormPlugin.Instance?.LogFeatureInfo(((Object)particles).name + ": " + num3 + "/" + selected.Length + " native ship interior triggers registered."); } } } private void ClearSlots() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)particles == (Object)null || selected == null) { return; } TriggerModule trigger = particles.trigger; ((TriggerModule)(ref trigger)).enabled = false; for (int i = 0; i < selected.Length; i++) { if (selected[i] != null) { selected[i] = null; ((TriggerModule)(ref trigger)).SetCollider(i, (Component)null); } } nextSelection = 0f; } private void OnDisable() { ClearSlots(); } } [HarmonyPatch(typeof(WanderingStormLightning), "LightningStrike")] internal static class UniversalLightningPatch { [HarmonyPrefix] private static bool Prefix(WanderingStormLightning __instance) { //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) BetterStormPlugin instance = BetterStormPlugin.Instance; if ((Object)(object)instance == (Object)null) { return true; } ModStormController componentInParent = ((Component)__instance).GetComponentInParent<ModStormController>(); if ((Object)(object)componentInParent != (Object)null && (!instance.IsEnabled(componentInParent.Definition.Id) || !componentInParent.Definition.SupportsLightning)) { return false; } LightningProfile lightningProfile = (((Object)(object)componentInParent != (Object)null) ? componentInParent.Definition.Lightning : StormCatalog.VanillaLightning); float num = Mathf.Max(0.01f, lightningProfile.Interval); StormAccess.LightningCooldown.Invoke(__instance) = Random.Range(num, num * 3f); Vector2 val = Random.insideUnitCircle * lightningProfile.SpawnRadius; ((Component)__instance).transform.localPosition = new Vector3(val.x, lightningProfile.StrikeHeight, val.y); Vector3 position = ((Component)__instance).transform.position; if ((Object)(object)Refs.observerMirror == (Object)null) { return false; } float num2 = Vector3.Distance(position, ((Component)Refs.observerMirror).transform.position); float delay = Mathf.Max(0f, num2 / 340f - 1.47f); if (num2 <= lightningProfile.SchedulingDistance) { AudioClip[] array = ((num2 > 1600f) ? __instance.farThunders : __instance.closeThunders); if (array != null && array.Length != 0) { AudioClip clip = array[Random.Range(0, array.Length)]; ThunderPoolRegistry.Play(__instance, position, clip, delay, lightningProfile.AudioSourceMaxDistance); } } Light val2 = StormAccess.LightningLight.Invoke(__instance); if ((Object)(object)val2 == (Object)null) { val2 = ((Component)__instance).GetComponent<Light>(); } ParticleSystem val3 = StormAccess.LightningParticles.Invoke(__instance); if ((Object)(object)val3 == (Object)null) { val3 = ((Component)__instance).GetComponent<ParticleSystem>(); } if ((Object)(object)val2 != (Object)null) { val2.range = lightningProfile.LightRange; StormAccess.LightningIntensity.Invoke(__instance) = lightningProfile.LightIntensity; GlobalLightningSettings.ApplyToLight(val2); } if ((Object)(object)val2 != (Object)null && (Object)(object)val3 != (Object)null && num2 <= lightningProfile.VisualMaximum) { ((Behaviour)val2).enabled = true; val2.intensity = lightningProfile.LightIntensity; StormAccess.LightningLightTimer.Invoke(__instance) = 0f; val3.Play(); } return false; } } internal static class ThunderPoolRegistry { private static readonly Dictionary<WanderingStormLightning, ThunderEmitterPool> Pools = new Dictionary<WanderingStormLightning, ThunderEmitterPool>(); internal static void Play(WanderingStormLightning owner, Vector3 fixedWorldPosition, AudioClip clip, float delay, float maximumDistance) { //IL_007f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)owner == (Object)null || (Object)(object)clip == (Object)null) { return; } if (!Pools.TryGetValue(owner, out var value) || value == null) { AudioSource val = StormAccess.LightningAudio1.Invoke(owner); if ((Object)(object)val == (Object)null) { val = StormAccess.LightningAudio2.Invoke(owner); } if ((Object)(object)val == (Object)null) { AudioSource[] components = ((Component)owner).GetComponents<AudioSource>(); if (components.Length != 0) { val = components[0]; } } if ((Object)(object)val == (Object)null) { return; } value = new ThunderEmitterPool(owner, val); Pools[owner] = value; } value.Play(fixedWorldPosition, clip, delay, maximumDistance); } internal static void Reset(ModStormController controller) { if ((Object)(object)controller == (Object)null) { return; } WanderingStormLightning[] componentsInChildren = ((Component)controller).GetComponentsInChildren<WanderingStormLightning>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if (Pools.TryGetValue(componentsInChildren[i], out var value)) { value.StopAll(); } } } internal static void Shutdown() { foreach (ThunderEmitterPool value in Pools.Values) { value?.Dispose(); } Pools.Clear(); } } internal sealed class ThunderEmitterPool { private sealed class Slot { internal GameObject Object; internal AudioSource Source; internal double BusyUntilDsp; } private const int MaximumEmitters = 30; private readonly WanderingStormLightning owner; private readonly AudioSource template; private readonly GameObject root; private readonly List<Slot> slots = new List<Slot>(); private double nextExhaustionWarningDsp; internal ThunderEmitterPool(WanderingStormLightning owner, AudioSource template) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown this.owner = owner; this.template = template; root = new GameObject("Better Storm fixed thunder pool"); if ((Object)(object)Refs.shiftingWorld != (Object)null) { root.transform.SetParent(Refs.shiftingWorld, true); } else { Object.DontDestroyOnLoad((Object)(object)root); } AddSlot(); AddSlot(); } internal void Play(Vector3 worldPosition, AudioClip clip, float delay, float maximumDistance) { //IL_00ac: Unknown result type (might be due to invalid IL or missing references) double dspTime = AudioSettings.dspTime; Slot slot = null; for (int i = 0; i < slots.Count; i++) { if (slots[i].BusyUntilDsp <= dspTime) { slot = slots[i]; break; } } if (slot == null && slots.Count < 30) { slot = AddSlot(); } if (slot == null) { if (dspTime >= nextExhaustionWarningDsp) { nextExhaustionWarningDsp = dspTime + 10.0; BetterStormPlugin.Instance?.LogFeatureWarning("Thunder emitter pool exhausted for " + ((Object)owner).name + "."); } } else { slot.Object.transform.position = worldPosition; slot.Source.minDistance = 250f; slot.Source.maxDistance = maximumDistance; slot.Source.clip = clip; double num = dspTime + (double)Mathf.Max(0f, delay); slot.BusyUntilDsp = num + (double)clip.length + 0.1; slot.Source.PlayScheduled(num); } } internal void StopAll() { for (int i = 0; i < slots.Count; i++) { if ((Object)(object)slots[i].Source != (Object)null) { slots[i].Source.Stop(); slots[i].Source.clip = null; } slots[i].BusyUntilDsp = 0.0; } } internal void Dispose() { StopAll(); if ((Object)(object)root != (Object)null) { Object.Destroy((Object)(object)root); } } private Slot AddSlot() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown GameObject val = new GameObject("Fixed thunder emitter"); val.transform.SetParent(root.transform, false); AudioSource val2 = val.AddComponent<AudioSource>(); CopySettings(template, val2); val2.playOnAwake = false; val2.loop = false; val2.minDistance = 250f; Slot slot = new Slot { Object = val, Source = val2, BusyUntilDsp = 0.0 }; slots.Add(slot); return slot; } private static void CopySettings(AudioSource from, AudioSource to) { //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Expected O, but got Unknown to.outputAudioMixerGroup = from.outputAudioMixerGroup; to.mute = from.mute; to.bypassEffects = from.bypassEffects; to.bypassListenerEffects = from.bypassListenerEffects; to.bypassReverbZones = from.bypassReverbZones; to.priority = from.priority; to.volume = from.volume; to.pitch = from.pitch; to.panStereo = from.panStereo; to.spatialBlend = from.spatialBlend; to.reverbZoneMix = from.reverbZoneMix; to.dopplerLevel = from.dopplerLevel; to.spread = from.spread; to.rolloffMode = from.rolloffMode; to.maxDistance = from.maxDistance; AudioSourceCurveType[] array = new AudioSourceCurveType[4]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); AudioSourceCurveType[] array2 = (AudioSourceCurveType[])(object)array; for (int i = 0; i < array2.Length; i++) { AnimationCurve customCurve = from.GetCustomCurve(array2[i]); if (customCurve != null) { to.SetCustomCurve(array2[i], new AnimationCurve(customCurve.keys)); } } } } internal static class GlobalLightningSettings { private static readonly Dictionary<Light, LightShadows> OriginalShadows = new Dictionary<Light, LightShadows>(); internal static void ApplyToLiveStorms() { WanderingStormLightning[] array = Resources.FindObjectsOfTypeAll<WanderingStormLightning>(); for (int i = 0; i < array.Length; i++) { Light val = StormAccess.LightningLight.Invoke(array[i]); if ((Object)(object)val == (Object)null) { val = ((Component)array[i]).GetComponent<Light>(); } ApplyToLight(val); } } internal static void ApplyToLight(Light light) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)light == (Object)null)) { if (!OriginalShadows.ContainsKey(light)) { OriginalShadows.Add(light, light.shadows); } light.shadows = (LightShadows)1; } } internal static void RestoreSnapshots() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) foreach (KeyValuePair<Light, LightShadows> originalShadow in OriginalShadows) { if ((Object)(object)originalShadow.Key != (Object)null) { originalShadow.Key.shadows = originalShadow.Value; } } OriginalShadows.Clear(); } } internal static class StormPositionCoordinates { internal static Vector3 ToSaveCoordinates(Vector3 runtimePosition) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) FloatingOriginManager instance = FloatingOriginManager.instance; if (!((Object)(object)instance != (Object)null)) { return runtimePosition; } return instance.ShiftingPosToRealPos(runtimePosition); } internal static Vector3 ToRuntimeCoordinates(Vector3 savedPosition) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) FloatingOriginManager instance = FloatingOriginManager.instance; if (!((Object)(object)instance != (Object)null)) { return savedPosition; } return instance.RealPosToShiftingPos(savedPosition); } } internal static class StormPositionPersistence { internal sealed class PositionOwner { private readonly CustomStormId stormId; private readonly string displayName; private readonly string betterStormV2Key; private bool loadCompleted; private bool hasLoadedPosition; private Vector3 loadedPosition; internal CustomStormId StormId => stormId; internal PositionOwner(CustomStormId stormId, string displayName, string betterStormV2Key) { this.stormId = stormId; this.displayName = displayName; this.betterStormV2Key = betterStormV2Key; } internal void BeginLoad() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) loadCompleted = false; hasLoadedPosition = false; loadedPosition = default(Vector3); } internal void Save() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) ModStormController modStormController = ModStormFactory.Find(stormId); if (!((Object)(object)modStormController == (Object)null)) { if (GameState.modData == null) { GameState.modData = new Dictionary<string, string>(); } Vector3 val = StormPositionCoordinates.ToSaveCoordinates(((Component)modStormController).transform.position); SaveData saveData = new SaveData { version = 2, x = val.x, y = val.y, z = val.z }; GameState.modData[betterStormV2Key] = JsonUtility.ToJson((object)saveData); } } internal void Load() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) loadCompleted = true; hasLoadedPosition = false; if (TryLoadKey(betterStormV2Key, out var position)) { loadedPosition = position; hasLoadedPosition = true; } ApplyLoadedPosition(ModStormFactory.Find(stormId)); } internal void ApplyLoadedPosition(ModStormController controller) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) if (loadCompleted && hasLoadedPosition && !((Object)(object)controller == (Object)null)) { ((Component)controller).transform.position = StormPositionCoordinates.ToRuntimeCoordinates(loadedPosition); controller.EnsureValidInitialPlacement(); } } internal void Reset() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) loadCompleted = false; hasLoadedPosition = false; loadedPosition = default(Vector3); } private bool TryLoadKey(string key, out Vector3 position) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) position = default(Vector3); if (GameState.modData == null || !GameState.modData.TryGetValue(key, out var value) || string.IsNullOrEmpty(value)) { return false; } try { SaveData saveData = JsonUtility.FromJson<SaveData>(value); if (saveData == null || saveData.version != 2 || !IsFinite(saveData.x) || !IsFinite(saveData.y) || !IsFinite(saveData.z)) { BetterStormPlugin.Instance?.LogFeatureWarning("Ignoring invalid " + displayName + " save data in key " + key + "."); return false; } position = new Vector3(saveData.x, saveData.y, saveData.z); return true; } catch (Exception ex) { BetterStormPlugin.Instance?.LogFeatureWarning("Ignoring invalid " + displayName + " save data in key " + key + ": " + ex.Message); return false; } } private static bool IsFinite(float value) { if (!float.IsNaN(value)) { return !float.IsInfinity(value); } return false; } } [Serializable] private sealed class SaveData { public int version; public float x; public float y; public float z; } private static readonly PositionOwner[] Owners = BuildOwners(); private static PositionOwner[] BuildOwners() { PositionOwner[] array = new PositionOwner[StormCatalog.Custom.Length]; for (int i = 0; i < StormCatalog.Custom.Length; i++) { StormDefinition stormDefinition = StormCatalog.Custom[i]; array[i] = new PositionOwner(stormDefinition.Id, stormDefinition.Name, stormDefinition.SaveKey); } return array; } internal static void BeginLoadAll() { for (int i = 0; i < Owners.Length; i++) { Owners[i].BeginLoad(); } } internal static void LoadAll() { for (int i = 0; i < Owners.Length; i++) { Owners[i].Load(); } } internal static void SaveAll() { for (int i = 0; i < Owners.Length; i++) { Owners[i].Save(); } } internal static void ResetAll() { for (int i = 0; i < Owners.Length; i++) { Owners[i].Reset(); } } internal static void ApplyLoadedPosition(CustomStormId id, ModStormController controller) { for (int i = 0; i < Owners.Length; i++) { if (Owners[i].StormId == id) { Owners[i].ApplyLoadedPosition(controller); break; } } } } [HarmonyPatch(typeof(SaveLoadManager), "LoadGame")] internal static class CustomStormBeginLoadPatch { [HarmonyPrefix] private static void Prefix() { WindOverrideState.RestoreImmediately(); RuntimeEffectLifecycle.ShutdownTransientEffects(); StormPositionPersistence.BeginLoadAll(); } } [HarmonyPatch(typeof(SaveLoadManager), "SaveModData")] internal static class CustomStormSavePatch { [HarmonyPostfix] private static void Postfix() { StormPositionPersistence.SaveAll(); } } [HarmonyPatch(typeof(SaveLoadManager), "LoadModData")] internal static class CustomStormLoadPatch { [HarmonyPostfix] private static void Postfix() { StormPositionPersistence.LoadAll(); } } [BepInPlugin("DogEggz.BetterStorm", "Better Storm", "1.1.6")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class BetterStormPlugin : BaseUnityPlugin { public const string PluginGuid = "DogEggz.BetterStorm"; public const string PluginName = "Better Storm"; public const string PluginVersion = "1.1.6"; public const string ChaoticWindGuid = "com.pete.sailwind.windconfigurator"; public const string ClimateGuid = "com.raddude.climate"; public const string BorderExpanderGuid = "com.nandbrew.borderexpander"; private Harmony harmony; private readonly Dictionary<CustomStormId, ConfigEntry<bool>> stormEnabledEntries = new Dictionary<CustomStormId, ConfigEntry<bool>>(); internal static BetterStormPlugin Instance { get; private set; } internal ConfigEntry<bool> DisableSeasonLimits { get; private set; } internal ConfigEntry<float> FallbackBonusCap { get; private set; } internal ConfigEntry<int> RelocationDistance { get; private set; } private void Awake() { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown Instance = this; if (!StormCatalog.TryValidate(out var error)) { ((BaseUnityPlugin)this).Logger.LogError((object)("Better Storm cannot start: " + error)); Instance = null; ((Behaviour)this).enabled = false; return; } BindConfiguration(); if (ChaoticWindCompatibility.HasLegacyStormOwner()) { ((BaseUnityPlugin)this).Logger.LogError((object)"Better Storm cannot start while the legacy storm-owning Chaotic Wind 1.3.4 build is loaded. Install the reduced Chaotic Wind companion separately, or remove Chaotic Wind."); Instance = null; ((Behaviour)this).enabled = false; return; } Subscribe(); harmony = new Harmony("DogEggz.BetterStorm"); harmony.PatchAll(Assembly.GetExecutingAssembly()); ClimateCompatibility.Install(harmony); ApplyRuntimeSettings(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Better Storm 1.1.6 loaded."); } private void Update() { WindOverrideState.Tick(); SandstormVisuals.Tick(); GentleSnowVisuals.Tick(); SandstormDirt.Tick(); } private void OnDestroy() { Unsubscribe(); WindOverrideState.RestoreImmediately(); RuntimeEffectLifecycle.ShutdownTransientEffects(); GlobalLightningSettings.RestoreSnapshots(); ModStormFactory.Shutdown(); StormPositionPersistence.ResetAll(); if (harmony != null) { harmony.UnpatchSelf(); } if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } private void BindConfiguration() { //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Expected O, but got Unknown //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Expected O, but got Unknown for (int i = 0; i < StormCatalog.Custom.Length; i++) { StormDefinition stormDefinition = StormCatalog.Custom[i]; stormEnabledEntries.Add(stormDefinition.Id, ((BaseUnityPlugin)this).Config.Bind<bool>("Custom Storms", "Enable " + stormDefinition.Name, true, stormDefinition.EnableDescription)); } DisableSeasonLimits = ((BaseUnityPlugin)this).Config.Bind<bool>("Climate Compatibility", "Disable Seasonal Storm Limits", false, "Allow Hurricane, Sandstorm, Dry Thunderstorm, and Gentle Snow year-round, even while Climate Custom Winds is enabled."); FallbackBonusCap = BindSteppedSlider("Wind", "Storm + Ocean Bonus Cap", 40f, 0f, 100f, 1f, "Used when Chaotic Wind is not installed. Chaotic Wind's setting has priority when both mods are installed.", 10); RelocationDistance = ((BaseUnityPlugin)this).Config.Bind<int>("Storms", "Storm Relocation Distance", 44000, new ConfigDescription("Distance at which a custom storm is recycled across the player. Increasing this reduces the chance of encountering a storm.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(18000, 90000), new object[1] { new ConfigurationManagerAttributes { ShowRangeAsPercent = false, Order = 10 } })); ((BaseUnityPlugin)this).Config.Bind<string>("Debug", "Custom Storm Controls", string.Empty, new ConfigDescription("Always-available storm controls. Expand the compact panel to summon or push the priority-1 vanilla storm or a custom storm to its outer weather edge.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { CustomDrawer = DebugStormControls.DrawButtons, HideDefaultButton = true, HideSettingName = true, Order = -10 } })); } private ConfigEntry<float> BindSteppedSlider(string section, string key, float defaultValue, float minimum, float maximum, float step, string description, int order) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown return ((BaseUnityPlugin)this).Config.Bind<float>(section, key, defaultValue, new ConfigDescription(description, (AcceptableValueBase)(object)new SteppedAcceptableValueRange(minimum, maximum, step), new object[1] { new ConfigurationManagerAttributes { ShowRangeAsPercent = false, Order = order } })); } private ConfigEntry<int> BindSteppedIntSlider(string section, string key, int defaultValue, int minimum, int maximum, int step, string description, int order) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown return ((BaseUnityPlugin)this).Config.Bind<int>(section, key, defaultValue, new ConfigDescription(description, (AcceptableValueBase)(object)new SteppedAcceptableIntRange(minimum, maximum, step), new object[1] { new ConfigurationManagerAttributes { ShowRangeAsPercent = false, Order = order } })); } private void Subscribe() { foreach (ConfigEntry<bool> value in stormEnabledEntries.Values) { value.SettingChanged += OnStormToggleChanged; } DisableSeasonLimits.SettingChanged += OnStormToggleChanged; } private void Unsubscribe() { foreach (ConfigEntry<bool> value in stormEnabledEntries.Values) { value.SettingChanged -= OnStormToggleChanged; } if (DisableSeasonLimits != null) { DisableSeasonLimits.SettingChanged -= OnStormToggleChanged; } } private void OnStormToggleChanged(object sender, EventArgs e) { ModStormFactory.ApplyEnabledState(); if (!IsEnabled(CustomStormId.Sandstorm)) { SandstormVisuals.DeactivateImmediately(); SandstormDirt.Reset(); } if (!IsEnabled(CustomStormId.GentleSnow)) { GentleSnowVisuals.DeactivateImmediately(); } RefreshCurrentStorm(); WindOverrideState.Tick(); } private void ApplyRuntimeSettings() { ModStormFactory.ApplyEnabledState(); ModStormFactory.RefreshSandstormCloudVisuals(); GlobalLightningSettings.ApplyToLiveStorms(); } internal bool IsEnabled(CustomStormId id) { if (stormEnabledEntries.TryGetValue(id, out var value)) { return value.Value; } return false; } internal void LogFeatureInfo(string message) { ((BaseUnityPlugin)this).Logger.LogInfo((object)message); } internal void LogFeatureWarning(string message) { ((BaseUnityPlugin)this).Logger.LogWarning((object)message); } internal void LogFeatureError(string message) { ((BaseUnityPlugin)this).Logger.LogError((object)message); } internal static void RefreshCurrentStorm() { WeatherStorms instance = WeatherStorms.instance; if (GameState.playing && !((Object)(object)instance == (Object)null)) { instance.FindClosestStorm(); if ((Object)(object)instance.GetCurrentStorm() != (Object)null) { instance.ApplyStorm(); } } } } internal static class RuntimeEffectLifecycle { internal static void ShutdownTransientEffects() { ThunderPoolRegistry.Shutdown(); StormRainVisuals.Shutdown(); RainEffects.RestoreRainSettings(); SandstormVisuals.Shutdown(); GentleSnowVisuals.Shutdown(); IndoorPrecipitationExclusion.ResetCaches(); SandstormDirt.Reset(); } } internal static class ChaoticWindCompatibility { internal static bool IsLoaded => Chainloader.PluginInfos.ContainsKey("com.pete.sailwind.windconfigurator"); internal static bool HasLegacyStormOwner() { if (!Chainloader.PluginInfos.TryGetValue("com.pete.sailwind.windconfigurator", out var value) || value == null || (Object)(object)value.Instance == (Object)null) { return false; } return ((object)value.Instance).GetType().Assembly.GetType("ChaoticWind.StormInfluenceService", throwOnError: false) != null; } internal static bool TryGetFloat(string section, string key, out float value) { value = 0f; if (!TryGetPlugin(out var info)) { return false; } ConfigEntry<float> val = default(ConfigEntry<float>); if (!info.Instance.Config.TryGetEntry<float>(section, key, ref val)) { return false; } value = val.Value; return true; } internal static bool TryGetBool(string section, string key, out bool value) { value = false; if (!TryGetPlugin(out var info)) { return false; } ConfigEntry<bool> val = default(ConfigEntry<bool>); if (!info.Instance.Config.TryGetEntry<bool>(section, key, ref val)) { return false; } value = val.Value; return true; } private static bool TryGetPlugin(out PluginInfo info) { if (Chainloader.PluginInfos.TryGetValue("com.pete.sailwind.windconfigurator", out info) && info != null) { return (Object)(object)info.Instance != (Object)null; } return false; } } internal enum CustomStormId { Squall1, Squall2, Squall3, Hurricane, DryThunderstorm, Sandstorm, GentleSnow } internal enum StormKind { Vanilla, Squall, Hurricane, DryThunderstorm, Sandstorm, GentleSnow } internal readonly struct LightningProfile { internal readonly float Interval; internal readonly float SpawnRadius; internal readonly float SchedulingDistance; internal readonly float AudioSourceMaxDistance; internal readonly float LightRange; internal readonly float StrikeHeight; internal readonly float LightIntensity; internal float VisualMaximum => LightRange + 500f; internal LightningProfile(float interval, float spawnRadius, float schedulingDistance, float lightRange, float strikeHeight, float lightIntensity) : this(interval, spawnRadius, schedulingDistance, schedulingDistance, lightRange, strikeHeight, lightIntensity) { } internal LightningProfile(float interval, float spawnRadius, float schedulingDistance, float audioSourceMaxDistance, float lightRange, float strikeHeight, float lightIntensity) { Interval = interval; SpawnRadius = spawnRadius; SchedulingDistance = schedulingDistance; AudioSourceMaxDistance = audioSourceMaxDistance; LightRange = lightRange; StrikeHeight = strikeHeight; LightIntensity = lightIntensity; } } internal sealed class StormDefinition { internal string Name; internal string EnableDescription; internal string SaveKey; internal CustomStormId Id; internal StormKind Kind; internal Vector3 InitialOffset; internal int Priority; internal float Radius; internal float ParticleDistance; internal float MoveSpeed; internal bool UsesFixedWeatherRange; internal float FixedWeatherRange; internal float WindCoefficient; internal float? RainTarget; internal bool SuppressRainParticles; internal bool SuppressFog; internal bool SupportsLightning; internal HashSet<string> AllowedRegions; internal ClimateSeasonMask AllowedClimateSeasons = ClimateSeasonMask.All; internal float? MinimumLatitude; internal LightningProfile Lightning; internal bool AllowsRegion(string regionName) { if (AllowedRegions != null) { return AllowedRegions.Contains(regionName); } return true; } } internal static class StormCatalog { internal const float CloseThunderDistance = 1600f; internal const float AudioMinimumDistance = 250f; internal const float VisualPadding = 500f; internal static readonly LightningProfile VanillaLightning = new LightningProfile(16f, 1500f, 5500f, 4980f, 500f, 3f); internal static readonly StormDefinition[] Custom = new StormDefinition[7] { Squall("Squall 1", CustomStormId.Squall1, "DogEggz.BetterStorm.squall-1-position.v2", new Vector3(18000f, 0f, 0f), 1, 13f), Squall("Squall 2", CustomStormId.Squall2, "DogEggz.BetterStorm.squall-2-position.v2", new Vector3(-18000f, 0f, 0f), 2, 26f), Squall("Squall 3", CustomStormId.Squall3, "DogEggz.BetterStorm.squall-3-position.v2", new Vector3(0f, 0f, 18000f), 3, 19f), new StormDefinition { Name = "Hurricane", EnableDescription = "Enable the priority-2 Hurricane in Medi East, Emerald, and Emerald Lagoon only.", SaveKey = "DogEggz.BetterStorm.hurricane-position.v2", Id = CustomStormId.Hurricane, Kind = StormKind.Hurricane, InitialOffset = new Vector3(0f, 0f, -24000f), Priority = 2, Radius = 6000f, ParticleDistance = 18000f, MoveSpeed = 10f, UsesFixedWeatherRange = false, WindCoefficient = 34f, RainTarget = 13f, AllowedRegions = new HashSet<string>(StringComparer.Ordinal) { "Region Medi East", "Region Emerald (new smaller)", "Region Emerald Lagoon" }, AllowedClimateSeasons = (ClimateSeasonMask.Summer | ClimateSeasonMask.Autumn), SupportsLightning = true, Lightning = new LightningProfile(12f, 3000f, 18000f, 18000f, 9960f, 500f, 4f) }, new StormDefinition { Name = "Dry Thunderstorm", EnableDescription = "Enable the priority-2 Dry Thunderstorm in Medi and Medi East only.", SaveKey = "DogEggz.BetterStorm.dry-thunderstorm-position.v2", Id = CustomStormId.DryThunderstorm, Kind = StormKind.DryThunderstorm, InitialOffset = new Vector3(-24000f, 0f, 24000f), Priority = 2, Radius = 1800f, ParticleDistance = 2700f, MoveSpeed = 9f, UsesFixedWeatherRange = true, FixedWeatherRange = 900f, WindCoefficient = 30f, RainTarget = null, SuppressRainParticles = true, SuppressFog = true, AllowedClimateSeasons = (ClimateSeasonMask.Winter | ClimateSeasonMask.Autumn), SupportsLightning = true, AllowedRegions = new HashSet<string>(StringComparer.Ordinal) { "Region Medi", "Region Medi East" }, Lightning = new LightningProfile(1f, 1800f, 3200f, 6400f, 2394f, 500f, 4.5f) }, new StormDefinition { Name = "Sandstorm", EnableDescription = "Enable the priority-1 dry Sandstorm in Al'Ankh only.", SaveKey = "DogEggz.BetterStorm.sandstorm-position.v2", Id = CustomStormId.Sandstorm, Kind = StormKind.Sandstorm, InitialOffset = new Vector3(24000f, 0f, 24000f), Priority = 1, Radius = 2250f, ParticleDistance = 3600f, MoveSpeed = 14f, UsesFixedWeatherRange = true, FixedWeatherRange = 1350f, WindCoefficient = 26f, RainTarget = null, SuppressRainParticles = true, AllowedClimateSeasons = (ClimateSeasonMask.Spring | ClimateSeasonMask.Summer), SupportsLightning = false, AllowedRegions = new HashSet<string>(StringComparer.Ordinal) { "Region Al'ankh" } }, new StormDefinition { Name = "Gentle Snow", EnableDescription = "Enable the priority-1 Gentle Snow above latitude 38.", SaveKey = "DogEggz.BetterStorm.gentle-snow-position.v2", Id = CustomStormId.GentleSnow, Kind = StormKind.GentleSnow, InitialOffset = new Vector3(12000f, 0f, 22000f), Priority = 1, Radius = 2500f, ParticleDistance = 0f, MoveSpeed = 7f, UsesFixedWeatherRange = true, FixedWeatherRange = 2000f, WindCoefficient = 0f, RainTarget = null, SuppressRainParticles = true, SuppressFog = true, AllowedClimateSeasons = (ClimateSeasonMask.Winter | ClimateSeasonMask.Spring), SupportsLightning = false, MinimumLatitude = 38f } }; private static StormDefinition Squall(string name, CustomStormId id, string saveKey, Vector3 initialOffset, int priority, float windCoefficient) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) return new StormDefinition { Name = name, EnableDescription = "Enable the priority-" + priority + " Squall.", SaveKey = saveKey, Id = id, Kind = StormKind.Squall, InitialOffset = initialOffset, Priority = priority, Radius = 1350f, ParticleDistance = 1350f, MoveSpeed = 24f, UsesFixedWeatherRange = true, FixedWeatherRange = 450f, WindCoefficient = windCoefficient, RainTarget = 25f, SupportsLightning = true, Lightning = new LightningProfile(8f, 1350f, 1800f, 3600f, 1800f, 500f, 3f) }; } internal static StormDefinition Find(CustomStormId id) { for (int i = 0; i < Custom.Length; i++) { if (Custom[i].Id == id) { return Custom[i]; } } return null; } internal static bool TryValidate(out string error) { error = null; if (Custom.Length != Enum.GetValues(typeof(CustomStormId)).Length) { error = "The custom-storm catalog does not cover every storm ID."; return false; } HashSet<CustomStormId> hashSet = new HashSet<CustomStormId>(); HashSet<string> hashSet2 = new HashSet<string>(StringComparer.Ordinal); HashSet<string> hashSet3 = new HashSet<string>(StringComparer.Ordinal); for (int i = 0; i < Custom.Length; i++) { StormDefinition stormDefinition = Custom[i]; if (stormDefinition == null || string.IsNullOrEmpty(stormDefinition.Name) || string.IsNullOrEmpty(stormDefinition.EnableDescription) || string.IsNullOrEmpty(stormDefinition.SaveKey) || !hashSet.Add(stormDefinition.Id) || !hashSet2.Add(stormDefinition.Name) || !hashSet3.Add(stormDefinition.SaveKey)) { error = "The custom-storm catalog contains missing or duplicate identity metadata at index " + i + "."; return false; } if (stormDefinition.SupportsLightning && (stormDefinition.Lightning.SchedulingDistance <= 0f || stormDefinition.Lightning.AudioSourceMaxDistance < stormDefinition.Lightning.SchedulingDistance)) { error = stormDefinition.Name + " has invalid lightning audio distances."; return false; } if (stormDefinition.MinimumLatitude.HasValue && (stormDefinition.MinimumLatitude.Value < -90f || stormDefinition.MinimumLatitude.Value > 90f)) { error = stormDefinition.Name + " has an invalid minimum latitude."; return false; } } return true; } } internal static class StormAccess { internal static readonly FieldRef<WeatherStorms, WanderingStorm[]> Storms = AccessTools.FieldRefAccess<WeatherStorms, WanderingStorm[]>("storms"); internal static readonly FieldRef<WeatherStorms, float> CurrentStormRange = AccessTools.FieldRefAccess<WeatherStorms, float>("currentStormRange"); internal static readonly FieldRef<WeatherStorms, WanderingStorm> CurrentStorm = AccessTools.FieldRefAccess<WeatherStorms, WanderingStorm>("currentStorm"); internal static readonly FieldRef<WeatherStorms, float> RainBorder = AccessTools.FieldRefAccess<WeatherStorms, float>("rainBorder"); internal static readonly FieldRef<WeatherStorms, float> CloudyBorder = AccessTools.FieldRefAccess<WeatherStorms, float>("cloudyBorder"); internal static readonly FieldRef<Weather, WeatherParticlesSettings> FinalParticles = AccessTools.FieldRefAccess<Weather, WeatherParticlesSettings>("finalParticles"); internal static readonly FieldRef<Wind, float> WindTimer = AccessTools.FieldRefAccess<Wind, float>("timer"); internal static readonly FieldRef<Wind, float> GustTimer = AccessTools.FieldRefAccess<Wind, float>("gustTimer"); internal static readonly FieldRef<WanderingStorm, int> Priority = AccessTools.FieldRefAccess<WanderingStorm, int>("stormPriority"); internal static readonly FieldRef<WanderingStorm, float> ParticleDistance = AccessTools.FieldRefAccess<WanderingStorm, float>("particlesDistance"); internal static readonly FieldRef<WanderingStorm, float> Radius = AccessTools.FieldRefAccess<WanderingStorm, float>("stormRadius"); internal static readonly FieldRef<WanderingStorm, ParticleSystem> TopParticles = AccessTools.FieldRefAccess<WanderingStorm, ParticleSystem>("topParticles"); internal static readonly FieldRef<WanderingStorm, ParticleSystem> BottomParticles = AccessTools.FieldRefAccess<WanderingStorm, ParticleSystem>("bottomParticles"); internal static readonly FieldRef<WanderingStormLightning, float> LightningInterval = AccessTools.FieldRefAccess<WanderingStormLightning, float>("lightningInterval"); internal static readonly FieldRef<WanderingStormLightning, float> LightningIntensity = AccessTools.FieldRefAccess<WanderingStormLightning, float>("lightIntensity"); internal static readonly FieldRef<WanderingStormLightning, Light> LightningLight = AccessTools.FieldRefAccess<WanderingStormLightning, Light>("light"); internal static readonly FieldRef<WanderingStormLightning, ParticleSystem> LightningParticles = AccessTools.FieldRefAccess<WanderingStormLightning, ParticleSystem>("particles"); internal static readonly FieldRef<WanderingStormLightning, AudioSource> LightningAudio1 = AccessTools.FieldRefAccess<WanderingStormLightning, AudioSource>("audio1"); internal static readonly FieldRef<WanderingStormLightning, AudioSource> LightningAudio2 = AccessTools.FieldRefAccess<WanderingStormLightning, AudioSource>("audio2"); internal static readonly FieldRef<WanderingStormLightning, float> LightningCooldown = AccessTools.FieldRefAccess<WanderingStormLightning, float>("lightningCooldown"); internal static readonly FieldRef<WanderingStormLightning, float> LightningLightTimer = AccessTools.FieldRefAccess<WanderingStormLightning, float>("lightTimer"); internal static readonly FieldRef<CleanableObject, Texture2D> DirtCoat = AccessTools.FieldRefAccess<CleanableObject, Texture2D>("dirtCoat"); internal static readonly FieldInfo RegionBlenderTargetRegion = AccessTools.Field(typeof(RegionBlender), "currentTargetRegion"); } internal static class GameplayRegionResolver { internal static Region GetCurrentRegion() { if ((Object)(object)RegionBlender.instance != (Object)null && StormAccess.RegionBlenderTargetRegion != null) { object? value = StormAccess.RegionBlenderTargetRegion.GetValue(RegionBlender.instance); Region val = (Region)((value is Region) ? value : null); if ((Object)(object)val != (Object)null) { return val; } } if (!((Object)(object)Weather.instance != (Object)null)) { return null; } return Weather.instance.currentRegion; } } internal readonly struct StormInfluence { internal readonly StormDefinition Definition; internal readonly float CenterDistance; internal readonly float Radius; internal readonly float WeatherRange; internal readonly float OuterEdge; internal readonly float WeatherLerp; internal bool Inside => CenterDistance < OuterEdge; internal float NormalizedDistance => Mathf.Clamp01((CenterDistance - Radius) / Mathf.Max(0.0001f, WeatherRange)); internal StormKind Kind { get { if (Definition == null) { return StormKind.Vanilla; } return Definition.Kind; } } internal float WindLerp => Mathf.InverseLerp(OuterEdge, Radius * 0.5f, CenterDistance); internal bool IsSquall { get { if (Definition != null) { return Definition.Kind == StormKind.Squall; } return false; } } internal bool IsSandstorm { get { if (Definition != null) { return Definition.Kind == StormKind.Sandstorm; } return false; } } internal bool IsGentleSnow { get { if (Definition != null) { return Definition.Kind == StormKind.GentleSnow; } return false; } } internal StormInfluence(ModStormController controller, float centerDistance, float radius, float weatherRange) { Definition = (((Object)(object)controller != (Object)null) ? controller.Definition : null); CenterDistance = centerDistance; Radius = radius; WeatherRange = weatherRange; OuterEdge = radius + weatherRange; WeatherLerp = Mathf.InverseLerp(OuterEdge, radius, centerDistance); } } internal static class GentleSnowRules { internal const float MinimumLatitude = 38f; internal const float ParkingLatitudeBuffer = 0.05f; internal const float WorldUnitsPerLatitude = 9000f; internal const float MaximumWindTarget = 18f; internal const float FinalLerpSpeed = 0.25f; internal const float FullSnowNormalizedDistance = 0.33f; internal static bool IsLatitudeAllowed(float latitude, float minimumLatitude) { return latitude >= minimumLatitude; } internal static float GetParkingLatitude(float minimumLatitude) { return minimumLatitude + 0.05f; } internal static float GetMinimumDistanceToLatitude(float playerLatitude, float targetLatitude) { return Mathf.Max(0f, targetLatitude - playerLatitude) * 9000f; } internal static bool ShouldPark(float playerLatitude, float minimumLatitude, float relocationDistance) { return GetMinimumDistanceToLatitude(playerLatitude, GetParkingLatitude(minimumLatitude)) > relocationDistance; } internal static float GetSnowEmissionLerp(float normalizedDistance) { return Mathf.InverseLerp(1f, 0.33f, normalizedDistance); } } internal static class StormSelectionRules { internal const float RetainUntilNormalizedDistance = 0.66f; internal const float SandstormYieldNormalizedDistance = 0.5f; internal static bool ShouldRetainCurrent(float normalizedDistance) { return normalizedDistance <= 0.66f; } internal static bool ShouldSandstormYield(StormKind selectedKind, StormKind candidateKind, float candidateDistance, float candidateRadius, float candidateWeatherRange) { if (selectedKind == StormKind.Sandstorm && candidateKind != StormKind.Sandstorm) { return candidateDistance < candidateRadius + candidateWeatherRange * 0.5f; } return false; } internal static bool ShouldDryThunderstormYield(StormKind selectedKind, StormKind candidateKind, float candidateDistance, float candidateRadius) { if (selectedKind == StormKind.DryThunderstorm && candidateKind == StormKind.Squall) { return candidateDistance < candidateRadius; } return false; } internal static bool IsBetterCandidate(float normalizedDistance, float distance, float bestNormalizedDistance, float bestDistance) { if (!(normalizedDistance < bestNormalizedDistance)) { if (Mathf.Approximately(normalizedDistance, bestNormalizedDistance)) { return distance < bestDistance; } return false; } return true; } } internal static class StormInfluenceService { internal static StormInfluence Evaluate(WeatherStorms weatherStorms, WanderingStorm storm, float distance) { ModStormController controller = (((Object)(object)storm != (Object)null) ? ((Component)storm).GetComponent<ModStormController>() : null); float radius = (((Object)(object)storm != (Object)null) ? storm.GetRadius() : 0f); float weatherRange = GetWeatherRange(weatherStorms, controller); return new StormInfluence(controller, distance, radius, weatherRange); } internal static float GetWeatherRange(WeatherStorms weatherStorms, ModStormController controller) { if ((Object)(object)controller != (Object)null && controller.Definition.UsesFixedWeatherRange) { return controller.Definition.FixedWeatherRange; } if (!((Object)(object)weatherStorms != (Object)null)) { return 0f; } return Mathf.Max(0f, StormAccess.CurrentStormRange.Invoke(weatherStorms)); } internal static bool TryGetCurrent(out StormInfluence influence) { return TryGetCurrent(WeatherStorms.currentStormDistance, out influence); } internal static bool TryGetCurrent(float distance, out StormInfluence influence) { influence = default(StormInfluence); WeatherStorms instance = WeatherStorms.instance; WanderingStorm val = (((Object)(object)instance != (Object)null) ? instance.GetCurrentStorm() : null); if ((Object)(object)instance == (Object)null || (Object)(object)val == (Object)null || !val.active) { return false; } influence = Evaluate(instance, val, distance); return influence.Inside; } internal static float GetEffectiveWindLerp(float originalStart, float originalEnd, float distance) { if ((Object)(object)BetterStormPlugin.Instance == (Object)null) { return Mathf.InverseLerp(originalStart, originalEnd, distance); } if (!TryGetCurrent(distance, out var influence)) { return 0f; } float num = ((influence.Definition != null) ? influence.Definition.WindCoefficient : 26f); return influence.WindLerp * num / 26f; } } internal readonly struct StormRainProfile { internal readonly float Emission; internal readonly int MaximumParticles; internal readonly float StreakLength; internal readonly float SimulationSpeed; internal readonly float MinimumSize; internal readonly float MaximumSize; internal readonly float RainVolume; internal StormRainProfile(float emission, float streakLength, float simulationSpeed, float minimumSize, float maximumSize, float rainVolume) { Emission = emission; MaximumParticles = StormRainRules.CalculateParticleCapacity(emission); StreakLength = streakLength; SimulationSpeed = simulationSpeed; MinimumSize = minimumSize; MaximumSize = maximumSize; RainVolume = rainVolume; } } internal static class StormRainRules { internal const float Radius = 120f; internal const float SpawnHeight = 50f; internal const float MinimumLifetime = 2f; internal const float MaximumLifetime = 2.6f; internal const float MinimumSize = 0.04f; internal const float MaximumSize = 0.1f; internal const float MinimumAlpha = 0.02f; internal const float MaximumAlpha = 0.12f; internal const float FallSpeed = 25f; internal const float WindInfluence = 0.6f; internal const float Gravity = 0f; internal const float MaximumScreenSize = 0.5f; internal const float Turbulence = 0f; internal const float TurbulenceFrequency = 0.22f; internal const float TurbulenceScrollSpeed = 0.2f; internal static int CalculateParticleCapacity(float emission) { return (int)Math.Ceiling((double)(emission * 2.6f) * 1.2 / 2000.0) * 2000; } internal static bool IsRainStorm(StormKind kind) { if (kind != StormKind.Vanilla && kind != StormKind.Squall) { return kind == StormKind.Hurricane; } return true; } internal static bool ShouldUseStormRain(bool insideStorm, StormKind kind, float baseRain) { if (insideStorm && IsRainStorm(kind)) { return baseRain > 0f; } return false; } internal static StormRainProfile GetProfile(StormKind kind) { return kind switch { StormKind.Vanilla => new StormRainProfile(7000f, 6f, 1.8f, 0.08f, 0.16f, 0.35f), StormKind.Squall => new StormRainProfile(25000f, 12f, 3f, 0.12f, 0.24f, 0.6f), StormKind.Hurricane => new StormRainProfile(14000f, 8f, 2.3f, 0.08f, 0.2f, 0.5f), _ => throw new ArgumentOutOfRangeException("kind"), }; } internal static float GetBaseRain(float distance, float cloudyBorder, float rainBorder, float cloudyRain, float lightRain, float peakRain) { if (distance >= cloudyBorder || cloudyBorder <= 0f) { return 0f; } if (distance > rainBorder) { return Mathf.Max(0f, Mathf.Lerp(cloudyRain, lightRain, Mathf.InverseLerp(cloudyBorder, rainBorder, distance))); } return Mathf.Max(0f, Mathf.Lerp(lightRain, peakRain, Mathf.InverseLerp(rainBorder, 0f, distance))); } internal static float GetVisualStrength(float baseRain, float peakRain) { if (!(peakRain > 0f)) { return 0f; } return Mathf.Clamp01(baseRain / peakRain); } } internal static class StormRainVisuals { private static readonly Color RainColor = new Color(115f / 136f, 0.9552738f, 1f, 1f); private static ParticleSystem sourceOuterRain; private static ParticleSystem customRain; private static ParticleSystemRenderer renderer; private static ParticleSystemRenderer sourceRenderer; private static bool active; internal static bool ApplyWeather(StormKind kind, float intensity, float strength, ParticleSystem rain, ParticleSystem outerRain, ParticleSystem splash) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) if (!StormRainRules.IsRainStorm(kind) || (Object)(object)rain == (Object)null || (Object)(object)outerRain == (Object)null) { return false; } EnsureInitialized(outerRain); if ((Object)(object)customRain == (Object)null) { return false; } StormRainProfile profile = StormRainRules.GetProfile(kind); MainModule main = customRain.main; ((MainModule)(ref main)).maxParticles = Math.Max(profile.MaximumParticles, customRain.particleCount); ((MainModule)(ref main)).simulationSpeed = profile.SimulationSpeed; ((MainModule)(ref main)).startSize = new MinMaxCurve(profile.MinimumSize, profile.MaximumSize); if ((Object)(object)renderer != (Object)null) { renderer.lengthScale = profile.StreakLength; } active = true; UpdateMotion(); CustomPrecipitationParticles.SetEmissionRate(rain, 0f); CustomPrecipitationParticles.SetEmissionRate(outerRain, 0f); CustomPrecipitationParticles.SetEmissionRate(customRain, profile.Emission * Mathf.Clamp01(strength)); RainEffects.ApplySplashSettings(splash); CustomPrecipitationParticles.SetEmissionRate(splash, intensity * 1000f * RainEffects.GetEmissionMultiplier(kind)); GameState.rainIntensity = intensity; return true; } internal static void Tick() { if (!((Object)(object)customRain == (Object)null)) { RefreshMaterial(); if (active) { UpdateMotion(); } } } internal static void Deactivate() { CustomPrecipitationParticles.SetEmissionRate(customRain, 0f); active = false; } internal static void Shutdown() { Deactivate(); CustomPrecipitationParticles.Clear(customRain); if ((Object)(object)customRain != (Object)null) { Object.Destroy((Object)(object)((Component)customRain).gameObject); } sourceOuterRain = null; customRain = null; renderer = null; sourceRenderer = null; } private static void EnsureInitialized(ParticleSystem source) { //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_02f2: Unknown result type (might be due to invalid IL or missing references) Transform val = (((Object)(object)Refs.shiftingWorld != (Object)null) ? Refs.shiftingWorld : ((Component)source).transform.parent); if ((Object)(object)customRain != (Object)null && (Object)(object)sourceOuterRain == (Object)(object)source) { if ((Object)(object)((Component)customRain).transform.parent != (Object)(object)val) { ((Component)customRain).transform.SetParent(val, true); } RefreshMaterial(); return; } Shutdown(); sourceOuterRain = source; GameObject val2 = Object.Instantiate<GameObject>(((Component)source).gameObject, ((Component)source).transform.position, Quaternion.identity, val); ((Object)val2).name = "Better Storm Rain"; val2.transform.localScale = Vector3.one; CustomPrecipitationParticles.DisableInheritedComponents(val2); customRain = val2.GetComponent<ParticleSystem>(); if ((Object)(object)customRain == (Object)null) { Object.Destroy((Object)(object)val2); return; } renderer = val2.GetComponent<ParticleSystemRenderer>(); sourceRenderer = ((Component)source).GetComponent<ParticleSystemRenderer>(); RefreshMaterial(); MainModule main = customRain.main; ((MainModule)(ref main)).startLifetime = new MinMaxCurve(2f, 2.6f); ((MainModule)(ref main)).startSize3D = false; ((MainModule)(ref main)).startSize = new MinMaxCurve(0.04f, 0.1f); SizeOverLifetimeModule sizeOverLifetime = customRain.sizeOverLifetime; ((SizeOverLifetimeModule)(ref sizeOverLifetime)).enabled = false; SizeBySpeedModule sizeBySpeed = customRain.sizeBySpeed; ((SizeBySpeedModule)(ref sizeBySpeed)).enabled = false; ((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(0f); ((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(0f); Color rainColor = RainColor; Color rainColor2 = RainColor; rainColor.a = 0.02f; rainColor2.a = 0.12f; ((MainModule)(ref main)).startColor = new MinMaxGradient(rainColor, rainColor2); ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1; ShapeModule shape = customRain.shape; ((ShapeModule)(ref shape)).enabled = true; ((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)10; ((ShapeModule)(ref shape)).radius = 120f; ((ShapeModule)(ref shape)).radiusThickness = 1f; ((ShapeModule)(ref shape)).arc = 360f; ((ShapeModule)(ref shape)).scale = Vector3.one; ((ShapeModule)(ref shape)).position = Vector3.zero; ((ShapeModule)(ref shape)).rotation = new Vector3(90f, 0f, 0f); NoiseModule noise = customRain.noise; ((NoiseModule)(ref noise)).enabled = false; ((NoiseModule)(ref noise)).separateAxes = true; ((NoiseModule)(ref noise)).strengthX = MinMaxCurve.op_Implicit(0f); ((NoiseModule)(ref noise)).strengthY = MinMaxCurve.op_Implicit(0f); ((NoiseModule)(ref noise)).strengthZ = MinMaxCurve.op_Implicit(0f); ((NoiseModule)(ref noise)).frequency = 0.22f; ((NoiseModule)(ref noise)).scrollSpeed = MinMaxCurve.op_Implicit(0.2f); ((NoiseModule)(ref noise)).damping = true; if ((Object)(object)renderer != (Object)null) { renderer.renderMode = (ParticleSystemRenderMode)1; renderer.cameraVelocityScale = 0f; renderer.velocityScale = 0f; renderer.maxParticleSize = 0.5f; } IndoorPrecipitationExclusion.Attach(customRain); EmissionModule emission = customRain.emission; ((EmissionModule)(ref emission)).enabled = true; CustomPrecipitationParticles.SetEmissionRate(customRain, 0f); customRain.Clear(true); customRain.Play(true); } private static void UpdateMotion() { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) Camera main = Camera.main; if ((Object)(object)main != (Object)null) { ((Component)customRain).transform.position = ((Component)main).transform.position + Vector3.up * 50f; } Vector3 val = Wind.currentWind * 0.6f; VelocityOverLifetimeModule velocityOverLifetime = customRain.velocityOverLifetime; ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).enabled = true; ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).space = (ParticleSystemSimulationSpace)1; ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).x = MinMaxCurve.op_Implicit(val.x); ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).y = MinMaxCurve.op_Implicit(-25f); ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).z = MinMaxCurve.op_Implicit(val.z); } private static void RefreshMaterial() { if (!((Object)(object)renderer == (Object)null) && !((Object)(object)sourceRenderer == (Object)null)) { Material sharedMaterial = ((Renderer)sourceRenderer).sharedMaterial; if ((Object)(object)sharedMaterial != (Object)null && (Object)(object)((Renderer)renderer).sharedMaterial != (Object)(object)sharedMaterial) { ((Renderer)renderer).sharedMaterial = sharedMaterial; } } } } internal sealed class ModStormController : MonoBehaviour { private Transform player; private ParticleSystem topParticles; private ParticleSystem bottomParticles; private float oneSecondTimer; private bool latitudeParked; internal WanderingStorm Storm { get; private set; } internal StormDefinition Definition { get; private set; } internal void Configure(StormDefinition definition, Transform playerTransform) { Definition = definition; Storm = ((Component)this).GetComponent<WanderingStorm>(); player = playerTransform; if ((Object)(object)Storm == (Object)null) { throw new InvalidOperationException("Custom storm clone has no WanderingStorm component."); } StormAccess.Priority.Invoke(Storm) = definition.Priority; StormAccess.Radius.Invoke(Storm) = definition.Radius; StormAccess.ParticleDistance.Invoke(Storm) = definition.ParticleDistance; topParticles = StormAccess.TopParticles.Invoke(Storm); bottomParticles = StormAccess.BottomParticles.Invoke(Storm); if (definition.Kind == StormKind.GentleSnow) { HideInheritedStormClouds(); } if (definition.SupportsLightning) { ConfigureLightning(definition.Lightning); } else { DisableInheritedLightning(); } if (definition.Kind == StormKind.Sandstorm) { SandstormVisuals.ApplyStormCloudColors(topParticles, bottomParticles); } oneSecondTimer = 0f; } internal bool ShouldBeActive() { BetterStormPlugin instance = BetterStormPlugin.Instance; Region currentRegion = GameplayRegionResolver.GetCurrentRegion(); if ((Object)(object)instance != (Object)null && instance.IsEnabled(Definition.Id) && (Object)(object)currentRegion != (Object)null && Definition.AllowsRegion(((Object)((Component)currentRegion).gameObject).name) && ClimateSeasonCompatibility.Allows(Definition) && currentRegion.stormCount >= Definition.Priority) { return StormLatitudePlacement.IsAllowed(((Component)this).transform, Definition); } return false; } internal void CustomUpdate() { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) if (!GameState.playing || (Object)(object)Storm == (Object)null) { return; } if ((Object)(object)player == (Object)null && (Object)(object)Camera.main != (Object)null) { player = ((Component)Camera.main).transform; } if ((Object)(object)player == (Object)null) { return; } if (!latitudeParked) { ((Component)this).transform.Translate(((Vector3)(ref Wind.currentWind)).normalized * Time.deltaTime * Definition.MoveSpeed, (Space)0); Vector3 val = ((Component)this).transform.position - player.position; val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude > 0.0001f) { ((Component)this).transform.Translate(((Vector3)(ref val)).normalized * Time.deltaTime * WeatherStorms.totemAttraction * Storm.totemMult, (Space)0); } } oneSecondTimer -= Time.deltaTime; if (!(oneSecondTimer > 0f)) { oneSecondTimer = 1f; Vector3 val2 = ((Component)this).transform.position - player.position; val2.y = 0f; float magnitude = ((Vector3)(ref val2)).magnitude; BetterStormPlugin instance = BetterStormPlugin.Instance; float num = (((Object)(object)instance != (Object)null) ? ((float)instance.RelocationDistance.Value) : 44000f); bool flag = ShouldBeActive(); if (Definition.MinimumLatitude.HasValue) { UpdateLatitudeRelocation(flag, magnitude, num); } else if (flag && magnitude > num) { ((Component)this).transform.Translate(-val2 * 1.75f, (Space)0); } Storm.active = ShouldBeActive(); val2 = ((Component)this).transform.position - player.position; val2.y = 0f; magnitude = ((Vector3)(ref val2)).magnitude; SetParticleEmission(Storm.active && magnitude <= Definition.ParticleDistance); } } internal void EnsureValidInitialPlacement() { if (!((Object)(object)player == (Object)null) && Definition.MinimumLatitude.HasValue) { BetterStormPlugin instance = BetterStormPlugin.Instance; float relocationDistance = (((Object)(object)instance != (Object)null) ? ((float)instance.RelocationDistance.Value) : 44000f); float latitude = StormLatitudePlacement.GetLatitude(player); float value = Definition.MinimumLatitude.Value; if (GentleSnowRules.ShouldPark(latitude, value, relocationDistance)) { ParkAtMinimumLatitude(value); } else if (!StormLatitudePlacement.IsAllowed(((Component)this).transform, Definition)) { RelocateAcrossPlayer(relocationDistance, value); } } } internal void SetDebugPosition(Vector3 target) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) target.y = ((Component)this).transform.position.y; if (Definition.MinimumLatitude.HasValue) { float value = Definition.MinimumLatitude.Value; target = StormLatitudePlacement.ClampTargetLatitude(target, ((Component)this).transform, GentleSnowRules.GetParkingLatitude(value)); BetterStormPlugin instance = BetterStormPlugin.Instance; float relocationDistance = (((Object)(object)instance != (Object)null) ? ((float)instance.RelocationDistance.Value) : 44000f); latitudeParked = (Object)(object)player != (Object)null && GentleSnowRules.ShouldPark(StormLatitudePlacement.GetLatitude(player), value, relocationDistance); } ((Component)this).transform.position = target; } internal void SetModEnabled(bool enabled) { SetParticleEmission(enabled: false); if (!enabled) { ThunderPoolRegistry.Reset(this); Storm.active = false; ((Component)this).gameObject.SetActive(false); oneSecondTimer = 0f; } else { ((Component)this).gameObject.SetActive(true); EnsureValidInitialPlacement(); Storm.active = ShouldBeActive(); oneSecondTimer = 0f; } } internal void RefreshSandstormCloudVisuals() { if (Definition.Kind == StormKind.Sandstorm) { SandstormVisuals.ApplyStormCloudColors(topParticles, bottomParticles); } } internal void PrepareDebugMove(bool resetLightningCooldown) { //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) ((Component)this).gameObject.SetActive(true); Storm.active = ShouldBeActive(); oneSecondTimer = 0f; if (resetLightningCooldown && Definition.SupportsLightning) { WanderingStormLightning[] componentsInChildren = ((Component)this).GetComponentsInChildren<WanderingStormLightning>(true); for (int i = 0; i < componentsInChildren.Length; i++) { StormAccess.LightningCooldown.Invoke(componentsInChildren[i]) = 0f; } } if ((Object)(object)player != (Object)null) { Vector3 val = ((Component)this).transform.position - player.position; val.y = 0f; SetParticleEmission(Storm.active && ((Vector3)(ref val)).magnitude <= Definition.ParticleDistance); } } private void ConfigureLightning(LightningProfile profile) { WanderingStormLightning[] componentsInChildren = ((Component)this).GetComponentsInChildren<WanderingStormLightning>(true); foreach (WanderingStormLightning val in componentsInChildren) { StormAccess.LightningInterval.Invoke(val) = profile.Interval; StormAccess.LightningCooldown.Invoke(val) = profile.Interval; StormAccess.LightningIntensity.Invoke(val) = profile.LightIntensity; Light component = ((Component)val).GetComponent<Light>(); if ((Object)(object)component != (Object)null) { component.range = profile.LightRange; } AudioSource[] components = ((Component)val).GetComponents<AudioSource>(); for (int j = 0; j < components.Length; j++) { components[j].minDistance = 250f; components[j].maxDistance = profile.AudioSourceMaxDistance; } } } private void DisableInheritedLightning() { WanderingStormLightning[] componentsInChildren = ((Component)this).GetComponentsInChildren<WanderingStormLightning>(true); foreach (WanderingStormLightning obj in componentsInChildren) { ((Behaviour)obj).enabled = false; Light component = ((Component)obj).GetComponent<Light>(); if ((Object)(object)component != (Object)null) { ((Behaviour)component).enabled = false; } ParticleSystem component2 = ((Component)obj).GetComponent<ParticleSystem>(); if ((Object)(object)component2 != (Object)null) { component2.Stop(true, (ParticleSystemStopBehavior)0); } AudioSource[] components = ((Component)obj).GetComponents<AudioSource>(); for (int j = 0; j < components.Length; j++) { components[j].Stop(); ((Behaviour)components[j]).enabled = false; } } } private void SetParticleEmission(bool enabled) { if (Definition.Kind == StormKind.GentleSnow) { enabled = false; } SetEmission(topParticles, enabled); SetEmission(bottomParticles, enabled); } private void UpdateLatitudeRelocation(bool activeBeforeRelocation, float distance, float relocationDistance) { float value = Definition.MinimumLatitude.Value; bool flag = GentleSnowRules.ShouldPark(StormLatitudePlacement.GetLatitude(player), value, relocationDistance); if (latitudeParked) { if (!flag) { latitudeParked = false; RelocateAcrossPlayer(relocationDistance, value); } } else if (!StormLatitudePlacement.IsAllowed(((Component)this).transform, Definition) || (activeBeforeRelocation && !(distance <= relocationDistance))) { if (flag) { ParkAtMinimumLatitude(value); } else { RelocateAcrossPlayer(relocationDistance, value); } } } private void ParkAtMinimumLatitude(float minimumLatitude) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) Vector3 position = ((Component)this).transform.position; position.x = player.position.x; position = StormLatitudePlacement.ClampTargetLatitude(position, ((Component)this).transform, GentleSnowRules.GetParkingLatitude(minimumLatitude)); ((Component)this).transform.position = position; latitudeParked = true; } private void RelocateAcrossPlayer(float relocationDistance, float minimumLatitude) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ((Component)this).transform.position - player.position; val.y = 0f; Vector3 val2 = ((((Vector3)(ref val)).sqrMagnitude > 0.0001f) ? (-((Vector3)(ref val)).normalized) : Vector3.forward); Vector3 target = player.position + val2 * relocationDistance * 0.75f; target.y = ((Component)this).transform.position.y; target = StormLatitudePlacement.ClampTargetLatitude(target, ((Component)this).transform, GentleSnowRules.GetParkingLatitude(minimumLatitude)); Vector3 val3 = target - player.position; val3.y = 0f; if (((Vector3)(ref val3)).magnitu