Decompiled source of WorldCataclysms v1.3.50

plugins/WorldCataclysms.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using SoftReferenceableAssets;
using TMPro;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.UI;
using WorldCataclysms.Config;
using WorldCataclysms.Core;
using WorldCataclysms.Events;
using WorldCataclysms.Seasons;
using WorldCataclysms.Survival;
using WorldCataclysms.Visuals;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("WorldCataclysms")]
[assembly: AssemblyDescription("Server-coordinated cataclysm events for Valheim")]
[assembly: AssemblyFileVersion("1.3.50.0")]
[assembly: AssemblyInformationalVersion("1.3.50")]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyVersion("1.3.50.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 WorldCataclysms
{
	[BepInPlugin("mitsu.worldcataclysms", "WorldCataclysms", "1.3.50")]
	[BepInDependency("com.jotunn.jotunn", "2.30.2")]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "mitsu.worldcataclysms";

		public const string PluginName = "WorldCataclysms";

		public const string PluginVersion = "1.3.50";

		private Harmony patches;

		public static Plugin Instance { get; private set; }

		public static ManualLogSource Log { get; private set; }

		private void Awake()
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			ModConfig.Bind(((BaseUnityPlugin)this).Config, ((BaseUnityPlugin)this).Logger);
			CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new AdminCommand());
			CataclysmItems.Init();
			patches = new Harmony("mitsu.worldcataclysms");
			Type[] types = typeof(Plugin).Assembly.GetTypes();
			foreach (Type type in types)
			{
				try
				{
					patches.CreateClassProcessor(type).Patch();
				}
				catch (Exception arg)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)$"[WorldCataclysms] Error aplicando parche Harmony en {type.FullName}: {arg}");
				}
			}
			((Component)this).gameObject.AddComponent<SeasonManager>();
			((Component)this).gameObject.AddComponent<WorldEventManager>();
			((Component)this).gameObject.AddComponent<AuroraVisual>();
			((Component)this).gameObject.AddComponent<NativeMeteorAssets>();
			((Component)this).gameObject.AddComponent<DustStormVisual>();
			((Component)this).gameObject.AddComponent<CreatureResponseController>();
			((Component)this).gameObject.AddComponent<WorldCataclysmsHud>();
			((Component)this).gameObject.AddComponent<PersistentHazardController>();
			((Component)this).gameObject.AddComponent<CataclysmEnvironmentRegistry>();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"WorldCataclysms 1.3.50 cargado correctamente.");
		}

		private void OnDestroy()
		{
			Harmony obj = patches;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}
	}
}
namespace WorldCataclysms.Survival
{
	internal static class DustEffortRules
	{
		internal const float MovementLoss = 0.22f;

		internal static float Cost(float intensity, float exposure)
		{
			return Math.Min(1.65f, 1f + 0.3f * Math.Max(0f, intensity) * Math.Max(0f, exposure));
		}

		internal static float Recovery(float intensity, float exposure)
		{
			return Math.Max(0.4f, 1f - 0.35f * Math.Max(0f, intensity) * Math.Max(0f, exposure));
		}

		internal static float RunningFatigue(float intensity, float exposure, bool running)
		{
			if (!running)
			{
				return 0f;
			}
			return 2f * Math.Max(0f, intensity) * Math.Max(0f, exposure);
		}
	}
	internal static class EventBalanceRules
	{
		internal static float EffortIntensity(float intensity)
		{
			return Math.Max(0.75f, Math.Min(1.25f, 0.75f + 0.25f * intensity));
		}

		internal static float MovementLoss(WorldEventType type)
		{
			return type switch
			{
				WorldEventType.Thunderstorm => 0.15f, 
				WorldEventType.ToxicFog => 0.12f, 
				WorldEventType.Blizzard => 0.2f, 
				WorldEventType.MeteorShower => 0.08f, 
				WorldEventType.DustStorm => 0.22f, 
				_ => 0f, 
			};
		}

		internal static float Cost(WorldEventType type, float intensity, float mitigation)
		{
			float num;
			switch (type)
			{
			case WorldEventType.Thunderstorm:
				num = 0.2f;
				break;
			case WorldEventType.Blizzard:
				num = 0.22f;
				break;
			case WorldEventType.ToxicFog:
				num = 0.12f;
				break;
			case WorldEventType.MeteorShower:
				num = 0.1f;
				break;
			case WorldEventType.DustStorm:
				return DustEffortRules.Cost(intensity, mitigation);
			default:
				return 1f;
			}
			return 1f + num * EffortIntensity(intensity) * Math.Max(0f, Math.Min(1f, mitigation));
		}

		internal static float Recovery(WorldEventType type, float intensity, float mitigation)
		{
			float num;
			switch (type)
			{
			case WorldEventType.Thunderstorm:
				num = 0.25f;
				break;
			case WorldEventType.Blizzard:
				num = 0.25f;
				break;
			case WorldEventType.ToxicFog:
				num = 0.2f;
				break;
			case WorldEventType.MeteorShower:
				num = 0.15f;
				break;
			case WorldEventType.DustStorm:
				return DustEffortRules.Recovery(intensity, mitigation);
			default:
				return 1f;
			}
			return 1f - num * EffortIntensity(intensity) * Math.Max(0f, Math.Min(1f, mitigation));
		}

		internal static float Impact(WorldEventType type, float nominal, float maxHealth, float intensity, float mitigation)
		{
			if (nominal <= 0f || maxHealth <= 0f || mitigation <= 0f)
			{
				return 0f;
			}
			float num = ((type == WorldEventType.MeteorShower) ? 0.5f : 0.4f);
			float num2 = ((type == WorldEventType.MeteorShower) ? 0.4f : 0.3f);
			float num3 = Math.Max(0.8f, Math.Min(1.25f, intensity));
			return Math.Min(nominal * num * num3, maxHealth * num2) * Math.Max(0f, Math.Min(1f, mitigation));
		}

		internal static float Drain(float current, float requested, float floor)
		{
			return Math.Min(Math.Max(0f, current - floor), Math.Max(0f, requested));
		}
	}
	internal static class ProtectionRules
	{
		internal static float WispMitigation = 0.4f;

		internal static float WispFactor => 1f - Math.Max(0f, Math.Min(0.9f, WispMitigation));

		internal static float PartialFactor(bool wisp, bool partial)
		{
			if (!wisp)
			{
				if (!partial)
				{
					return 1f;
				}
				return 0.5f;
			}
			return WispFactor;
		}

		internal static bool Sheltered(bool interior, bool covered, bool nearFire, bool blizzard)
		{
			if (!interior)
			{
				if (covered)
				{
					return !blizzard || nearFire;
				}
				return false;
			}
			return true;
		}

		internal static float MarineWaveFactor(float distanceSquared)
		{
			if (distanceSquared <= 625f)
			{
				return 0f;
			}
			if (distanceSquared >= 900f)
			{
				return 1f;
			}
			float num = (distanceSquared - 625f) / 275f;
			return num * num * (3f - 2f * num);
		}
	}
	[Flags]
	internal enum SurvivalDebuff
	{
		None = 0,
		Cold = 1,
		Heat = 2,
		Thirst = 4,
		ToxicAir = 8
	}
	internal static class SurvivalIndicators
	{
		public static SurvivalDebuff Active(bool suppressed, float temperature, float hydration, float normalizedAir)
		{
			if (suppressed)
			{
				return SurvivalDebuff.None;
			}
			SurvivalDebuff survivalDebuff = SurvivalDebuff.None;
			if (temperature < 30f)
			{
				survivalDebuff |= SurvivalDebuff.Cold;
			}
			if (temperature > 80f)
			{
				survivalDebuff |= SurvivalDebuff.Heat;
			}
			if (hydration < 35f)
			{
				survivalDebuff |= SurvivalDebuff.Thirst;
			}
			if (normalizedAir < 0.45f)
			{
				survivalDebuff |= SurvivalDebuff.ToxicAir;
			}
			return survivalDebuff;
		}

		public static string Name(SurvivalDebuff kind, float temperature, float hydration, float air)
		{
			switch (kind)
			{
			case SurvivalDebuff.Cold:
				if (!(temperature < 15f))
				{
					return "Frío · exposición";
				}
				return "Hipotermia";
			case SurvivalDebuff.Heat:
				if (!(temperature > 85f))
				{
					return "Calor · exposición";
				}
				return "Sobrecalentamiento";
			case SurvivalDebuff.Thirst:
				if (!(hydration < 15f))
				{
					return "Sed · exposición";
				}
				return "Deshidratación";
			case SurvivalDebuff.ToxicAir:
				if (!(air < 0.2f))
				{
					return "Aire viciado";
				}
				return "Aire tóxico";
			default:
				return "";
			}
		}

		public static string CountermeasureForEvent(SurvivalDebuff kind, bool dust)
		{
			if (dust && kind == SurvivalDebuff.ToxicAir)
			{
				return "Busca techo; Wisp equipado mitiga el polvo. Equipa la antorcha Ápex de Lox con durabilidad para protegerte.";
			}
			return Countermeasure(kind);
		}

		public static string Countermeasure(SurvivalDebuff kind)
		{
			return kind switch
			{
				SurvivalDebuff.Cold => "Busca techo con fuego o un interior; usa protección contra el frío o la Antorcha Polar Ápex.", 
				SurvivalDebuff.Heat => "Busca refugio y protección contra el fuego o la Antorcha Ígnea Ápex.", 
				SurvivalDebuff.Thirst => "Come o bebe para recuperar 15 puntos; el refugio recupera hidratación lentamente.", 
				SurvivalDebuff.ToxicAir => "Busca refugio, Wisp como mitigación o protección Miasmática Ápex.", 
				_ => "", 
			};
		}
	}
	public sealed class ExposureSample
	{
		public Player Player { get; internal set; }

		public bool Sheltered { get; internal set; }

		public bool ApexProtected { get; internal set; }

		public bool Wet { get; internal set; }

		public bool Cold { get; internal set; }

		public bool Freezing { get; internal set; }

		public bool TemperatureEnabled { get; internal set; }

		public bool HydrationEnabled { get; internal set; }

		public bool AirQualityEnabled { get; internal set; }

		public float AirQuality { get; internal set; }

		public float Temperature { get; internal set; }

		public float Hydration { get; internal set; }

		public string Penalty { get; internal set; }

		public string Protection { get; internal set; }

		public string Effect { get; internal set; }

		public EventPhase Phase { get; internal set; }
	}
	public static class SurvivalManager
	{
		private static readonly MethodInfo GetDamageModifierMethod = AccessTools.Method(typeof(Character), "GetDamageModifier", (Type[])null, (Type[])null);

		private static float nextSample;

