Decompiled source of Seasons v1.8.2

Seasons.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using ConditionalConfigSync;
using HarmonyLib;
using JetBrains.Annotations;
using LocalizationManager;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Seasons;
using Seasons.Compatibility;
using Seasons.Controllers;
using Splatform;
using TMPro;
using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Networking;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("Seasons")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Seasons")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("076e7e5f-9182-41e5-a76b-5c051d6b3957")]
[assembly: AssemblyFileVersion("1.8.2")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.8.2.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
public struct HSLColor
{
	public float h;

	public float s;

	public float l;

	public float a;

	public HSLColor(float h, float s, float l, float a)
	{
		this.h = h;
		this.s = s;
		this.l = l;
		this.a = a;
	}

	public HSLColor(float h, float s, float l)
	{
		this.h = h;
		this.s = s;
		this.l = l;
		a = 1f;
	}

	public HSLColor(Color c)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		HSLColor hSLColor = FromRGBA(c);
		h = hSLColor.h;
		s = hSLColor.s;
		l = hSLColor.l;
		a = hSLColor.a;
	}

	public static HSLColor FromRGBA(Color c)
	{
		//IL_0001: 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_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: 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_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: 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_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_0104: Unknown result type (might be due to invalid IL or missing references)
		//IL_010a: Unknown result type (might be due to invalid IL or missing references)
		float num = c.a;
		float num2 = Mathf.Min(Mathf.Min(c.r, c.g), c.b);
		float num3 = Mathf.Max(Mathf.Max(c.r, c.g), c.b);
		float num4 = (num2 + num3) / 2f;
		float num5;
		float num6;
		if (num2 == num3)
		{
			num5 = 0f;
			num6 = 0f;
		}
		else
		{
			float num7 = num3 - num2;
			num5 = ((num4 <= 0.5f) ? (num7 / (num3 + num2)) : (num7 / (2f - (num3 + num2))));
			num6 = 0f;
			if (c.r == num3)
			{
				num6 = (c.g - c.b) / num7;
			}
			else if (c.g == num3)
			{
				num6 = 2f + (c.b - c.r) / num7;
			}
			else if (c.b == num3)
			{
				num6 = 4f + (c.r - c.g) / num7;
			}
			num6 = Mathf.Repeat(num6 * 60f, 360f);
		}
		return new HSLColor(num6, num5, num4, num);
	}

	public Color ToRGBA()
	{
		//IL_00bc: 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_00c5: Unknown result type (might be due to invalid IL or missing references)
		float num = a;
		float num2 = ((l <= 0.5f) ? (l * (1f + s)) : (l + s - l * s));
		float n = 2f * l - num2;
		float num3;
		float num4;
		float num5;
		if (s == 0f)
		{
			num3 = (num4 = (num5 = l));
		}
		else
		{
			num3 = Value(n, num2, h + 120f);
			num4 = Value(n, num2, h);
			num5 = Value(n, num2, h - 120f);
		}
		return new Color(num3, num4, num5, num);
	}

	private static float Value(float n1, float n2, float hue)
	{
		hue = Mathf.Repeat(hue, 360f);
		if (hue < 60f)
		{
			return n1 + (n2 - n1) * hue / 60f;
		}
		if (hue < 180f)
		{
			return n2;
		}
		if (hue < 240f)
		{
			return n1 + (n2 - n1) * (240f - hue) / 60f;
		}
		return n1;
	}

	public static implicit operator HSLColor(Color src)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		return FromRGBA(src);
	}

	public static implicit operator Color(HSLColor src)
	{
		//IL_0003: 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_000b: Unknown result type (might be due to invalid IL or missing references)
		return src.ToRGBA();
	}
}
namespace LocalizationManager
{
	[PublicAPI]
	public class Localizer
	{
		private const string defaultLanguage = "English";

		private static readonly Dictionary<string, Dictionary<string, Func<string>>> PlaceholderProcessors;

		private static readonly Dictionary<string, Dictionary<string, string>> loadedTexts;

		private static readonly ConditionalWeakTable<Localization, string> localizationLanguage;

		private static readonly List<WeakReference<Localization>> localizationObjects;

		private static BaseUnityPlugin? _plugin;

		private static readonly List<string> fileExtensions;

		private static BaseUnityPlugin Plugin
		{
			get
			{
				//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b2: Expected O, but got Unknown
				if (_plugin == null)
				{
					IEnumerable<TypeInfo> source;
					try
					{
						source = Assembly.GetExecutingAssembly().DefinedTypes.ToList();
					}
					catch (ReflectionTypeLoadException ex)
					{
						source = from t in ex.Types
							where t != null
							select t.GetTypeInfo();
					}
					_plugin = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First((TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t)));
				}
				return _plugin;
			}
		}

		private static void UpdatePlaceholderText(Localization localization, string key)
		{
			localizationLanguage.TryGetValue(localization, out string value);
			string text = loadedTexts[value][key];
			if (PlaceholderProcessors.TryGetValue(key, out Dictionary<string, Func<string>> value2))
			{
				text = value2.Aggregate(text, (string current, KeyValuePair<string, Func<string>> kv) => current.Replace("{" + kv.Key + "}", kv.Value()));
			}
			localization.AddWord(key, text);
		}

		public static void AddPlaceholder<T>(string key, string placeholder, ConfigEntry<T> config, Func<T, string>? convertConfigValue = null) where T : notnull
		{
			if (convertConfigValue == null)
			{
				convertConfigValue = (T val) => val.ToString();
			}
			if (!PlaceholderProcessors.ContainsKey(key))
			{
				PlaceholderProcessors[key] = new Dictionary<string, Func<string>>();
			}
			config.SettingChanged += delegate
			{
				UpdatePlaceholder();
			};
			if (loadedTexts.ContainsKey(Localization.instance.GetSelectedLanguage()))
			{
				UpdatePlaceholder();
			}
			void UpdatePlaceholder()
			{
				PlaceholderProcessors[key][placeholder] = () => convertConfigValue(config.Value);
				UpdatePlaceholderText(Localization.instance, key);
			}
		}

		public static void AddText(string key, string text)
		{
			List<WeakReference<Localization>> list = new List<WeakReference<Localization>>();
			foreach (WeakReference<Localization> localizationObject in localizationObjects)
			{
				if (localizationObject.TryGetTarget(out var target))
				{
					Dictionary<string, string> dictionary = loadedTexts[localizationLanguage.GetOrCreateValue(target)];
					if (!target.m_translations.ContainsKey(key))
					{
						dictionary[key] = text;
						target.AddWord(key, text);
					}
				}
				else
				{
					list.Add(localizationObject);
				}
			}
			foreach (WeakReference<Localization> item in list)
			{
				localizationObjects.Remove(item);
			}
		}

		public static IEnumerator Load()
		{
			yield return (object)new WaitUntil((Func<bool>)(() => PlatformManager.DistributionPlatform != null && PlatformInitializer.PreferencesInitialized));
			if (string.IsNullOrEmpty(PlatformPrefs.GetString("language", "")))
			{
				PlatformPrefs.SetString("language", "English");
			}
			LoadLocalization(Localization.instance, Localization.instance.GetSelectedLanguage());
		}

		private static void LoadLocalization(Localization __instance, string language)
		{
			if (!localizationLanguage.Remove(__instance))
			{
				localizationObjects.Add(new WeakReference<Localization>(__instance));
			}
			localizationLanguage.Add(__instance, language);
			Dictionary<string, string> localizationFiles = new Dictionary<string, string>();
			string[] prefixes = new string[2]
			{
				Plugin.Info.Metadata.Name + ".",
				Plugin.Info.Metadata.Name.Replace(" ", "") + "."
			};
			Scan(Paths.ConfigPath, warn: true);
			Scan(Paths.PluginPath, warn: false);
			byte[] array = LoadTranslationFromAssembly("English");
			if (array == null)
			{
				throw new Exception("Found no English localizations in mod " + Plugin.Info.Metadata.Name + ". Expected an embedded resource Translations/English.json or Translations/English.yml.");
			}
			Dictionary<string, string> dictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(Encoding.UTF8.GetString(array)) ?? throw new Exception("Localization for mod " + Plugin.Info.Metadata.Name + " failed: Localization file was empty.");
			string text = null;
			if (language != "English")
			{
				if (localizationFiles.ContainsKey(language))
				{
					text = File.ReadAllText(localizationFiles[language]);
				}
				else
				{
					byte[] array2 = LoadTranslationFromAssembly(language);
					if (array2 != null)
					{
						text = Encoding.UTF8.GetString(array2);
					}
				}
			}
			if (text == null && localizationFiles.ContainsKey("English"))
			{
				text = File.ReadAllText(localizationFiles["English"]);
			}
			if (text != null)
			{
				foreach (KeyValuePair<string, string> item in JsonConvert.DeserializeObject<Dictionary<string, string>>(text) ?? new Dictionary<string, string>())
				{
					dictionary[item.Key] = item.Value;
				}
			}
			loadedTexts[language] = dictionary;
			foreach (KeyValuePair<string, string> item2 in dictionary)
			{
				UpdatePlaceholderText(__instance, item2.Key);
			}
			void Scan(string root, bool warn)
			{
				foreach (string item3 in from f in Directory.GetFiles(root, "*.*", SearchOption.AllDirectories)
					where fileExtensions.Contains(Path.GetExtension(f))
					select f)
				{
					string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(item3);
					string[] array3 = prefixes;
					foreach (string text2 in array3)
					{
						if (fileNameWithoutExtension.StartsWith(text2))
						{
							string text3 = fileNameWithoutExtension.Substring(text2.Length);
							if (!string.IsNullOrWhiteSpace(text3))
							{
								if (localizationFiles.ContainsKey(text3))
								{
									if (warn)
									{
										global::Seasons.Seasons.LogWarning("Duplicate localization '" + text3 + "' for " + Plugin.Info.Metadata.Name + ". Skipping " + item3);
									}
								}
								else
								{
									localizationFiles[text3] = item3;
								}
							}
							break;
						}
					}
				}
			}
		}

		static Localizer()
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			PlaceholderProcessors = new Dictionary<string, Dictionary<string, Func<string>>>();
			loadedTexts = new Dictionary<string, Dictionary<string, string>>();
			localizationLanguage = new ConditionalWeakTable<Localization, string>();
			localizationObjects = new List<WeakReference<Localization>>();
			fileExtensions = new List<string> { ".json", ".yml" };
			Harmony val = new Harmony("org.bepinex.helpers.LocalizationManager");
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "LoadCSV", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "LoadLocalization", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		private static byte[]? LoadTranslationFromAssembly(string language)
		{
			foreach (string fileExtension in fileExtensions)
			{
				byte[] array = ReadEmbeddedFileBytes("Translations." + language + fileExtension);
				if (array != null)
				{
					return array;
				}
			}
			return null;
		}

		public static byte[]? ReadEmbeddedFileBytes(string resourceFileName, Assembly? containingAssembly = null)
		{
			using MemoryStream memoryStream = new MemoryStream();
			if ((object)containingAssembly == null)
			{
				containingAssembly = Assembly.GetCallingAssembly();
			}
			string text = containingAssembly.GetManifestResourceNames().FirstOrDefault((string str) => str.EndsWith(resourceFileName, StringComparison.Ordinal));
			if (text != null)
			{
				containingAssembly.GetManifestResourceStream(text)?.CopyTo(memoryStream);
			}
			return (memoryStream.Length == 0L) ? null : memoryStream.ToArray();
		}
	}
}
namespace Seasons
{
	public static class LoadingTips
	{
		[HarmonyPatch(typeof(Hud), "Awake")]
		public static class Hud_Awake_LoadingTips
		{
			private static void Postfix()
			{
				UpdateLoadingTips();
			}
		}

		private static readonly List<string> summerHeatCombinedTips = new List<string>();

