Decompiled source of BetterStorm v1.0.8

BepInEx/plugins/BetterStorm/BetterStorm.dll

Decompiled 9 hours ago
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.0.8.0")]
[assembly: AssemblyInformationalVersion("1.0.8")]
[assembly: AssemblyProduct("BetterStorm")]
[assembly: AssemblyTitle("BetterStorm")]
[assembly: AssemblyVersion("1.0.8.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
{
	[BepInPlugin("DogEggz.BetterStorm", "Better Storm", "1.0.8")]
	[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.0.8";

		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 ConfigEntry<string> debugStormButtons;

		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.0.8 loaded.");
		}

		private void Update()
		{
			WindOverrideState.Tick();
			SandstormVisuals.Tick();
			SandstormDirt.Tick();
		}

		private void OnDestroy()
		{
			Unsubscribe();
			WindOverrideState.RestoreImmediately();
			MediEastStormSetting.Apply(enabled: false);
			SandstormVisuals.Shutdown();
			SandstormDirt.Reset();
			GlobalLightningSettings.RestoreSnapshots();
			ThunderPoolRegistry.Shutdown();
			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_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: 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, and Dry Thunderstorm 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
				}
			}));
			debugStormButtons = ((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 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 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();
			MediEastStormSetting.Apply(ModStormFactory.AnyMediStormEnabled);
			if (!IsEnabled(CustomStormId.Sandstorm))
			{
				SandstormVisuals.Deactivate();
				SandstormDirt.Reset();
			}
			RefreshCurrentStorm();
			WindOverrideState.Tick();
		}

		private void ApplyRuntimeSettings()
		{
			ModStormFactory.ApplyEnabledState();
			MediEastStormSetting.Apply(ModStormFactory.AnyMediStormEnabled);
			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 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;
		}
	}
	[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 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) });
				for (int i = 0; i < StormCatalog.Custom.Length; i++)
				{
					StormDefinition stormDefinition = StormCatalog.Custom[i];
					DrawControls(stormDefinition.Name, stormDefinition.Id);
				}
				GUILayout.EndVertical();
			}
		}

		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_0025: 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)
			if (!TryGetContext(id, out var controller, out var weatherStorms, out var player))
			{
				return false;
			}
			ThunderPoolRegistry.Reset(controller);
			Vector3 position = player.position;
			position.y = ((Component)controller).transform.position.y;
			((Component)controller).transform.position = position;
			controller.PrepareDebugMove(resetLightningCooldown: true);
			WindOverrideState.NotifyDebugSummon(controller.Definition.Kind);
			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_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: 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 position = player.position + val * num;
			position.y = ((Component)controller).transform.position.y;
			((Component)controller).transform.position = position;
			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();
		}
	}
	[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 ResetAll()
		{
			foreach (ThunderEmitterPool value in Pools.Values)
			{
				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);
				}
			}

			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();
			ThunderPoolRegistry.Shutdown();
			SandstormVisuals.Shutdown();
			SandstormDirt.Reset();
			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();
		}
	}
	internal enum CustomStormId
	{
		Squall1,
		Squall2,
		Squall3,
		Hurricane,
		DryThunderstorm,
		Sandstorm
	}
	internal enum StormKind
	{
		Vanilla,
		Squall,
		Hurricane,
		DryThunderstorm,
		Sandstorm
	}
	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 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[6]
		{
			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-3 Hurricane.",
				SaveKey = "DogEggz.BetterStorm.hurricane-position.v2",
				Id = CustomStormId.Hurricane,
				Kind = StormKind.Hurricane,
				InitialOffset = new Vector3(0f, 0f, -24000f),
				Priority = 3,
				Radius = 6000f,
				ParticleDistance = 9960f,
				MoveSpeed = 5.5f,
				UsesFixedWeatherRange = false,
				WindCoefficient = 34f,
				RainTarget = 13f,
				AllowedClimateSeasons = (ClimateSeasonMask.Summer | ClimateSeasonMask.Autumn),
				SupportsLightning = true,
				Lightning = new LightningProfile(12f, 3000f, 12500f, 7980f, 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, 2250f, 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 = 12f,
				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" }
			}
		};

		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, 2000f, 1500f, 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;
				}
			}
			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, float> RainBorder = AccessTools.FieldRefAccess<WeatherStorms, float>("rainBorder");

		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 ModStormController Controller;

		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 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 StormInfluence(ModStormController controller, float centerDistance, float radius, float weatherRange)
		{
			Controller = controller;
			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 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 NormalizeForSelection(WeatherStorms weatherStorms, WanderingStorm storm, float distance)
		{
			StormInfluence stormInfluence = Evaluate(weatherStorms, storm, distance);
			return Mathf.Clamp01((distance - stormInfluence.Radius) / Mathf.Max(0.0001f, stormInfluence.WeatherRange));
		}

		internal static float GetStormContribution(StormInfluence influence)
		{
			if (!influence.Inside)
			{
				return 0f;
			}
			return ((influence.Definition != null) ? influence.Definition.WindCoefficient : 26f) * influence.WindLerp;
		}

		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 sealed class ModStormController : MonoBehaviour
	{
		private Transform player;

		private ParticleSystem topParticles;

		private ParticleSystem bottomParticles;

		private float oneSecondTimer;

		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.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))
			{
				return currentRegion.stormCount >= Definition.Priority;
			}
			return false;
		}

		internal void CustomUpdate()
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: 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_0091: 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_009b: 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)
			//IL_00c8: 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_00e2: 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_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_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: 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)
			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;
			}
			((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;
				Storm.active = ShouldBeActive();
				Vector3 val2 = ((Component)this).transform.position - player.position;
				val2.y = 0f;
				float magnitude = ((Vector3)(ref val2)).magnitude;
				BetterStormPlugin instance = BetterStormPlugin.Instance;
				if (Storm.active && (Object)(object)instance != (Object)null && magnitude > (float)instance.RelocationDistance.Value)
				{
					((Component)this).transform.Translate(-val2 * 1.75f, (Space)0);
					val2 = ((Component)this).transform.position - player.position;
					val2.y = 0f;
					magnitude = ((Vector3)(ref val2)).magnitude;
				}
				SetParticleEmission(Storm.active && magnitude <= Definition.ParticleDistance);
			}
		}

		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);
				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)
		{
			SetEmission(topParticles, enabled);
			SetEmission(bottomParticles, enabled);
		}

		private static void SetEmission(ParticleSystem particles, bool enabled)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)particles == (Object)null))
			{
				EmissionModule emission = particles.emission;
				((EmissionModule)(ref emission)).enabled = enabled;
			}
		}
	}
	internal static class ModStormFactory
	{
		private static readonly List<ModStormController> CustomStorms = new List<ModStormController>();

		private static WeatherStorms owner;

		private static WanderingStorm[] originalStorms;

		private static bool initialized;

		internal static ModStormController Hurricane { get; private set; }

		internal static ModStormController Sandstorm { get; private set; }

		internal static bool AnyMediStormEnabled
		{
			get
			{
				BetterStormPlugin instance = BetterStormPlugin.Instance;
				if ((Object)(object)instance == (Object)null)
				{
					return false;
				}
				for (int i = 0; i < StormCatalog.Custom.Length; i++)
				{
					StormDefinition stormDefinition = StormCatalog.Custom[i];
					if (stormDefinition.AllowsRegion("Region Medi East") && instance.IsEnabled(stormDefinition.Id))
					{
						return true;
					}
				}
				return false;
			}
		}

		internal static void Initialize(WeatherStorms weatherStorms)
		{
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)weatherStorms == (Object)null || (initialized && (Object)(object)owner == (Object)(object)weatherStorms))
			{
				return;
			}
			if (initialized)
			{
				Shutdown();
			}
			WanderingStorm[] array = StormAccess.Storms.Invoke(weatherStorms);
			WanderingStorm val = FindTemplate(array);
			Camera main = Camera.main;
			if (array == null || (Object)(object)val == (Object)null || (Object)(object)main == (Object)null)
			{
				BetterStormPlugin.Instance?.LogFeatureError("Custom storms could not initialize because the vanilla storm template or player camera was unavailable.");
				return;
			}
			owner = weatherStorms;
			originalStorms = array;
			bool activeSelf = ((Component)val).gameObject.activeSelf;
			((Component)val).gameObject.SetActive(false);
			try
			{
				for (int i = 0; i < StormCatalog.Custom.Length; i++)
				{
					StormDefinition stormDefinition = StormCatalog.Custom[i];
					GameObject val2 = Object.Instantiate<GameObject>(((Component)val).gameObject, ((Component)main).transform.position + stormDefinition.InitialOffset, ((Component)val).transform.rotation, ((Component)val).transform.parent);
					((Object)val2).name = "Better Storm " + stormDefinition.Name;
					SaveableObject[] componentsInChildren = val2.GetComponentsInChildren<SaveableObject>(true);
					for (int j = 0; j < componentsInChildren.Length; j++)
					{
						Object.DestroyImmediate((Object)(object)componentsInChildren[j]);
					}
					ModStormController modStormController = val2.AddComponent<ModStormController>();
					modStormController.Configure(stormDefinition, ((Component)main).transform);
					CustomStorms.Add(modStormController);
					StormPositionPersistence.ApplyLoadedPosition(stormDefinition.Id, modStormController);
					if (stormDefinition.Id == CustomStormId.Hurricane)
					{
						Hurricane = modStormController;
					}
					else if (stormDefinition.Id == CustomStormId.Sandstorm)
					{
						Sandstorm = modStormController;
					}
				}
				WanderingStorm[] array2 = (WanderingStorm[])(object)new WanderingStorm[array.Length + CustomStorms.Count];
				Array.Copy(array, array2, array.Length);
				for (int k = 0; k < CustomStorms.Count; k++)
				{
					array2[array.Length + k] = CustomStorms[k].Storm;
				}
				StormAccess.Storms.Invoke(weatherStorms) = array2;
				initialized = true;
				ApplyEnabledState();
				MediEastStormSetting.Apply(AnyMediStormEnabled);
				RefreshSandstormCloudVisuals();
				GlobalLightningSettings.ApplyToLiveStorms();
				BetterStormPlugin.Instance?.LogFeatureInfo("Initialized three Squalls, one Hurricane, one Dry Thunderstorm, and one Sandstorm.");
			}
			catch (Exception ex)
			{
				BetterStormPlugin.Instance?.LogFeatureError("Custom storm initialization failed: " + ex);
				Shutdown();
			}
			finally
			{
				if ((Object)(object)val != (Object)null)
				{
					((Component)val).gameObject.SetActive(activeSelf);
				}
			}
		}

		internal static void ApplyEnabledState()
		{
			BetterStormPlugin instance = BetterStormPlugin.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			for (int i = 0; i < CustomStorms.Count; i++)
			{
				ModStormController modStormController = CustomStorms[i];
				if ((Object)(object)modStormController != (Object)null)
				{
					modStormController.SetModEnabled(instance.IsEnabled(modStormController.Definition.Id));
				}
			}
		}

		internal static ModStormController Find(CustomStormId id)
		{
			for (int i = 0; i < CustomStorms.Count; i++)
			{
				ModStormController modStormController = CustomStorms[i];
				if ((Object)(object)modStormController != (Object)null && modStormController.Definition.Id == id)
				{
					return modStormController;
				}
			}
			return null;
		}

		internal static void RefreshSandstormCloudVisuals()
		{
			Sandstorm?.RefreshSandstormCloudVisuals();
		}

		internal static void Shutdown()
		{
			if ((Object)(object)owner != (Object)null && originalStorms != null)
			{
				StormAccess.Storms.Invoke(owner) = originalStorms;
			}
			for (int i = 0; i < CustomStorms.Count; i++)
			{
				ModStormController modStormController = CustomStorms[i];
				if ((Object)(object)modStormController != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)modStormController).gameObject);
				}
			}
			CustomStorms.Clear();
			Hurricane = null;
			Sandstorm = null;
			originalStorms = null;
			owner = null;
			initialized = false;
		}

		private static WanderingStorm FindTemplate(WanderingStorm[] storms)
		{
			if (storms == null)
			{
				return null;
			}
			for (int i = 0; i < storms.Length; i++)
			{
				if ((Object)(object)storms[i] != (Object)null && (Object)(object)((Component)storms[i]).GetComponent<ModStormController>() == (Object)null)
				{
					return storms[i];
				}
			}
			return null;
		}
	}
	internal static class MediEastStormSetting
	{
		private static Region mediEast;

		private static int originalStormCount;

		internal static void Apply(bool enabled)
		{
			if ((Object)(object)mediEast == (Object)null)
			{
				Region[] array = Object.FindObjectsOfType<Region>();
				for (int i = 0; i < array.Length; i++)
				{
					if (((Object)((Component)array[i]).gameObject).name == "Region Medi East")
					{
						mediEast = array[i];
						originalStormCount = array[i].stormCount;
						break;
					}
				}
			}
			if ((Object)(object)mediEast != (Object)null)
			{
				mediEast.stormCount = (enabled ? 3 : originalStormCount);
			}
		}
	}
	[HarmonyPatch(typeof(WeatherStorms), "Start")]
	internal static class WeatherStormsStartPatch
	{
		[HarmonyPostfix]
		private static void Postfix(WeatherStorms __instance)
		{
			ThunderPoolRegistry.Shutdown();
			SandstormVisuals.Shutdown();
			SandstormDirt.Reset();
			GlobalLightningSettings.RestoreSnapshots();
			ModStormFactory.Initialize(__instance);
		}
	}
	[HarmonyPatch(typeof(WeatherStorms), "FindClosestStorm")]
	internal static class StrongestStormPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(WeatherStorms __instance, WanderingStorm[] ___storms, Transform ___player, ref WanderingStorm ___currentStorm)
		{
			//IL_0039: 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)
			if (___storms == null || (Object)(object)___player == (Object)null)
			{
				return true;
			}
			WanderingStorm val = null;
			float num = float.MaxValue;
			float num2 = float.MaxValue;
			foreach (WanderingStorm val2 in ___storms)
			{
				if (!((Object)(object)val2 == (Object)null) && val2.active)
				{
					float num3 = Vector3.Distance(___player.position, ((Component)val2).transform.position);
					float num4 = StormInfluenceService.NormalizeForSelection(__instance, val2, num3);
					if (num4 < num || (Mathf.Approximately(num4, num) && num3 < num2))
					{
						val = val2;
						num = num4;
						num2 = num3;
					}
				}
			}
			___currentStorm = val;
			WeatherStorms.currentStormDistance = (((Object)(object)val != (Object)null) ? num2 : 100000000f);
			return false;
		}
	}
	[HarmonyPatch(typeof(WeatherStorms), "GetNormalizedDistance")]
	internal static class CustomStormRangePatch
	{
		[HarmonyPrefix]
		private static bool Prefix(WanderingStorm ___currentStorm, ref float __result)
		{
			if ((Object)(object)___currentStorm == (Object)null)
			{
				return true;
			}
			ModStormController component = ((Component)___currentStorm).GetComponent<ModStormController>();
			if ((Object)(object)component == (Object)null || !component.Definition.UsesFixedWeatherRange)
			{
				return true;
			}
			__result = Mathf.Clamp01((WeatherStorms.currentStormDistance - component.Definition.Radius) / Mathf.Max(0.0001f, component.Definition.FixedWeatherRange));
			return false;
		}
	}
	[HarmonyPatch(typeof(WanderingStorm), "Update")]
	internal static class CustomStormMovementPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(WanderingStorm __instance)
		{
			ModStormController component = ((Component)__instance).GetComponent<ModStormController>();
			if ((Object)(object)component == (Object)null)
			{
				return true;
			}
			component.CustomUpdate();
			return false;
		}
	}
	[HarmonyPatch(typeof(RegionBlender), "Start")]
	internal static class RegionBlenderStartPatch
	{
		[HarmonyPostfix]
		[HarmonyAfter(new string[] { "com.nandbrew.borderexpander" })]
		private static void Postfix()
		{
			MediEastStormSetting.Apply(ModStormFactory.AnyMediStormEnabled);
			ModStormFactory.ApplyEnabledState();
		}
	}
	internal static class DryStormGameplay
	{
		internal static bool ShouldSuppressRain()
		{
			if (StormInfluenceService.TryGetCurrent(out var influence) && influence.Definition != null)
			{
				return influence.Definition.SuppressRainParticles;
			}
			return false;
		}

		internal static bool ShouldSuppressFog()
		{
			if (StormInfluenceService.TryGetCurrent(out var influence) && influence.Definition != null)
			{
				return influence.Definition.SuppressFog;
			}
			return false;
		}

		internal static void SuppressRainGameplay()
		{
			if (ShouldSuppressRain())
			{
				GameState.rainIntensity = 0f;
			}
		}
	}
	internal static class SandstormVisuals
	{
		private const float VerticalVelocity = -4f;

		private const float StartLifetime = 2f;

		private const float SandParticleIntensity = 50f;

		private const float SandParticleSize = 0.015f;

		private const float SandParticleSpawnRadius = 60f;

		private const float SandstormFogDensity = 0.03f;

		private const float NoiseStrength = 1.2f;

		private const float WindInfluence = 0.3f;

		private const float HorizontalVelocityMultiplier = 2f;

		private const int MaximumParticles = 30000;

		private const float EmissionRateMultiplier = 200f;

		private const float DistantStormAlpha = 1f;

		private const float OverheadStormAlpha = 0.6f;

		private const string StormCloudTintShaderName = "Particles/Priority Alpha Blended";

		private static readonly Color SandParticleColor = new Color(0.4352941f, 0.2588235f, 0.1215686f, 0.5f);

		private static readonly Color SandFogColor = new Color(0.7647059f, 0.6f, 0.2823529f, 1f);

		private static readonly Color DistantStormColor = SandFogColor;

		private static ParticleSystem sourceRain;

		private static ParticleSystem sourceOuterRain;

		private static ParticleSystem sandRain;

		private static bool active;

		private static bool rainStageActive;

		internal static void ApplyWeather(StormInfluence influence, ParticleSystem rain, ParticleSystem outerRain, ParticleSystem rainSplash)
		{
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: 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)
			if (!influence.IsSandstorm)
			{
				Deactivate();
				return;
			}
			EnsureInitialized(rain, outerRain);
			if (!active)
			{
				ClearParticles(rain);
				ClearParticles(outerRain);
				ClearParticles(rainSplash);
			}
			active = true;
			SuppressVanillaRain(rain, outerRain, rainSplash);
			GameState.rainIntensity = 0f;
			if (!TryGetRainStageLerp(influence, out var stageLerp))
			{
				if (rainStageActive)
				{
					SetEmissionRate(sandRain, 0f);
					ClearParticles(sandRain);
				}
				rainStageActive = false;
			}
			else
			{
				rainStageActive = true;
				SetEmissionRate(sandRain, 50f * stageLerp * 200f);
				RenderSettings.fogDensity = Mathf.Lerp(RenderSettings.fogDensity, 0.03f, stageLerp);
				RenderSettings.fogColor = Color.Lerp(RenderSettings.fogColor, SandFogColor, stageLerp);
			}
		}

		internal static void Tick()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			if (active && rainStageActive && TryGetActiveInfluence(out var _))
			{
				UpdateParticleMotion(sandRain, Wind.currentWind * 0.3f);
			}
		}

		internal static void ApplyFogParticleColor(FogEffectController fog)
		{
			//IL_0031: 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_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: 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_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: 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_005e: 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_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)fog == (Object)null) && !((Object)(object)fog.fogParticles == (Object)null) && TryGetActiveInfluence(out var influence) && TryGetRainStageLerp(influence, out var stageLerp))
			{
				MainModule main = fog.fogParticles.main;
				MinMaxGradient startColor = ((MainModule)(ref main)).startColor;
				Color color = ((MinMaxGradient)(ref startColor)).color;
				Color sandFogColor = SandFogColor;
				sandFogColor.a = color.a;
				((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(Color.Lerp(color, sandFogColor, stageLerp));
			}
		}

		internal static void ApplyStormCloudColors(ParticleSystem topParticles, ParticleSystem bottomParticles)
		{
			//IL_0001: 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)
			ApplyStormCloudColor(topParticles, DistantStormColor, 1f);
			ApplyStormCloudColor(bottomParticles, DistantStormColor, 0.6f);
		}

		internal static void Deactivate()
		{
			rainStageActive = false;
			if (active)
			{
				SetEmissionRate(sandRain, 0f);
				ClearParticles(sandRain);
				active = false;
			}
		}

		internal static void Shutdown()
		{
			Deactivate();
			if ((Object)(object)sandRain != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)sandRain).gameObject);
			}
			sourceRain = null;
			sourceOuterRain = null;
			sandRain = null;
		}

		private static bool TryGetActiveInfluence(out StormInfluence influence)
		{
			influence = default(StormInfluence);
			if (StormInfluenceService.TryGetCurrent(out influence) && influence.IsSandstorm && (Object)(object)BetterStormPlugin.Instance != (Object)null && BetterStormPlugin.Instance.IsEnabled(CustomStormId.Sandstorm) && (Object)(object)GameplayRegionResolver.GetCurrentRegion() != (Object)null)
			{
				return ((Object)((Component)GameplayRegionResolver.GetCurrentRegion()).gameObject).name == "Region Al'ankh";
			}
			return false;
		}

		private static bool TryGetRainStageLerp(StormInfluence influence, out float stageLerp)
		{
			WeatherStorms instance = WeatherStorms.instance;
			if ((Object)(object)instance == (Object)null)
			{
				stageLerp = 0f;
				return false;
			}
			float num = StormAccess.RainBorder.Invoke(instance);
			float num2 = 1f - influence.WeatherLerp;
			if (num <= 0f || num2 >= num)
			{
				stageLerp = 0f;
				return false;
			}
			stageLerp = Mathf.InverseLerp(num, 0f, num2);
			return stageLerp > 0f;
		}

		private static void EnsureInitialized(ParticleSystem rain, ParticleSystem outerRain)
		{
			if (!((Object)(object)rain == (Object)null) && !((Object)(object)outerRain == (Object)null) && (!((Object)(object)sandRain != (Object)null) || !((Object)(object)sourceRain == (Object)(object)rain) || !((Object)(object)sourceOuterRain == (Object)(object)outerRain)))
			{
				Shutdown();
				sourceRain = rain;
				sourceOuterRain = outerRain;
				sandRain = CloneAndConfigure(outerRain, "Better Storm Sand Particles");
			}
		}

		private static ParticleSystem CloneAndConfigure(ParticleSystem source, string name)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: 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_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: 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_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(((Component)source).gameObject, ((Component)source).transform.position, ((Component)source).transform.rotation, ((Component)source).transform.parent);
			((Object)val).name = name;
			val.transform.localScale = ((Component)source).transform.localScale;
			Rain[] componentsInChildren = val.GetComponentsInChildren<Rain>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				((Behaviour)componentsInChildren[i]).enabled = false;
			}
			LitParticles[] componentsInChildren2 = val.GetComponentsInChildren<LitParticles>(true);
			for (int j = 0; j < componentsInChildren2.Length; j++)
			{
				((Behaviour)componentsInChildren2[j]).enabled = false;
			}
			AudioSource[] componentsInChildren3 = val.GetComponentsInChildren<AudioSource>(true);
			for (int k = 0; k < componentsInChildren3.Length; k++)
			{
				componentsInChildren3[k].Stop();
				((Behaviour)componentsInChildren3[k]).enabled = false;
			}
			ParticleSystem component = val.GetComponent<ParticleSystem>();
			if ((Object)(object)component == (Object)null)
			{
				Object.Destroy((Object)(object)val);
				return null;
			}
			MainModule main = component.main;
			((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(2f);
			((MainModule)(ref main)).startSize3D = false;
			((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(0.015f);
			((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(0f);
			((MainModule)(ref main)).maxParticles = 30000;
			((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(0f);
			((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(SandParticleColor);
			ShapeModule shape = component.shape;
			((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)8;
			((ShapeModule)(ref shape)).angle = 0f;
			((ShapeModule)(ref shape)).length = 29f;
			((ShapeModule)(ref shape)).radius = 60f;
			((ShapeModule)(ref shape)).radiusThickness = 1f;
			((ShapeModule)(ref shape)).arc = 360f;
			((ShapeModule)(ref shape)).rotation = Vector3.zero;
			((ShapeModule)(ref shape)).position = Vector3.zero;
			NoiseModule noise = component.noise;
			((NoiseModule)(ref noise)).enabled = true;
			((NoiseModule)(ref noise)).separateAxes = false;
			((NoiseModule)(ref noise)).strength = MinMaxCurve.op_Implicit(1.2f);
			ParticleSystemRenderer component2 = val.GetComponent<ParticleSystemRenderer>();
			if ((Object)(object)component2 != (Object)null)
			{
				component2.renderMode = (ParticleSystemRenderMode)0;
			}
			SetEmissionRate(component, 0f);
			EmissionModule emission = component.emission;
			((EmissionModule)(ref emission)).enabled = true;
			component.Clear(true);
			component.Play(true);
			return component;
		}

		private static void UpdateParticleMotion(ParticleSystem particles, Vector3 windVelocity)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: 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_0027: 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_0044: 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_006f: 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_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: 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)
			if (!((Object)(object)particles == (Object)null))
			{
				VelocityOverLifetimeModule velocityOverLifetime = particles.velocityOverLifetime;
				((VelocityOverLifetimeModule)(ref velocityOverLifetime)).enabled = true;
				((VelocityOverLifetimeModule)(ref velocityOverLifetime)).x = MinMaxCurve.op_Implicit(windVelocity.x * 2f);
				((VelocityOverLifetimeModule)(ref velocityOverLifetime)).y = MinMaxCurve.op_Implicit(-4f);
				((VelocityOverLifetimeModule)(ref velocityOverLifetime)).z = MinMaxCurve.op_Implicit(windVelocity.z * 2f);
				Camera main = Camera.main;
				if ((Object)(object)main != (Object)null)
				{
					Vector3 position = ((Component)main).transform.position - windVelocity;
					position.y = 1f;
					((Component)particles).transform.position = position;
				}
			}
		}

		private static void ApplyStormCloudColor(ParticleSystem particles, Color baseColor, float alpha)
		{
			//IL_000a: 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_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_0033: 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_00b4: 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_00bd: 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)
			//IL_0094: 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_0100: 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_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Expected O, but got Unknown
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)particles == (Object)null)
			{
				return;
			}
			Color val = baseColor;
			val.a = Mathf.Clamp01(alpha);
			ParticleSystemRenderer component = ((Component)particles).GetComponent<ParticleSystemRenderer>();
			if ((Object)(object)component == (Object)null)
			{
				MainModule main = particles.main;
				((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(val);
				return;
			}
			Material sharedMaterial = ((Renderer)component).sharedMaterial;
			Shader val2 = Shader.Find("Particles/Priority Alpha Blended");
			SandstormCloudMaterialOwner sandstormCloudMaterialOwner = ((Component)particles).GetComponent<SandstormCloudMaterialOwner>();
			if ((Object)(object)sandstormCloudMaterialOwner != (Object)null && (Object)(object)sandstormCloudMaterialOwner.OwnedMaterial != (Object)null && (Object)(object)sandstormCloudMaterialOwner.OwnedMaterial.shader == (Object)(object)val2)
			{
				DisableParticleLighting(particles);
				ApplyTintAndAlpha(particles, sandstormCloudMaterialOwner.OwnedMaterial, baseColor, val.a);
				return;
			}
			if ((Object)(object)sharedMaterial == (Object)null || (Object)(object)val2 == (Object)null)
			{
				MainModule main2 = particles.main;
				((MainModule)(ref main2)).startColor = MinMaxGradient.op_Implicit(val);
				return;
			}
			Texture val3 = (sharedMaterial.HasProperty("_MainTex") ? sharedMaterial.GetTexture("_MainTex") : null);
			Vector2 val4 = (sharedMaterial.HasProperty("_MainTex") ? sharedMaterial.GetTextureScale("_MainTex") : Vector2.one);
			Vector2 val5 = (sharedMaterial.HasProperty("_MainTex") ? sharedMaterial.GetTextureOffset("_MainTex") : Vector2.zero);
			float num = (sharedMaterial.HasProperty("_InvFade") ? sharedMaterial.GetFloat("_InvFade") : 1f);
			Material val6 = new Material(val2)
			{
				name = "Better Storm Sandstorm Cloud Tint",
				hideFlags = (HideFlags)52,
				renderQueue = sharedMaterial.renderQueue
			};
			val6.SetTexture("_MainTex", val3);
			val6.SetTextureScale("_MainTex", val4);
			val6.SetTextureOffset("_MainTex", val5);
			val6.SetFloat("_InvFade", num);
			DisableParticleLighting(particles);
			ApplyTintAndAlpha(particles, val6, baseColor, val.a);
			((Renderer)component).sharedMaterial = val6;
			if ((Object)(object)sandstormCloudMaterialOwner == (Object)null)
			{
				sandstormCloudMaterialOwner = ((Component)particles).gameObject.AddComponent<SandstormCloudMaterialOwner>();
			}
			sandstormCloudMaterialOwner.Own(val6);
		}

		private static void ApplyTintAndAlpha(ParticleSystem particles, Material material, Color baseColor, float alpha)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Clamp01(alpha);
			Color val = baseColor;
			val.r *= 0.5f;
			val.g *= 0.5f;
			val.b *= 0.5f;
			val.a = num * 0.5f;
			material.SetColor("_TintColor", val);
			Color white = Color.white;
			white.a = num;
			MainModule main = particles.main;
			((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(white);
			ApplyColorToExistingParticles(particles, white);
		}

		private static void ApplyColorToExistingParticles(ParticleSystem particles, Color color)
		{
			//IL_001b: 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_0021: 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)
			int particleCount = particles.particleCount;
			if (particleCount > 0)
			{
				Particle[] array = (Particle[])(object)new Particle[particleCount];
				int particles2 = particles.GetParticles(array);
				Color32 startColor = Color32.op_Implicit(color);
				for (int i = 0; i < particles2; i++)
				{
					((Particle)(ref array[i])).startColor = startColor;
				}
				particles.SetParticles(array, particles2);
			}
		}

		private static void DisableParticleLighting(ParticleSystem particles)
		{
			LitParticles[] components = ((Component)particles).GetComponents<LitParticles>();
			for (int i = 0; i < components.Length; i++)
			{
				((Behaviour)components[i]).enabled = false;
			}
		}

		private static void SuppressVanillaRain(ParticleSystem rain, ParticleSystem outerRain, ParticleSystem rainSplash)
		{
			SetEmissionRate(rain, 0f);
			SetEmissionRate(outerRain, 0f);
			SetEmissionRate(rainSplash, 0f);
		}

		internal static void SetEmissionRate(ParticleSystem particles, float rate)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: 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)
			if (!((Object)(object)particles == (Object)null))
			{
				EmissionModule emission = particles.emission;
				((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(rate);
			}
		}

		private static void ClearParticles(ParticleSystem particles)
		{
			if ((Object)(object)particles != (Object)null)
			{
				particles.Clear(true);
			}
		}
	}
	internal sealed class SandstormCloudMaterialOwner : MonoBehaviour
	{
		private Material ownedMaterial;

		internal Material OwnedMaterial => ownedMaterial;

		internal void Own(Material material)
		{
			if ((Object)(object)ownedMaterial != (Object)null && (Object)(object)ownedMaterial != (Object)(object)material)
			{
				Object.Destroy((Object)(object)ownedMaterial);
			}
			ownedMaterial = material;
		}

		private void OnDestroy()
		{
			if ((Object)(object)ownedMaterial != (Object)null)
			{
				Object.Destroy((Object)(object)ownedMaterial);
				ownedMaterial = null;
			}
		}
	}
	internal static class SandstormDirt
	{
		private const float ApplicationInterval = 20f;

		private const float DirtStrength = 0.02f;

		private static Transform cachedBoat;

		private static CleanableObject cachedCleanable;

		private static float exposureTimer;

		internal static void Tick()
		{
			if (!TryGetExposedCleanable(out var cleanable))
			{
				Reset();
				return;
			}
			exposureTimer += Time.deltaTime;
			if (!(exposureTimer < 20f) && ApplyVanillaDirt(cleanable))
			{
				exposureTimer -= 20f;
			}
		}

		internal static void Reset()
		{
			cachedBoat = null;
			cachedCleanable = null;
			exposureTimer = 0f;
		}

		private static bool TryGetExposedCleanable(out CleanableObject cleanable)
		{
			//IL_0078: 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_0088: 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)
			cleanable = null;
			BetterStormPlugin instance = BetterStormPlugin.Instance;
			ModStormController sandstorm = ModStormFactory.Sandstorm;
			Transform lastBoat = GameState.lastBoat;
			if (!GameState.playing || (Object)(object)instance == (Object)null || !instance.IsEnabled(CustomStormId.Sandstorm) || (Object)(object)sandstorm == (Object)null || (Object)(object)sandstorm.Storm == (Object)null || !sandstorm.Storm.active || !((Component)sandstorm).gameObject.activeInHierarchy || (Object)(object)lastBoat == (Object)null || (Object)(object)MasterPainter.instance == (Object)null)
			{
				return false;
			}
			Vector3 val = lastBoat.position - ((Component)sandstorm).transform.position;
			val.y = 0f;
			float num = sandstorm.Definition.Radius + sandstorm.Definition.FixedWeatherRange;
			if (((Vector3)(ref val)).sqrMagnitude >= num * num)
			{
				return false;
			}
			if ((Object)(object)cachedBoat != (Object)(object)lastBoat || (Object)(object)cachedCleanable == (Object)null)
			{
				cachedBoat = lastBoat;
				SaveableObject component = ((Component)lastBoat).GetComponent<SaveableObject>();
				cachedCleanable = (((Object)(object)component != (Object)null) ? component.GetCleanable() : null);
				exposureTimer = 0f;
			}
			cleanable = cachedCleanable;
			if ((Object)(object)cleanable != (Object)null)
			{
				return ((Behaviour)cleanable).isActiveAndEnabled;
			}
			return false;
		}

		private static bool ApplyVanillaDirt(CleanableObject cleanable)
		{
			MasterPainter instance = MasterPainter.instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)cleanable == (Object)null)
			{
				return false;
			}
			Texture2D val = StormAccess.DirtCoat.Invoke(cleanable);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			instance.ApplyCoat(cleanable, (Texture)(object)val, 0.02f);
			return true;
		}
	}
	[HarmonyPatch(typeof(Weather), "ApplyWeather")]
	[HarmonyAfter(new string[] { "com.raddude.climate" })]
	internal static class CustomStormWeatherPatch
	{
		[HarmonyPostfix]
		[HarmonyPriority(0)]
		private static void Postfix(ParticleSystem ___rain, ParticleSystem ___outerRain, ParticleSystem ___rainSplash)
		{
			if ((Object)(object)BetterStormPlugin.Instance == (Object)null)
			{
				return;
			}
			if (!StormInfluenceService.TryGetCurrent(out var influence) || influence.Definition == null)
			{
				SandstormVisuals.Deactivate();
				return;
			}
			if (influence.Definition.Kind == StormKind.Sandstorm)
			{
				SandstormVisuals.ApplyWeather(influence, ___rain, ___outerRain, ___rainSplash);
				return;
			}
			SandstormVisuals.Deactivate();
			if (influence.Definition.SuppressFog)
			{
				RenderSettings.fogDensity = 0f;
			}
			if (influence.Definition.SuppressRainParticles)
			{
				SandstormVisuals.SetEmissionRate(___rain, 0f);
				SandstormVisuals.SetEmissionRate(___outerRain, 0f);
				SandstormVisuals.SetEmissionRate(___rainSplash, 0f);
				GameState.rainIntensity = 0f;
			}
			else if (influence.Definition.RainTarget.HasValue)
			{
				ApplyRainTarget(influence, influence.Definition.RainTarget.Value, ___rain, ___outerRain, ___rainSplash);
			}
		}

		private static void ApplyRainTarget(StormInfluence influence, float rainTarget, ParticleSystem rain, ParticleSystem outerRain, ParticleSystem rainSplash)
		{
			WeatherStorms instance = WeatherStorms.instance;
			Weather instance2 = Weather.instance;
			if (!((Object)(object)instance == (Object)null) && !((Object)(object)instance2 == (Object)null) && !((Object)(object)instance2.currentRegion == (Object)null) && !((Object)(object)instance2.currentRegion.rainWeather == (Object)null) && instance2.currentRegion.rainWeather.particles != null && !((Object)(object)rain == (Object)null) && !((Object)(object)outerRain == (Object)null) && !((Object)(object)rainSplash == (Object)null))
			{
				float num = StormAccess.RainBorder.Invoke(instance);
				float num2 = 1f - influence.WeatherLerp;
				if (!(num2 > num))
				{
					float num3 = Mathf.InverseLerp(num, 0f, num2);
					float num4 = Mathf.Lerp(instance2.currentRegion.rainWeather.particles.rainDensity, rainTarget, num3);
					SandstormVisuals.SetEmissionRate(rain, num4 * 75f);
					SandstormVisuals.SetEmissionRate(outerRain, num4 * 125f);
					SandstormVisuals.SetEmissionRate(rainSplash, num4 * 250f);
					GameState.rainIntensity = num4;
				}
			}
		}
	}
	[HarmonyPatch(typeof(Rain), "Update")]
	internal static class DryStormRainAudioPatch
	{
		[HarmonyPrefix]
		[HarmonyPriority(0)]
		private static void Prefix()
		{
			DryStormGameplay.SuppressRainGameplay();
		}
	}
	[HarmonyPatch(typeof(BoatDamage), "Update")]
	internal static class DryStormShipWaterPatch
	{
		[HarmonyPrefix]
		[HarmonyPriority(0)]
		private static void Prefix()
		{
			DryStormGameplay.SuppressRainGameplay();
		}
	}
	[HarmonyPatch(typeof(FogEffectController), "Update")]
	internal static class CustomStormFogPatch
	{
		[HarmonyPostfix]
		[HarmonyPriority(0)]
		private static void Postfix(FogEffectController __instance)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//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_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			if (DryStormGameplay.ShouldSuppressFog())