		private static float temperature = 55f;

		private static float hydration = 100f;

		private static float air = 100f;

		private static float nextDamage;

		private static float nextSave;

		private static float nextShipDamage;

		private static float exposureSeconds;

		private static string loadedStorageKey;

		public static ExposureSample Current { get; private set; }

		public static float MovementMultiplier
		{
			get
			{
				if (Current == null)
				{
					return 1f;
				}
				float num = SurvivalRules.MovementMultiplier(Current.TemperatureEnabled, Current.Temperature, Current.HydrationEnabled, Current.Hydration, Current.AirQualityEnabled, Current.AirQuality);
				WorldEventManager instance = WorldEventManager.Instance;
				Player player = Current.Player;
				if (RespawnProtection.IsProtected((Character)(object)player))
				{
					return 1.2f;
				}
				if ((Object)(object)instance != (Object)null && instance.Phase == EventPhase.Active)
				{
					if ((Object)(object)player == (Object)null || !RegionalEventRules.Affects(instance.EventType, (Character)(object)player))
					{
						return num;
					}
					if (CataclysmItems.HasApexProtection(instance.EventType, player, out var _))
					{
						return 1.08f;
					}
				}
				if ((Object)(object)instance == (Object)null || instance.Phase != EventPhase.Active || Current.Sheltered)
				{
					return num;
				}
				return num * CataclysmStatBalance.GetEventMovementFactor(instance.EventType, player, CataclysmDayScaling.GetDayIntensity());
			}
		}

		internal static float StaminaCostMultiplier
		{
			get
			{
				if (Current == null)
				{
					return 1f;
				}
				Player player = Current.Player;
				if (RespawnProtection.IsProtected((Character)(object)player))
				{
					return 0.85f;
				}
				WorldEventManager instance = WorldEventManager.Instance;
				bool flag = (Object)(object)instance != (Object)null && instance.Phase == EventPhase.Active && (Object)(object)player != (Object)null && RegionalEventRules.Affects(instance.EventType, (Character)(object)player);
				if (flag && instance.EventType == WorldEventType.MagicalAurora)
				{
					return 0.9f;
				}
				if (flag && CataclysmItems.HasApexProtection(instance.EventType, player, out var _))
				{
					return 0.9f;
				}
				float num = (flag ? EventProtection.PartialFactor(player, instance.EventType) : (((Object)(object)player != (Object)null && CataclysmItems.HasWispProtection(player)) ? ProtectionRules.WispFactor : 1f));
				float dayIntensity = CataclysmDayScaling.GetDayIntensity();
				float num2 = ((Current.Temperature < 30f || Current.Temperature > 80f || Current.Hydration < 35f || Current.AirQuality < 0.45f) ? Mathf.Clamp(1f + 0.16f * dayIntensity * num, 1f, 1.25f) : 1f);
				if (flag && !Current.Sheltered)
				{
					num2 = Mathf.Max(num2, EventBalanceRules.Cost(instance.EventType, dayIntensity, num));
				}
				return num2;
			}
		}

		internal static float RecoveryMultiplier
		{
			get
			{
				if (Current == null)
				{
					return 1f;
				}
				Player player = Current.Player;
				if (RespawnProtection.IsProtected((Character)(object)player))
				{
					return 1.35f;
				}
				WorldEventManager instance = WorldEventManager.Instance;
				bool flag = (Object)(object)instance != (Object)null && instance.Phase == EventPhase.Active && (Object)(object)player != (Object)null && RegionalEventRules.Affects(instance.EventType, (Character)(object)player);
				if (flag && instance.EventType == WorldEventType.MagicalAurora)
				{
					return 1.15f;
				}
				if (flag && CataclysmItems.HasApexProtection(instance.EventType, player, out var _))
				{
					return 1.15f;
				}
				float num = (flag ? EventProtection.PartialFactor(player, instance.EventType) : (((Object)(object)player != (Object)null && CataclysmItems.HasWispProtection(player)) ? ProtectionRules.WispFactor : 1f));
				float dayIntensity = CataclysmDayScaling.GetDayIntensity();
				bool num2 = Current.Temperature < 15f || Current.Temperature > 90f || Current.Hydration < 15f || Current.AirQuality < 0.2f;
				bool flag2 = Current.Temperature < 30f || Current.Temperature > 80f || Current.Hydration < 35f || Current.AirQuality < 0.45f;
				float num3 = (num2 ? Mathf.Clamp(1f - 0.35f * dayIntensity * num, 0.5f, 1f) : (flag2 ? Mathf.Clamp(1f - 0.18f * dayIntensity * num, 0.72f, 1f) : 1f));
				if (flag && !Current.Sheltered)
				{
					num3 = Mathf.Min(num3, EventBalanceRules.Recovery(instance.EventType, dayIntensity, num));
				}
				return num3;
			}
		}

		public static event Action<ExposureSample> ExposureUpdated;

		internal static void Reset()
		{
			SaveExposure();
			Current = null;
			nextSample = (exposureSeconds = 0f);
			loadedStorageKey = null;
			temperature = 55f;
			hydration = (air = 100f);
		}

		internal static void ResetExposureToSafe()
		{
			exposureSeconds = 0f;
			temperature = 55f;
			hydration = 100f;
			air = 100f;
			SaveExposure();
		}

		internal static void Rehydrate(float amount)
		{
			if (amount > 0f)
			{
				hydration = Mathf.Clamp(hydration + amount, 0f, 100f);
			}
		}