		public static void UpdateLoadingTips()
		{
			if (Seasons.UseTextureControllers() && !((Object)(object)Hud.instance == (Object)null) && SeasonState.IsActive)
			{
				UpdateTipBasedOnValue("$seasons_loadscreen_tip_ice", Seasons.enableFrozenWater.Value);
				UpdateTipBasedOnValue("$seasons_loadscreen_tip_torch", Seasons.seasonState.GetSeasonSettings(Seasons.Season.Winter).m_torchAsFiresource);
				UpdateTipBasedOnValue("$seasons_loadscreen_tip_harvests", Seasons.seasonState.GetSeasonSettings(Seasons.Season.Spring).m_plantsGrowthMultiplier != 1f || Seasons.seasonState.GetSeasonSettings(Seasons.Season.Summer).m_plantsGrowthMultiplier != 1f);
				UpdateTipBasedOnValue("$seasons_loadscreen_tip_nights", Seasons.seasonState.GetSeasonSettings(Seasons.Season.Winter).m_nightLength > 30 || Seasons.controlLightings.Value);
				UpdateTipBasedOnValue("$seasons_loadscreen_tip_overheat", !Seasons.summerHeatEnabled.Value && Seasons.summerHeatAddsExtraWarmCloth.Value && Seasons.seasonState.GetSeasonSettings(Seasons.Season.Summer).m_overheatIn2WarmClothes);
				UpdateTipBasedOnValue("$seasons_loadscreen_tip_summer_heat", Seasons.summerHeatEnabled.Value);
				UpdateTipBasedOnValue("$seasons_loadscreen_tip_summer_heat_cold_food", Seasons.summerHeatEnabled.Value && !string.IsNullOrWhiteSpace(Seasons.summerHeatCoolingFoods.Value));
				UpdateTipBasedOnValue("$seasons_loadscreen_tip_summer_heat_risk", Seasons.summerHeatEnabled.Value);
				UpdateTipBasedOnValue("$seasons_loadscreen_tip_firewood", Seasons.seasonState.GetSeasonSettings(Seasons.Season.Winter).m_fireplaceDrainMultiplier > 1f);
				UpdateTipBasedOnValue("$seasons_loadscreen_tip_perish", Seasons.cropsDiesAfterSetDayInWinter.Value != 0);
				UpdateTipBasedOnValue("$seasons_loadscreen_tip_traders", Seasons.controlTraders.Value);
				UpdateTipBasedOnValue("$seasons_loadscreen_tip_stats", Seasons.controlStats.Value);
				UpdateTipBasedOnValue("$seasons_loadscreen_tip_wolves", Seasons.controlRandomEvents.Value);
				UpdateTipBasedOnValue("$seasons_loadscreen_tip_swimming", Seasons.freezingSwimmingInWinter.Value);
				UpdateTipBasedOnValue("$seasons_loadscreen_tip_clutter", Seasons.controlGrass.Value);
				UpdateSummerHeatCombinedTips();
				Hud.instance.m_haveSetupLoadScreen = false;
				Seasons.LogInfo("Loading tips updated.");
			}
		}

		private static void UpdateTipBasedOnValue(string tip, bool value)
		{
			if (Seasons.enableLoadingTips.Value && value && !Hud.instance.m_loadingTips.Contains(tip))
			{
				Hud.instance.m_loadingTips.Add(tip);
			}
			else if ((!Seasons.enableLoadingTips.Value || !value) && Hud.instance.m_loadingTips.Contains(tip))
			{
				Hud.instance.m_loadingTips.Remove(tip);
			}
		}

		private static void UpdateSummerHeatCombinedTips()
		{
			foreach (string summerHeatCombinedTip in summerHeatCombinedTips)
			{
				Hud.instance.m_loadingTips.Remove(summerHeatCombinedTip);
			}
			summerHeatCombinedTips.Clear();
			if (Seasons.enableLoadingTips.Value && Seasons.summerHeatEnabled.Value)
			{
				AddSummerHeatCombinedTips(BuildSummerHeatOutfitTipParts());
				AddSummerHeatCombinedTips(BuildSummerHeatBehaviorTipParts());
			}
		}

		private static IEnumerable<string> BuildSummerHeatOutfitTipParts()
		{
			bool armorHeatEnabled = Seasons.summerHeatArmorHeatEnabled.Value;
			bool hasOutfitSpecificRules = HasText(Seasons.summerHeatOpenHelmetItems.Value) || HasText(Seasons.summerHeatOpenChestItems.Value) || HasText(Seasons.summerHeatOpenLegItems.Value) || HasText(Seasons.summerHeatLightCloakItems.Value) || HasColdWeatherArmorHeatRules();
			if (armorHeatEnabled)
			{
				yield return "$seasons_loadscreen_tip_summer_heat_clothing";
			}
			if (armorHeatEnabled && hasOutfitSpecificRules)
			{
				yield return "$seasons_loadscreen_tip_summer_heat_cold_clothing";
			}
			if (armorHeatEnabled && HasText(Seasons.summerHeatBareHeadHairItems.Value))
			{
				yield return "$seasons_loadscreen_tip_summer_heat_hairstyle";
			}
		}

		private static IEnumerable<string> BuildSummerHeatBehaviorTipParts()
		{
			if (Seasons.summerHeatInstantHeatSources.Value || Seasons.summerHeatEncumberedAddsHeat.Value)
			{
				yield return "$seasons_loadscreen_tip_summer_heat_activity";
			}
			if (Seasons.summerHeatCampFireAddsHeat.Value)
			{
				yield return "$seasons_loadscreen_tip_summer_heat_campfire";
			}
			if (Seasons.summerHeatNoonEffectPercent.Value > 0f || Seasons.summerHeatNightFactor.Value < 1f)
			{
				yield return "$seasons_loadscreen_tip_summer_heat_day_night";
			}
		}

		private static void AddSummerHeatCombinedTips(IEnumerable<string> parts)
		{
			List<string> list = parts.Where((string part) => !string.IsNullOrWhiteSpace(part)).ToList();
			if (list.Count == 0)
			{
				return;
			}
			string text = "$seasons_loadscreen_tip_summer_heat_prefix";
			for (int num = 0; num < list.Count; num += 3)
			{
				string item = text + " " + string.Join(" ", list.Skip(num).Take(3));
				summerHeatCombinedTips.Add(item);
				if (!Hud.instance.m_loadingTips.Contains(item))
				{
					Hud.instance.m_loadingTips.Add(item);
				}
			}
		}

		private static bool HasText(string value)
		{
			return !string.IsNullOrWhiteSpace(value);
		}

		private static bool HasColdWeatherArmorHeatRules()
		{
			return Seasons.summerHeatColdArmorHeating.Value > 0f || Seasons.summerHeatColdArmorCoolingPenalty.Value > 0f || Seasons.summerHeatColdCloakHeating.Value > 0f || Seasons.summerHeatColdCloakCoolingPenalty.Value > 0f;
		}
	}
	public static class ControlledComponentsExtentions
	{
		public static string Localize(this string text)
		{
			return Localization.instance.Localize(text);
		}

		public static bool ShouldBePickedInWinter(this Pickable pickable)
		{
			return pickable.CanBePicked() && !pickable.GetPicked() && pickable.IsVulnerableToWinter() && Seasons.seasonState.GetCurrentDay() >= Seasons.cropsDiesAfterSetDayInWinter.Value && !((MonoBehaviour)(object)pickable).IsProtectedPosition() && !((MonoBehaviour)(object)pickable).ProtectedWithHeat();
		}

		public static bool IsVulnerableToWinter(this Pickable pickable)
		{
			return Seasons.seasonState.GetPlantsGrowthMultiplier() == 0f && Seasons.seasonState.GetCurrentSeason() == Seasons.Season.Winter && !((MonoBehaviour)(object)pickable).ShouldSurviveWinter() && !pickable.SurvivedCurrentWinter();
		}

		public static bool SurvivedCurrentWinter(this Pickable pickable)
		{
			return Object.op_Implicit((Object)(object)pickable.m_nview) && pickable.m_nview.IsValid() && Seasons.seasonState.GetCurrentSeason() == Seasons.Season.Winter && Mathf.Abs(pickable.m_nview.GetZDO().GetInt(SeasonsVars.s_cropSurvivedWinterDayHash, 0) - Seasons.seasonState.GetCurrentWorldDay()) <= Seasons.seasonState.GetDaysInSeason();
		}

		public static bool IsFreezingToDeath(this Pickable pickable)
		{
			return Object.op_Implicit((Object)(object)pickable.m_nview) && pickable.m_nview.IsValid() && Seasons.seasonState.GetCurrentSeason() == Seasons.Season.Winter && pickable.GetSecondsToFreeze() > 0.0;
		}

		public static double GetSecondsToFreeze(this Pickable pickable)
		{
			if (Object.op_Implicit((Object)(object)pickable.m_nview) && pickable.m_nview.IsValid() && Object.op_Implicit((Object)(object)ZNet.instance))
			{
				long num = pickable.m_nview.GetZDO().GetLong(SeasonsVars.s_cropStartedFreezingHash, 0L);
				if (num <= 0)
				{
					return 0.0;
				}
				float num2 = Seasons.secondsToFreezeForCropInWinter.Value;
				if (num2 % 60f == 0f)
				{
					num2 -= 2f;
				}
				return (new DateTime(num).AddSeconds(num2) - ZNet.instance.GetTime()).TotalSeconds;
			}
			return 0.0;
		}

		public static bool CheckForPerishInWinter(this Pickable pickable)
		{
			if (!pickable.ShouldBePickedInWinter())
			{
				pickable.SetFreezing(freezing: false);
				return false;
			}
			if (Seasons.secondsToFreezeForCropInWinter.Value > 0f)
			{
				pickable.SetFreezing(freezing: true);
			}
			if (pickable.IsFreezingToDeath())
			{
				return false;
			}
			((MonoBehaviour)pickable).StartCoroutine(Seasons.PickableSetPickedInWinter(pickable));
			return true;
		}

		public static void SetFreezing(this Pickable pickable, bool freezing)
		{
			if (!Object.op_Implicit((Object)(object)pickable.m_nview) || !pickable.m_nview.IsValid() || !Object.op_Implicit((Object)(object)ZNet.instance))
			{
				return;
			}
			ZDO zDO = pickable.m_nview.GetZDO();
			if (zDO != null)
			{
				if (freezing && zDO.GetLong(SeasonsVars.s_cropStartedFreezingHash, 0L) == 0L && Seasons.seasonState.GetCurrentSeason() == Seasons.Season.Winter && Seasons.seasonState.GetCurrentDay() >= Seasons.cropsDiesAfterSetDayInWinter.Value)
				{
					zDO.Set(SeasonsVars.s_cropStartedFreezingHash, ZNet.instance.GetTime().Ticks);
				}
				else if (!freezing)
				{
					zDO.Set(SeasonsVars.s_cropStartedFreezingHash, 0L);
				}
			}
		}

		public static bool IsIgnored(this Pickable pickable)
		{
			return (Object)(object)pickable.m_nview == (Object)null || !pickable.m_nview.IsValid() || (pickable.m_nview.HasOwner() && !pickable.m_nview.IsOwner()) || !((MonoBehaviour)(object)pickable).ControlPlantGrowth() || ((MonoBehaviour)(object)pickable).IsIgnoredPosition();
		}

		public static string GetColdStatus(this Pickable pickable)
		{
			if (((MonoBehaviour)(object)pickable).ShouldSurviveWinter())
			{
				return "$seasons_plant_frost_resistant";
			}
			if (((MonoBehaviour)(object)pickable).ProtectedWithHeat())
			{
				return "$seasons_plant_heat_protected";
			}
			if (pickable.SurvivedCurrentWinter())
			{
				return "$seasons_plant_survived_winter";
			}
			double secondsToFreeze = pickable.GetSecondsToFreeze();
			if (secondsToFreeze != 0.0 && Seasons.secondsToFreezeForCropInWinter.Value > 0f)
			{
				if (secondsToFreeze > 0.0)
				{
					return "$seasons_plant_is_freezing\n" + Seasons.FromPercent(secondsToFreeze / (double)Seasons.secondsToFreezeForCropInWinter.Value);
				}
				return "$seasons_plant_is_frozen";
			}
			if (Seasons.seasonState.GetCurrentDay() > Seasons.cropsDiesAfterSetDayInWinter.Value)
			{
				return "$seasons_plant_will_perish";
			}
			return "$seasons_plant_is_exposed";
		}

		public static bool ControlPlantGrowth(this MonoBehaviour behaviour)
		{
			return Seasons.ControlPlantGrowth(((Component)behaviour).gameObject);
		}

		public static bool ShouldSurviveWinter(this MonoBehaviour behaviour)
		{
			return Seasons.PlantWillSurviveWinter(((Component)behaviour).gameObject);
		}

		public static bool IsIgnoredPosition(this MonoBehaviour behaviour)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return Seasons.IsIgnoredPosition(((Component)behaviour).transform.position);
		}

