Decompiled source of Seasons v1.9.2

Seasons.dll

Decompiled a week 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.Reflection.Emit;
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 Newtonsoft.Json.Converters;
using Seasons;
using Seasons.Compatibility;
using Seasons.Controllers;
using Splatform;
using TMPro;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;
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.9.2")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.9.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
	{
		private sealed class FailedAttempt
		{
			public uint Revision;

			public int WorldDay;
		}

		[HarmonyPatch(typeof(TerrainComp), "Update")]
		private static class TerrainComp_Update_DecultivateOwnedTerrain
		{
			private static void Prefix(TerrainComp __instance)
			{
				if (!SeasonState.IsActive || !ZoneSystemVariantController.IsTimeToDecultivateGround() || !__instance.m_initialized || (Object)(object)__instance.m_nview == (Object)null || !__instance.m_nview.IsValid() || !__instance.m_nview.IsOwner())
				{
					return;
				}
				ZDO zDO = __instance.m_nview.GetZDO();
				int currentWorldDay = Seasons.seasonState.GetCurrentWorldDay();
				if (!IsDecultivationDue(zDO, currentWorldDay, Seasons.seasonState.GetYearLengthInDays()))
				{
					return;
				}
				WorldGenerator instance = WorldGenerator.instance;
				if (instance == null)
				{
					return;
				}
				World world = instance.m_world;
				bool? obj;
				if (world == null)
				{
					obj = null;
				}
				else
				{
					AltBiomeWorldData biomeData = world.m_biomeData;
					obj = ((biomeData != null) ? new bool?(biomeData.IsReady) : ((bool?)null));
				}
				bool? flag = obj;
				if (flag != true || (failedAttempts.TryGetValue(__instance, out var value) && value.Revision == zDO.DataRevision && value.WorldDay == currentWorldDay))
				{
					return;
				}
				if (TryDecultivateGround(zDO, out var _))
				{
					zDO.Set(SeasonsVars.s_terrainDecultivated, currentWorldDay, false);
					failedAttempts.Remove(__instance);
					return;
				}
				FailedAttempt value2 = failedAttempts.GetValue(__instance, (TerrainComp _) => new FailedAttempt());
				value2.Revision = zDO.DataRevision;
				value2.WorldDay = currentWorldDay;
			}
		}

		private static ConditionalWeakTable<TerrainComp, FailedAttempt> failedAttempts = new ConditionalWeakTable<TerrainComp, FailedAttempt>();

		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 void ResetRuntimeState()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			failedAttempts = new ConditionalWeakTable<TerrainComp, FailedAttempt>();
			terrainCompVersion = 0;
			m_operations = 0;
			m_lastOpPoint = Vector3.zero;
			m_lastOpRadius = 0f;
			m_modifiedHeight = null;
			m_levelDelta = null;
			m_smoothDelta = null;
			m_modifiedPaint = null;
			m_paintMask = null;
		}

		public static bool DecultivateGround(ZDO zdo)
		{
			bool changed;
			return TryDecultivateGround(zdo, out changed) && changed;
		}

		internal static bool IsDecultivationDue(ZDO zdo, int worldDay, int yearLength)
		{
			int num = default(int);
			return !zdo.GetInt(SeasonsVars.s_terrainDecultivated, ref num) || Math.Abs((long)worldDay - (long)num) >= yearLength;
		}

		internal static bool TryDecultivateGround(ZDO zdo, out bool changed)
		{
			changed = false;
			try
			{
				return DecultivateGroundCore(zdo, out changed);
			}
			catch (Exception arg)
			{
				changed = false;
				Seasons.LogWarning($"Seasons could not process terrain decultivation; the processed day was not advanced:\n{arg}");
				return false;
			}
		}

		private static bool DecultivateGroundCore(ZDO zdo, out bool changed)
		{
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Expected O, but got Unknown
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			//IL_0327: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			//IL_0312: Unknown result type (might be due to invalid IL or missing references)
			//IL_0448: Unknown result type (might be due to invalid IL or missing references)
			//IL_044d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0483: Unknown result type (might be due to invalid IL or missing references)
			//IL_048d: Unknown result type (might be due to invalid IL or missing references)
			//IL_049d: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a3: Expected I4, but got Unknown
			//IL_04aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ca: Expected I4, but got Unknown
			//IL_04d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04db: Unknown result type (might be due to invalid IL or missing references)
			//IL_04eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f1: Expected I4, but got Unknown
			//IL_04f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0502: Unknown result type (might be due to invalid IL or missing references)
			//IL_0512: Unknown result type (might be due to invalid IL or missing references)
			//IL_0518: Expected I4, but got Unknown
			//IL_0540: Unknown result type (might be due to invalid IL or missing references)
			//IL_0545: Unknown result type (might be due to invalid IL or missing references)
			//IL_0547: Unknown result type (might be due to invalid IL or missing references)
			//IL_0563: Unknown result type (might be due to invalid IL or missing references)
			//IL_057f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0586: Unknown result type (might be due to invalid IL or missing references)
			//IL_0594: Unknown result type (might be due to invalid IL or missing references)
			//IL_069c: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a3: Expected O, but got Unknown
			//IL_06bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_040f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0414: Unknown result type (might be due to invalid IL or missing references)
			//IL_05bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c6: Invalid comparison between Unknown and I4
			//IL_063e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0645: Unknown result type (might be due to invalid IL or missing references)
			//IL_0666: Unknown result type (might be due to invalid IL or missing references)
			//IL_0668: Unknown result type (might be due to invalid IL or missing references)
			//IL_05cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0611: Unknown result type (might be due to invalid IL or missing references)
			//IL_061a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0625: Unknown result type (might be due to invalid IL or missing references)
			//IL_062c: Invalid comparison between Unknown and I4
			changed = false;
			if (zdo != null && zdo.IsValid() && (!zdo.HasOwner() || zdo.IsOwner()))
			{
				WorldGenerator instance = WorldGenerator.instance;
				if (instance != null)
				{
					World world = instance.m_world;
					bool? obj;
					if (world == null)
					{
						obj = null;
					}
					else
					{
						AltBiomeWorldData biomeData = world.m_biomeData;
						obj = ((biomeData != null) ? new bool?(biomeData.IsReady) : ((bool?)null));
					}
					bool? flag = obj;
					if (flag == true)
					{
						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("Seasons cannot decultivate ground: unsupported terrain compiler data version.");
							return false;
						}
						bool flag2 = false;
						m_operations = val.ReadInt();
						m_lastOpPoint = val.ReadVector3();
						m_lastOpRadius = val.ReadSingle();
						int num = val.ReadInt();
						TerrainComp val2 = TerrainComp.s_instances.Find((TerrainComp compiler) => (Object)(object)compiler != (Object)null && (Object)(object)compiler.m_nview != (Object)null && compiler.m_nview.GetZDO() == zdo);
						object obj2;
						if (!((Object)(object)val2 != (Object)null))
						{
							ZoneSystem instance2 = ZoneSystem.instance;
							if (instance2 == null)
							{
								obj2 = null;
							}
							else
							{
								GameObject zonePrefab = instance2.m_zonePrefab;
								obj2 = ((zonePrefab != null) ? zonePrefab.GetComponentInChildren<Heightmap>(true) : null);
							}
						}
						else
						{
							obj2 = val2.m_hmap;
						}
						Heightmap val3 = (Heightmap)obj2;
						if ((Object)(object)val3 == (Object)null || num != (val3.m_width + 1) * (val3.m_width + 1))
						{
							Seasons.LogWarning("Seasons cannot decultivate ground: the terrain dimensions could not be resolved safely.");
							return false;
						}
						m_modifiedHeight = new bool[num];
						m_levelDelta = new float[num];
						m_smoothDelta = new float[num];
						for (int num2 = 0; num2 < m_modifiedHeight.Length; num2++)
						{
							m_modifiedHeight[num2] = val.ReadBool();
							if (m_modifiedHeight[num2])
							{
								m_levelDelta[num2] = val.ReadSingle();
								m_smoothDelta[num2] = val.ReadSingle();
							}
							else
							{
								m_levelDelta[num2] = 0f;
								m_smoothDelta[num2] = 0f;
							}
						}
						int num3 = val.ReadInt();
						if (num3 != num && num3 != val3.m_width * val3.m_width)
						{
							Seasons.LogWarning("Seasons cannot decultivate ground: unsupported terrain paint grid dimensions.");
							return false;
						}
						m_modifiedPaint = new bool[num3];
						m_paintMask = (Color[])(object)new Color[num3];
						for (int num4 = 0; num4 < m_modifiedPaint.Length; num4++)
						{
							m_modifiedPaint[num4] = val.ReadBool();
							if (m_modifiedPaint[num4])
							{
								Color val4 = new Color
								{
									r = val.ReadSingle(),
									g = val.ReadSingle(),
									b = val.ReadSingle(),
									a = val.ReadSingle()
								};
								m_paintMask[num4] = val4;
							}
							else
							{
								m_paintMask[num4] = Color.black;
							}
						}
						if (val.GetPos() != val.Size())
						{
							Seasons.LogWarning("Seasons cannot decultivate ground: unexpected trailing terrain data.");
							return false;
						}
						int num5 = val3.m_width + 1;
						if (num3 != num)
						{
							bool[] modifiedPaint = m_modifiedPaint;
							Color[] paintMask = m_paintMask;
							m_modifiedPaint = new bool[num];
							m_paintMask = (Color[])(object)new Color[num];
							for (int num6 = 0; num6 < num5; num6++)
							{
								for (int num7 = 0; num7 < num5; num7++)
								{
									int num8 = num6 * num5 + num7;
									int num9 = Math.Min(num6, val3.m_width - 1) * val3.m_width + Math.Min(num7, val3.m_width - 1);
									m_modifiedPaint[num8] = modifiedPaint[num9];
									m_paintMask[num8] = paintMask[num9];
								}
							}
						}
						Vector3 position = zdo.GetPosition();
						int num10 = val3.m_width / 2;
						float scale = val3.m_scale;
						float num11 = (float)val3.m_width * scale * 0.5f;
						Biome[] corners = (Biome[])(object)new Biome[4]
						{
							(Biome)(int)WorldGenerator.instance.GetBiomeSector(position.x - num11, position.z - num11, false).Biome,
							(Biome)(int)WorldGenerator.instance.GetBiomeSector(position.x + num11, position.z - num11, false).Biome,
							(Biome)(int)WorldGenerator.instance.GetBiomeSector(position.x - num11, position.z + num11, false).Biome,
							(Biome)(int)WorldGenerator.instance.GetBiomeSector(position.x + num11, position.z + num11, false).Biome
						};
						for (int num12 = 0; num12 < m_modifiedPaint.Length; num12++)
						{
							if (m_modifiedPaint[num12])
							{
								Color val5 = m_paintMask[num12];
								float num13 = position.x + ((float)(num12 % num5 - num10) - 0.5f) * scale;
								float num14 = position.z + ((float)(num12 / num5 - num10) - 0.5f) * scale;
								float num15 = Mathf.Min(val5.r, val5.b);
								if (!(val5.g <= num15) && !WorldGenerator.IsDeepnorth(num13, num14) && (int)WorldGenerator.instance.GetBiomeSector(num13, num14, false).Biome != 64 && !IsNorthernTerrain(corners, (num13 - position.x) / (num11 * 2f) + 0.5f, (num14 - position.z) / (num11 * 2f) + 0.5f) && (!((Object)(object)val2 != (Object)null) || (int)val3.GetBiome(new Vector3(num13, position.y, num14), 0.02f, false) != 64))
								{
									val5.r = Mathf.Max(val5.r, val5.g);
									val5.g = num15;
									m_paintMask[num12] = val5;
									flag2 = true;
								}
							}
						}
						if (!flag2)
						{
							return true;
						}
						ZPackage val6 = new ZPackage();
						val6.Write(terrainCompVersion);
						val6.Write(m_operations);
						val6.Write(m_lastOpPoint);
						val6.Write(m_lastOpRadius);
						val6.Write(m_modifiedHeight.Length);
						for (int num16 = 0; num16 < m_modifiedHeight.Length; num16++)
						{
							val6.Write(m_modifiedHeight[num16]);
							if (m_modifiedHeight[num16])
							{
								val6.Write(m_levelDelta[num16]);
								val6.Write(m_smoothDelta[num16]);
							}
						}
						val6.Write(m_modifiedPaint.Length);
						for (int num17 = 0; num17 < m_modifiedPaint.Length; num17++)
						{
							val6.Write(m_modifiedPaint[num17]);
							if (m_modifiedPaint[num17])
							{
								val6.Write(m_paintMask[num17].r);
								val6.Write(m_paintMask[num17].g);
								val6.Write(m_paintMask[num17].b);
								val6.Write(m_paintMask[num17].a);
							}
						}
						byte[] array = Utils.Compress(val6.GetArray());
						zdo.Set(ZDOVars.s_TCData, array);
						if ((Object)(object)val2 != (Object)null)
						{
							val2.CheckLoad();
							val2.m_lastHash = val2.ComputePaintMaskHash();
						}
						changed = true;
						return true;
					}
				}
			}
			return false;
		}

		private static bool IsNorthernTerrain(Biome[] corners, float x, float y)
		{
			Vector4 val = default(Vector4);
			((Vector4)(ref val))..ctor(Heightmap.Distance(x, y, 0f, 0f), Heightmap.Distance(x, y, 1f, 0f), Heightmap.Distance(x, y, 0f, 1f), Heightmap.Distance(x, y, 1f, 1f));
			float num = 0f;
			for (int i = 0; i < corners.Length; i++)
			{
				if ((int)corners[i] == 64)
				{
					num += ((Vector4)(ref val))[i];
				}
			}
			if (num == 0f)
			{
				return false;
			}
			for (int j = 0; j < corners.Length; j++)
			{
				if ((int)corners[j] == 64)
				{
					continue;
				}
				float num2 = 0f;
				for (int k = 0; k < corners.Length; k++)
				{
					if ((int)corners[k] == (int)corners[j])
					{
						num2 += ((Vector4)(ref val))[k];
					}
				}
				if (num2 > num)
				{
					return false;
				}
			}
			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()
			{
				Dictionary<int, byte[]> values;
				byte[] value;
				return properties != null && Enum.GetValues(typeof(Seasons.Season)).Cast<Seasons.Season>().All((Seasons.Season season) => variants.TryGetValue(season, out values) && Enumerable.Range(0, 4).All((int variant) => values.TryGetValue(variant, out value) && value != null && value.Length != 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()
		{
			Dictionary<string, PrefabController> dictionary = controllers;
			int result;
			if (dictionary != null && dictionary.Count > 0)
			{
				Dictionary<int, TextureData> dictionary2 = textures;
				if (dictionary2 != null && dictionary2.Count > 0)
				{
					result = (textures.Values.All((TextureData texture) => texture?.Initialized() ?? false) ? 1 : 0);
					goto IL_0061;
				}
			}
			result = 0;
			goto IL_0061;
			IL_0061:
			return (byte)result != 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()
		{
			try
			{
				if (Seasons.cacheStorageFormat.Value == Seasons.CacheFormat.Json)
				{
					LoadFromJSON();
				}
				else
				{
					LoadFromBinary();
				}
			}
			catch (Exception arg)
			{
				controllers = new Dictionary<string, PrefabController>();
				textures = new Dictionary<int, TextureData>();
				Seasons.LogWarning($"Unable to load seasonal texture cache:\n{arg}");
			}
		}

		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)
			{
				if (int.TryParse(directoryInfo2.Name, out var result) && !textures.ContainsKey(result))
				{
					TextureData textureData = new TextureData(directoryInfo2);
					if (textureData.Initialized())
					{
						textures.Add(result, 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;

		private bool m_reloading;

		private static readonly object s_diskLock = new object();

		public bool IsUpdating => m_reloading || TextureCachingController.InProcess;

		public void Dispose()
		{
			foreach (TextureVariants value in textures.Values)
			{
				value.Dispose();
			}
			textures.Clear();
			controllers.Clear();
		}

		public bool Initialize(bool force = false)
		{
			if (!force && Initialized())
			{
				return true;
			}
			if (m_reloading || TextureCachingController.InProcess)
			{
				return false;
			}
			PrefabVariantController.instance?.RevertPrefabsState();
			ClutterVariantController.Instance?.RevertColors();
			Dispose();
			revision = SeasonalTexturePrefabCache.GetRevision();
			CachedData cachedData = new CachedData(revision);
			if (force)
			{
				lock (s_diskLock)
				{
					if (Directory.Exists(cachedData.CacheDirectory()))
					{
						Directory.Delete(cachedData.CacheDirectory(), recursive: true);
					}
				}
			}
			else
			{
				lock (s_diskLock)
				{
					cachedData.LoadFromDisk();
				}
			}
			if (cachedData.Initialized())
			{
				DictionaryExt.Copy<string, PrefabController>(controllers, cachedData.controllers);
				foreach (KeyValuePair<int, CachedData.TextureData> texture in cachedData.textures)
				{
					TextureVariants textureVariants = new TextureVariants(texture.Value);
					if (!textureVariants.Initialized())
					{
						textureVariants.Dispose();
					}
					else
					{
						textures.Add(texture.Key, textureVariants);
					}
				}
				Seasons.LogInfo($"Loaded from cache revision:{revision} controllers:{controllers.Count} textures:{textures.Count}");
				return Initialized();
			}
			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);
			foreach (KeyValuePair<int, TextureVariants> texVariants in textures)
			{
				CachedData.TextureData texData = new CachedData.TextureData(texVariants.Value);
				if (texData.Initialized())
				{
					cachedData.textures.Add(texVariants.Key, texData);
				}
			}
			DictionaryExt.Copy<string, PrefabController>(cachedData.controllers, controllers);
			Exception saveError = null;
			Thread internalThread = new Thread((ThreadStart)delegate
			{
				try
				{
					lock (s_diskLock)
					{
						if (Directory.Exists(cachedData.CacheDirectory()))
						{
							Directory.Delete(cachedData.CacheDirectory(), recursive: true);
						}
						cachedData.SaveOnDisk();
					}
				}
				catch (Exception ex)
				{
					saveError = ex;
				}
			})
			{
				IsBackground = true
			};
			internalThread.Start();
			while (internalThread.IsAlive)
			{
				yield return Seasons.waitForFixedUpdate;
			}
			if (saveError != null)
			{
				Seasons.LogWarning($"Unable to save seasonal texture cache:\n{saveError}");
			}
			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()
		{
			if (m_reloading || TextureCachingController.InProcess)
			{
				yield break;
			}
			m_reloading = true;
			ZoneSystem sourceZone = ZoneSystem.instance;
			try
			{
				CachedData cachedData = new CachedData(SeasonalTexturePrefabCache.GetRevision());
				Thread reader = new Thread((ThreadStart)delegate
				{
					lock (s_diskLock)
					{
						cachedData.LoadFromDisk();
					}
				})
				{
					IsBackground = true
				};
				reader.Start();
				while (reader.IsAlive)
				{
					yield return Seasons.waitForFixedUpdate;
				}
				if (!Object.op_Implicit((Object)(object)sourceZone) || (Object)(object)sourceZone != (Object)(object)ZoneSystem.instance)
				{
					yield break;
				}
				if (!cachedData.Initialized())
				{
					m_reloading = false;
					yield return RebuildCache();
					yield break;
				}
				Stopwatch stopwatch = Stopwatch.StartNew();
				List<TextureVariants> oldTextures = new List<TextureVariants>(textures.Values);
				Dictionary<int, TextureVariants> loadedTextures = new Dictionary<int, TextureVariants>();
				foreach (KeyValuePair<int, CachedData.TextureData> texData in cachedData.textures)
				{
					TextureVariants variants = new TextureVariants(texData.Value);
					if (variants.Initialized())
					{
						loadedTextures.Add(texData.Key, variants);
					}
					else
					{
						variants.Dispose();
					}
				}
				if (loadedTextures.Count == 0)
				{
					m_reloading = false;
					yield return RebuildCache();
					yield break;
				}
				PrefabVariantController.instance?.RevertPrefabsState();
				ClutterVariantController.Instance?.RevertColors();
				controllers.Clear();
				textures.Clear();
				revision = cachedData.revision;
				DictionaryExt.Copy<string, PrefabController>(controllers, cachedData.controllers);
				DictionaryExt.Copy<int, TextureVariants>(textures, loadedTextures);
				try
				{
					ClutterVariantController.Reinitialize();
					PrefabVariantController.ReinitializePrefabVariants();
				}
				finally
				{
					foreach (TextureVariants oldTexture in oldTextures)
					{
						oldTexture.Dispose();
					}
				}
				m_reloading = false;
				yield return Seasons.waitForFixedUpdate;
				PrefabVariantController.UpdatePrefabColors();
				ClutterVariantController.Instance?.UpdateColors();
				Seasons.LogInfo($"Loaded from cache revision:{revision} controllers:{controllers.Count} textures:{textures.Count} in {stopwatch.Elapsed.TotalSeconds,-4:F2} seconds");
			}
			finally
			{
				m_reloading = false;
				if (Object.op_Implicit((Object)(object)sourceZone) && (Object)(object)sourceZone == (Object)(object)ZoneSystem.instance)
				{
					SeasonalTexturePrefabCache.SetCurrentTextureVariants(this);
				}
			}
		}

		public IEnumerator RebuildCache()
		{
			if (m_reloading || TextureCachingController.InProcess)
			{
				yield break;
			}
			m_reloading = true;
			ZoneSystem sourceZone = ZoneSystem.instance;
			SeasonalTextureVariants newTexturesVariants = new SeasonalTextureVariants();
			try
			{
				SeasonalTexturePrefabCache.SetCurrentTextureVariants(newTexturesVariants);
				PrefabVariantController.instance?.RevertPrefabsState();
				ClutterVariantController.Instance?.RevertColors();
				yield return Seasons.waitForFixedUpdate;
				if (!Object.op_Implicit((Object)(object)sourceZone) || (Object)(object)sourceZone != (Object)(object)ZoneSystem.instance)
				{
					yield break;
				}
				yield return SeasonalTexturePrefabCache.FillWithGameData();
				if (!Object.op_Implicit((Object)(object)sourceZone) || (Object)(object)sourceZone != (Object)(object)ZoneSystem.instance || !newTexturesVariants.Initialized())
				{
					yield break;
				}
				Stopwatch stopwatch = Stopwatch.StartNew();
				List<TextureVariants> oldTextures = new List<TextureVariants>(textures.Values);
				controllers.Clear();
				textures.Clear();
				revision = newTexturesVariants.revision;
				DictionaryExt.Copy<string, PrefabController>(controllers, newTexturesVariants.controllers);
				DictionaryExt.Copy<int, TextureVariants>(textures, newTexturesVariants.textures);
				newTexturesVariants.controllers.Clear();
				newTexturesVariants.textures.Clear();
				SeasonalTexturePrefabCache.SetCurrentTextureVariants(this);
				try
				{
					ClutterVariantController.Reinitialize();
					PrefabVariantController.ReinitializePrefabVariants();
				}
				finally
				{
					foreach (TextureVariants oldTexture in oldTextures)
					{
						oldTexture.Dispose();
					}
				}
				yield return SaveCacheOnDisk();
				yield return Seasons.waitForFixedUpdate;
				if (Object.op_Implicit((Object)(object)sourceZone) && !((Object)(object)sourceZone != (Object)(object)ZoneSystem.instance))
				{
					m_reloading = false;
					PrefabVariantController.UpdatePrefabColors();
					ClutterVariantController.Instance?.UpdateColors();
					Seasons.LogInfo($"Colors reinitialized in {stopwatch.Elapsed.TotalSeconds,-4:F2} seconds");
					Seasons.LogInfo("Cache rebuild ended");
				}
			}
			finally
			{
				newTexturesVariants.Dispose();
				m_reloading = false;
				if (Object.op_Implicit((Object)(object)sourceZone) && (Object)(object)sourceZone == (Object)(object)ZoneSystem.instance)
				{
					SeasonalTexturePrefabCache.SetCurrentTextureVariants(this);
				}
			}
		}
	}
	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;
			if (properties == null)
			{
				return;
			}
			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)
		{
			if (texture is Texture2D)
			{
				original = (Texture2D)(object)((texture is Texture2D) ? texture : null);
				properties = new TextureProperties((Texture2D)(object)((texture is Texture2D) ? texture : null));
				originalName = ((Object)original).name;
			}
		}

		public void Dispose()
		{
			foreach (Dictionary<int, Texture2D> value in seasons.Values)
			{
				foreach (Texture2D value2 in value.Values)
				{
					if (Object.op_Implicit((Object)(object)value2))
					{
						Object.Destroy((Object)(object)value2);
					}
				}
			}
			seasons.Clear();
		}

		public bool Initialized()
		{
			Dictionary<int, Texture2D> variants;
			Texture2D value;
			return properties != null && Enum.GetValues(typeof(Seasons.Season)).Cast<Seasons.Season>().All((Seasons.Season season) => seasons.TryGetValue(season, out variants) && Enumerable.Range(0, 4).All((int variant) => variants.TryGetValue(variant, out value) && Object.op_Implicit((Object)(object)value)));
		}

		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