		internal static void Tick(WorldEventManager manager)
		{
			//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02de: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e3: Invalid comparison between Unknown and I4
			//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ec: Invalid comparison between Unknown and I4
			//IL_04d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04de: Invalid comparison between Unknown and I4
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)EnvMan.instance == (Object)null)
			{
				Current = null;
				return;
			}
			RespawnProtection.TickPlayerState(localPlayer);
			EnsureLoaded(localPlayer);
			if (Time.realtimeSinceStartup < nextSample)
			{
				return;
			}
			nextSample = Time.realtimeSinceStartup + 1f;
			float maxHealth = ((Character)localPlayer).GetMaxHealth();
			float health = ((Character)localPlayer).GetHealth();
			float maxStamina = ((Character)localPlayer).GetMaxStamina();
			float stamina = localPlayer.GetStamina();
			float maxEitr = ((Character)localPlayer).GetMaxEitr();
			float eitr = localPlayer.GetEitr();
			bool partial = false;
			bool flag = RegionalEventRules.Affects(manager.EventType, (Character)(object)localPlayer);
			bool flag2 = RespawnProtection.IsProtected((Character)(object)localPlayer);
			bool flag3 = manager.Phase == EventPhase.Active && flag;
			bool flag4 = flag3 && CataclysmItems.HasApexProtection(manager.EventType, localPlayer, out partial);
			bool flag5 = flag && CataclysmItems.HasWispProtection(localPlayer);
			if (flag5)
			{
				partial = true;
			}
			bool flag6 = flag2 || flag4 || EventProtection.IsSheltered(localPlayer, manager.EventType);
			exposureSeconds = ((flag3 && manager.EventType != WorldEventType.MagicalAurora && !flag6) ? (exposureSeconds + (flag5 ? ProtectionRules.WispFactor : 1f)) : Mathf.Max(0f, exposureSeconds - 2f));
			if (manager.TemperatureEnabled)
			{
				float num = BaseTemperature(localPlayer);
				if (flag2 || flag4)
				{
					num = 55f;
				}
				else if (flag3 && manager.EventType == WorldEventType.MagicalAurora)
				{
					num = 58f;
				}
				else if (!flag6 && flag3 && manager.EventType == WorldEventType.Blizzard)
				{
					num = (flag5 ? 38f : (partial ? 25f : 0f));
				}
				else if (!flag6 && flag3 && manager.EventType == WorldEventType.MeteorShower)
				{
					num = (flag5 ? 68f : (partial ? 75f : 100f));
				}
				if (flag6 || StrikeDamage.IsNearFire(localPlayer))
				{
					num = Mathf.MoveTowards(num, 58f, 18f);
				}
				else if (flag5)
				{
					num = Mathf.MoveTowards(num, 55f, 10f);
				}
				temperature = Mathf.MoveTowards(temperature, num, flag6 ? 2.2f : ((!flag3) ? 0.55f : (flag5 ? 0.55f : 1.35f)));
			}
			else
			{
				temperature = 55f;
			}
			if (manager.HydrationEnabled)
			{
				float num2 = ((flag2 || flag4 || (flag3 && manager.EventType == WorldEventType.MagicalAurora)) ? 0.12f : SurvivalRules.EventHydrationDelta(flag3, manager.EventType == WorldEventType.MeteorShower, manager.EventType == WorldEventType.DustStorm, flag6, ProtectionRules.PartialFactor(flag5, partial)));
				if (!flag6 && !flag5 && temperature > 80f)
				{
					num2 -= 0.04f;
				}
				hydration = Mathf.Clamp(hydration + num2, 0f, 100f);
			}
			else
			{
				hydration = 100f;
			}
			if (manager.AirQualityEnabled)
			{
				Biome currentBiome = localPlayer.GetCurrentBiome();
				float num3 = (((int)currentBiome == 2) ? 82f : (((int)currentBiome != 512) ? 100f : 88f));
				float num4 = num3;
				if (flag2 || flag4 || (flag3 && manager.EventType == WorldEventType.MagicalAurora))
				{
					num4 = 100f;
				}
				else if (flag3 && manager.EventType == WorldEventType.ToxicFog && !flag6)
				{
					num4 = (flag5 ? 72f : (partial ? 50f : 5f));
				}
				if (flag3 && manager.EventType == WorldEventType.DustStorm && !flag6)
				{
					num4 = (flag5 ? 72f : (partial ? 50f : 35f));
				}
				if (flag6)
				{
					num4 = 100f;
				}
				air = Mathf.MoveTowards(air, num4, (!(num4 < air)) ? 2f : ((!flag3) ? 0.35f : (flag5 ? 1.5f : 4.5f)));
			}
			else
			{
				air = 100f;
			}
			bool flag7 = flag3 && manager.EventType == WorldEventType.MagicalAurora;
			if (flag7)
			{
				SEMan sEMan = ((Character)localPlayer).GetSEMan();
				if (sEMan != null)
				{
					int stableHashCode = StringExtensionMethods.GetStableHashCode("Freezing");
					int stableHashCode2 = StringExtensionMethods.GetStableHashCode("Cold");
					if (sEMan.HaveStatusEffect(stableHashCode))
					{
						sEMan.RemoveStatusEffect(stableHashCode, true);
					}
					if (sEMan.HaveStatusEffect(stableHashCode2))
					{
						sEMan.RemoveStatusEffect(stableHashCode2, true);
					}
				}
			}
			string penalty = (flag2 ? "Protección Post-Muerte (10s)" : (flag4 ? "Ninguna (Ápex: antorcha equipada)" : (flag7 ? "Ninguna (Aurora Serena)" : ((SurvivalRules.Penalty(manager.TemperatureEnabled, temperature, manager.HydrationEnabled, hydration, manager.AirQualityEnabled, air) == "Ninguna" && flag3) ? "Efectos del evento activos; sin condición fisiológica crítica" : SurvivalRules.Penalty(manager.TemperatureEnabled, temperature, manager.HydrationEnabled, hydration, manager.AirQualityEnabled, air)))));
			bool flag8 = flag3 && manager.EventType == WorldEventType.MeteorShower && !flag6 && ((int)localPlayer.GetCurrentBiome() == 256 || ((Character)localPlayer).IsAttachedToShip());
			string effect = (flag2 ? "Inmunidad total post-muerte" : (flag4 ? "Protección completa frente al evento" : (flag5 ? "Wisp equipado: mitigación global del 40% frente al cataclismo; no cuenta como refugio" : (flag7 ? "Armonía de Aurora: +25% velocidad, recursos naturales x2 en su región y calma" : Effect(manager, flag6, flag8)))));
			string protection = (flag2 ? "RENACIDO (INMUNE)" : (flag4 ? "PROTEGIDO (ÁPEX: ANTORCHA EQUIPADA)" : (flag7 ? "SERENO (AURORA)" : (flag6 ? "PROTEGIDO" : (flag5 ? "MITIGADO (WISP)" : ((flag8 || partial) ? "MITIGADO" : (flag3 ? "EXPUESTO" : "AMBIENTE")))))));
			Current = new ExposureSample
			{
				Player = localPlayer,
				Sheltered = (flag6 || flag7),
				ApexProtected = flag4,
				Wet = (!flag6 && !flag7 && EnvMan.IsWet()),
				Cold = (!flag7 && !flag6 && EnvMan.IsCold()),
				Freezing = (!flag7 && !flag6 && EnvMan.IsFreezing()),
				TemperatureEnabled = manager.TemperatureEnabled,
				HydrationEnabled = manager.HydrationEnabled,
				AirQualityEnabled = manager.AirQualityEnabled,
				AirQuality = air / 100f,
				Temperature = (flag7 ? 60f : temperature),
				Hydration = hydration,
				Penalty = penalty,
				Phase = manager.Phase,
				Protection = protection,
				Effect = effect
			};
			FoodExposure.AdjustCurrentResources(localPlayer, maxHealth, health, maxStamina, stamina, maxEitr, eitr);
			bool flag9 = !flag7 && SurvivalRules.IsDangerous(manager.TemperatureEnabled, temperature, manager.HydrationEnabled, hydration, manager.AirQualityEnabled, air);
			if (Time.realtimeSinceStartup >= nextDamage)
			{
				nextDamage = Time.realtimeSinceStartup + 1f;
				float dayIntensity = CataclysmDayScaling.GetDayIntensity();
				if (!flag2 && !flag7)
				{
					float num5 = ProtectionRules.PartialFactor(flag5, partial);
					if (flag3 && manager.EventType == WorldEventType.DustStorm && !flag6)
					{
						float num6 = DustEffortRules.RunningFatigue(dayIntensity, num5, ((Character)localPlayer).IsRunning());
						if (num6 > 0f)
						{
							((Character)localPlayer).UseStamina(num6);
						}
					}
					float num7 = ExposureDamage(manager, localPlayer, flag6, flag9) * dayIntensity * num5;
					if (num7 > 0f)
					{
						if (localPlayer.GetStamina() > 15f)
						{
							((Character)localPlayer).AddStamina(0f - SurvivalRules.EnvironmentalDrain(localPlayer.GetStamina(), num7 * 0.45f));
						}
						if ((flag9 || (flag3 && (manager.EventType == WorldEventType.ToxicFog || manager.EventType == WorldEventType.Blizzard || manager.EventType == WorldEventType.MeteorShower))) && ((Character)localPlayer).GetHealth() > ((Character)localPlayer).GetMaxHealth() * 0.18f)
						{
							float num8 = Mathf.Clamp(num7 / num5 * 0.28f, 0.35f, 2.2f) * num5;
							float health2 = Mathf.Max(((Character)localPlayer).GetMaxHealth() * 0.18f, ((Character)localPlayer).GetHealth() - num8);
							((Character)localPlayer).SetHealth(health2);
						}
						if (flag3 && (manager.EventType == WorldEventType.MeteorShower || manager.EventType == WorldEventType.Thunderstorm || manager.EventType == WorldEventType.ToxicFog) && localPlayer.GetEitr() > 5f)
						{
							((Character)localPlayer).AddEitr(0f - EventBalanceRules.Drain(localPlayer.GetEitr(), Mathf.Clamp(num7 / num5 * 0.3f, 0.4f, 1.8f) * num5, 5f));
						}
					}
				}
				if (flag3 && manager.EventType == WorldEventType.MeteorShower && ((Character)localPlayer).IsAttachedToShip() && Time.realtimeSinceStartup >= nextShipDamage)
				{
					nextShipDamage = Time.realtimeSinceStartup + 5f;
					StrikeDamage.ApplyShipExposure(localPlayer, 1.5f);
				}
			}
			if (Time.realtimeSinceStartup >= nextSave)
			{
				nextSave = Time.realtimeSinceStartup + 30f;
				SaveExposure();
			}
			HookDispatcher.Invoke(SurvivalManager.ExposureUpdated, Current);
		}

		private static float BaseTemperature(Player player)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Invalid comparison between Unknown and I4
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Invalid comparison between Unknown and I4
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Invalid comparison between Unknown and I4
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Invalid comparison between Unknown and I4
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Invalid comparison between Unknown and I4
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Invalid comparison between Unknown and I4
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Invalid comparison between Unknown and I4
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Invalid comparison between Unknown and I4
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Invalid comparison between Unknown and I4
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Invalid comparison between Unknown and I4
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Invalid comparison between Unknown and I4
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Invalid comparison between Unknown and I4
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Invalid comparison between Unknown and I4
			Biome currentBiome = player.GetCurrentBiome();
			bool flag = (Object)(object)EnvMan.instance != (Object)null && EnvMan.IsNight();
			float num;
			if ((int)currentBiome <= 16)
			{
				if ((int)currentBiome <= 4)
				{
					if ((int)currentBiome != 2)
					{
						if ((int)currentBiome != 4)
						{
							goto IL_00a8;
						}
						num = 12f;
					}
					else
					{
						num = 42f;
					}
				}
				else if ((int)currentBiome != 8)
				{
					if ((int)currentBiome != 16)
					{
						goto IL_00a8;
					}
					num = (flag ? 44f : 72f);
				}
				else
				{
					num = 44f;
				}
			}
			else if ((int)currentBiome <= 64)
			{
				if ((int)currentBiome != 32)
				{
					if ((int)currentBiome != 64)
					{
						goto IL_00a8;
					}
					num = 3f;
				}
				else
				{
					num = 94f;
				}
			}
			else if ((int)currentBiome != 256)
			{
				if ((int)currentBiome != 512)
				{
					goto IL_00a8;
				}
				num = 46f;
			}
			else
			{
				num = 48f;
			}
			goto IL_00ae;
			IL_00a8:
			num = 55f;
			goto IL_00ae;
			IL_00ae:
			float num2 = num;
			if (flag && (int)currentBiome != 16 && (int)currentBiome != 32)
			{
				num2 -= 10f;
			}
			if (EnvMan.IsFreezing())
			{
				num2 = Mathf.Min(num2, 8f);
			}
			else if (EnvMan.IsCold())
			{
				num2 = Mathf.Min(num2, 28f);
			}
			if (EnvMan.IsWet())
			{
				num2 -= 10f;
			}
			if (((Character)player).InWater())
			{
				num2 -= 12f;
			}
			else if (((Character)player).IsAttachedToShip() && EnvMan.instance.GetWindIntensity() > 0.65f)
			{
				num2 -= 4f;
			}
			return Mathf.Clamp(num2, 0f, 100f);
		}

		private static void EnsureLoaded(Player player)
		{
			string text = (((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetWorldUID().ToString() : "none");
			string text2 = "WC_Exposure_" + text + "_" + player.GetPlayerID();
			if (!(loadedStorageKey == text2))
			{
				loadedStorageKey = text2;
				temperature = PlayerPrefs.GetFloat(text2 + "_Temperature", 55f);
				hydration = PlayerPrefs.GetFloat(text2 + "_Hydration", 100f);
				air = PlayerPrefs.GetFloat(text2 + "_Air", 100f);
			}
		}

		private static void SaveExposure()
		{
			if (!string.IsNullOrEmpty(loadedStorageKey))
			{
				PlayerPrefs.SetFloat(loadedStorageKey + "_Temperature", temperature);
				PlayerPrefs.SetFloat(loadedStorageKey + "_Hydration", hydration);
				PlayerPrefs.SetFloat(loadedStorageKey + "_Air", air);
				PlayerPrefs.Save();
			}
		}

		private static float ExposureDamage(WorldEventManager manager, Player player, bool sheltered, bool dangerous)
		{
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Invalid comparison between Unknown and I4
			if ((Object)(object)player == (Object)null || sheltered)
			{
				return 0f;
			}
			if (manager.Phase == EventPhase.Active && RegionalEventRules.Affects(manager.EventType, (Character)(object)player))
			{
				switch (manager.EventType)
				{
				case WorldEventType.ToxicFog:
					return Mathf.Lerp(3f, 5f, Mathf.Clamp01(exposureSeconds / 60f)) * Resistance(player, (DamageType)256, 0.45f);
				case WorldEventType.Blizzard:
					return Mathf.Lerp(4f, 6f, Mathf.Clamp01(exposureSeconds / 75f)) * Resistance(player, (DamageType)64, 0.45f);
				case WorldEventType.MeteorShower:
				{
					float num = (((int)player.GetCurrentBiome() == 256 || ((Character)player).IsAttachedToShip()) ? 0.4f : 1f);
					return Mathf.Lerp(1.5f, 2.5f, Mathf.Clamp01(exposureSeconds / 60f)) * Resistance(player, (DamageType)32, 0.35f) * num;
				}
				case WorldEventType.DustStorm:
					return 0f;
				case WorldEventType.Thunderstorm:
					return 0f;
				}
			}
			if (!dangerous)
			{
				return 0f;
			}
			if (temperature < 8f)
			{
				return 1.25f * Resistance(player, (DamageType)64, 0f);
			}
			if (temperature > 92f)
			{
				return 1.25f * Resistance(player, (DamageType)32, 0.2f);
			}
			if (air < 8f)
			{
				return 1.25f * Resistance(player, (DamageType)256, 0.2f);
			}
			return 1.25f;
		}

		private static float Resistance(Player player, DamageType type, float minimum)
		{
			//IL_0021: 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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected I4, but got Unknown
			if (GetDamageModifierMethod == null)
			{
				return 1f;
			}
			DamageModifier val = (DamageModifier)GetDamageModifierMethod.Invoke(player, new object[1] { type });
			switch (val - 1)
			{
			case 2:
			case 4:
				return minimum;
			case 0:
				return Mathf.Max(minimum, 0.65f);
			case 1:
				return 1.25f;
			case 5:
				return 1.5f;
			default:
				return 1f;
			}
		}

		private static string Effect(WorldEventManager manager, bool sheltered, bool oceanMitigated)
		{
			if (manager.Phase == EventPhase.Warning)
			{
				return "Prepárate y busca refugio";
			}
			if (manager.Phase == EventPhase.Idle)
			{
				return "Condición natural del bioma";
			}
			if (sheltered)
			{
				return "El techo bloquea la exposición";
			}
			if (oceanMitigated)
			{
				return "Navegación oceánica · daño reducido 60%";
			}
			return manager.EventType switch
			{
				WorldEventType.Thunderstorm => "Rayos cercanos · daño eléctrico", 
				WorldEventType.DustStorm => "Polvo en suspensión · sed y aire viciado; busca techo, come o bebe; antorcha Ápex de Lox equipada protege", 
				WorldEventType.ToxicFog => "Veneno continuo · aire irrespirable", 
				WorldEventType.MagicalAurora => "Armonía: x2 recolección de recursos, velocidad y paz", 
				WorldEventType.MeteorShower => "Calor extremo · impactos incendiarios", 
				WorldEventType.Blizzard => "Frío y desgaste; busca techo con fuego", 
				_ => "Exposición peligrosa", 
			};
		}
	}
	[HarmonyPatch(typeof(Player), "ConsumeItem")]
	internal static class HydrationConsumePatch
	{
		private static void Postfix(Player __instance, bool __result, ItemData item)
		{
			if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && __result && item != null && !((Object)(object)WorldEventManager.Instance == (Object)null) && WorldEventManager.Instance.HydrationEnabled)
			{
				FoodExposure.Invalidate();
				SurvivalManager.Rehydrate(15f);
			}
		}
	}
	internal static class SurvivalRules
	{
		public static float MovementMultiplier(bool temperatureEnabled, float temperature, bool hydrationEnabled, float hydration, bool airEnabled, float air)
		{
			bool num = (hydrationEnabled && hydration < 15f) || (temperatureEnabled && (temperature < 15f || temperature > 90f)) || (airEnabled && air < 0.2f);
			bool flag = (hydrationEnabled && hydration < 35f) || (temperatureEnabled && (temperature < 30f || temperature > 80f)) || (airEnabled && air < 0.45f);
			if (!num)
			{
				if (!flag)
				{
					return 1f;
				}
				return 0.9f;
			}
			return 0.75f;
		}

		public static float HydrationDelta(bool enabled, bool active, bool meteorShower, bool sheltered)
		{
			if (enabled)
			{
				if (!sheltered)
				{
					if (!(active && meteorShower))
					{
						if (!active)
						{
							return 0f;
						}
						return -0.035f;
					}
					return -0.075f;
				}
				return 0.05f;
			}
			return 0f;
		}

		public static float EventHydrationDelta(bool active, bool meteor, bool dust, bool sheltered, float mitigation)
		{
			float num = HydrationDelta(enabled: true, active, meteor, sheltered);
			if (!active || sheltered)
			{
				return num;
			}
			if (dust)
			{
				num -= 0.465f;
			}
			return num * Math.Max(0f, Math.Min(1f, mitigation));
		}

		public static float EnvironmentalDrain(float current, float requested)
		{
			return Math.Min(Math.Max(0f, current - 15f), Math.Max(0f, requested));
		}

		public static bool IsDangerous(bool temperatureEnabled, float temperature, bool hydrationEnabled, float hydration, bool airEnabled, float air)
		{
			if ((!temperatureEnabled || (!(temperature < 8f) && !(temperature > 92f))) && (!hydrationEnabled || !(hydration < 5f)))
			{
				if (airEnabled)
				{
					return air < 8f;
				}
				return false;
			}
			return true;
		}

		public static string Penalty(bool temperatureEnabled, float temperature, bool hydrationEnabled, float hydration, bool airEnabled, float air)
		{
			if (!temperatureEnabled || !(temperature < 15f))
			{
				if (!temperatureEnabled || !(temperature > 85f))
				{
					if (!hydrationEnabled || !(hydration < 15f))
					{
						if (!airEnabled || !(air < 20f))
						{
							if ((!temperatureEnabled || !(temperature < 30f)) && (!hydrationEnabled || !(hydration < 35f)) && (!airEnabled || !(air < 45f)))
							{
								return "Ninguna";
							}
							return "Exposición moderada";
						}
						return "Aire tóxico";
					}
					return "Deshidratación";
				}
				return "Sobrecalentamiento";
			}
			return "Hipotermia";
		}

		public static float DayProgressionFraction(int worldDay)
		{
			return DayProgressionFraction(worldDay, 300);
		}

		public static float DayProgressionFraction(int worldDay, int maxProgressionDay)
		{
			if (worldDay <= 1)
			{
				return 0f;
			}
			if (worldDay >= maxProgressionDay)
			{
				return 1f;
			}
			float num = (float)maxProgressionDay / 300f;
			float num2 = 50f * num;
			float num3 = 100f * num;
			float num4 = 200f * num;
			float num5 = worldDay;
			if (num5 <= num2)
			{
				return (num5 - 1f) / Math.Max(1f, num2 - 1f) * 0.15384616f;
			}
			if (num5 <= num3)
			{
				float num6 = (num5 - num2) / Math.Max(1f, num3 - num2);
				return 0.15384616f + num6 * 0.15384616f;
			}
			if (num5 <= num4)
			{
				float num7 = (num5 - num3) / Math.Max(1f, num4 - num3);
				return 0.30769232f + num7 * 0.30769232f;
			}
			float num8 = (num5 - num4) / Math.Max(1f, (float)maxProgressionDay - num4);
			return 0.61538464f + num8 * 0.3846154f;
		}

		public static float DayDurationSeconds(int worldDay)
		{
			return DayDurationSeconds(worldDay, 120f, 900f, 300);
		}

		public static float DayDurationSeconds(int worldDay, float minSeconds, float maxSeconds, int maxProgressionDay)
		{
			float num = DayProgressionFraction(worldDay, maxProgressionDay);
			return minSeconds + (maxSeconds - minSeconds) * num;
		}

		public static float DayDurationMultiplier(int worldDay)
		{
			return DayDurationSeconds(worldDay, 120f, 900f, 300) / 300f;
		}

		public static float DayIntensityMultiplier(int worldDay)
		{
			return DayIntensityMultiplier(worldDay, 1.75f);
		}

		public static float DayIntensityMultiplier(int worldDay, float maxMultiplier)
		{
			if (worldDay <= 1)
			{
				return 0.55f;
			}
			if (worldDay >= 300)
			{
				return maxMultiplier;
			}
			float num = worldDay;
			if (num <= 50f)
			{
				float num2 = (num - 1f) / 49f;
				return 0.55f + 0.19999999f * num2;
			}
			if (num <= 100f)
			{
				float num3 = (num - 50f) / 50f;
				return 0.75f + 0.25f * num3;
			}
			if (num <= 200f)
			{
				float num4 = (num - 100f) / 100f;
				return 1f + 0.375f * num4;
			}
			float num5 = (num - 200f) / 100f;
			return 1.375f + (maxMultiplier - 1.375f) * num5;
		}

		public static void ThunderstormStrikeRange(int worldDay, out int minStrikes, out int maxStrikes)
		{
			ThunderstormStrikeRange(worldDay, 2, 10, 300, out minStrikes, out maxStrikes);
		}

		public static void ThunderstormStrikeRange(int worldDay, int configMin, int configMax, int maxProgressionDay, out int minStrikes, out int maxStrikes)
		{
			int num = Math.Max(1, configMin);
			int num2 = Math.Max(num, configMax);
			if (worldDay <= 1)
			{
				minStrikes = num;
				maxStrikes = Math.Min(num2, num + 1);
				return;
			}
			if (worldDay >= maxProgressionDay)
			{
				maxStrikes = num2;
				minStrikes = Math.Max(num, num2 - 3);
				return;
			}
			float num3 = (float)maxProgressionDay / 300f;
			float num4 = 50f * num3;
			float num5 = 100f * num3;
			float num6 = 200f * num3;
			float num7 = worldDay;
			float num9;
			float num10;
			if (num7 <= num4)
			{
				float num8 = (num7 - 1f) / Math.Max(1f, num4 - 1f);
				num9 = 2f + 1f * num8;
				num10 = 3f + 1f * num8;
			}
			else if (num7 <= num5)
			{
				float num11 = (num7 - num4) / Math.Max(1f, num5 - num4);
				num9 = 3f + 1f * num11;
				num10 = 4f + 1f * num11;
			}
			else if (num7 <= num6)
			{
				float num12 = (num7 - num5) / Math.Max(1f, num6 - num5);
				num9 = 4f + 1f * num12;
				num10 = 5f + 2f * num12;
			}
			else
			{
				float num13 = (num7 - num6) / Math.Max(1f, (float)maxProgressionDay - num6);
				num9 = 5f + 2f * num13;
				num10 = 7f + 3f * num13;
			}
			float num14 = (float)(num2 - num) / 8f;
			minStrikes = Math.Max(num, Math.Min(num2, (int)Math.Round((float)num + (num9 - 2f) * num14, MidpointRounding.AwayFromZero)));
			maxStrikes = Math.Max(minStrikes, Math.Min(num2, (int)Math.Round((float)num + (num10 - 2f) * num14, MidpointRounding.AwayFromZero)));
		}
	}
}
namespace WorldCataclysms.Seasons
{
	public static class SeasonalityAdapter
	{
		public static WorldSeason GetCurrentSeason()
		{
			if (!ModConfig.EnableSeasonalityIntegration.Value || (Object)(object)ZoneSystem.instance == (Object)null)
			{
				return WorldSeason.Unknown;
			}
			int num = 0;
			WorldSeason result = WorldSeason.Unknown;
			if (ZoneSystem.instance.GetGlobalKey(ModConfig.SpringKey.Value))
			{
				num++;
				result = WorldSeason.Spring;
			}
			if (ZoneSystem.instance.GetGlobalKey(ModConfig.SummerKey.Value))
			{
				num++;
				result = WorldSeason.Summer;
			}
			if (ZoneSystem.instance.GetGlobalKey(ModConfig.FallKey.Value))
			{
				num++;
				result = WorldSeason.Fall;
			}
			if (ZoneSystem.instance.GetGlobalKey(ModConfig.WinterKey.Value))
			{
				num++;
				result = WorldSeason.Winter;
			}
			if (num != 1)
			{
				return WorldSeason.Unknown;
			}
			return result;
		}
	}
	public sealed class SeasonManager : MonoBehaviour
	{
		private float _refreshTimer;