		public static bool IsProtectedPosition(this MonoBehaviour behaviour)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return Seasons.IsProtectedPosition(((Component)behaviour).transform.position);
		}

		public static bool ProtectedWithHeat(this MonoBehaviour behaviour)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return Seasons.ProtectedWithHeat(((Component)behaviour).transform.position);
		}
	}
	public static class TerrainDecultivation
	{
		public static int terrainCompVersion;

		public static int m_operations;

		public static Vector3 m_lastOpPoint;

		public static float m_lastOpRadius;

		public static bool[] m_modifiedHeight;

		public static float[] m_levelDelta;

		public static float[] m_smoothDelta;

		public static bool[] m_modifiedPaint;

		public static Color[] m_paintMask;

		public static bool DecultivateGround(ZDO zdo)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//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_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Expected O, but got Unknown
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			byte[] byteArray = zdo.GetByteArray(ZDOVars.s_TCData, (byte[])null);
			if (byteArray == null)
			{
				return false;
			}
			ZPackage val = new ZPackage(Utils.Decompress(byteArray));
			terrainCompVersion = val.ReadInt();
			if (terrainCompVersion != 1)
			{
				Seasons.LogWarning("Season can not decultivate ground due to changes in terrain compiler data");
				return false;
			}
			bool flag = false;
			m_operations = val.ReadInt();
			m_lastOpPoint = val.ReadVector3();
			m_lastOpRadius = val.ReadSingle();
			m_modifiedHeight = new bool[val.ReadInt()];
			m_levelDelta = new float[m_modifiedHeight.Length];
			m_smoothDelta = new float[m_modifiedHeight.Length];
			for (int i = 0; i < m_modifiedHeight.Length; i++)
			{
				m_modifiedHeight[i] = val.ReadBool();
				if (m_modifiedHeight[i])
				{
					m_levelDelta[i] = val.ReadSingle();
					m_smoothDelta[i] = val.ReadSingle();
				}
				else
				{
					m_levelDelta[i] = 0f;
					m_smoothDelta[i] = 0f;
				}
			}
			m_modifiedPaint = new bool[val.ReadInt()];
			m_paintMask = (Color[])(object)new Color[m_modifiedPaint.Length];
			for (int j = 0; j < m_modifiedPaint.Length; j++)
			{
				m_modifiedPaint[j] = val.ReadBool();
				if (m_modifiedPaint[j])
				{
					Color val2 = new Color
					{
						r = val.ReadSingle(),
						g = val.ReadSingle(),
						b = val.ReadSingle(),
						a = val.ReadSingle()
					};
					if (val2.g > 0f)
					{
						val2.r = Mathf.Max(val2.r, val2.g);
						val2.g = 0f;
						flag = true;
					}
					m_paintMask[j] = val2;
				}
				else
				{
					m_paintMask[j] = Color.black;
				}
			}
			if (!flag)
			{
				return false;
			}
			ZPackage val3 = new ZPackage();
			val3.Write(terrainCompVersion);
			val3.Write(m_operations);
			val3.Write(m_lastOpPoint);
			val3.Write(m_lastOpRadius);
			val3.Write(m_modifiedHeight.Length);
			for (int k = 0; k < m_modifiedHeight.Length; k++)
			{
				val3.Write(m_modifiedHeight[k]);
				if (m_modifiedHeight[k])
				{
					val3.Write(m_levelDelta[k]);
					val3.Write(m_smoothDelta[k]);
				}
			}
			val3.Write(m_modifiedPaint.Length);
			for (int l = 0; l < m_modifiedPaint.Length; l++)
			{
				val3.Write(m_modifiedPaint[l]);
				if (m_modifiedPaint[l])
				{
					val3.Write(m_paintMask[l].r);
					val3.Write(m_paintMask[l].g);
					val3.Write(m_paintMask[l].b);
					val3.Write(m_paintMask[l].a);
				}
			}
			byte[] array = Utils.Compress(val3.GetArray());
			zdo.Set(ZDOVars.s_TCData, array);
			return true;
		}
	}
	[Serializable]
	public class CachedData
	{
		[Serializable]
		public class TextureData
		{
			public string name;

			public byte[] originalPNG;

			public TextureProperties properties;

			public Dictionary<Seasons.Season, Dictionary<int, byte[]>> variants = new Dictionary<Seasons.Season, Dictionary<int, byte[]>>();

			public bool Initialized()
			{
				return variants.Any((KeyValuePair<Seasons.Season, Dictionary<int, byte[]>> variant) => variant.Value.Count > 0);
			}

			public TextureData(TextureVariants textureVariants)
			{
				if (textureVariants == null)
				{
					return;
				}
				originalPNG = textureVariants.originalPNG;
				name = textureVariants.originalName;
				properties = textureVariants.properties;
				foreach (KeyValuePair<Seasons.Season, Dictionary<int, Texture2D>> season in textureVariants.seasons)
				{
					variants.Add(season.Key, new Dictionary<int, byte[]>());
					foreach (KeyValuePair<int, Texture2D> item in season.Value)
					{
						variants[season.Key].Add(item.Key, ImageConversion.EncodeToPNG(item.Value));
					}
				}
			}

			public TextureData(DirectoryInfo texDirectory)
			{
				FileInfo[] files = texDirectory.GetFiles("properties.json");
				if (files.Length != 0)
				{
					properties = JsonUtility.FromJson<TextureProperties>(File.ReadAllText(files[0].FullName));
				}
				foreach (Seasons.Season value in Enum.GetValues(typeof(Seasons.Season)))
				{
					variants.Add(value, new Dictionary<int, byte[]>());
					for (int i = 0; i < 4; i++)
					{
						FileInfo[] files2 = texDirectory.GetFiles(SeasonFileName(value, i));
						if (files2.Length != 0)
						{
							variants[value].Add(i, File.ReadAllBytes(files2[0].FullName));
						}
					}
				}
			}
		}

		internal const string cacheSubdirectory = "Cache";

		internal const string prefabCacheCommonFile = "cache.bin";

		internal const string prefabCacheFileName = "cache.json";

		internal const string texturesDirectory = "textures";

		internal const string originalPostfix = ".orig.png";

		internal const string texturePropertiesFileName = "properties.json";

		public Dictionary<string, PrefabController> controllers = new Dictionary<string, PrefabController>();

		public Dictionary<int, TextureData> textures = new Dictionary<int, TextureData>();

		public uint revision = 0u;

		public CachedData(uint revision)
		{
			this.revision = revision;
		}

		public bool Initialized()
		{
			return controllers.Count > 0 && textures.Count > 0;
		}

		public void SaveOnDisk()
		{
			if (Initialized())
			{
				if (Seasons.cacheStorageFormat.Value == Seasons.CacheFormat.Binary)
				{
					SaveToBinary();
					return;
				}
				if (Seasons.cacheStorageFormat.Value == Seasons.CacheFormat.Json)
				{
					SaveToJSON();
					return;
				}
				SaveToJSON();
				SaveToBinary();
			}
		}

		public void LoadFromDisk()
		{
			if (Seasons.cacheStorageFormat.Value == Seasons.CacheFormat.Json)
			{
				LoadFromJSON();
			}
			else
			{
				LoadFromBinary();
			}
		}

		private void SaveToJSON()
		{
			//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_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			string text = CacheDirectory();
			Directory.CreateDirectory(text);
			string text2 = Path.Combine(text, "cache.json");
			File.WriteAllText(text2, JsonConvert.SerializeObject((object)controllers, (Formatting)1, new JsonSerializerSettings
			{
				NullValueHandling = (NullValueHandling)1,
				DefaultValueHandling = (DefaultValueHandling)1
			}));
			string text3 = Path.Combine(text, "textures");
			Seasons.LogInfo("Saved cache file " + text2);
			foreach (KeyValuePair<int, TextureData> texture in textures)
			{
				string text4 = Path.Combine(text3, texture.Key.ToString());
				Directory.CreateDirectory(text4);
				File.WriteAllBytes(Path.Combine(text4, texture.Value.name + ".orig.png"), texture.Value.originalPNG);
				File.WriteAllText(Path.Combine(text4, "properties.json"), JsonUtility.ToJson((object)texture.Value.properties, true));
				foreach (KeyValuePair<Seasons.Season, Dictionary<int, byte[]>> variant in texture.Value.variants)
				{
					foreach (KeyValuePair<int, byte[]> item in variant.Value)
					{
						File.WriteAllBytes(Path.Combine(text4, SeasonFileName(variant.Key, item.Key)), item.Value);
					}
				}
			}
			Seasons.LogInfo($"Saved {textures.Count} textures at {text3}");
		}

		private void LoadFromJSON()
		{
			string text = CacheDirectory();
			DirectoryInfo directoryInfo = new DirectoryInfo(text);
			if (!directoryInfo.Exists)
			{
				return;
			}
			FileInfo[] files = directoryInfo.GetFiles("cache.json");
			if (files.Length == 0)
			{
				Seasons.LogInfo("File not found: " + Path.Combine(text, "cache.json"));
				return;
			}
			try
			{
				controllers = JsonConvert.DeserializeObject<Dictionary<string, PrefabController>>(File.ReadAllText(files[0].FullName));
			}
			catch (Exception arg)
			{
				Seasons.LogWarning($"Error loading JSON cache data from {files[0].FullName}\n{arg}");
				return;
			}
			DirectoryInfo[] directories = directoryInfo.GetDirectories("textures");
			if (directories.Length == 0)
			{
				return;
			}
			DirectoryInfo[] directories2 = directories[0].GetDirectories();
			foreach (DirectoryInfo directoryInfo2 in directories2)
			{
				int key = int.Parse(directoryInfo2.Name);
				if (!textures.ContainsKey(key))
				{
					TextureData textureData = new TextureData(directoryInfo2);
					if (textureData.Initialized())
					{
						textures.Add(key, textureData);
					}
				}
			}
		}

		private void SaveToBinary()
		{
			string text = CacheDirectory();
			Directory.CreateDirectory(text);
			using (FileStream fileStream = new FileStream(Path.Combine(text, "cache.bin"), FileMode.Create))
			{
				BinaryFormatter binaryFormatter = new BinaryFormatter();
				binaryFormatter.Serialize(fileStream, this);
				fileStream.Dispose();
			}
			Seasons.LogInfo("Saved cache file " + Path.Combine(text, "cache.bin"));
		}

		private void LoadFromBinary()
		{
			string path = CacheDirectory();
			string text = Path.Combine(path, "cache.bin");
			if (!File.Exists(text))
			{
				Seasons.LogInfo("File not found: " + text);
				return;
			}
			try
			{
				using FileStream fileStream = new FileStream(text, FileMode.Open, FileAccess.Read, FileShare.Read);
				BinaryFormatter binaryFormatter = new BinaryFormatter();
				CachedData cachedData = (CachedData)binaryFormatter.Deserialize(fileStream);
				fileStream.Dispose();
				DictionaryExt.Copy<string, PrefabController>(controllers, cachedData.controllers);
				DictionaryExt.Copy<int, TextureData>(textures, cachedData.textures);
				cachedData = null;
			}
			catch (Exception arg)
			{
				Seasons.LogWarning($"Error loading binary cache data from {text}:\n {arg}");
			}
		}

		public string CacheDirectory()
		{
			return Path.Combine(Seasons.cacheDirectory, revision.ToString());
		}

		public static string SeasonFileName(Seasons.Season season, int variant)
		{
			return $"{season}_{variant + 1}.png";
		}
	}
	[Serializable]
	public class PrefabController
	{
		[Serializable]
		public class CachedMaterial
		{
			public string name = string.Empty;

			public string shaderName = string.Empty;

			public Dictionary<string, int> textureProperties = new Dictionary<string, int>();

			public Dictionary<string, string[]> colorVariants = new Dictionary<string, string[]>();

			public CachedMaterial()
			{
			}

			public CachedMaterial(string materialName, string shader, string propertyName, int textureID)
			{
				name = materialName;
				shaderName = shader;
				AddTexture(propertyName, textureID);
			}

			public CachedMaterial(string materialName, string shader, string propertyName, Color[] colors)
			{
				name = materialName;
				shaderName = shader;
				AddColors(propertyName, colors);
			}

			public void AddTexture(string propertyName, int textureID)
			{
				if (!textureProperties.ContainsKey(propertyName))
				{
					textureProperties.Add(propertyName, textureID);
				}
			}

			public void AddColors(string propertyName, Color[] colors)
			{
				List<string> vec = new List<string>();
				CollectionExtensions.Do<Color>((IEnumerable<Color>)colors, (Action<Color>)delegate(Color x)
				{
					//IL_000b: Unknown result type (might be due to invalid IL or missing references)
					vec.Add("#" + ColorUtility.ToHtmlStringRGBA(x));
				});
				if (!colorVariants.ContainsKey(propertyName))
				{
					colorVariants.Add(propertyName, vec.ToArray());
				}
			}
		}

		[Serializable]
		public class CachedRenderer
		{
			public string name = string.Empty;

			public string type = string.Empty;

			public Dictionary<string, CachedMaterial> materials = new Dictionary<string, CachedMaterial>();

			public CachedRenderer()
			{
			}

			public CachedRenderer(string rendererName, string rendererType)
			{
				name = rendererName;
				type = rendererType;
			}

			public bool Initialized()
			{
				return materials.Any((KeyValuePair<string, CachedMaterial> m) => m.Value.textureProperties.Count > 0 || m.Value.colorVariants.Count > 0);
			}

			public void AddMaterialTexture(Material material, string propertyName, int textureID)
			{
				if (!materials.TryGetValue(((Object)material).name, out var value))
				{
					materials.Add(((Object)material).name, new CachedMaterial(((Object)material).name, ((Object)material.shader).name, propertyName, textureID));
				}
				else
				{
					value.AddTexture(propertyName, textureID);
				}
			}

			public void AddMaterialColors(Material material, string propertyName, Color[] colors)
			{
				if (!materials.TryGetValue(((Object)material).name, out var value))
				{
					materials.Add(((Object)material).name, new CachedMaterial(((Object)material).name, ((Object)material.shader).name, propertyName, colors));
				}
				else
				{
					value.AddColors(propertyName, colors);
				}
			}
		}

		public Dictionary<string, Dictionary<int, List<CachedRenderer>>> lodsInHierarchy = new Dictionary<string, Dictionary<int, List<CachedRenderer>>>();

		public Dictionary<int, List<CachedRenderer>> lodLevelMaterials = new Dictionary<int, List<CachedRenderer>>();

		public Dictionary<string, CachedRenderer> renderersInHierarchy = new Dictionary<string, CachedRenderer>();

		public CachedRenderer cachedRenderer;

		public Dictionary<string, string[]> particleSystemStartColors;

		[NonSerialized]
		public long elapsedTicks = 0L;

		public bool Initialized()
		{
			return lodsInHierarchy.Count > 0 || lodLevelMaterials.Count > 0 || renderersInHierarchy.Count > 0 || cachedRenderer != null || particleSystemStartColors != null;
		}

		public override string ToString()
		{
			return ((cachedRenderer == null) ? "" : " 1 main renderer") + ((particleSystemStartColors == null) ? "" : " 1 particles start color") + " " + ((lodsInHierarchy.Count > 0) ? $" {lodsInHierarchy.Count} LOD groups" : "") + ((lodLevelMaterials.Count > 0) ? $" {lodLevelMaterials.Count} LODs" : "") + ((renderersInHierarchy.Count > 0) ? $" {renderersInHierarchy.Count} renderersInHierarchy" : "") + ((elapsedTicks > 0) ? $" in {(double)elapsedTicks / (double)Stopwatch.Frequency * 1000.0:F2} ms" : "");
		}
	}
	public class SeasonalTextureVariants
	{
		public Dictionary<string, PrefabController> controllers = new Dictionary<string, PrefabController>();

		public Dictionary<int, TextureVariants> textures = new Dictionary<int, TextureVariants>();

		public uint revision = 0u;

		public bool Initialize(bool force = false)
		{
			if (!force && Initialized())
			{
				return true;
			}
			controllers.Clear();
			textures.Clear();
			revision = SeasonalTexturePrefabCache.GetRevision();
			CachedData cachedData = new CachedData(revision);
			if (force && Directory.Exists(cachedData.CacheDirectory()))
			{
				Directory.Delete(cachedData.CacheDirectory(), recursive: true);
			}
			cachedData.LoadFromDisk();
			if (cachedData.Initialized())
			{
				DictionaryExt.Copy<string, PrefabController>(controllers, cachedData.controllers);
				foreach (KeyValuePair<int, CachedData.TextureData> texture in cachedData.textures)
				{
					if (!textures.ContainsKey(texture.Key))
					{
						TextureVariants textureVariants = new TextureVariants(texture.Value);
						if (textureVariants.Initialized())
						{
							textures.Add(texture.Key, textureVariants);
						}
					}
				}
				Seasons.LogInfo($"Loaded from cache revision:{revision} controllers:{controllers.Count} textures:{textures.Count}");
			}
			else if (!Seasons.runTextureCachingSync.Value)
			{
				TextureCachingController.StartCaching(this);
			}
			else
			{
				SeasonalTexturePrefabCache.SetCurrentTextureVariants(this);
				Seasons.StartCoroutineSync(SeasonalTexturePrefabCache.FillWithGameData());
				Seasons.StartCoroutineSync(SaveCacheOnDisk());
			}
			return Initialized();
		}

		public IEnumerator SaveCacheOnDisk()
		{
			if (!Initialized())
			{
				yield break;
			}
			CachedData cachedData = new CachedData(revision);
			cachedData.textures.Clear();
			foreach (KeyValuePair<int, TextureVariants> texVariants in textures)
			{
				CachedData.TextureData texData = new CachedData.TextureData(texVariants.Value);
				if (texData.Initialized())
				{
					cachedData.textures.Add(texVariants.Key, texData);
				}
			}
			Thread internalThread = new Thread((ThreadStart)delegate
			{
				DictionaryExt.Copy<string, PrefabController>(cachedData.controllers, controllers);
				if (Directory.Exists(cachedData.CacheDirectory()))
				{
					Directory.Delete(cachedData.CacheDirectory(), recursive: true);
				}
				cachedData.SaveOnDisk();
			});
			internalThread.Start();
			while (internalThread.IsAlive)
			{
				yield return Seasons.waitForFixedUpdate;
			}
			ApplyTexturesToGPU();
		}

		public bool Initialized()
		{
			return controllers.Count > 0 && textures.Count > 0;
		}

		public void ApplyTexturesToGPU()
		{
			foreach (KeyValuePair<int, TextureVariants> texture in textures)
			{
				texture.Value.ApplyTextures();
			}
		}

		public IEnumerator ReloadCache()
		{
			Stopwatch stopwatch = Stopwatch.StartNew();
			CachedData cachedData = new CachedData(SeasonalTexturePrefabCache.GetRevision());
			Thread internalThread = new Thread((ThreadStart)delegate
			{
				cachedData.LoadFromDisk();
			});
			internalThread.Start();
			while (internalThread.IsAlive)
			{
				yield return Seasons.waitForFixedUpdate;
			}
			if (cachedData.Initialized())
			{
				revision = cachedData.revision;
				foreach (KeyValuePair<int, CachedData.TextureData> texData in cachedData.textures)
				{
					if (!textures.ContainsKey(texData.Key))
					{
						TextureVariants texVariants = new TextureVariants(texData.Value);
						if (texVariants.Initialized())
						{
							textures.Add(texData.Key, texVariants);
						}
					}
				}
				internalThread = new Thread((ThreadStart)delegate
				{
					DictionaryExt.Copy<string, PrefabController>(controllers, cachedData.controllers);
				});
				internalThread.Start();
				while (internalThread.IsAlive)
				{
					yield return Seasons.waitForFixedUpdate;
				}
				Seasons.LogInfo($"Loaded from cache revision:{revision} controllers:{controllers.Count} textures:{textures.Count} in {stopwatch.Elapsed.TotalSeconds,-4:F2} seconds");
				stopwatch.Restart();
				ClutterVariantController.Reinitialize();
				PrefabVariantController.ReinitializePrefabVariants();
				yield return Seasons.waitForFixedUpdate;
				PrefabVariantController.UpdatePrefabColors();
				ClutterVariantController.Instance.UpdateColors();
				Seasons.LogInfo($"Colors reinitialized in {stopwatch.Elapsed.TotalSeconds,-4:F2} seconds");
			}
			else
			{
				yield return RebuildCache();
			}
		}

		public IEnumerator RebuildCache()
		{
			SeasonalTextureVariants newTexturesVariants = new SeasonalTextureVariants();
			SeasonalTexturePrefabCache.SetCurrentTextureVariants(newTexturesVariants);
			PrefabVariantController.instance?.RevertPrefabsState();
			ClutterVariantController.Instance?.RevertColors();
			yield return Seasons.waitForFixedUpdate;
			yield return SeasonalTexturePrefabCache.FillWithGameData();
			if (newTexturesVariants.Initialized())
			{
				Stopwatch stopwatch = Stopwatch.StartNew();
				controllers.Clear();
				textures.Clear();
				revision = newTexturesVariants.revision;
				Thread internalThread = new Thread((ThreadStart)delegate
				{
					DictionaryExt.Copy<string, PrefabController>(controllers, newTexturesVariants.controllers);
					DictionaryExt.Copy<int, TextureVariants>(textures, newTexturesVariants.textures);
				});
				internalThread.Start();
				while (internalThread.IsAlive)
				{
					yield return Seasons.waitForFixedUpdate;
				}
				yield return SaveCacheOnDisk();
				SeasonalTexturePrefabCache.SetCurrentTextureVariants(this);
				ClutterVariantController.Reinitialize();
				PrefabVariantController.ReinitializePrefabVariants();
				yield return Seasons.waitForFixedUpdate;
				Seasons.LogInfo($"Colors reinitialized in {stopwatch.Elapsed.TotalSeconds,-4:F2} seconds");
			}
			yield return Seasons.waitForFixedUpdate;
			SeasonalTexturePrefabCache.SetCurrentTextureVariants(this);
			PrefabVariantController.UpdatePrefabColors();
			ClutterVariantController.Instance?.UpdateColors();
			Seasons.LogInfo("Cache rebuild ended");
		}
	}
	public class TextureVariants
	{
		public Texture2D original;

		public string originalName;

		public byte[] originalPNG;

		public TextureProperties properties;

		public Dictionary<Seasons.Season, Dictionary<int, Texture2D>> seasons = new Dictionary<Seasons.Season, Dictionary<int, Texture2D>>();

		public TextureVariants(CachedData.TextureData texData)
		{
			if (texData == null)
			{
				return;
			}
			properties = texData.properties;
			foreach (Seasons.Season value3 in Enum.GetValues(typeof(Seasons.Season)))
			{
				if (!texData.variants.TryGetValue(value3, out var value))
				{
					continue;
				}
				for (int i = 0; i < 4; i++)
				{
					if (value.TryGetValue(i, out var value2))
					{
						Texture2D val = properties.CreateTexture();
						if (ImageConversion.LoadImage(val, value2, true))
						{
							AddVariant(value3, i, val);
						}
						else
						{
							Object.Destroy((Object)(object)val);
						}
					}
				}
			}
		}

		public TextureVariants(Texture texture)
		{
			SetOriginalTexture(texture);
		}

		public void SetOriginalTexture(Texture texture)
		{
			original = (Texture2D)(object)((texture is Texture2D) ? texture : null);
			properties = new TextureProperties((Texture2D)(object)((texture is Texture2D) ? texture : null));
			originalName = ((Object)original).name;
		}

		public bool Initialized()
		{
			return seasons.Any((KeyValuePair<Seasons.Season, Dictionary<int, Texture2D>> season) => season.Value.Count > 0);
		}

		public bool HaveOriginalTexture()
		{
			return Object.op_Implicit((Object)(object)original);
		}

		public void ApplyTextures()
		{
			foreach (KeyValuePair<Seasons.Season, Dictionary<int, Texture2D>> season in seasons)
			{
				foreach (KeyValuePair<int, Texture2D> item in season.Value)
				{
					item.Value.Apply(true, true);
				}
			}
		}

		public void AddVariant(Seasons.Season season, int variant, Texture2D tex)
		{
			if (!seasons.TryGetValue(season, out var value))
			{
				value = new Dictionary<int, Texture2D>();
				seasons.Add(season, value);
			}
			if (!value.ContainsKey(variant))
			{
				value.Add(variant, tex);
			}
		}

		public Texture2D GetSeasonalVariant(Seasons.Season season, int variant)
		{
			if (CustomTextures.HaveCustomTexture(originalName, season, variant, properties, out var texture))
			{
				return texture;
			}
			if (seasons.TryGetValue(season, out var value) && value.TryGetValue(variant, out var value2))
			{
				return value2;
			}
			return original;
		}
	}
	[Serializable]
	public class TextureProperties
	{
		public TextureFormat format = (TextureFormat)5;

		public int mipmapCount = 1;

		public TextureWrapMode wrapMode = (TextureWrapMode)0;

		public FilterMode filterMode = (FilterMode)0;

		public int anisoLevel = 1;

		public float mipMapBias = 0f;

		public int width = 2;

		public int height = 2;

		public TextureProperties(Texture2D tex)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			mipmapCount = ((Texture)tex).mipmapCount;
			wrapMode = ((Texture)tex).wrapMode;
			filterMode = ((Texture)tex).filterMode;
			anisoLevel = ((Texture)tex).anisoLevel;
			mipMapBias = ((Texture)tex).mipMapBias;
			width = ((Texture)tex).width;
			height = ((Texture)tex).height;
		}

		public Texture2D CreateTexture()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: 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_0021: 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_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			return new Texture2D(width, height, format, mipmapCount, false)
			{
				filterMode = filterMode,
				anisoLevel = anisoLevel,
				mipMapBias = mipMapBias,
				wrapMode = wrapMode
			};
		}
	}
	public class SE_SummerHeat : SE_Stats
	{
		private const char DefaultBarSymbol = '▄';

		private const float PartialSegmentEpsilon = 0.0001f;

		private static readonly StringBuilder TooltipBuilder = new StringBuilder(256);

		private float _damageTimer;

		public override void Setup(Character character)
		{
			StatusEffectHud.EnsureTimeTextRichText();
			((StatusEffect)this).m_name = "$seasons_status_summer_heat_name";
			((StatusEffect)this).m_tooltip = "$seasons_status_summer_heat_description";
			if (((StatusEffect)this).m_icon == null)
			{
				((StatusEffect)this).m_icon = Seasons.iconWarm ?? Seasons.iconSummer;
			}
			((StatusEffect)this).m_ttl = 0f;
			((StatusEffect)this).m_cooldownIcon = false;
			((StatusEffect)this).m_flashIcon = false;
			((SE_Stats)this).Setup(character);
		}

		public override void UpdateStatusEffect(float dt)
		{
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Expected O, but got Unknown
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			((SE_Stats)this).UpdateStatusEffect(dt);
			if (SummerHeat.IsReady && SummerHeat.IsMechanicActive)
			{
				Character character = ((StatusEffect)this).m_character;
				Player val = (Player)(object)((character is Player) ? character : null);
				if (val != null)
				{
					float maxEffectFactor = SummerHeat.MaxEffectFactor;
					if (maxEffectFactor <= 0f)
					{
						_damageTimer = 0f;
						return;
					}
					_damageTimer += dt;
					if (_damageTimer < Mathf.Max(0.1f, Seasons.summerHeatDamageTickInterval.Value))
					{
						return;
					}
					_damageTimer = 0f;
					float minSoftHpCap = SummerHeatUtils.GetMinSoftHpCap();
					float num = Mathf.Lerp(1f, minSoftHpCap, maxEffectFactor);
					if (!(((Character)val).GetHealthPercentage() <= num) && (!Seasons.summerHeatDamageMaxOnly.Value || SummerHeat.CurrentZone == HeatZone.Max))
					{
						float num2 = Mathf.Abs(Seasons.summerHeatDamageHealthPerTick.Value);
						if (!(num2 <= 0f))
						{
							HitData val2 = new HitData();
							val2.m_damage.m_damage = num2;
							val2.m_hitType = Seasons.summerHeatDamageHitType.Value;
							val2.m_point = ((Character)val).GetTopPoint();
							((Character)val).Damage(val2);
						}
					}
					return;
				}
			}
			_damageTimer = 0f;
		}

		public override string GetIconText()
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			if (!SummerHeat.IsReady || !SummerHeat.IsMechanicActive)
			{
				return string.Empty;
			}
			Seasons.SummerHeatDisplayMode value = Seasons.summerHeatDisplayMode.Value;
			if (1 == 0)
			{
			}
			string result = value switch
			{
				Seasons.SummerHeatDisplayMode.None => string.Empty, 
				Seasons.SummerHeatDisplayMode.Bar => BuildBarText(), 
				Seasons.SummerHeatDisplayMode.Percent => ColorizeText($"{SummerHeat.HeatPercent:0}%", GetHeatDisplayColor()), 
				_ => BuildBarText(), 
			};
			if (1 == 0)
			{
			}
			return result;
		}

		public override string GetTooltipString()
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			TooltipBuilder.Clear();
			TooltipBuilder.Append("$seasons_status_summer_heat_description".Localize()).Append('\n').Append('\n');
			TooltipBuilder.AppendFormat("{0}: {1}\n", "$seasons_status_summer_heat_current".Localize(), ColorizeText($"{SummerHeat.HeatPercent:0}%", GetHeatDisplayColor()));
			TooltipBuilder.AppendFormat("{0}: <color=orange>{1}</color>\n", "$seasons_status_summer_heat_zone".Localize(), GetZoneText(SummerHeat.CurrentZone).Localize());
			TooltipBuilder.AppendFormat("{0}: <color=orange>{1}</color>\n", "$seasons_status_summer_heat_weather".Localize(), (SummerHeat.IsSunny ? "$seasons_status_summer_heat_sunny" : "$seasons_status_summer_heat_not_sunny").Localize());
			TooltipBuilder.AppendFormat("{0}: <color=orange>{1}</color>\n", "$seasons_status_summer_heat_exposure".Localize(), GetExposureText().Localize());
			string modifierSummary = GetModifierSummary();
			if (!string.IsNullOrEmpty(modifierSummary))
			{
				TooltipBuilder.Append(modifierSummary);
			}
			AppendActiveFactors(TooltipBuilder);
			if (SummerHeat.MaxEffectFactor > 0f)
			{
				float minSoftHpCap = SummerHeatUtils.GetMinSoftHpCap();
				float num = Mathf.Lerp(1f, minSoftHpCap, SummerHeat.MaxEffectFactor) * 100f;
				TooltipBuilder.AppendFormat("<color=red>{0}</color>\n", string.Format("$seasons_status_summer_heat_cap_warning".Localize(), num.ToString("0")));
			}
			AppendTechnicalInfo(TooltipBuilder);
			return TooltipBuilder.ToString();
		}

		public override void ModifyHealthRegen(ref float regenMultiplier)
		{
			if (SummerHeat.IsMechanicActive)
			{
				ApplyMultiplier(ref regenMultiplier, GetHeatMultiplier(Seasons.summerHeatHealthRegenMultiplier.Value), regenStyle: true);
			}
		}

		public override void ModifyStaminaRegen(ref float staminaRegen)
		{
			if (SummerHeat.IsMechanicActive)
			{
				ApplyMultiplier(ref staminaRegen, GetHeatMultiplier(Seasons.summerHeatStaminaRegenMultiplier.Value), regenStyle: true);
			}
		}

		public override void ModifyEitrRegen(ref float eitrRegen)
		{
			if (SummerHeat.IsMechanicActive)
			{
				ApplyMultiplier(ref eitrRegen, GetHeatMultiplier(Seasons.summerHeatEitrRegenMultiplier.Value), regenStyle: true);
			}
		}

		public override void ModifyRunStaminaDrain(float baseDrain, ref float drain, Vector3 dir)
		{
			if (SummerHeat.IsMechanicActive)
			{
				drain += baseDrain * GetSignedModifier(Seasons.summerHeatStaminaUseMultiplier.Value);
			}
		}

		public override void ModifyAdrenaline(float baseValue, ref float use)
		{
			if (SummerHeat.IsMechanicActive)
			{
				use += baseValue * GetSignedModifier(Seasons.summerHeatAdrenalineMultiplier.Value);
			}
		}

		private static void ApplyMultiplier(ref float value, float multiplier, bool regenStyle)
		{
			if (!Mathf.Approximately(multiplier, 1f))
			{
				if (regenStyle && multiplier > 1f)
				{
					value += multiplier - 1f;
				}
				else
				{
					value *= multiplier;
				}
			}
		}

		private string BuildBarText()
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			int num = Mathf.Clamp(Seasons.summerHeatBarSegments.Value, 1, 32);
			char barSymbol = GetBarSymbol();
			GetBarBrightness(out var emptyAlpha, out var fullAlpha);
			float num2 = Mathf.Clamp01(SummerHeat.HeatFactor) * (float)num;
			int num3 = Mathf.Clamp(Mathf.FloorToInt(num2), 0, num);
			float num4 = num2 - (float)num3;
			bool flag = num4 > 0.0001f && num3 < num;
			int num5 = Mathf.Max(0, num - num3 - (flag ? 1 : 0));
			float alpha = Mathf.Lerp(emptyAlpha, fullAlpha, Mathf.Clamp01(num4));
			Color heatDisplayColor = GetHeatDisplayColor();
			string value = ((num3 > 0) ? new string(barSymbol, num3) : string.Empty);
			string value2 = (flag ? barSymbol.ToString() : string.Empty);
			string value3 = ((num5 > 0) ? new string(barSymbol, num5) : string.Empty);
			return WrapBarText(ColorizeText(value, heatDisplayColor, fullAlpha) + ColorizeText(value2, heatDisplayColor, alpha) + ColorizeText(value3, heatDisplayColor, emptyAlpha));
		}

		private static string WrapBarText(string barText)
		{
			Seasons.SummerHeatBarTagMode value = Seasons.summerHeatBarTagMode.Value;
			if (1 == 0)
			{
			}
			string result = value switch
			{
				Seasons.SummerHeatBarTagMode.None => barText, 
				Seasons.SummerHeatBarTagMode.Sub => "<sub>" + barText + "</sub>", 
				_ => "<sup>" + barText + "</sup>", 
			};
			if (1 == 0)
			{
			}
			return result;
		}

		private static char GetBarSymbol()
		{
			string value = Seasons.summerHeatBarSymbol.Value;
			if (string.IsNullOrWhiteSpace(value))
			{
				return '▄';
			}
			value = value.Trim();
			return (value.Length > 0) ? value[0] : '▄';
		}

		private static void GetBarBrightness(out float emptyAlpha, out float fullAlpha)
		{
			float num = Mathf.Clamp01(Seasons.summerHeatBarMinBrightness.Value);
			float num2 = Mathf.Clamp01(Seasons.summerHeatBarMaxBrightness.Value);
			emptyAlpha = Mathf.Min(num, num2);
			fullAlpha = Mathf.Max(num, num2);
		}

		private static Color GetHeatDisplayColor()
		{
			//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_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: 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_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: 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_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: 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_0098: 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_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			Color value = Seasons.summerHeatBarBonusColor.Value;
			Color value2 = Seasons.summerHeatBarNeutralColor.Value;
			Color value3 = Seasons.summerHeatBarPenaltyColor.Value;
			Color value4 = Seasons.summerHeatBarMaxColor.Value;
			if (SummerHeat.MaxEffectFactor > 0f)
			{
				return Color.Lerp(value3, value4, SummerHeat.MaxEffectFactor);
			}
			if (SummerHeat.RedFactor > 0f)
			{
				return Color.Lerp(value2, value3, SummerHeat.RedFactor);
			}
			if (SummerHeat.GreenFactor > 0f)
			{
				return Color.Lerp(value2, value, SummerHeat.GreenFactor);
			}
			return value2;
		}

		private static string ColorizeText(string value, Color color, float alpha = 1f)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrEmpty(value))
			{
				return string.Empty;
			}
			return "<color=#" + ColorHex(color, alpha) + ">" + value + "</color>";
		}

		private static string ColorHex(Color color, float alpha)
		{
			//IL_0001: 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_0045: 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)
			int num = Mathf.Clamp(Mathf.RoundToInt(Mathf.Clamp01(color.r) * 255f), 0, 255);
			int num2 = Mathf.Clamp(Mathf.RoundToInt(Mathf.Clamp01(color.g) * 255f), 0, 255);
			int num3 = Mathf.Clamp(Mathf.RoundToInt(Mathf.Clamp01(color.b) * 255f), 0, 255);
			int num4 = Mathf.Clamp(Mathf.RoundToInt(Mathf.Clamp01(alpha) * Mathf.Clamp01(color.a) * 255f), 0, 255);
			return $"{num:x2}{num2:x2}{num3:x2}{num4:x2}";
		}

		private static float GetHeatMultiplier(float configuredEffect)
		{
			configuredEffect = Mathf.Clamp01(configuredEffect);
			if (Mathf.Approximately(configuredEffect, 0f))
			{
				return 1f;
			}
			float num = Mathf.Lerp(1f, 1f + configuredEffect, SummerHeat.GreenFactor);
			float num2 = Mathf.Max(SummerHeat.RedFactor, SummerHeat.MaxEffectFactor);
			float num3 = Mathf.Lerp(1f, 1f - configuredEffect, num2);
			return (num2 > 0f) ? num3 : num;
		}

		private static float GetSignedModifier(float configuredValue)
		{
			configuredValue = Mathf.Clamp01(configuredValue);
			float num = Mathf.Max(SummerHeat.RedFactor, SummerHeat.MaxEffectFactor);
			if (num > 0f)
			{
				return configuredValue * num;
			}
			return 0f - configuredValue * SummerHeat.GreenFactor;
		}

		private static void AppendTechnicalInfo(StringBuilder builder)
		{
			//IL_00e4: 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_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: 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_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02df: Unknown result type (might be due to invalid IL or missing references)
			if (Seasons.summerHeatRavenTechnicalInfo.Value && TextsDialog_AddActiveEffects_SeasonTooltipWhenBuffDisabled.isActiveEffectsListCall && SummerHeat.IsReady)
			{
				bool flag = (Object)(object)SummerHeat.Instance == (Object)null || SummerHeat.Instance.IsDaytime();
				float nightFactor = SummerHeatUtils.GetNightFactor();
				GetThresholds(flag, nightFactor, out var greenThreshold, out var neutralThreshold, out var maxThreshold);
				float num = Mathf.Max(0.1f, SummerHeatUtils.ScaleHeatPercentForTime(SummerHeatUtils.ClampPercent(Seasons.summerHeatGreenFadeWidth.Value), flag, nightFactor));
				float num2 = Mathf.Max(0.1f, SummerHeatUtils.ScaleHeatPercentForTime(SummerHeatUtils.ClampPercent(Seasons.summerHeatRedRampWidth.Value), flag, nightFactor));
				float value = Mathf.Max(0f, greenThreshold - num);
				float value2 = greenThreshold + num;
				float value3 = Mathf.Min(maxThreshold, neutralThreshold + num2);
				float value4 = (flag ? 100f : (100f * nightFactor));
				float value5 = SummerHeatUtils.ClampPercent(Seasons.summerHeatMaxOverflow.Value);
				Color heatDisplayColor = GetHeatDisplayColor();
				Color value6 = Seasons.summerHeatBarBonusColor.Value;
				Color value7 = Seasons.summerHeatBarPenaltyColor.Value;
				Color value8 = Seasons.summerHeatBarMaxColor.Value;
				builder.Append('\n');
				builder.AppendFormat("<color=orange>{0}</color>\n", "$seasons_status_summer_heat_technical".Localize());
				builder.AppendFormat("{0}: {1} / {2}\n", "$seasons_status_summer_heat_technical_heat_values".Localize(), FormatPercent(SummerHeat.HeatPercent, heatDisplayColor), FormatPercent(SummerHeat.OverflowHeatPercent, value8));
				builder.AppendFormat("{0}: {1} / {2} / {3}\n", "$seasons_status_summer_heat_technical_factors".Localize(), FormatFactorPercent(SummerHeat.GreenFactor, value6), FormatFactorPercent(SummerHeat.RedFactor, value7), FormatBoolColored(SummerHeat.MaxEffectFactor > 0f, value8));
				builder.AppendFormat("{0}: <color=orange>{1}</color>\n", "$seasons_status_summer_heat_technical_direction".Localize(), GetTrendText().Localize());
				builder.AppendFormat("{0}: <color=orange>{1}</color> / <color=orange>{2}</color> / <color=orange>{3}</color> / <color=orange>{4}</color>\n", "$seasons_status_summer_heat_technical_conditions".Localize(), FormatBool(flag), FormatBool(SummerHeat.IsSunny), FormatBool(SummerHeat.IsInShade), FormatBool(SummerHeatVisuals.IsWorldHazeActive()));
				AppendArmorTechnicalInfo(builder);
				builder.AppendFormat("{0}: {1}\n", "$seasons_status_summer_heat_technical_heat_scale".Localize(), BuildTechnicalHeatScale(flag));
				builder.AppendFormat("{0}: {1} / {2} / {3}\n", "$seasons_status_summer_heat_technical_comfort_range".Localize(), FormatPercent(value, value6), FormatPercent(greenThreshold, value6), FormatPercent(value2, value6));
				builder.AppendFormat("{0}: {1} / {2}\n", "$seasons_status_summer_heat_technical_penalty_ramp".Localize(), FormatPercent(neutralThreshold, value7), FormatPercent(value3, value7));
				builder.AppendFormat("{0}: {1} / {2} / {3}\n", "$seasons_status_summer_heat_technical_overheated".Localize(), FormatPercent(maxThreshold, value8), FormatPercent(value4, value8), FormatPercent(value5, value8));
			}
		}

		private static void GetThresholds(bool isDaytime, float nightFactor, out float greenThreshold, out float neutralThreshold, out float maxThreshold)
		{
			float num = SummerHeatUtils.ClampPercent(Seasons.summerHeatGreenThreshold.Value);
			float num2 = SummerHeatUtils.ClampPercent(Mathf.Max(num + 1f, Seasons.summerHeatNeutralThreshold.Value));
			float value = SummerHeatUtils.ClampPercent(Mathf.Max(num2 + 1f, Seasons.summerHeatMaxThreshold.Value));
			greenThreshold = SummerHeatUtils.ScaleHeatPercentForTime(num, isDaytime, nightFactor);
			neutralThreshold = SummerHeatUtils.ScaleHeatPercentForTime(num2, isDaytime, nightFactor);
			maxThreshold = SummerHeatUtils.ScaleHeatPercentForTime(value, isDaytime, nightFactor);
		}

		private static string FormatPercent(float value, Color color)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			return ColorizeText($"{value:0.#}%", color);
		}

		private static string FormatFactorPercent(float value, Color color)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			return ColorizeText($"{Mathf.Clamp01(value) * 100f:0}%", color);
		}

		private static string FormatBool(bool value)
		{
			return (value ? "$seasons_status_summer_heat_yes" : "$seasons_status_summer_heat_no").Localize();
		}

		private static string FormatBoolColored(bool value, Color yesColor)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			string text = FormatBool(value);
			return value ? ColorizeText(text, yesColor) : text;
		}

		private static void AppendArmorTechnicalInfo(StringBuilder builder)
		{
			if (Seasons.summerHeatArmorHeatEnabled.Value && !((Object)(object)SummerHeat.Instance == (Object)null))
			{
				SummerHeatArmorState armorState = SummerHeat.Instance.ArmorState;
				builder.AppendFormat("{0}: {1} / {2}\n", "$seasons_status_summer_heat_technical_armor".Localize(), FormatArmorModifier(armorState.HeatingModifier, positiveIsGood: false), FormatArmorModifier(armorState.CoolingModifier, positiveIsGood: true));
				builder.AppendFormat("{0}: <color=orange>{1}</color> / <color=orange>{2}</color> / <color=orange>{3}</color> / <color=orange>{4}</color>\n", "$seasons_status_summer_heat_technical_armor_slots".Localize(), LocalizeState(armorState.HeadState), LocalizeState(armorState.CloakState), LocalizeState(armorState.ChestState), LocalizeState(armorState.LegsState));
			}
		}

		private static string FormatArmorModifier(float value, bool positiveIsGood)
		{
			//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_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			Color value2 = Seasons.summerHeatBarBonusColor.Value;
			Color value3 = Seasons.summerHeatBarNeutralColor.Value;
			Color value4 = Seasons.summerHeatBarPenaltyColor.Value;
			Color color = (Mathf.Approximately(value, 0f) ? value3 : ((value > 0f == positiveIsGood) ? value2 : value4));
			return ColorizeText($"{value * 100f:+0;-0;0}%", color);
		}

		private static string LocalizeState(string token)
		{
			return string.IsNullOrEmpty(token) ? string.Empty : token.Localize();
		}

		private static string BuildTechnicalHeatScale(bool isDaytime)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			StringBuilder stringBuilder = new StringBuilder(2400);
			for (int i = 0; i < 100; i++)
			{
				float heatPercent = (float)i * 100f / 99f;
				stringBuilder.Append(ColorizeText('|'.ToString(), GetHeatDisplayColorForValue(heatPercent, isDaytime)));
			}
			return $"<cspace=-0.08em>{stringBuilder}</cspace>";
		}

		private static Color GetHeatDisplayColorForValue(float heatPercent, bool isDaytime)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_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)
			//IL_0082: 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_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: 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_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: 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_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			float nightFactor = SummerHeatUtils.GetNightFactor();
			GetThresholds(isDaytime, nightFactor, out var greenThreshold, out var neutralThreshold, out var maxThreshold);
			float num = Mathf.Max(0.1f, SummerHeatUtils.ScaleHeatPercentForTime(SummerHeatUtils.ClampPercent(Seasons.summerHeatGreenFadeWidth.Value), isDaytime, nightFactor));
			float num2 = Mathf.Max(0.1f, SummerHeatUtils.ScaleHeatPercentForTime(SummerHeatUtils.ClampPercent(Seasons.summerHeatRedRampWidth.Value), isDaytime, nightFactor));
			Color value = Seasons.summerHeatBarBonusColor.Value;
			Color value2 = Seasons.summerHeatBarNeutralColor.Value;
			Color value3 = Seasons.summerHeatBarPenaltyColor.Value;
			Color value4 = Seasons.summerHeatBarMaxColor.Value;
			if (!isDaytime && nightFactor <= 0f)
			{
				return value2;
			}
			if (heatPercent >= maxThreshold)
			{
				return value4;
			}
			if (heatPercent > neutralThreshold)
			{
				float num3 = Mathf.Min(maxThreshold, neutralThreshold + num2);
				float num4 = ((heatPercent < num3) ? Mathf.InverseLerp(neutralThreshold, num3, heatPercent) : 1f);
				return Color.Lerp(value2, value3, num4);
			}
			float num5 = Mathf.Max(0f, greenThreshold - num);
			float num6 = greenThreshold + num;
			if (heatPercent >= num5 && heatPercent <= num6)
			{
				float num7 = ((heatPercent <= greenThreshold) ? Mathf.InverseLerp(num5, greenThreshold, heatPercent) : (1f - Mathf.InverseLerp(greenThreshold, num6, heatPercent)));
				float num8 = Mathf.Lerp(0.25f, 1f, num7);
				return Color.Lerp(value2, value, num8);
			}
			return value2;
		}

		private static string GetZoneText(HeatZone zone)
		{
			if (1 == 0)
			{
			}
			string result = zone switch
			{
				HeatZone.Green => "$seasons_status_summer_heat_zone_green", 
				HeatZone.Neutral => "$seasons_status_summer_heat_zone_neutral", 
				HeatZone.Red => "$seasons_status_summer_heat_zone_red", 
				HeatZone.Max => "$seasons_status_summer_heat_zone_max", 
				_ => "$seasons_status_summer_heat_zone_neutral", 
			};
			if (1 == 0)
			{
			}
			return result;
		}

		private static string GetExposureText()
		{
			if (SummerHeat.IsInSun)
			{
				return "$seasons_status_summer_heat_exposure_sun";
			}
			if (SummerHeat.IsInShade)
			{
				return "$seasons_status_summer_heat_exposure_shade";
			}
			return "$seasons_status_summer_heat_exposure_none";
		}

		private static string GetTrendText()
		{
			if (SummerHeat.Direction > 0)
			{
				return "$seasons_status_summer_heat_trend_heating";
			}
			if (SummerHeat.Direction < 0)
			{
				return "$seasons_status_summer_heat_trend_cooling";
			}
			return "$seasons_status_summer_heat_trend_stable";
		}

		private static string GetModifierSummary()
		{
			StringBuilder stringBuilder = new StringBuilder(128);
			AppendModifierLine(stringBuilder, "$seasons_status_summer_heat_modifier_health_regen", GetHeatMultiplier(Seasons.summerHeatHealthRegenMultiplier.Value));
			AppendModifierLine(stringBuilder, "$seasons_status_summer_heat_modifier_stamina_regen", GetHeatMultiplier(Seasons.summerHeatStaminaRegenMultiplier.Value));
			AppendModifierLine(stringBuilder, "$seasons_status_summer_heat_modifier_eitr_regen", GetHeatMultiplier(Seasons.summerHeatEitrRegenMultiplier.Value));
			AppendModifierLine(stringBuilder, "$seasons_status_summer_heat_modifier_stamina_use", 1f + GetSignedModifier(Seasons.summerHeatStaminaUseMultiplier.Value));
			AppendModifierLine(stringBuilder, "$seasons_status_summer_heat_modifier_adrenaline", 1f + GetSignedModifier(Seasons.summerHeatAdrenalineMultiplier.Value));
			if (stringBuilder.Length == 0)
			{
				return string.Empty;
			}
			return "\n" + stringBuilder;
		}

		private static void AppendActiveFactors(StringBuilder builder)
		{
			bool flag = false;
			if ((Object)(object)SummerHeat.Instance != (Object)null && SummerHeat.Instance.HasCoolingFood())
			{
				builder.AppendFormat("<color=orange>{0}</color>\n", "$seasons_status_summer_heat_factor_cooling_food".Localize());
				flag = true;
			}
			if ((Object)(object)SummerHeat.Instance != (Object)null && SummerHeat.Instance.HasCampFireHeat())
			{
				builder.AppendFormat("<color=orange>{0}</color>\n", "$seasons_status_summer_heat_factor_campfire".Localize());
				flag = true;
			}
			if ((Object)(object)SummerHeat.Instance != (Object)null && SummerHeat.Instance.HasEncumberedHeat())
			{
				builder.AppendFormat("<color=orange>{0}</color>\n", "$seasons_status_summer_heat_factor_encumbered".Localize());
				flag = true;
			}
			if (flag)
			{
				builder.Append('\n');
			}
		}

		private static void AppendModifierLine(StringBuilder builder, string label, float multiplier)
		{
			if (!Mathf.Approximately(multiplier, 1f))
			{
				builder.AppendFormat("{0}: <color=orange>{1}%</color>\n", label.Localize(), ((multiplier - 1f) * 100f).ToString("+0;-0"));
			}
		}
	}
	internal struct SummerHeatArmorState
	{
		public static readonly SummerHeatArmorState Empty = new SummerHeatArmorState
		{
			HeadState = "$seasons_status_summer_heat_armor_disabled",
			CloakState = "$seasons_status_summer_heat_armor_disabled",
			ChestState = "$seasons_status_summer_heat_armor_disabled",
			LegsState = "$seasons_status_summer_heat_armor_disabled"
		};

		public float HeatingModifier;

		public float CoolingModifier;

		public string HeadState;

		public string CloakState;

		public string ChestState;

		public string LegsState;
	}
	internal class SummerHeatController : MonoBehaviour
	{
		internal const float EvaluationInterval = 1f;

		internal const float DaytimeHeatCap = 100f;

		internal const float ShadowRayDistance = 100f;

		internal const float StableEpsilon = 0.01f;

		internal const float WetCoolingPerSecond = 5f;

		internal const float ShelterCoolingPerSecond = 2f;

		internal const float BurningHeatPerSecond = 5f;

		internal const float RunningHeatPerSecond = 0.5f;

		internal const float WalkingCoolingPerSecond = 0.5f;

		internal const float StandingCoolingPerSecond = 1f;

		internal const float CoolingFoodHeatPerSecond = 5f;

		internal const float CampFireHeatPerSecond = 0.5f;

		internal const float EncumberedHeatPerSecond = 0.5f;

		internal const float MovementThreshold = 0.1f;

		internal const float NoonPeak = 0.5f;

		internal const float NoonStart = 0.42f;

		internal const float NoonEnd = 0.58f;

		internal const float SecondaryAttackHeat = 1f;

		internal const float PrimaryAttackHeat = 0.5f;

		internal const float DodgeHeat = 0.5f;

		internal const float JumpHeat = 0.25f;

		internal const float BlockHeat = 1f;

		internal const float PerfectBlockHeat = 0.5f;

		internal const float FireDamageHeat = 10f;

		internal const float FrostDamageHeat = -10f;

		private const float BareHeadHairHeatRateBonus = 0.2f;

		private static readonly HashSet<string> s_configuredNonSunnySystems = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		private static readonly HashSet<string> s_openHelmetItems = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		private static readonly HashSet<string> s_bareHeadHairItems = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		private static readonly HashSet<string> s_lightCloakItems = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		private static readonly HashSet<string> s_openChestItems = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		private static readonly HashSet<string> s_openLegItems = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		private static string s_configuredNonSunnySystemsValue = string.Empty;

		private static string s_openHelmetItemsValue = string.Empty;

		private static string s_bareHeadHairItemsValue = string.Empty;

		private static string s_lightCloakItemsValue = string.Empty;

		private static string s_openChestItemsValue = string.Empty;

		private static string s_openLegItemsValue = string.Empty;

		private float _evaluationTimer;

		private float _overflowHeat;

		private SummerHeatMode _mode = SummerHeatMode.Stable;

		private SummerHeatState _state;

		private string _currentEnvironmentName = string.Empty;

		private bool _isDaytime = true;

		private bool _hasWetStatus;

		private bool _hasShelterStatus;

		private bool _hasBurningStatus;

		private bool _hasColdStatus;

		private bool _hasCoolingFood;

		private bool _hasCampFireStatus;

		private bool _biomeAllowsSummerHeat = true;

		private Biome _currentBiome = (Biome)0;

		private SummerHeatArmorState _armorState = SummerHeatArmorState.Empty;

		internal static SummerHeatController Instance { get; private set; }

		internal Player Player { get; private set; }

		internal SummerHeatState State => _state;

		internal SummerHeatArmorState ArmorState => _armorState;

		private void Awake()
		{
			Player = ((Component)this).GetComponent<Player>();
			if ((Object)(object)Player != (Object)(object)Player.m_localPlayer)
			{
				((Behaviour)this).enabled = false;
				return;
			}
			Instance = this;
			EvaluateState(forceStatusRefresh: true);
		}

		private void OnDestroy()
		{
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
			SummerHeatVisuals.UpdateHazeState();
		}

		private void Update()
		{
			if (!((Object)(object)Player == (Object)null) && !((Object)(object)Player != (Object)(object)Player.m_localPlayer) && !((Character)Player).IsDead())
			{
				float deltaTime = Time.deltaTime;
				_evaluationTimer += deltaTime;
				if (_evaluationTimer >= 1f)
				{
					_evaluationTimer = 0f;
					EvaluateState(forceStatusRefresh: false);
				}
				UpdateHeat(deltaTime);
				SummerHeatVisuals.UpdateHazeState();
			}
		}

		internal static void EnsureForPlayer(Player player)
		{
			SummerHeatController summerHeatController = default(SummerHeatController);
			if (!((Object)(object)player == (Object)null) && !((Object)(object)player != (Object)(object)Player.m_localPlayer) && !((Component)player).TryGetComponent<SummerHeatController>(ref summerHeatController))
			{
				((Component)player).gameObject.AddComponent<SummerHeatController>();
			}
		}

		internal static HeatZone GetZoneForHeat(float heatPercent, HeatZone previousZone, bool biomeSupported, bool isDaytime, float overflowHeat)
		{
			if (!biomeSupported)
			{
				return HeatZone.Neutral;
			}
			float greenThreshold = GetGreenThreshold(isDaytime);
			float neutralThreshold = GetNeutralThreshold(isDaytime);
			float maxThreshold = GetMaxThreshold(isDaytime);
			float zoneHysteresis = GetZoneHysteresis(isDaytime);
			if (heatPercent <= 0f && overflowHeat <= 0f && maxThreshold <= 0f)
			{
				return HeatZone.Neutral;
			}
			float greenReturnThreshold = greenThreshold + zoneHysteresis * 0.5f;
			float num = greenThreshold + zoneHysteresis;
			float num2 = neutralThreshold - zoneHysteresis;
			if (overflowHeat > 0f || heatPercent >= maxThreshold)
			{
				return HeatZone.Max;
			}
			if (1 == 0)
			{
			}
			HeatZone result = previousZone switch
			{
				HeatZone.Green => (heatPercent >= num) ? HeatZone.Neutral : HeatZone.Green, 
				HeatZone.Red => (heatPercent < num2) ? HeatZone.Neutral : HeatZone.Red, 
				HeatZone.Max => HeatZone.Red, 
				_ => ResolveNeutralZone(heatPercent, greenReturnThreshold, neutralThreshold), 
			};
			if (1 == 0)
			{
			}
			return result;
		}

		internal string GetCurrentEnvironmentName()
		{
			return _currentEnvironmentName;
		}

		internal bool IsDaytime()
		{
			return _isDaytime;
		}

		internal void RefreshState(bool forceStatusRefresh = true)
		{
			EvaluateState(forceStatusRefresh);
		}

		internal void AddInstantHeat(float amount, bool useConfigGate = false)
		{
			if (!Seasons.summerHeatEnabled.Value || Mathf.Approximately(amount, 0f) || (useConfigGate && !Seasons.summerHeatInstantHeatSources.Value) || !_biomeAllowsSummerHeat)
			{
				return;
			}
			if (amount > 0f)
			{
				if (!_state.SeasonHeatWindowActive || _hasColdStatus || _hasCoolingFood)
				{
					return;
				}
			}
			else if (!_state.SeasonHeatWindowActive && _state.TotalHeatPercent <= 0f)
			{
				return;
			}
			float totalHeatPercent = _state.TotalHeatPercent;
			ApplyHeatDelta(amount, GetCurrentHeatCap());
			RefreshDerivedState(totalHeatPercent, forceStatusRefresh: false);
		}

		private static HeatZone ResolveNeutralZone(float heatPercent, float greenReturnThreshold, float neutralThreshold)
		{
			if (heatPercent < greenReturnThreshold)
			{
				return HeatZone.Green;
			}
			if (heatPercent >= neutralThreshold)
			{
				return HeatZone.Red;
			}
			return HeatZone.Neutral;
		}

		private void EvaluateState(bool forceStatusRefresh)
		{
			//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_0054: Unknown result type (might be due to invalid IL or missing references)
			if (!Seasons.summerHeatEnabled.Value)
			{
				ClearHeatState(forceStatusRefresh);
				return;
			}
			_isDaytime = !EnvMan.IsNight();
			_currentBiome = (Biome)(((Object)(object)Player != (Object)null) ? ((int)Player.GetCurrentBiome()) : 0);
			_biomeAllowsSummerHeat = AllowsSummerHeatBiome(_currentBiome);
			bool flag = _biomeAllowsSummerHeat && IsSeasonHeatWindowActive();
			EnvSetup env = EnvMan.instance?.m_currentEnv;
			_currentEnvironmentName = GetEnvironmentName(env);
			bool flag2 = flag && IsEnvironmentSunny(env);
			bool flag3 = false;
			bool flag4 = false;
			if (flag && flag2 && _isDaytime)
			{
				flag4 = ComputeShade(Player);
				flag3 = !flag4;
			}
			else
			{
				flag4 = true;
			}
			SEMan sEMan = ((Character)Player).GetSEMan();
			_hasWetStatus = sEMan.HaveStatusEffect(SEMan.s_statusEffectWet);
			_hasShelterStatus = sEMan.HaveStatusEffect(SEMan.s_statusEffectShelter);
			_hasBurningStatus = sEMan.HaveStatusEffect(SEMan.s_statusEffectBurning);
			_hasCampFireStatus = sEMan.HaveStatusEffect(SEMan.s_statusEffectCampFire);
			_hasColdStatus = sEMan.HaveStatusEffect(SEMan.s_statusEffectCold) || sEMan.HaveStatusEffect(SEMan.s_statusEffectFreezing) || sEMan.HaveStatusEffect(SEMan.s_statusEffectFrost);
			_hasCoolingFood = SeasonState.HasCoolingFood(Player);
			bool flag5 = IsPlayerCoolingByWater(Player);
			bool isHeating = flag && flag2 && _isDaytime && flag3 && !flag5;
			_mode = GetMode(flag, isHeating, flag5, flag4);
			_state.SeasonHeatWindowActive = flag;
			_state.IsSunny = flag2;
			_state.IsInSun = flag3;
			_state.IsInShade = flag4;
			_state.BiomeSupported = _biomeAllowsSummerHeat;
			RefreshArmorState();
			RefreshDerivedState(_state.TotalHeatPercent, forceStatusRefresh);
		}

		private void ClearHeatState(bool forceStatusRefresh)
		{
			float totalHeatPercent = _state.TotalHeatPercent;
			_overflowHeat = 0f;
			_mode = SummerHeatMode.Stable;
			_currentEnvironmentName = string.Empty;
			_isDaytime = !EnvMan.IsNight();
			_hasWetStatus = false;
			_hasShelterStatus = false;
			_hasBurningStatus = false;
			_hasColdStatus = false;
			_hasCoolingFood = false;
			_hasCampFireStatus = false;
			_biomeAllowsSummerHeat = false;
			_state.SetHeat(0f, 0f, 0f, 100f, HeatZone.Neutral, 0f, 0f, 0f);
			_state.Direction = ((totalHeatPercent > 0f) ? (-1) : 0);
			_state.IsCooling = false;
			_state.IsSunny = false;
			_state.IsInSun = false;
			_state.IsInShade = true;
			_state.SeasonHeatWindowActive = false;
			_state.BiomeSupported = false;
			_state.MechanicActive = false;
			_armorState = SummerHeatArmorState.Empty;
			EnsureStatusEffect(shouldHaveEffect: false);
			SummerHeatVisuals.UpdateHazeState();
		}

		private void UpdateHeat(float dt)
		{
			float totalHeatPercent = _state.TotalHeatPercent;
			if (!Seasons.summerHeatEnabled.Value)
			{
				ClearHeatState(forceStatusRefresh: true);
				return;
			}
			if (!_biomeAllowsSummerHeat)
			{
				_overflowHeat = 0f;
				_state.SetHeat(0f, 0f, 0f, 100f, HeatZone.Neutral, 0f, 0f, 0f);
				_state.Direction = ((totalHeatPercent > 0f) ? (-1) : 0);
				_state.IsCooling = totalHeatPercent > 0f;
				_state.MechanicActive = false;
				EnsureStatusEffect(shouldHaveEffect: false);
				return;
			}
			float currentHeatCap = GetCurrentHeatCap();
			float num = 0f;
			float num2 = 100f / Mathf.Max(1f, Seasons.summerHeatTimeToMax.Value);
			switch (_mode)
			{
			case SummerHeatMode.Heating:
				num += num2 * dt;
				break;
			case SummerHeatMode.CoolingFast:
				num -= num2 * 2.5f * dt;
				break;
			case SummerHeatMode.CoolingNormal:
				num -= num2 * 1.25f * dt;
				break;
			case SummerHeatMode.CoolingSlow:
				num -= num2 * 0.4f * dt;
				break;
			}
			if (_state.SeasonHeatWindowActive)
			{
				if (_hasBurningStatus)
				{
					num += 5f * dt;
				}
				if (_hasWetStatus)
				{
					num -= 5f * dt;
				}
				if (_hasShelterStatus)
				{
					num -= 2f * dt;
				}
				num += GetActivityHeatDelta(Player, dt);
			}
			num = ApplyDynamicRateModifiers(num);
			num = ApplyArmorRateModifiers(num);
			ApplyHeatDelta(num, currentHeatCap);
			if (_hasColdStatus)
			{
				_overflowHeat = 0f;
				ApplyHeatDelta(0f - GetLiveTotalHeat(), currentHeatCap);
			}
			else if (_hasCoolingFood)
			{
				ApplyHeatDelta(GetCoolingDeltaTowards(GetGreenThreshold(_isDaytime), 5f, dt), currentHeatCap);
			}
			if (_state.SeasonHeatWindowActive)
			{
				if (Seasons.summerHeatCampFireAddsHeat.Value && _hasCampFireStatus)
				{
					ApplyHeatDelta(GetHeatingDeltaTowards(GetGreenThreshold(_isDaytime), 0.5f, dt), currentHeatCap);
				}
				if (Seasons.summerHeatEncumberedAddsHeat.Value && ((Character)Player).IsEncumbered())
				{
					ApplyHeatDelta(GetHeatingDeltaTowards(GetNeutralThreshold(_isDaytime), 0.5f, dt), currentHeatCap);
				}
			}
			RefreshDerivedState(totalHeatPercent, forceStatusRefresh: false);
		}

		private void RefreshDerivedState(float previousTotalHeat, bool forceStatusRefresh)
		{
			float currentHeatCap = GetCurrentHeatCap();
			float num = Mathf.Clamp(_state.HeatPercent, 0f, currentHeatCap);
			float num2 = Mathf.Max(0f, num + _overflowHeat);
			HeatZone zoneForHeat = GetZoneForHeat(num, _state.Zone, _biomeAllowsSummerHeat, _isDaytime, _overflowHeat);
			float greenFactor = CalculateGreenFactor(num);
			float redFactor = CalculateRedFactor(num);
			float maxFactor = CalculateMaxFactor(num, num2, currentHeatCap);
			_state.SetHeat(num, _overflowHeat, num2, 100f, zoneForHeat, greenFactor, redFactor, maxFactor);
			float num3 = num2 - previousTotalHeat;
			_state.Direction = ((!(Mathf.Abs(num3) <= 0.01f)) ? ((num3 > 0f) ? 1 : (-1)) : 0);
			_state.IsCooling = _hasColdStatus || (_hasCoolingFood && num2 > GetGreenThreshold(_isDaytime)) || _hasWetStatus || _hasShelterStatus || _state.Direction < 0;
			_state.MechanicActive = _state.SeasonHeatWindowActive || num2 > 0f;
			_state.BiomeSupported = _biomeAllowsSummerHeat;
			if (forceStatusRefresh || _state.MechanicActive != ((Character)Player).GetSEMan().HaveStatusEffect(SeasonsVars.s_statusEffectSummerHeatHash))
			{
				EnsureStatusEffect(_state.MechanicActive);
			}
		}

		private void RefreshArmorState()
		{
			_armorState = CalculateArmorState(Player, _state.IsInSun);
		}

		private static SummerHeatArmorState CalculateArmorState(Player player, bool isInDirectSun)
		{
			if (!Seasons.summerHeatArmorHeatEnabled.Value || (Object)(object)player == (Object)null)
			{
				return SummerHeatArmorState.Empty;
			}
			SummerHeatArmorState state = new SummerHeatArmorState
			{
				HeadState = "$seasons_status_summer_heat_armor_empty",
				CloakState = "$seasons_status_summer_heat_armor_empty",
				ChestState = "$seasons_status_summer_heat_armor_empty",
				LegsState = "$seasons_status_summer_heat_armor_empty"
			};
			ApplyHeadArmor(player, isInDirectSun, ref state);
			ApplyCloakArmor(player, ref state);
			ApplyBodyArmor(player, (ItemType)7, GetConfiguredItemList(Seasons.summerHeatOpenChestItems, ref s_openChestItemsValue, s_openChestItems), ref state.HeatingModifier, ref state.CoolingModifier, ref state.ChestState);
			ApplyBodyArmor(player, (ItemType)11, GetConfiguredItemList(Seasons.summerHeatOpenLegItems, ref s_openLegItemsValue, s_openLegItems), ref state.HeatingModifier, ref state.CoolingModifier, ref state.LegsState);
			state.HeatingModifier = Mathf.Clamp(state.HeatingModifier, -0.95f, 3f);
			state.CoolingModifier = Mathf.Clamp(state.CoolingModifier, -0.95f, 3f);
			return state;
		}

		private static void ApplyHeadArmor(Player player, bool isInDirectSun, ref SummerHeatArmorState state)
		{
			ItemData equippedItem = GetEquippedItem(player, (ItemType)6);
			if (equippedItem == null)
			{
				bool flag = IsBareHeadHair(player);
				if (isInDirectSun)
				{
					state.HeatingModifier += SummerHeatUtils.ClampEffect(Seasons.summerHeatUncoveredHeadSunHeating.Value) + (flag ? 0.2f : 0f);
					state.HeadState = (flag ? "$seasons_status_summer_heat_armor_bald_head" : "$seasons_status_summer_heat_armor_uncovered_sun");
				}
				else
				{
					state.CoolingModifier += SummerHeatUtils.ClampEffect(Seasons.summerHeatUncoveredHeadShadeCooling.Value) + (flag ? 0.2f : 0f);
					state.HeadState = (flag ? "$seasons_status_summer_heat_armor_bald_head" : "$seasons_status_summer_heat_armor_uncovered_shade");
				}
			}
			else if (IsConfiguredItem(equippedItem, GetConfiguredItemList(Seasons.summerHeatOpenHelmetItems, ref s_openHelmetItemsValue, s_openHelmetItems)))
			{
				state.HeatingModifier += SummerHeatUtils.ClampEffect(Seasons.summerHeatOpenHelmetHeating.Value);
				state.HeadState = "$seasons_status_summer_heat_armor_open_helmet";
			}
			else
			{
				state.HeatingModifier += SummerHeatUtils.ClampEffect(Seasons.summerHeatClosedHelmetHeating.Value);
				state.CoolingModifier -= SummerHeatUtils.ClampEffect(Seasons.summerHeatClosedHelmetCoolingPenalty.Value);
				state.HeadState = "$seasons_status_summer_heat_armor_closed_helmet";
			}
		}

		private static void ApplyCloakArmor(Player player, ref SummerHeatArmorState state)
		{
			ItemData equippedItem = GetEquippedItem(player, (ItemType)17);
			if (equippedItem == null)
			{
				state.HeatingModifier -= SummerHeatUtils.ClampEffect(Seasons.summerHeatNoCloakHeatingReduction.Value);
				state.CoolingModifier += SummerHeatUtils.ClampEffect(Seasons.summerHeatNoCloakCoolingBonus.Value);
				state.CloakState = "$seasons_status_summer_heat_armor_no_cloak";
			}
			else if (IsConfiguredItem(equippedItem, GetConfiguredItemList(Seasons.summerHeatLightCloakItems, ref s_lightCloakItemsValue, s_lightCloakItems)))
			{
				state.HeatingModifier -= SummerHeatUtils.ClampEffect(Seasons.summerHeatLightCloakHeatingReduction.Value);
				state.CoolingModifier += SummerHeatUtils.ClampEffect(Seasons.summerHeatLightCloakCoolingBonus.Value);
				state.CloakState = "$seasons_status_summer_heat_armor_light_cloak";
			}
			else if (IsFrostResistantItem(equippedItem))
			{
				state.HeatingModifier += SummerHeatUtils.ClampEffect(Seasons.summerHeatColdCloakHeating.Value);
				state.CoolingModifier -= SummerHeatUtils.ClampEffect(Seasons.summerHeatColdCloakCoolingPenalty.Value);
				state.CloakState = "$seasons_status_summer_heat_armor_cold_cloak";
			}
			else
			{
				state.HeatingModifier += SummerHeatUtils.ClampEffect(Seasons.summerHeatCloakHeating.Value);
				state.CloakState = "$seasons_status_summer_heat_armor_cloak";
			}
		}

		private static void ApplyBodyArmor(Player player, ItemType itemType, HashSet<string> openItems, ref float heatingModifier, ref float coolingModifier, ref string stateKey)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			ItemData equippedItem = GetEquippedItem(player, itemType);
			if (equippedItem == null)
			{
				heatingModifier -= SummerHeatUtils.ClampEffect(Seasons.summerHeatEmptyArmorSlotHeatingReduction.Value);
				coolingModifier += SummerHeatUtils.ClampEffect(Seasons.summerHeatEmptyArmorSlotCoolingBonus.Value);
				stateKey = "$seasons_status_summer_heat_armor_empty";
			}
			else if (IsConfiguredItem(equippedItem, openItems))
			{
				heatingModifier -= SummerHeatUtils.ClampEffect(Seasons.summerHeatOpenArmorHeatingReduction.Value);
				coolingModifier += SummerHeatUtils.ClampEffect(Seasons.summerHeatOpenArmorCoolingBonus.Value);
				stateKey = "$seasons_status_summer_heat_armor_open_armor";
			}
			else if (IsFrostResistantItem(equippedItem))
			{
				heatingModifier += SummerHeatUtils.ClampEffect(Seasons.summerHeatColdArmorHeating.Value);
				coolingModifier -= SummerHeatUtils.ClampEffect(Seasons.summerHeatColdArmorCoolingPenalty.Value);
				stateKey = "$seasons_status_summer_heat_armor_cold_armor";
			}
			else
			{
				heatingModifier += SummerHeatUtils.ClampEffect(Seasons.summerHeatClosedArmorHeating.Value);
				stateKey