		public static SeasonManager Instance { get; private set; }

		public WorldSeason CurrentSeason { get; private set; }

		private void Awake()
		{
			Instance = this;
		}

		private void Update()
		{
			_refreshTimer += Time.deltaTime;
			if (_refreshTimer < 5f)
			{
				return;
			}
			_refreshTimer = 0f;
			WorldSeason currentSeason = SeasonalityAdapter.GetCurrentSeason();
			if (currentSeason != CurrentSeason)
			{
				CurrentSeason = currentSeason;
				if ((Object)(object)Plugin.Instance != (Object)null)
				{
					Plugin.Log.LogInfo((object)$"Estación detectada: {CurrentSeason}");
				}
			}
		}
	}
	public enum WorldSeason
	{
		Unknown,
		Spring,
		Summer,
		Fall,
		Winter
	}
}
namespace WorldCataclysms.Events
{
	public sealed class BlizzardEvent : PulsedWorldEvent
	{
		public override WorldEventType Type => WorldEventType.Blizzard;

		public override bool IsAllowedInSeason(WorldSeason season)
		{
			if (season != WorldSeason.Unknown)
			{
				return season == WorldSeason.Winter;
			}
			return true;
		}

		protected override void EmitPulse(WorldEventManager manager)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			manager.BroadcastHazard(Type, Vector3.zero, Vector3.zero, global: true);
		}
	}
	public sealed class DustStormEvent : WorldEventBase
	{
		public override WorldEventType Type => WorldEventType.DustStorm;

		public override bool IsAllowedInSeason(WorldSeason season)
		{
			if (season != WorldSeason.Unknown && season != WorldSeason.Summer)
			{
				return season == WorldSeason.Fall;
			}
			return true;
		}
	}
	internal static class EventTargeting
	{
		public static bool TryRandomPlayer(out Vector3 position)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: 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)
			position = Vector3.zero;
			if ((Object)(object)ZNet.instance == (Object)null)
			{
				return false;
			}
			List<ZDO> allCharacterZDOS = ZNet.instance.GetAllCharacterZDOS();
			if (allCharacterZDOS.Count == 0)
			{
				return false;
			}
			WorldEventManager instance = WorldEventManager.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return false;
			}
			int num = Random.Range(0, allCharacterZDOS.Count);
			for (int i = 0; i < allCharacterZDOS.Count; i++)
			{
				Vector3 position2 = allCharacterZDOS[(num + i) % allCharacterZDOS.Count].GetPosition();
				if (RegionalEventRules.At(instance.EventType, position2))
				{
					position = position2;
					return true;
				}
			}
			return false;
		}

		public static bool TryRandomCoastalPlayer(out Vector3 position)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: 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_0086: Unknown result type (might be due to invalid IL or missing references)
			position = Vector3.zero;
			if ((Object)(object)ZNet.instance == (Object)null || (Object)(object)ZoneSystem.instance == (Object)null)
			{
				return false;
			}
			List<ZDO> allCharacterZDOS = ZNet.instance.GetAllCharacterZDOS();
			if (allCharacterZDOS.Count == 0)
			{
				return false;
			}
			int num = Random.Range(0, allCharacterZDOS.Count);
			for (int i = 0; i < allCharacterZDOS.Count; i++)
			{
				Vector3 position2 = allCharacterZDOS[(num + i) % allCharacterZDOS.Count].GetPosition();
				if (RegionalEventRules.At(WorldEventType.Tsunami, position2) && position2.y <= ZoneSystem.instance.m_waterLevel + 10f)
				{
					position = position2;
					return true;
				}
			}
			return false;
		}

		public static bool HasCoastalPlayer()
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: 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)
			if ((Object)(object)ZNet.instance == (Object)null || (Object)(object)ZoneSystem.instance == (Object)null)
			{
				return false;
			}
			foreach (ZDO allCharacterZDO in ZNet.instance.GetAllCharacterZDOS())
			{
				Vector3 position = allCharacterZDO.GetPosition();
				if (RegionalEventRules.At(WorldEventType.Tsunami, position) && position.y <= ZoneSystem.instance.m_waterLevel + 10f)
				{
					return true;
				}
			}
			return false;
		}

		public static List<Biome> GetActivePlayerBiomes()
		{
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: 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)
			HashSet<Biome> hashSet = new HashSet<Biome>();
			if ((Object)(object)ZNet.instance != (Object)null)
			{
				foreach (ZDO allCharacterZDO in ZNet.instance.GetAllCharacterZDOS())
				{
					Vector3 position = allCharacterZDO.GetPosition();
					if (!Character.InInterior(position))
					{
						Biome item = (Biome)((WorldGenerator.instance == null) ? 1 : ((int)WorldGenerator.instance.GetBiome(position)));
						hashSet.Add(item);
					}
				}
			}
			if ((Object)(object)Player.m_localPlayer != (Object)null && !((Character)Player.m_localPlayer).InInterior())
			{
				hashSet.Add(Player.m_localPlayer.GetCurrentBiome());
			}
			return new List<Biome>(hashSet);
		}

		public static Vector3 GroundTarget(Vector3 center, float radius)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: 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)
			Vector2 val = Random.insideUnitCircle * radius;
			Vector3 val2 = center + new Vector3(val.x, 0f, val.y);
			if (WorldGenerator.instance != null)
			{
				val2.y = WorldGenerator.instance.GetHeight(val2);
			}
			float y = default(float);
			if ((Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGroundHeight(val2, ref y))
			{
				val2.y = y;
			}
			if ((Object)(object)ZoneSystem.instance != (Object)null)
			{
				val2.y = Mathf.Max(val2.y, ZoneSystem.instance.m_waterLevel);
			}
			return val2;
		}

		public static Vector3 DistributedStrikeTarget(Vector3 center, int strikeIndex, int strikeCount, float baseRadius)
		{
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: 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_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			int num = Mathf.Max(1, strikeCount);
			float num2 = (float)Math.PI * 2f / (float)num;
			float num3 = (float)strikeIndex * num2 + Random.Range((0f - num2) * 0.35f, num2 * 0.35f);
			float num4 = Mathf.Max(6f, baseRadius);
			float num5;
			float num6;
			if (strikeIndex == 0)
			{
				num5 = 4.5f;
				num6 = Mathf.Max(14f, num4 * 1.6f);
			}
			else if (strikeIndex < (num + 1) / 2)
			{
				num5 = Mathf.Max(12f, num4 * 1.3f);
				num6 = Mathf.Max(28f, num4 * 3.2f);
			}
			else
			{
				num5 = Mathf.Max(24f, num4 * 2.6f);
				num6 = Mathf.Max(52f, num4 * 5.8f);
			}
			float num7 = Random.Range(num5, num6);
			Vector3 val = center + new Vector3(Mathf.Cos(num3) * num7, 0f, Mathf.Sin(num3) * num7);
			if (WorldGenerator.instance != null)
			{
				val.y = WorldGenerator.instance.GetHeight(val);
			}
			float y = default(float);
			if ((Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGroundHeight(val, ref y))
			{
				val.y = y;
			}
			if ((Object)(object)ZoneSystem.instance != (Object)null)
			{
				val.y = Mathf.Max(val.y, ZoneSystem.instance.m_waterLevel);
			}
			return val;
		}

		public static Vector3 HorizontalDirection()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: 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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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)
			Vector2 insideUnitCircle = Random.insideUnitCircle;
			Vector2 val = ((Vector2)(ref insideUnitCircle)).normalized;
			if (((Vector2)(ref val)).sqrMagnitude < 0.1f)
			{
				val = Vector2.right;
			}
			return new Vector3(val.x, 0f, val.y);
		}

		public static bool TryOceanToLandDirection(Vector3 coast, out Vector3 direction)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: 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_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			direction = Vector3.zero;
			if (WorldGenerator.instance == null || (Object)(object)ZoneSystem.instance == (Object)null)
			{
				return false;
			}
			float waterLevel = ZoneSystem.instance.m_waterLevel;
			float num = float.MaxValue;
			Vector3 val = Vector3.zero;
			Vector3 val2 = default(Vector3);
			for (int i = 0; i < 16; i++)
			{
				float num2 = (float)i * (float)Math.PI * 2f / 16f;
				((Vector3)(ref val2))..ctor(Mathf.Cos(num2), 0f, Mathf.Sin(num2));
				Vector3 val3 = coast + val2 * 90f;
				float height = WorldGenerator.instance.GetHeight(val3);
				if (height < num)
				{
					num = height;
					val = val2;
				}
			}
			if (((Vector3)(ref val)).sqrMagnitude < 0.1f || num > waterLevel - 2f)
			{
				return false;
			}
			direction = -((Vector3)(ref val)).normalized;
			return true;
		}
	}
	public sealed class HurricaneEvent : PulsedWorldEvent
	{
		public override WorldEventType Type => WorldEventType.Hurricane;

		public override bool IsAllowedInSeason(WorldSeason season)
		{
			return false;
		}

		protected override void EmitPulse(WorldEventManager manager)
		{
		}
	}
	public sealed class MagicalAuroraEvent : WorldEventBase
	{
		public override WorldEventType Type => WorldEventType.MagicalAurora;

		public override bool IsAllowedInSeason(WorldSeason season)
		{
			if (season != WorldSeason.Unknown && season != WorldSeason.Winter)
			{
				return season == WorldSeason.Fall;
			}
			return true;
		}
	}
	public sealed class MeteorShowerEvent : PulsedWorldEvent
	{
		public override WorldEventType Type => WorldEventType.MeteorShower;

		public override bool IsAllowedInSeason(WorldSeason season)
		{
			return true;
		}

		protected override void EmitPulse(WorldEventManager manager)
		{
			//IL_0094: 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_009c: 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_00a7: Unknown result type (might be due to invalid IL or missing references)
			if (EventTargeting.TryRandomPlayer(out var position))
			{
				int num = ((ModConfig.MeteorMinPerWave != null) ? ModConfig.MeteorMinPerWave.Value : 2);
				int num2 = ((ModConfig.MeteorMaxPerWave != null) ? ModConfig.MeteorMaxPerWave.Value : 6);
				int maxProgressionDay = ((ModConfig.MaxProgressionWorldDay != null) ? ModConfig.MaxProgressionWorldDay.Value : 300);
				float num3 = SurvivalRules.DayProgressionFraction(CataclysmDayScaling.GetWorldDay(), maxProgressionDay);
				int num4 = Mathf.Clamp(Mathf.RoundToInt(Mathf.Lerp((float)num, (float)num2, num3)), num, num2);
				float value = ModConfig.Hazards[Type].TargetRadius.Value;
				for (int i = 0; i < num4; i++)
				{
					Vector3 position2 = EventTargeting.GroundTarget(position, value);
					manager.BroadcastHazard(Type, position2, Vector3.zero, global: false);
				}
			}
		}
	}
	public abstract class PulsedWorldEvent : WorldEventBase
	{
		private double nextPulse;

		protected virtual float InitialDelay => ModConfig.Hazards[Type].Interval.Value;

		public override void BeginServer(double now)
		{
			nextPulse = now + (double)InitialDelay;
		}

		public override void TickServer(double now, WorldEventManager manager)
		{
			if (!(now < nextPulse))
			{
				nextPulse = now + (double)ModConfig.Hazards[Type].Interval.Value;
				EmitPulse(manager);
			}
		}

		protected abstract void EmitPulse(WorldEventManager manager);
	}
	public sealed class ThunderstormEvent : WorldEventBase
	{
		private double nextStrike;

		public override WorldEventType Type => WorldEventType.Thunderstorm;

		public override float Weight => ModConfig.Events[Type].Weight.Value;

		public override float DurationSeconds => ModConfig.Events[Type].Duration.Value;

		public override bool IsAllowedInSeason(WorldSeason season)
		{
			return true;
		}

		public override void BeginServer(double now)
		{
			nextStrike = now + (double)ModConfig.Hazards[Type].Interval.Value;
		}

		public override void TickServer(double now, WorldEventManager manager)
		{
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			if (now < nextStrike)
			{
				return;
			}
			nextStrike = now + (double)ModConfig.Hazards[Type].Interval.Value;
			if (EventTargeting.TryRandomPlayer(out var position))
			{
				HazardSettings hazardSettings = ModConfig.Hazards[Type];
				SurvivalRules.ThunderstormStrikeRange(configMin: (ModConfig.ThunderstormMinStrikesPerWave != null) ? ModConfig.ThunderstormMinStrikesPerWave.Value : 2, configMax: (ModConfig.ThunderstormMaxStrikesPerWave != null) ? ModConfig.ThunderstormMaxStrikesPerWave.Value : 10, maxProgressionDay: (ModConfig.MaxProgressionWorldDay != null) ? ModConfig.MaxProgressionWorldDay.Value : 300, worldDay: CataclysmDayScaling.GetWorldDay(), minStrikes: out var minStrikes, maxStrikes: out var maxStrikes);
				int num = Random.Range(minStrikes, maxStrikes + 1);
				float value = hazardSettings.TargetRadius.Value;
				for (int i = 0; i < num; i++)
				{
					Vector3 position2 = EventTargeting.DistributedStrikeTarget(position, i, num, value);
					manager.BroadcastHazard(Type, position2, Vector3.zero, global: false);
				}
			}
		}
	}
	public sealed class ToxicFogEvent : PulsedWorldEvent
	{
		public override WorldEventType Type => WorldEventType.ToxicFog;

		public override bool IsAllowedInSeason(WorldSeason season)
		{
			if (season != WorldSeason.Unknown && season != WorldSeason.Spring && season != WorldSeason.Summer)
			{
				return season == WorldSeason.Fall;
			}
			return true;
		}

		protected override void EmitPulse(WorldEventManager manager)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			manager.BroadcastHazard(Type, Vector3.zero, Vector3.zero, global: true);
		}
	}
	public sealed class TsunamiEvent : PulsedWorldEvent
	{
		public override WorldEventType Type => WorldEventType.Tsunami;

		protected override float InitialDelay => 4f;

		public override bool IsAllowedInSeason(WorldSeason season)
		{
			return false;
		}

		protected override void EmitPulse(WorldEventManager manager)
		{
		}
	}
	public abstract class WorldEventBase
	{
		public abstract WorldEventType Type { get; }

		public virtual float Weight => ModConfig.Events[Type].Weight.Value;

		public virtual float DurationSeconds => ModConfig.Events[Type].Duration.Value;

		public virtual bool IsAllowedInSeason(WorldSeason season)
		{
			return true;
		}

		public virtual void BeginServer(double now)
		{
		}

		public virtual void TickServer(double now, WorldEventManager manager)
		{
		}
	}
	public enum WorldEventType
	{
		Thunderstorm,
		ToxicFog,
		MagicalAurora,
		MeteorShower,
		Tsunami,
		Hurricane,
		Blizzard,
		DustStorm
	}
}
namespace WorldCataclysms.Visuals
{
	internal sealed class LightningWarningVisual : MonoBehaviour
	{
		private static Material shared;

		private float until;

		internal static void Show(Vector3 position, float radius)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected O, but got Unknown
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).InInterior())
			{
				return;
			}
			Vector3 val = ((Component)localPlayer).transform.position - position;
			if (((Vector3)(ref val)).sqrMagnitude > 40000f)
			{
				return;
			}
			Shader val2 = Shader.Find("Sprites/Default") ?? Shader.Find("Unlit/Color");
			if (!((Object)(object)val2 == (Object)null))
			{
				if ((Object)(object)shared == (Object)null)
				{
					shared = new Material(val2);
				}
				GameObject val3 = new GameObject("WC_LightningWarning");
				val3.AddComponent<LightningWarningVisual>().until = Time.time + 1.4f;
				LineRenderer val4 = val3.AddComponent<LineRenderer>();
				((Renderer)val4).sharedMaterial = shared;
				val4.useWorldSpace = true;
				val4.loop = true;
				val4.positionCount = 32;
				float startWidth = (val4.endWidth = 0.12f);
				val4.startWidth = startWidth;
				Color val5 = default(Color);
				((Color)(ref val5))..ctor(0.65f, 0.85f, 1f, 0.75f);
				val4.endColor = val5;
				val4.startColor = val5;
				for (int i = 0; i < 32; i++)
				{
					float num2 = (float)i * (float)Math.PI * 2f / 32f;
					val4.SetPosition(i, position + new Vector3(Mathf.Cos(num2) * radius, 0.15f, Mathf.Sin(num2) * radius));
				}
			}
		}

		private void Update()
		{
			if (Time.time >= until)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}

		internal static void Release()
		{
			if ((Object)(object)shared != (Object)null)
			{
				Object.Destroy((Object)(object)shared);
			}
			shared = null;
		}
	}
	internal sealed class AuroraVisual : MonoBehaviour
	{
		private static WorldEventType requestedType;

		private static EventPhase requestedPhase;

		private GameObject root;

		private LineRenderer first;

		private LineRenderer second;

		private Material firstMaterial;

		private Material secondMaterial;

		public static void SetState(WorldEventType type, EventPhase phase)
		{
			requestedType = type;
			requestedPhase = phase;
		}

		private void Update()
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: 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)
			Player localPlayer = Player.m_localPlayer;
			if (requestedType != WorldEventType.MagicalAurora || requestedPhase != EventPhase.Active || !((Object)(object)localPlayer != (Object)null) || !RegionalEventRules.Affects(WorldEventType.MagicalAurora, (Character)(object)localPlayer) || ((Character)localPlayer).InInterior() || ((Character)localPlayer).InIntro())
			{
				Clear();
				return;
			}
			if ((Object)(object)root == (Object)null)
			{
				Build();
			}
			if (!((Object)(object)root == (Object)null))
			{
				Vector3 position = ((Component)localPlayer).transform.position;
				Draw(first, position, 0f, new Color(0.1f, 1f, 0.65f, 0.8f));
				Draw(second, position, 9f, new Color(0.55f, 0.2f, 1f, 0.72f));
			}
		}

		private void Build()
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			Shader val = Shader.Find("Sprites/Default") ?? Shader.Find("Unlit/Color");
			if (!((Object)(object)val == (Object)null))
			{
				root = new GameObject("WC_Aurora");
				firstMaterial = new Material(val);
				secondMaterial = new Material(val);
				first = MakeLine("AuroraGreen", firstMaterial, 3.8f);
				second = MakeLine("AuroraViolet", secondMaterial, 3f);
			}
		}

		private LineRenderer MakeLine(string name, Material material, float width)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.SetParent(root.transform, false);
			LineRenderer obj = val.AddComponent<LineRenderer>();
			((Renderer)obj).material = material;
			obj.useWorldSpace = true;
			obj.positionCount = 28;
			float startWidth = (obj.endWidth = width);
			obj.startWidth = startWidth;
			return obj;
		}

		private static void Draw(LineRenderer line, Vector3 center, float phase, Color color)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			Color startColor = (line.endColor = color);
			line.startColor = startColor;
			for (int i = 0; i < line.positionCount; i++)
			{
				float num = ((float)i - (float)(line.positionCount - 1) / 2f) * 5f;
				float num2 = 38f + Mathf.Sin(Time.unscaledTime * 0.5f + (float)i * 0.42f + phase) * 5f;
				float num3 = Mathf.Sin((float)i * 0.23f + phase) * 12f;
				line.SetPosition(i, center + new Vector3(num, num2, num3));
			}
		}

		private void Clear()
		{
			if ((Object)(object)root != (Object)null)
			{
				Object.Destroy((Object)(object)root);
			}
			root = null;
			first = (second = null);
			if ((Object)(object)firstMaterial != (Object)null)
			{
				Object.Destroy((Object)(object)firstMaterial);
			}
			if ((Object)(object)secondMaterial != (Object)null)
			{
				Object.Destroy((Object)(object)secondMaterial);
			}
			firstMaterial = (secondMaterial = null);
		}

		private void OnDestroy()
		{
			Clear();
		}
	}
	internal sealed class DustStormVisual : MonoBehaviour
	{
		internal const string EnvironmentName = "WC_DustStorm";

		private SoftReference<Material> fineReference;

		private SoftReference<Material> bankReference;

		private bool requested;

		private bool fineRequested;

		private bool bankRequested;

		private bool prepared;

		private bool failed;

		private bool showing;

		private float nextCheck;

		private float nextBank;

		private int terrainMask;

		private Camera camera;

		private GameObject root;

		private ParticleSystem fine;

		private ParticleSystem banks;

		private Material fineMaterial;

		private Material bankMaterial;

		private Texture2D fallbackTexture;

		private Vector3 lastCenter;

		internal static bool AppliesToBiome(Biome biome)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			if ((int)biome != 16)
			{
				return (int)biome == 1;
			}
			return true;
		}

		internal static bool HasEnvironment()
		{
			if ((Object)(object)EnvMan.instance == (Object)null)
			{
				return false;
			}
			foreach (EnvSetup environment in EnvMan.instance.m_environments)
			{
				if (environment != null && environment.m_name == "WC_DustStorm")
				{
					return true;
				}
			}
			return false;
		}

		private void Update()
		{
			//IL_012a: 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_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: 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_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: 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_02b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0300: Unknown result type (might be due to invalid IL or missing references)
			//IL_0304: Unknown result type (might be due to invalid IL or missing references)
			//IL_030e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0313: Unknown result type (might be due to invalid IL or missing references)
			//IL_0318: Unknown result type (might be due to invalid IL or missing references)
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			//IL_0324: Unknown result type (might be due to invalid IL or missing references)
			//IL_032e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0333: Unknown result type (might be due to invalid IL or missing references)
			//IL_0338: Unknown result type (might be due to invalid IL or missing references)
			//IL_0355: Unknown result type (might be due to invalid IL or missing references)
			//IL_035f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0364: Unknown result type (might be due to invalid IL or missing references)
			//IL_036e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0373: Unknown result type (might be due to invalid IL or missing references)
			//IL_037f: Unknown result type (might be due to invalid IL or missing references)
			//IL_038d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03db: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
			if (Time.realtimeSinceStartup >= nextCheck)
			{
				nextCheck = Time.realtimeSinceStartup + 0.25f;
				Player localPlayer = Player.m_localPlayer;
				WorldEventManager instance = WorldEventManager.Instance;
				bool flag = (Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsDedicated() && (Object)(object)localPlayer != (Object)null && !((Character)localPlayer).IsDead() && !((Character)localPlayer).InInterior() && !((Character)localPlayer).InIntro() && AppliesToBiome(localPlayer.GetCurrentBiome()) && (Object)(object)instance != (Object)null && instance.EventType == WorldEventType.DustStorm && instance.Phase != EventPhase.Idle;
				if (flag && !prepared && !failed)
				{
					PrepareAssets();
				}
				camera = (flag ? Camera.main : null);
				bool visible = flag && prepared && (Object)(object)camera != (Object)null && !localPlayer.InShelter();
				SetVisible(visible);
			}
			if (!showing || (Object)(object)camera == (Object)null || (Object)(object)EnvMan.instance == (Object)null)
			{
				return;
			}
			Vector3 position = ((Component)camera).transform.position;
			Vector3 val = position - lastCenter;
			if (((Vector3)(ref val)).sqrMagnitude > 1600f)
			{
				fine.Clear();
				banks.Clear();
			}
			root.transform.position = position;
			lastCenter = position;
			Vector3 val2 = EnvMan.instance.GetWindDir();
			val2.y = 0f;
			if (((Vector3)(ref val2)).sqrMagnitude < 0.01f)
			{
				val2 = Vector3.forward;
			}
			((Vector3)(ref val2)).Normalize();
			float num = 0.65f + 0.35f * Mathf.PerlinNoise(Time.time * 0.12f, 7.3f);
			VelocityOverLifetimeModule velocityOverLifetime = fine.velocityOverLifetime;
			((VelocityOverLifetimeModule)(ref velocityOverLifetime)).x = MinMaxCurve.op_Implicit(val2.x * (5f + 5f * num));
			((VelocityOverLifetimeModule)(ref velocityOverLifetime)).z = MinMaxCurve.op_Implicit(val2.z * (5f + 5f * num));
			EmissionModule emission = fine.emission;
			((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(48f + 28f * num);
			Color ambientLight = RenderSettings.ambientLight;
			float num2 = Mathf.Clamp(((Color)(ref ambientLight)).grayscale * 2.2f + (((Object)(object)EnvMan.instance.m_dirLight != (Object)null) ? (EnvMan.instance.m_dirLight.intensity * 0.4f) : 0f), 0.12f, 1f);
			if (!(Time.time < nextBank))
			{
				nextBank = Time.time + 0.2f;
				Vector3 val3 = default(Vector3);
				((Vector3)(ref val3))..ctor(0f - val2.z, 0f, val2.x);
				float num3 = Mathf.PerlinNoise(Time.time * 0.47f, 13.7f) * 2f - 1f;
				Vector3 val4 = position - val2 * 14f + val3 * num3 * 16f;
				RaycastHit val5 = default(RaycastHit);
				if (terrainMask != 0 && Physics.Raycast(val4 + Vector3.up * 30f, Vector3.down, ref val5, 85f, terrainMask, (QueryTriggerInteraction)1))
				{
					EmitParams val6 = default(EmitParams);
					((EmitParams)(ref val6)).position = ((RaycastHit)(ref val5)).point + Vector3.up * 0.55f;
					((EmitParams)(ref val6)).velocity = val2 * (4f + num * 3f);
					((EmitParams)(ref val6)).startLifetime = 4f;
					((EmitParams)(ref val6)).startSize = 4.5f + 2.5f * num;
					((EmitParams)(ref val6)).startColor = Color32.op_Implicit(new Color(0.68f * num2, 0.46f * num2, 0.26f * num2, 0.22f));
					EmitParams val7 = val6;
					banks.Emit(val7, 1);
				}
			}
		}

		private void PrepareAssets()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Expected O, but got Unknown
			AssetManager instance = AssetManager.Instance;
			if (!instance.IsReady())
			{
				return;
			}
			try
			{
				if (!requested)
				{
					fineReference = instance.GetSoftReference<Material>("dust_particle");
					bankReference = instance.GetSoftReference<Material>("slowwispysmoke_nearfade");
					requested = true;
					if (fineReference.IsValid)
					{
						fineReference.LoadAsync();
						fineRequested = true;
					}
					if (bankReference.IsValid)
					{
						bankReference.LoadAsync();
						bankRequested = true;
					}
					Plugin.Log.LogInfo((object)"Polvo de Planicies: solicitando materiales nativos de forma asincrona.");
				}
				else if ((!fineReference.IsValid || !fineReference.IsLoading) && (!bankReference.IsValid || !bankReference.IsLoading))
				{
					fineMaterial = CopyOrFallback((fineReference.IsValid && fineReference.IsLoaded) ? fineReference.Asset : null);
					bankMaterial = CopyOrFallback((bankReference.IsValid && bankReference.IsLoaded) ? bankReference.Asset : null);
					if ((Object)(object)fineMaterial == (Object)null || (Object)(object)bankMaterial == (Object)null)
					{
						throw new InvalidOperationException("No hay shader transparente compatible.");
					}
					root = new GameObject("WC_PlainsDust_Local");
					root.SetActive(false);
					root.transform.SetParent(((Component)this).transform, false);
					terrainMask = LayerMask.GetMask(new string[1] { "terrain" });
					fine = CreateEmitter("FineDust", fineMaterial, 384, ground: false);
					banks = CreateEmitter("GroundBanks", bankMaterial, 24, ground: true);
					prepared = true;
					Plugin.Log.LogInfo((object)"Polvo de Planicies preparado: 2 emisores locales, maximo 408 particulas, sin fisica ni entidades de red. Audio: viento nativo de EnvMan/AudioMan.");
				}
			}
			catch (Exception ex)
			{
				failed = true;
				Plugin.Log.LogWarning((object)("No se pudo preparar el polvo de Planicies; se conserva el ambiente: " + ex));
				DisposeVisuals();
			}
		}

		private Material CopyOrFallback(Material source)
		{
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Expected O, but got Unknown
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Expected O, but got Unknown
			//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_0059: 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_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			Shader val = Shader.Find("Custom/Particles/Alpha Blended") ?? Shader.Find("Particles/Standard Unlit") ?? Shader.Find("Sprites/Default");
			if ((Object)(object)source != (Object)null && (Object)(object)source.mainTexture != (Object)null && (Object)(object)val != (Object)null)
			{
				Material val2 = new Material(val)
				{
					name = ((Object)source).name,
					mainTexture = source.mainTexture,
					mainTextureScale = source.mainTextureScale,
					mainTextureOffset = source.mainTextureOffset
				};
				Plugin.Log.LogInfo((object)("Polvo: textura nativa " + ((Object)source).name + "; shader " + ((Object)val).name));
				return val2;
			}
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			if ((Object)(object)fallbackTexture == (Object)null)
			{
				fallbackTexture = new Texture2D(64, 64, (TextureFormat)4, false);
				((Object)fallbackTexture).name = "WC_SoftDustAlpha";
				Color32[] array = (Color32[])(object)new Color32[4096];
				for (int i = 0; i < 64; i++)
				{
					for (int j = 0; j < 64; j++)
					{
						float num = ((float)j - 31.5f) / 31.5f;
						float num2 = ((float)i - 31.5f) / 31.5f;
						float num3 = Mathf.Sqrt(num * num + num2 * num2);
						float num4 = Mathf.Clamp01(1f - num3);
						float num5 = num4 * num4 * (0.65f + 0.35f * Mathf.PerlinNoise((float)j * 0.13f, (float)i * 0.13f));
						array[i * 64 + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, (byte)(num5 * 255f));
					}
				}
				fallbackTexture.SetPixels32(array);
				fallbackTexture.Apply(false, true);
				((Texture)fallbackTexture).wrapMode = (TextureWrapMode)1;
			}
			Plugin.Log.LogWarning((object)"Material de polvo nativo no disponible; usando textura suave procedural local.");
			return new Material(val)
			{
				name = "WC_FallbackSoftDust",
				mainTexture = (Texture)(object)fallbackTexture
			};
		}

		private ParticleSystem CreateEmitter(string name, Material material, int cap, bool ground)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//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_005e: 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_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: 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_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: 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_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Expected O, but got Unknown
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0309: Unknown result type (might be due to invalid IL or missing references)
			//IL_0333: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.SetParent(root.transform, false);
			ParticleSystem val2 = val.AddComponent<ParticleSystem>();
			MainModule main = val2.main;
			((MainModule)(ref main)).playOnAwake = false;
			((MainModule)(ref main)).loop = true;
			((MainModule)(ref main)).maxParticles = cap;
			((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1;
			((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(ground ? 4f : 4.5f);
			((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(0f);
			((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(0f);
			((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(ground ? 4.5f : 0.16f);
			((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(ground ? new Color(0.7f, 0.43f, 0.22f, 0.27f) : new Color(0.72f, 0.49f, 0.28f, 0.32f));
			((MainModule)(ref main)).startRotation = new MinMaxCurve(0f, (float)Math.PI * 2f);
			RotationOverLifetimeModule rotationOverLifetime = val2.rotationOverLifetime;
			((RotationOverLifetimeModule)(ref rotationOverLifetime)).enabled = true;
			((RotationOverLifetimeModule)(ref rotationOverLifetime)).z = new MinMaxCurve(-0.35f, 0.35f);
			CollisionModule collision = val2.collision;
			((CollisionModule)(ref collision)).enabled = false;
			EmissionModule emission = val2.emission;
			((EmissionModule)(ref emission)).enabled = !ground;
			((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(60f);
			ShapeModule shape = val2.shape;
			((ShapeModule)(ref shape)).enabled = !ground;
			((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)5;
			((ShapeModule)(ref shape)).scale = new Vector3(28f, 7f, 28f);
			VelocityOverLifetimeModule velocityOverLifetime = val2.velocityOverLifetime;
			((VelocityOverLifetimeModule)(ref velocityOverLifetime)).enabled = !ground;
			((VelocityOverLifetimeModule)(ref velocityOverLifetime)).space = (ParticleSystemSimulationSpace)1;
			ColorOverLifetimeModule colorOverLifetime = val2.colorOverLifetime;
			((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled = true;
			Gradient val3 = new Gradient();
			val3.SetKeys((GradientColorKey[])(object)new GradientColorKey[2]
			{
				new GradientColorKey(Color.white, 0f),
				new GradientColorKey(Color.white, 1f)
			}, (GradientAlphaKey[])(object)new GradientAlphaKey[4]
			{
				new GradientAlphaKey(0f, 0f),
				new GradientAlphaKey(1f, 0.18f),
				new GradientAlphaKey(1f, 0.6f),
				new GradientAlphaKey(0f, 1f)
			});
			((ColorOverLifetimeModule)(ref colorOverLifetime)).color = MinMaxGradient.op_Implicit(val3);
			if (ground && (Object)(object)material != (Object)null && (((Object)material).name.IndexOf("smoke", StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)(object)material.mainTexture != (Object)null && ((Object)material.mainTexture).name.IndexOf("smoke", StringComparison.OrdinalIgnoreCase) >= 0)))
			{
				TextureSheetAnimationModule textureSheetAnimation = val2.textureSheetAnimation;
				((TextureSheetAnimationModule)(ref textureSheetAnimation)).enabled = true;
				((TextureSheetAnimationModule)(ref textureSheetAnimation)).numTilesX = 8;
				((TextureSheetAnimationModule)(ref textureSheetAnimation)).numTilesY = 8;
				((TextureSheetAnimationModule)(ref textureSheetAnimation)).mode = (ParticleSystemAnimationMode)0;
				((TextureSheetAnimationModule)(ref textureSheetAnimation)).animation = (ParticleSystemAnimationType)0;
				((TextureSheetAnimationModule)(ref textureSheetAnimation)).timeMode = (ParticleSystemAnimationTimeMode)0;
				((TextureSheetAnimationModule)(ref textureSheetAnimation)).cycleCount = 1;
				((TextureSheetAnimationModule)(ref textureSheetAnimation)).startFrame = new MinMaxCurve(0f, 0.999f);
				((TextureSheetAnimationModule)(ref textureSheetAnimation)).frameOverTime = new MinMaxCurve(1f, AnimationCurve.Linear(0f, 0f, 1f, 0.999f));
			}
			ParticleSystemRenderer component = val.GetComponent<ParticleSystemRenderer>();
			((Renderer)component).sharedMaterial = material;
			component.renderMode = (ParticleSystemRenderMode)0;
			((Renderer)component).shadowCastingMode = (ShadowCastingMode)0;
			((Renderer)component).receiveShadows = false;
			return val2;
		}

		private void SetVisible(bool value)
		{
			//IL_0060: 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)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			if (value == showing)
			{
				return;
			}
			showing = value;
			if (!((Object)(object)root == (Object)null))
			{
				if (!value)
				{
					fine.Stop(true, (ParticleSystemStopBehavior)0);
					banks.Stop(true, (ParticleSystemStopBehavior)0);
					root.SetActive(false);
					return;
				}
				root.transform.position = ((Component)camera).transform.position;
				lastCenter = root.transform.position;
				nextBank = Time.time;
				root.SetActive(true);
				fine.Play();
				banks.Play();
			}
		}

		private void DisposeVisuals()
		{
			showing = false;
			prepared = false;
			if ((Object)(object)root != (Object)null)
			{
				Object.Destroy((Object)(object)root);
			}
			if ((Object)(object)fineMaterial != (Object)null)
			{
				Object.Destroy((Object)(object)fineMaterial);
			}
			if ((Object)(object)bankMaterial != (Object)null)
			{
				Object.Destroy((Object)(object)bankMaterial);
			}
			if ((Object)(object)fallbackTexture != (Object)null)
			{
				Object.Destroy((Object)(object)fallbackTexture);
			}
			root = null;
			fine = (banks = null);
			fineMaterial = (bankMaterial = null);
			fallbackTexture = null;
		}

		private void OnDestroy()
		{
			DisposeVisuals();
			if (fineRequested)
			{
				fineReference.Release();
			}
			if (bankRequested)
			{
				bankReference.Release();
			}
		}
	}
	internal static class HazardVisual
	{
		private sealed class NativeWaterWaveVisual : MonoBehaviour
		{
			private const int Columns = 17;

			private const int Rows = 9;

			private Mesh mesh;

			private Vector3[] vertices;

			private Vector3 origin;

			private Vector3 direction;

			private float age;

			public void Build(Vector3 at, Vector3 travel)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				//IL_003a: 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_004a: Unknown result type (might be due to invalid IL or missing references)
				//IL_005a: Expected O, but got Unknown
				//IL_012a: 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)
				origin = at;
				direction = ((((Vector3)(ref travel)).sqrMagnitude < 0.01f) ? Vector3.forward : ((Vector3)(ref travel)).normalized);
				((Component)this).transform.rotation = Quaternion.LookRotation(direction, Vector3.up);
				mesh = new Mesh
				{
					name = "WC_NativeTsunamiMesh"
				};
				((Component)this).GetComponent<MeshFilter>().sharedMesh = mesh;
				vertices = (Vector3[])(object)new Vector3[153];
				Vector2[] array = (Vector2[])(object)new Vector2[vertices.Length];
				int[] array2 = new int[768];
				int num = 0;
				for (int i = 0; i < 8; i++)
				{
					for (int j = 0; j < 16; j++)
					{
						int num2 = i * 17 + j;
						int num3 = num2 + 1;
						int num4 = num2 + 17;
						int num5 = num4 + 1;
						array2[num++] = num2;
						array2[num++] = num4;
						array2[num++] = num3;
						array2[num++] = num3;
						array2[num++] = num4;
						array2[num++] = num5;
					}
				}
				for (int k = 0; k < 9; k++)
				{
					for (int l = 0; l < 17; l++)
					{
						array[k * 17 + l] = new Vector2((float)l * 0.55f, (float)k * 0.55f);
					}
				}
				mesh.vertices = vertices;
				mesh.uv = array;
				mesh.triangles = array2;
				UpdateMesh(0f);
			}

			private void Update()
			{
				//IL_003e: 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_004e: 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_0059: 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_006f: 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_0096: 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)
				age += Time.unscaledDeltaTime;
				float num = (((Object)(object)ZoneSystem.instance != (Object)null) ? ZoneSystem.instance.m_waterLevel : origin.y);
				((Component)this).transform.position = origin - direction * 38f + direction * (20f * age);
				((Component)this).transform.position = new Vector3(((Component)this).transform.position.x, num, ((Component)this).transform.position.z);
				UpdateMesh(Mathf.Sin(Mathf.Clamp01(age / 9f) * (float)Math.PI) * 22f);
				if (age > 9f)
				{
					Object.Destroy((Object)(object)((Component)this).gameObject);
				}
			}

			private void UpdateMesh(float height)
			{
				//IL_005c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0061: Unknown result type (might be due to invalid IL or missing references)
				int num = 0;
				for (int i = 0; i < 9; i++)
				{
					for (int j = 0; j < 17; j++)
					{
						float num2 = Mathf.Lerp(-42f, 42f, (float)j / 16f);
						float num3 = Mathf.Lerp(-12f, 12f, (float)i / 8f);
						float num4 = Mathf.Exp((0f - num3 * num3) / 35f) * height;
						vertices[num] = new Vector3(num2, num4, num3);
						num++;
					}
				}
				mesh.vertices = vertices;
				mesh.RecalculateNormals();
				mesh.RecalculateBounds();
			}

			private void OnDestroy()
			{
				Live.Remove(((Component)this).gameObject);
				if ((Object)(object)mesh != (Object)null)
				{
					Object.Destroy((Object)(object)mesh);
				}
			}
		}

		private sealed class MeteorVisual : MonoBehaviour
		{
			private GameObject projectile;

			private GameObject[] impacts;

			private Transform model;

			private Vector3 spin;

			private Vector3 start;

			private Vector3 end;

			private float started;

			private float gravity;

			private bool impacted;

			public bool Build(Vector3 position, int sequence)
			{
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_0055: Unknown result type (might be due to invalid IL or missing references)
				//IL_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_0065: Unknown result type (might be due to invalid IL or missing references)
				//IL_0066: Unknown result type (might be due to invalid IL or missing references)
				//IL_0093: Unknown result type (might be due to invalid IL or missing references)
				//IL_0098: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a4: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c0: 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_00df: Unknown result type (might be due to invalid IL or missing references)
				projectile = NativeMeteorAssets.CreateProjectile(((Component)this).transform);
				if ((Object)(object)projectile == (Object)null)
				{
					return false;
				}
				Random random = new Random(sequence);
				start = position + new Vector3(-38f + (float)random.NextDouble() * 16f, 105f, 24f + (float)random.NextDouble() * 18f);
				end = position;
				started = Time.time;
				gravity = NativeMeteorAssets.Gravity;
				model = NativeMeteorAssets.VisualOf(projectile);
				spin = NativeMeteorAssets.Spin;
				((Component)this).transform.position = start;
				((Component)this).transform.rotation = Quaternion.LookRotation(end - start, Vector3.up);
				projectile.transform.localPosition = Vector3.zero;
				return true;
			}

			private void Update()
			{
				//IL_004f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0055: Unknown result type (might be due to invalid IL or missing references)
				//IL_005b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0060: Unknown result type (might be due to invalid IL or missing references)
				//IL_0087: Unknown result type (might be due to invalid IL or missing references)
				//IL_008c: 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_003e: Unknown result type (might be due to invalid IL or missing refe