Decompiled source of LegacyFlavour v1.1.0

LegacyFlavour/LegacyFlavour.dll

Decompiled 9 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using Colossal.Localization;
using Colossal.Reflection;
using Colossal.Serialization.Entities;
using Colossal.UI;
using Colossal.UI.Binding;
using Game;
using Game.Audio;
using Game.Common;
using Game.Prefabs;
using Game.Rendering;
using Game.SceneFlow;
using Game.Simulation;
using Game.Tools;
using Game.UI;
using Game.UI.InGame;
using Game.UI.Localization;
using Game.UI.Tooltip;
using Game.UI.Widgets;
using Game.Zones;
using HarmonyLib;
using HookUILib.Core;
using LegacyFlavour.Configuration;
using LegacyFlavour.Helpers;
using LegacyFlavour.MonoBehaviours;
using LegacyFlavour.Systems;
using LegacyFlavour.UI;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Unity.Collections;
using Unity.Entities;
using Unity.Jobs;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("LegacyFlavour")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("0.1.1.0")]
[assembly: AssemblyInformationalVersion("0.1.1.0+bc692788065c963df02539603b556f897eb7282c")]
[assembly: AssemblyProduct("LegacyFlavour")]
[assembly: AssemblyTitle("LegacyFlavour")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace LegacyFlavour
{
	public enum ColourBlindness
	{
		None,
		Deuteranopia,
		Protanopia,
		Tritanopia,
		Custom
	}
	[BepInPlugin("LegacyFlavour", "LegacyFlavour", "0.1.1.0")]
	public class Plugin : BaseUnityPlugin
	{
		private void Awake()
		{
			Harmony val = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "LegacyFlavour_Cities2Harmony");
			MethodBase[] array = val.GetPatchedMethods().ToArray();
			((BaseUnityPlugin)this).Logger.LogInfo((object)(Environment.NewLine + "      :::        :::::::::: ::::::::      :::      ::::::::  :::   :::         \r\n      :+:        :+:       :+:    :+:   :+: :+:   :+:    :+: :+:   :+:         \r\n      +:+        +:+       +:+         +:+   +:+  +:+         +:+ +:+          \r\n      +#+        +#++:++#  :#:        +#++:++#++: +#+          +#++:           \r\n      +#+        +#+       +#+   +#+# +#+     +#+ +#+           +#+            \r\n      #+#        #+#       #+#    #+# #+#     #+# #+#    #+#    #+#            \r\n      ########## ########## ########  ###     ###  ########     ###            \r\n:::::::::: :::            :::     :::     :::  ::::::::  :::    ::: :::::::::  \r\n:+:        :+:          :+: :+:   :+:     :+: :+:    :+: :+:    :+: :+:    :+: \r\n+:+        +:+         +:+   +:+  +:+     +:+ +:+    +:+ +:+    +:+ +:+    +:+ \r\n:#::+::#   +#+        +#++:++#++: +#+     +:+ +#+    +:+ +#+    +:+ +#++:++#:  \r\n+#+        +#+        +#+     +#+  +#+   +#+  +#+    +#+ +#+    +#+ +#+    +#+ \r\n#+#        #+#        #+#     #+#   #+#+#+#   #+#    #+# #+#    #+# #+#    #+# \r\n###        ########## ###     ###     ###      ########   ########  ###    ### "));
			((BaseUnityPlugin)this).Logger.LogDebug((object)("Plugin LegacyFlavour is loaded! Patched methods: " + array.Length));
			MethodBase[] array2 = array;
			foreach (MethodBase methodBase in array2)
			{
				((BaseUnityPlugin)this).Logger.LogDebug((object)("Patched method: " + methodBase.Module.Name + ":" + methodBase.Name));
			}
		}
	}
	public class LegacyFlavourUI : UIExtension
	{
		public readonly ExtensionType extensionType = (ExtensionType)0;

		public readonly string extensionID = "cities2modding.legacyflavour";

		public readonly string extensionContent;

		public LegacyFlavourUI()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			extensionContent = ((UIExtension)this).LoadEmbeddedResource("LegacyFlavour.Resources.ui.js");
		}
	}
	public enum TimeOfDayOverride
	{
		Off,
		Night,
		Day,
		GoldenHour
	}
	public enum WeatherOverride
	{
		Off,
		Sun,
		Overcast,
		Rain,
		Snow
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "LegacyFlavour";

		public const string PLUGIN_NAME = "LegacyFlavour";

		public const string PLUGIN_VERSION = "0.1.1.0";
	}
}
namespace LegacyFlavour.UI
{
	public class ModelWriter : IJsonWritable
	{
		public static Dictionary<Type, PropertyInfo[]> _propertiesCache = new Dictionary<Type, PropertyInfo[]>();

		public void Write(IJsonWriter writer)
		{
			Type type = GetType();
			if (!_propertiesCache.TryGetValue(type, out var value))
			{
				value = type.GetProperties(BindingFlags.Instance | BindingFlags.Public);
				_propertiesCache[type] = value;
			}
			ParseType(writer, this, value);
		}

		private void ParseType(IJsonWriter writer, object instance, PropertyInfo[] properties)
		{
			writer.TypeBegin(instance.GetType().FullName);
			foreach (PropertyInfo propertyInfo in properties)
			{
				object value = propertyInfo.GetValue(instance);
				if (value == null)
				{
					writer.WriteNull();
				}
				else
				{
					WriteProperty(writer, propertyInfo, value);
				}
			}
			writer.TypeEnd();
		}

		private void WriteProperty(IJsonWriter writer, PropertyInfo property, object value)
		{
			writer.PropertyName(property.Name);
			WritePropertyValue(writer, value);
		}

		private void WritePropertyValue(IJsonWriter writer, object value)
		{
			Type type = value.GetType();
			if (!(value is string text))
			{
				if (!(value is float num))
				{
					if (!(value is double num2))
					{
						if (!(value is short num3))
						{
							if (!(value is uint num4))
							{
								if (!(value is int num5))
								{
									if (!(value is long num6))
									{
										if (!(value is bool flag))
										{
											if (!(value is decimal num7))
											{
												if (value is Enum @enum)
												{
													writer.Write(@enum.ToString());
												}
												else
												{
													WriteComplexType(writer, value, type);
												}
											}
											else
											{
												writer.Write((int)(num7 * 100m));
											}
										}
										else
										{
											writer.Write(flag);
										}
									}
									else
									{
										writer.Write((float)num6);
									}
								}
								else
								{
									writer.Write(num5);
								}
							}
							else
							{
								writer.Write(num4);
							}
						}
						else
						{
							writer.Write((int)num3);
						}
					}
					else
					{
						writer.Write(num2);
					}
				}
				else
				{
					writer.Write(num);
				}
			}
			else
			{
				writer.Write(text);
			}
		}

		private void WriteComplexType(IJsonWriter writer, object value, Type valueType)
		{
			if (ReflectionUtils.IsSubclassOfRawGeneric(valueType, typeof(List<>)))
			{
				HandleList(writer, value, valueType);
			}
			else if (valueType == typeof(Dictionary<string, string>))
			{
				HandleDictionary(writer, value);
			}
		}

		private void HandleList(IJsonWriter writer, object value, Type valueType)
		{
			if (!(value is IList list))
			{
				return;
			}
			int count = list.Count;
			JsonWriterExtensions.ArrayBegin(writer, count);
			foreach (object item in list)
			{
				object obj = item;
				object obj2 = obj;
				if (!(obj2 is string text))
				{
					if (!(obj2 is float num))
					{
						if (!(obj2 is double num2))
						{
							if (!(obj2 is short num3))
							{
								if (!(obj2 is uint num4))
								{
									if (!(obj2 is int num5))
									{
										if (!(obj2 is long num6))
										{
											if (!(obj2 is bool flag))
											{
												if (!(obj2 is decimal num7))
												{
													if (obj2 is Enum @enum)
													{
														writer.Write(@enum.ToString());
														continue;
													}
													Type type = valueType.GenericTypeArguments[0];
													PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public);
													ParseType(writer, item, properties);
												}
												else
												{
													writer.Write((int)(num7 * 100m));
												}
											}
											else
											{
												writer.Write(flag);
											}
										}
										else
										{
											writer.Write((float)num6);
										}
									}
									else
									{
										writer.Write(num5);
									}
								}
								else
								{
									writer.Write(num4);
								}
							}
							else
							{
								writer.Write((int)num3);
							}
						}
						else
						{
							writer.Write(num2);
						}
					}
					else
					{
						writer.Write(num);
					}
				}
				else
				{
					writer.Write(text);
				}
			}
			writer.ArrayEnd();
		}

		private void HandleDictionary(IJsonWriter writer, object value)
		{
			if (!(value is IDictionary<string, string> dictionary))
			{
				return;
			}
			int count = dictionary.Count;
			if (count == 0)
			{
				JsonWriterExtensions.WriteEmptyMap(writer);
				return;
			}
			JsonWriterExtensions.MapBegin(writer, count);
			foreach (KeyValuePair<string, string> item in dictionary)
			{
				writer.Write(item.Key);
				writer.Write(item.Value);
			}
			writer.MapEnd();
		}
	}
}
namespace LegacyFlavour.Systems
{
	public class LegacyFlavourSystem : GameSystemBase
	{
		private static string AssemblyPath = Path.GetDirectoryName(typeof(LegacyFlavourSystem).Assembly.Location);

		public static string UIPath = AssemblyPath + "\\UI\\";

		private static bool hasSetupUIFolder = false;

		private bool isInitialised;

		private LegacyFlavourUpdateSystem _updateSystem;

		private PlanetarySystem _planetarySystem;

		private ClimateSystem _climateSystem;

		private LightingSystem _lightingSystem;

		private ToolSystem _toolSystem;

		private float targetVisualTime;

		private bool seekGoldenHour;

		private LegacyFlavourConfig Config => _updateSystem.Config;

		public static void EnsureModUIFolder()
		{
			if (!hasSetupUIFolder)
			{
				UISystem uiSystem = GameManager.instance.userInterface.view.uiSystem;
				if (uiSystem == null)
				{
					Debug.LogError((object)"Failed to setup resource handler for LegacyFlavour.");
					return;
				}
				Debug.Log((object)"Setup resource handler for LegacyFlavour.");
				uiSystem.AddHostLocation("legacyflavourui", UIPath, false);
				hasSetupUIFolder = true;
			}
		}

		protected override void OnCreate()
		{
			((GameSystemBase)this).OnCreate();
			_updateSystem = ((ComponentSystemBase)this).World.GetExistingSystemManaged<LegacyFlavourUpdateSystem>();
			SetupKeybinds();
		}

		protected override void OnGameLoadingComplete(Purpose purpose, GameMode mode)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			((GameSystemBase)this).OnGameLoadingComplete(purpose, mode);
			if (GameModeExtensions.IsGameOrEditor(mode))
			{
				if (_lightingSystem == null)
				{
					_lightingSystem = ((ComponentSystemBase)this).World.GetExistingSystemManaged<LightingSystem>();
					_toolSystem = ((ComponentSystemBase)this).World.GetExistingSystemManaged<ToolSystem>();
					_climateSystem = ((ComponentSystemBase)this).World.GetExistingSystemManaged<ClimateSystem>();
					_planetarySystem = ((ComponentSystemBase)this).World.GetExistingSystemManaged<PlanetarySystem>();
				}
				UpdateTimeOfDay();
				UpdateWeather();
				isInitialised = true;
			}
		}

		public void TriggerUpdate(string property)
		{
			switch (property)
			{
			case "UseStickyWhiteness":
				if (Config.UseStickyWhiteness)
				{
					InfoviewPrefab activeInfoview2 = _toolSystem.activeInfoview;
					Shader.SetGlobalInt("colossal_InfoviewOn", (activeInfoview2 != null && ((ComponentBase)activeInfoview2).active && Config.WhitenessToggle) ? 1 : 0);
				}
				break;
			case "WhitenessToggle":
				if (Config.UseStickyWhiteness)
				{
					InfoviewPrefab activeInfoview = _toolSystem.activeInfoview;
					Shader.SetGlobalInt("colossal_InfoviewOn", (activeInfoview != null && ((ComponentBase)activeInfoview).active && Config.WhitenessToggle) ? 1 : 0);
				}
				break;
			case "FreezeVisualTime":
			case "TimeOfDay":
				UpdateTimeOfDay();
				break;
			case "Weather":
				UpdateWeather();
				break;
			}
		}

		private void UpdateTimeOfDay()
		{
			if (Config.FreezeVisualTime && Config.TimeOfDay == TimeOfDayOverride.Off)
			{
				_planetarySystem.overrideTime = true;
				return;
			}
			switch (Config.TimeOfDay)
			{
			default:
				if (!Config.FreezeVisualTime)
				{
					_planetarySystem.overrideTime = false;
				}
				targetVisualTime = 0f;
				break;
			case TimeOfDayOverride.Night:
				_planetarySystem.overrideTime = true;
				targetVisualTime = 0f;
				break;
			case TimeOfDayOverride.GoldenHour:
				_planetarySystem.overrideTime = true;
				_planetarySystem.time = 0f;
				targetVisualTime = 24f;
				seekGoldenHour = true;
				break;
			case TimeOfDayOverride.Day:
				_planetarySystem.overrideTime = true;
				targetVisualTime = 12f;
				break;
			}
		}

		private bool IsSunriseOrSunset()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Invalid comparison between Unknown and I4
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Invalid comparison between Unknown and I4
			return (int)_lightingSystem.state == 3 || (int)_lightingSystem.state == 1;
		}

		private void UpdateWeather()
		{
			switch (Config.Weather)
			{
			case WeatherOverride.Off:
				_climateSystem.temperature.overrideState = false;
				_climateSystem.precipitation.overrideState = false;
				_climateSystem.cloudiness.overrideState = false;
				break;
			case WeatherOverride.Sun:
				_climateSystem.temperature.overrideState = true;
				_climateSystem.temperature.overrideValue = 28f;
				_climateSystem.precipitation.overrideState = true;
				_climateSystem.precipitation.overrideValue = 0f;
				_climateSystem.cloudiness.overrideState = true;
				_climateSystem.cloudiness.overrideValue = 0f;
				break;
			case WeatherOverride.Overcast:
				_climateSystem.temperature.overrideState = true;
				_climateSystem.temperature.overrideValue = 15f;
				_climateSystem.precipitation.overrideState = true;
				_climateSystem.precipitation.overrideValue = 0f;
				_climateSystem.cloudiness.overrideState = true;
				_climateSystem.cloudiness.overrideValue = 0.8f;
				break;
			case WeatherOverride.Rain:
				_climateSystem.temperature.overrideState = true;
				_climateSystem.temperature.overrideValue = 15f;
				_climateSystem.precipitation.overrideState = true;
				_climateSystem.precipitation.overrideValue = 1f;
				_climateSystem.cloudiness.overrideState = true;
				_climateSystem.cloudiness.overrideValue = 0.8f;
				break;
			case WeatherOverride.Snow:
				_climateSystem.temperature.overrideState = true;
				_climateSystem.temperature.overrideValue = -3f;
				_climateSystem.precipitation.overrideState = true;
				_climateSystem.precipitation.overrideValue = 1f;
				_climateSystem.cloudiness.overrideState = true;
				_climateSystem.cloudiness.overrideValue = 0.8f;
				break;
			}
		}

		private void SetupKeybinds()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Expected O, but got Unknown
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: 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_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: 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_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			InputAction val = new InputAction("LegacyFlavour_ToggleUnits", (InputActionType)0, (string)null, (string)null, (string)null, (string)null);
			CompositeSyntax val2 = InputActionSetupExtensions.AddCompositeBinding(val, "ButtonWithOneModifier", (string)null, (string)null);
			val2 = ((CompositeSyntax)(ref val2)).With("Modifier", "<Keyboard>/alt", (string)null, (string)null);
			((CompositeSyntax)(ref val2)).With("Button", "<Keyboard>/u", (string)null, (string)null);
			val.performed += delegate
			{
				Config.UseUnits = !Config.UseUnits;
				_updateSystem.EnqueueConfigUpdate(immediate: true);
			};
			val.Enable();
			val = new InputAction("LegacyFlavour_StickyWhiteness", (InputActionType)0, (string)null, (string)null, (string)null, (string)null);
			val2 = InputActionSetupExtensions.AddCompositeBinding(val, "ButtonWithOneModifier", (string)null, (string)null);
			val2 = ((CompositeSyntax)(ref val2)).With("Modifier", "<Keyboard>/alt", (string)null, (string)null);
			((CompositeSyntax)(ref val2)).With("Button", "<Keyboard>/s", (string)null, (string)null);
			val.performed += delegate
			{
				Config.UseStickyWhiteness = !Config.UseStickyWhiteness;
				_updateSystem.EnqueueConfigUpdate(immediate: true);
				TriggerUpdate("UseStickyWhiteness");
			};
			val.Enable();
			val = new InputAction("LegacyFlavour_WhitenessToggle", (InputActionType)0, (string)null, (string)null, (string)null, (string)null);
			val2 = InputActionSetupExtensions.AddCompositeBinding(val, "ButtonWithOneModifier", (string)null, (string)null);
			val2 = ((CompositeSyntax)(ref val2)).With("Modifier", "<Keyboard>/shift", (string)null, (string)null);
			((CompositeSyntax)(ref val2)).With("Button", "<Keyboard>/w", (string)null, (string)null);
			val.performed += delegate
			{
				if (Config.UseStickyWhiteness)
				{
					Config.WhitenessToggle = !Config.WhitenessToggle;
					_updateSystem.EnqueueConfigUpdate(immediate: true);
					TriggerUpdate("WhitenessToggle");
				}
			};
			val.Enable();
			val = new InputAction("LegacyFlavour_Reload", (InputActionType)0, (string)null, (string)null, (string)null, (string)null);
			val2 = InputActionSetupExtensions.AddCompositeBinding(val, "ButtonWithOneModifier", (string)null, (string)null);
			val2 = ((CompositeSyntax)(ref val2)).With("Modifier", "<Keyboard>/alt", (string)null, (string)null);
			((CompositeSyntax)(ref val2)).With("Button", "<Keyboard>/r", (string)null, (string)null);
			val.performed += delegate
			{
				Debug.Log((object)"LegacyFlavour Config file reloaded!");
				_updateSystem.Reload();
				_updateSystem.EnqueueColoursUpdate(immediate: false, invalidateCache: true);
			};
			val.Enable();
		}

		protected override void OnUpdate()
		{
			if (isInitialised && Config.FreezeVisualTime && _planetarySystem != null)
			{
				if (seekGoldenHour && (Config.TimeOfDay != TimeOfDayOverride.GoldenHour || IsSunriseOrSunset()))
				{
					seekGoldenHour = false;
					targetVisualTime = _planetarySystem.time;
				}
				_planetarySystem.time = Mathf.Lerp(_planetarySystem.time, targetVisualTime, 1.5f * Time.deltaTime);
			}
		}
	}
	public class LegacyFlavourUISystem : UISystemBase
	{
		private string kGroup = "cities2modding_legacyflavour";

		private static GetterValueBinding<LegacyFlavourConfig> _binding;

		private static GetterValueBinding<LocaleGroup> _currentLocaleBinding;

		private static FieldInfo _dirtyField = typeof(GetterValueBinding<LegacyFlavourConfig>).GetField("m_ValueDirty", BindingFlags.Instance | BindingFlags.NonPublic);

		private static readonly string[] TRIGGER_UPDATE_PROPERTIES = new string[5] { "UseStickyWhiteness", "WhitenessToggle", "TimeOfDay", "Weather", "FreezeVisualTime" };

		private static readonly string[] TRIGGER_COLOUR_UPDATE_PROPERTIES = new string[8] { "Enabled", "CellOpacity", "CellBorderOpacity", "EmptyCellOpacity", "EmptyCellBorderOpacity", "Mode", "UseDynamicCellBorders", "OverrideIcons" };

		private LegacyFlavourUpdateSystem _updateSystem;

		private LegacyFlavourSystem _legacyFlavourSystem;

		private ZoneColourSystem _zoneColourSystem;

		private EntityQuery _soundQuery;

		private LegacyFlavourConfig Config => _updateSystem.Config;

		protected override void OnCreate()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Expected O, but got Unknown
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Expected O, but got Unknown
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Expected O, but got Unknown
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Expected O, but got Unknown
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Expected O, but got Unknown
			((UISystemBase)this).OnCreate();
			_legacyFlavourSystem = ((ComponentSystemBase)this).World.GetOrCreateSystemManaged<LegacyFlavourSystem>();
			_zoneColourSystem = ((ComponentSystemBase)this).World.GetOrCreateSystemManaged<ZoneColourSystem>();
			_soundQuery = ((ComponentSystemBase)this).GetEntityQuery((ComponentType[])(object)new ComponentType[1] { ComponentType.ReadOnly<ToolUXSoundSettingsData>() });
			_updateSystem = ((ComponentSystemBase)this).World.GetExistingSystemManaged<LegacyFlavourUpdateSystem>();
			_binding = new GetterValueBinding<LegacyFlavourConfig>(kGroup, "config", (Func<LegacyFlavourConfig>)(() => Config), (IWriter<LegacyFlavourConfig>)(object)ValueWriters.Nullable<LegacyFlavourConfig>((IWriter<LegacyFlavourConfig>)(object)new ValueWriter<LegacyFlavourConfig>()), (EqualityComparer<LegacyFlavourConfig>)null);
			_currentLocaleBinding = new GetterValueBinding<LocaleGroup>(kGroup, "currentLocale", (Func<LocaleGroup>)delegate
			{
				LocalizationManager localeManager = GameManager.instance.localizationManager;
				if (localeManager == null)
				{
					return LocaleConfig.Default.Locales[0];
				}
				LocaleGroup localeGroup = LocaleConfig.Default.Locales.FirstOrDefault((LocaleGroup l) => l.IDs.Contains(localeManager.activeLocaleId));
				return (localeGroup == null) ? LocaleConfig.Default.Locales[0] : localeGroup;
			}, (IWriter<LocaleGroup>)null, (EqualityComparer<LocaleGroup>)null);
			ConfigBase.OnUpdated = (Action)Delegate.Combine(ConfigBase.OnUpdated, (Action)delegate
			{
				_dirtyField.SetValue(_binding, true);
			});
			((UISystemBase)this).AddUpdateBinding((IUpdateBinding)(object)_binding);
			((UISystemBase)this).AddUpdateBinding((IUpdateBinding)(object)_currentLocaleBinding);
			((UISystemBase)this).AddBinding((IBinding)(object)new TriggerBinding<string>(kGroup, "updateProperty", (Action<string>)UpdateProperty, (IReader<string>)null));
			((UISystemBase)this).AddBinding((IBinding)new TriggerBinding(kGroup, "regenerateIcons", (Action)delegate
			{
				_updateSystem.EnqueueColoursUpdate(immediate: false, invalidateCache: true);
			}));
			((UISystemBase)this).AddBinding((IBinding)new TriggerBinding(kGroup, "setColoursToVanilla", (Action)_zoneColourSystem.SetCurrentToVanilla));
			((UISystemBase)this).AddBinding((IBinding)new TriggerBinding(kGroup, "triggerSound", (Action)TriggerUISound));
			((UISystemBase)this).AddBinding((IBinding)new TriggerBinding(kGroup, "resetZoneSettingsToDefault", (Action)_zoneColourSystem.ResetSettingsToDefault));
			((UISystemBase)this).AddBinding((IBinding)(object)new TriggerBinding<string>(kGroup, "setZoneSettingsPreset", (Action<string>)_zoneColourSystem.SetToPreset, (IReader<string>)null));
			((UISystemBase)this).AddBinding((IBinding)new TriggerBinding(kGroup, "resetColoursToDefault", (Action)_zoneColourSystem.ResetColoursToDefault));
			((UISystemBase)this).AddBinding((IBinding)(object)new TriggerBinding<string>(kGroup, "launchUrl", (Action<string>)OpenURL, (IReader<string>)null));
			((UISystemBase)this).AddBinding((IBinding)(object)new TriggerBinding<string, string>(kGroup, "updateZoneColour", (Action<string, string>)_zoneColourSystem.UpdateZoneColour, (IReader<string>)null, (IReader<string>)null));
		}

		private void OpenURL(string url)
		{
			if (string.IsNullOrEmpty(url))
			{
				return;
			}
			try
			{
				Process.Start(url);
			}
			catch (Exception ex)
			{
				Console.WriteLine("An error occurred: " + ex.Message);
			}
		}

		private void TriggerUISound()
		{
			//IL_000c: 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)
			AudioManager.instance.PlayUISoundIfNotPlaying(((EntityQuery)(ref _soundQuery)).GetSingleton<ToolUXSoundSettingsData>().m_SnapSound, 1f);
		}

		private void UpdateProperty(string json)
		{
			if (string.IsNullOrEmpty(json))
			{
				return;
			}
			PropertyInfo[] array = ModelWriter._propertiesCache[typeof(LegacyFlavourConfig)];
			if (array == null)
			{
				return;
			}
			Dictionary<string, object> dictionary = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
			if (dictionary == null || !dictionary.TryGetValue("property", out var propertyName))
			{
				return;
			}
			PropertyInfo propertyInfo = array.FirstOrDefault((PropertyInfo p) => p.Name == (string)propertyName);
			if (propertyInfo == null || !dictionary.TryGetValue("value", out var value))
			{
				return;
			}
			if (value.GetType() != propertyInfo.PropertyType)
			{
				if (TryConvertValue(propertyInfo.PropertyType, value, out var result))
				{
					propertyInfo.SetValue(Config, result);
				}
			}
			else
			{
				propertyInfo.SetValue(Config, value);
			}
			_updateSystem.EnqueueConfigUpdate();
			if (TRIGGER_UPDATE_PROPERTIES.Contains(propertyInfo.Name))
			{
				_legacyFlavourSystem.TriggerUpdate(propertyInfo.Name);
			}
			else if (TRIGGER_COLOUR_UPDATE_PROPERTIES.Contains(propertyInfo.Name))
			{
				_zoneColourSystem.TriggerUpdate(propertyInfo.Name);
			}
		}

		private bool TryConvertValue(Type propertyType, object val, out object result)
		{
			result = null;
			object result3;
			if (propertyType == typeof(decimal))
			{
				if (val is string s && int.TryParse(s, out var result2))
				{
					result = (decimal)result2 / 100m;
					return true;
				}
				if (val is long num)
				{
					result = (decimal)num / 100m;
					return true;
				}
				if (val is int num2)
				{
					result = (decimal)num2 / 100m;
					return true;
				}
			}
			else if (propertyType.IsEnum && val is string value && Enum.TryParse(propertyType, value, out result3))
			{
				result = result3;
				return true;
			}
			return false;
		}
	}
	public class LegacyFlavourUpdateSystem : GameSystemBase
	{
		private bool hasConfigUpdatePending;

		private float nextConfigUpdate;

		private bool hasZoneColourUpdatePending;

		private bool forceZoneInvalidateCache;

		private float nextZoneColourUpdate;

		private static LegacyFlavourConfig _config = ConfigBase.Load<LegacyFlavourConfig>();

		private ZoneColourSystem _zoneColourSystem;

		public LegacyFlavourConfig Config => _config;

		protected override void OnCreate()
		{
			((GameSystemBase)this).OnCreate();
			_zoneColourSystem = ((ComponentSystemBase)this).World.GetOrCreateSystemManaged<ZoneColourSystem>();
		}

		protected override void OnUpdate()
		{
			if (hasConfigUpdatePending && Time.time >= nextConfigUpdate)
			{
				hasConfigUpdatePending = false;
				try
				{
					_config.Save();
				}
				catch (Exception ex)
				{
					Debug.LogError((object)("Error writing config files!\n" + ex));
				}
			}
			if (hasZoneColourUpdatePending && Time.time >= nextZoneColourUpdate)
			{
				hasZoneColourUpdatePending = false;
				_zoneColourSystem.ForceUpdate(forceZoneInvalidateCache);
			}
		}

		public void EnqueueConfigUpdate(bool immediate = false)
		{
			nextConfigUpdate = (immediate ? 0f : (Time.time + 5f));
			hasConfigUpdatePending = true;
		}

		public void EnqueueColoursUpdate(bool immediate = false, bool invalidateCache = false)
		{
			nextZoneColourUpdate = (immediate ? 0f : (Time.time + 0.2f));
			hasZoneColourUpdatePending = true;
			if (invalidateCache)
			{
				forceZoneInvalidateCache = true;
			}
		}

		public void Reload()
		{
			_config = ConfigBase.Load<LegacyFlavourConfig>();
		}
	}
	public class ZoneColourSystem : GameSystemBase
	{
		private static FieldInfo m_FillColorArray = typeof(ZoneSystem).GetFields(BindingFlags.Instance | BindingFlags.NonPublic).FirstOrDefault((FieldInfo m) => m.Name == "m_FillColorArray");

		private static FieldInfo m_EdgeColorArray = typeof(ZoneSystem).GetFields(BindingFlags.Instance | BindingFlags.NonPublic).FirstOrDefault((FieldInfo m) => m.Name == "m_EdgeColorArray");

		private static MethodInfo _updateAllZoneColors = typeof(ZoneSystem).GetMethods(BindingFlags.Instance | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name == "UpdateZoneColors" && m.GetParameters().Length == 0);

		private static Dictionary<string, string> _vanillaColours = new Dictionary<string, string>();

		public bool enabled = true;

		public ColourBlindness colourBlindness;

		private bool hasSnow;

		private LegacyFlavourUpdateSystem _updateSystem;

		private ZoneSystem _zoneSystem;

		private SnowDetector _snowDetector;

		private DynamicZoneIcons _dynamicZoneIcons;

		public (ColourBlindness, Dictionary<string, Color>)[] AllColours => new(ColourBlindness, Dictionary<string, Color>)[5]
		{
			(ColourBlindness.None, GetColourSet(ColourBlindness.None)),
			(ColourBlindness.Deuteranopia, GetColourSet(ColourBlindness.Deuteranopia)),
			(ColourBlindness.Protanopia, GetColourSet(ColourBlindness.Protanopia)),
			(ColourBlindness.Tritanopia, GetColourSet(ColourBlindness.Tritanopia)),
			(ColourBlindness.Custom, GetColourSet(ColourBlindness.Custom))
		};

		public Dictionary<string, Color> Colours => GetColourSet(colourBlindness);

		public DynamicZoneIcons DynamicZoneIcons => _dynamicZoneIcons;

		private LegacyFlavourConfig Config => _updateSystem.Config;

		protected override void OnCreate()
		{
			((GameSystemBase)this).OnCreate();
			_updateSystem = ((ComponentSystemBase)this).World.GetOrCreateSystemManaged<LegacyFlavourUpdateSystem>();
			_dynamicZoneIcons = new DynamicZoneIcons();
			_zoneSystem = ((ComponentSystemBase)this).World.GetExistingSystemManaged<ZoneSystem>();
			SetupSnowDetector();
			Configure();
			SetupKeybinds();
			_updateSystem.EnqueueColoursUpdate(immediate: false, invalidateCache: true);
		}

		protected override void OnUpdate()
		{
		}

		private void Configure()
		{
			colourBlindness = Config.Mode;
			enabled = Config.Enabled;
			_snowDetector.Disable = !enabled;
			colourBlindness = Config.Mode;
		}

		private Dictionary<string, Color> GetColourSet(ColourBlindness mode)
		{
			return mode switch
			{
				ColourBlindness.Deuteranopia => Config.Zones.ToDictionary((ZoneColourConfig k) => k.Name, (ZoneColourConfig v) => ColourHelpers.HexToColor((v.Deuteranopia == "default") ? v.Colour : v.Deuteranopia)), 
				ColourBlindness.Protanopia => Config.Zones.ToDictionary((ZoneColourConfig k) => k.Name, (ZoneColourConfig v) => ColourHelpers.HexToColor((v.Protanopia == "default") ? v.Colour : v.Protanopia)), 
				ColourBlindness.Tritanopia => Config.Zones.ToDictionary((ZoneColourConfig k) => k.Name, (ZoneColourConfig v) => ColourHelpers.HexToColor((v.Tritanopia == "default") ? v.Colour : v.Tritanopia)), 
				ColourBlindness.Custom => Config.Zones.ToDictionary((ZoneColourConfig k) => k.Name, (ZoneColourConfig v) => ColourHelpers.HexToColor((v.Custom == "default") ? v.Colour : v.Custom)), 
				_ => Config.Zones.ToDictionary((ZoneColourConfig k) => k.Name, (ZoneColourConfig v) => ColourHelpers.HexToColor(v.Colour)), 
			};
		}

		public void TriggerUpdate(string property)
		{
			switch (property)
			{
			case "Enabled":
				UpdateEnabledStatus();
				break;
			case "Mode":
				colourBlindness = Config.Mode;
				_updateSystem.EnqueueColoursUpdate();
				break;
			case "OverrideIcons":
			case "CellOpacity":
			case "EmptyCellOpacity":
			case "CellBorderOpacity":
			case "EmptyCellBorderOpacity":
				_updateSystem.EnqueueColoursUpdate();
				break;
			case "UseDynamicCellBorders":
				_snowDetector.Disable = !Config.UseDynamicCellBorders;
				break;
			}
		}

		private void UpdateEnabledStatus(bool invalidateIcons = false)
		{
			enabled = Config.Enabled;
			_snowDetector.Disable = !enabled;
			_updateSystem.EnqueueColoursUpdate(immediate: false, invalidateIcons);
		}

		private void SetupKeybinds()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			InputAction val = new InputAction("LegacyFlavour_ColourToggle", (InputActionType)0, (string)null, (string)null, (string)null, (string)null);
			CompositeSyntax val2 = InputActionSetupExtensions.AddCompositeBinding(val, "ButtonWithOneModifier", (string)null, (string)null);
			val2 = ((CompositeSyntax)(ref val2)).With("Modifier", "<Keyboard>/alt", (string)null, (string)null);
			((CompositeSyntax)(ref val2)).With("Button", "<Keyboard>/z", (string)null, (string)null);
			val.performed += delegate
			{
				enabled = !enabled;
				Config.Enabled = enabled;
				_snowDetector.Disable = !enabled;
				_updateSystem.EnqueueConfigUpdate();
				_updateSystem.EnqueueColoursUpdate();
			};
			val.Enable();
			val = new InputAction("LegacyFlavour_Cycle", (InputActionType)0, (string)null, (string)null, (string)null, (string)null);
			val2 = InputActionSetupExtensions.AddCompositeBinding(val, "ButtonWithOneModifier", (string)null, (string)null);
			val2 = ((CompositeSyntax)(ref val2)).With("Modifier", "<Keyboard>/shift", (string)null, (string)null);
			((CompositeSyntax)(ref val2)).With("Button", "<Keyboard>/z", (string)null, (string)null);
			val.performed += delegate
			{
				int num = (int)(colourBlindness + 1);
				if (num >= Enum.GetValues(typeof(ColourBlindness)).Length)
				{
					num = 0;
				}
				colourBlindness = (ColourBlindness)num;
				Config.Mode = colourBlindness;
				_updateSystem.EnqueueConfigUpdate();
				_updateSystem.EnqueueColoursUpdate();
			};
			val.Enable();
		}

		private void SetupSnowDetector()
		{
			_snowDetector = SnowDetector.Create();
			SnowDetector snowDetector = _snowDetector;
			snowDetector.OnUpdate = (Action<float>)Delegate.Combine(snowDetector.OnUpdate, (Action<float>)delegate(float coverage)
			{
				if (coverage >= 20f)
				{
					hasSnow = true;
				}
				else
				{
					hasSnow = false;
				}
				_updateSystem.EnqueueColoursUpdate();
			});
		}

		public void ForceUpdate(bool invalidateCache = false)
		{
			_dynamicZoneIcons?.ModifyBasedOnColours(invalidateCache);
			_updateAllZoneColors.Invoke(_zoneSystem, null);
		}

		public void SetCurrentToVanilla()
		{
			foreach (ZoneColourConfig zone in Config.Zones)
			{
				if (_vanillaColours.ContainsKey(zone.Name))
				{
					string text = _vanillaColours[zone.Name];
					switch (Config.Mode)
					{
					case ColourBlindness.Deuteranopia:
						zone.Deuteranopia = text;
						break;
					case ColourBlindness.Protanopia:
						zone.Protanopia = text;
						break;
					case ColourBlindness.Tritanopia:
						zone.Tritanopia = text;
						break;
					case ColourBlindness.Custom:
						zone.Custom = text;
						break;
					case ColourBlindness.None:
						zone.Colour = text;
						break;
					}
				}
			}
			_updateSystem.EnqueueConfigUpdate();
			_updateSystem.EnqueueColoursUpdate(immediate: false, invalidateCache: true);
		}

		public void ResetSettingsToDefault()
		{
			LegacyFlavourConfig @default = LegacyFlavourConfig.Default;
			Config.Enabled = @default.Enabled;
			Config.UseDynamicCellBorders = @default.UseDynamicCellBorders;
			Config.CellOpacity = @default.CellOpacity;
			Config.CellBorderOpacity = @default.CellBorderOpacity;
			Config.EmptyCellOpacity = @default.EmptyCellOpacity;
			Config.EmptyCellBorderOpacity = @default.EmptyCellBorderOpacity;
			_updateSystem.EnqueueConfigUpdate();
			_updateSystem.EnqueueColoursUpdate();
		}

		public void SetToPreset(string name)
		{
			LegacyFlavourConfig @default = LegacyFlavourConfig.Default;
			Config.Enabled = true;
			Config.UseDynamicCellBorders = true;
			if (!string.IsNullOrEmpty(name) && name == "CityPlannerSpecial")
			{
				Config.CellOpacity = 0.1m;
				Config.CellBorderOpacity = 0.95m;
				Config.EmptyCellOpacity = 0m;
				Config.EmptyCellBorderOpacity = 0.5m;
			}
			else
			{
				Config.CellOpacity = @default.CellOpacity;
				Config.CellBorderOpacity = @default.CellBorderOpacity;
				Config.EmptyCellOpacity = @default.EmptyCellOpacity;
				Config.EmptyCellBorderOpacity = @default.EmptyCellBorderOpacity;
			}
			_updateSystem.EnqueueConfigUpdate();
			_updateSystem.EnqueueColoursUpdate();
		}

		public void ResetColoursToDefault()
		{
			foreach (ZoneColourConfig zone in Config.Zones)
			{
				ZoneColourConfig zoneColourConfig = LegacyFlavourConfig.Default.Zones.FirstOrDefault((ZoneColourConfig z) => z.Name == zone.Name);
				if (zoneColourConfig != null)
				{
					zone.Deuteranopia = zoneColourConfig.Deuteranopia;
					zone.Protanopia = zoneColourConfig.Protanopia;
					zone.Tritanopia = zoneColourConfig.Tritanopia;
					zone.Custom = zoneColourConfig.Custom;
					zone.Colour = zoneColourConfig.Colour;
				}
			}
			_updateSystem.EnqueueConfigUpdate();
			_updateSystem.EnqueueColoursUpdate(immediate: false, invalidateCache: true);
		}

		public void UpdateZoneColour(string name, string colour)
		{
			ZoneColourConfig zoneColourConfig = Config.Zones.FirstOrDefault((ZoneColourConfig z) => z.Name == name);
			if (zoneColourConfig != null)
			{
				switch (Config.Mode)
				{
				case ColourBlindness.Deuteranopia:
					zoneColourConfig.Deuteranopia = colour;
					break;
				case ColourBlindness.Protanopia:
					zoneColourConfig.Protanopia = colour;
					break;
				case ColourBlindness.Tritanopia:
					zoneColourConfig.Tritanopia = colour;
					break;
				case ColourBlindness.Custom:
					zoneColourConfig.Custom = colour;
					break;
				case ColourBlindness.None:
					zoneColourConfig.Colour = colour;
					break;
				}
				_updateSystem.EnqueueConfigUpdate();
				_updateSystem.EnqueueColoursUpdate(immediate: false, invalidateCache: true);
			}
		}

		public bool UpdateZones(ZonePrefab zonePrefab, ZoneData zoneData)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: 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_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Invalid comparison between Unknown and I4
			//IL_00d1: 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_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			if (enabled)
			{
				Color color = zonePrefab.m_Color;
				int colorIndex = ZoneUtils.GetColorIndex((CellFlags)8, zoneData.m_ZoneType);
				int colorIndex2 = ZoneUtils.GetColorIndex((CellFlags)40, zoneData.m_ZoneType);
				int colorIndex3 = ZoneUtils.GetColorIndex((CellFlags)72, zoneData.m_ZoneType);
				string text = ((Object)zonePrefab).name;
				if (text.StartsWith("EU ") || text.StartsWith("NA "))
				{
					string text2 = text;
					text = text2.Substring(3, text2.Length - 3);
				}
				if (!_vanillaColours.ContainsKey(text))
				{
					_vanillaColours[text] = ColourHelpers.ColorToHex(color);
				}
				Color originalColor = color;
				Dictionary<string, Color> colours = Colours;
				if (colours.ContainsKey(text))
				{
					originalColor = colours[text];
				}
				Color val = ColourHelpers.Darken(originalColor, 0.23f);
				bool flag = (int)zonePrefab.m_AreaType == 0;
				Vector4[] array = (Vector4[])m_FillColorArray.GetValue(_zoneSystem);
				Vector4[] array2 = (Vector4[])m_EdgeColorArray.GetValue(_zoneSystem);
				Color val2 = default(Color);
				((Color)(ref val2))..ctor(0f, 0f, 0f, (float)Config.EmptyCellOpacity);
				if (flag && hasSnow)
				{
					((Color)(ref val))..ctor(0f, 0f, 0f, 0.75f);
				}
				float num = (float)Config.CellOpacity;
				float opacity = Mathf.Clamp01(num - 0.1f);
				float opacity2 = (float)Config.CellBorderOpacity;
				float opacity3 = (float)Config.EmptyCellBorderOpacity;
				array[colorIndex] = Color.op_Implicit(flag ? val2 : ColourHelpers.SetAlpha(originalColor, opacity));
				array2[colorIndex] = Color.op_Implicit((!flag) ? ColourHelpers.SetAlpha(val, opacity2) : (hasSnow ? val : ColourHelpers.SetAlpha(val, opacity3)));
				array[colorIndex2] = Color.op_Implicit(flag ? val2 : ColourHelpers.SetAlpha(originalColor, opacity));
				array2[colorIndex2] = Color.op_Implicit(flag ? ColourHelpers.SetAlpha(val, opacity3) : ColourHelpers.SetAlpha(val, opacity2));
				array[colorIndex3] = Color.op_Implicit(flag ? val2 : ColourHelpers.SetAlpha(originalColor, num));
				array2[colorIndex3] = Color.op_Implicit(flag ? ColourHelpers.SetAlpha(val, opacity3) : val);
				return false;
			}
			return true;
		}
	}
}
namespace LegacyFlavour.Patches
{
	[HarmonyPatch(typeof(GuideLineTooltipSystem), "OnUpdate")]
	internal class GuideLineTooltipSystem_OnUpdatePatch
	{
		private static LegacyFlavourUpdateSystem _updateSystem;

		private static bool Prefix(GuideLineTooltipSystem __instance)
		{
			//IL_0063: 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_007e: 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_00f6: 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_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//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_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Expected O, but got Unknown
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Expected O, but got Unknown
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: 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_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Invalid comparison between Unknown and I4
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			if (_updateSystem == null)
			{
				_updateSystem = World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged<LegacyFlavourUpdateSystem>();
			}
			TooltipUISystem value = Traverse.Create((object)__instance).Field("m_TooltipUISystem").GetValue<TooltipUISystem>();
			List<TooltipGroup> value2 = Traverse.Create((object)__instance).Field("m_Groups").GetValue<List<TooltipGroup>>();
			GuideLinesSystem value3 = Traverse.Create((object)__instance).Field("m_GuideLinesSystem").GetValue<GuideLinesSystem>();
			JobHandle val = default(JobHandle);
			NativeList<TooltipInfo> tooltips = value3.GetTooltips(ref val);
			((JobHandle)(ref val)).Complete();
			for (int i = 0; i < tooltips.Length; i++)
			{
				TooltipInfo val2 = tooltips[i];
				if (value2.Count <= i)
				{
					TooltipGroup val3 = new TooltipGroup();
					((Widget)val3).path = PathSegment.op_Implicit($"guideLineTooltip{i}");
					val3.horizontalAlignment = (Alignment)1;
					val3.verticalAlignment = (Alignment)1;
					val3.children.Add((IWidget)new FloatTooltip());
					value2.Add(val3);
				}
				TooltipGroup val4 = value2[i];
				float2 val5 = WorldToTooltipPos(float3.op_Implicit(val2.m_Position));
				float2 position = val4.position;
				if (!((float2)(ref position)).Equals(val5))
				{
					val4.position = val5;
					((Widget)val4).SetChildrenChanged();
				}
				IWidget obj = val4.children[0];
				FloatTooltip val6 = (FloatTooltip)(object)((obj is FloatTooltip) ? obj : null);
				TooltipType type = val2.m_Type;
				TooltipType val7 = type;
				TooltipType val8 = val7;
				if ((int)val8 != 0)
				{
					if ((int)val8 == 1)
					{
						((IconTooltip)val6).icon = "Media/Glyphs/Length.svg";
						((NumberTooltip<float>)(object)val6).value = (_updateSystem.Config.UseUnits ? ((float)val2.m_IntValue / 8f) : ((float)val2.m_IntValue));
						((NumberTooltip<float>)(object)val6).unit = (_updateSystem.Config.UseUnits ? "floatTwoFractions" : "length");
						if (_updateSystem.Config.UseUnits)
						{
							((LabelIconTooltip)val6).label = LocalizedString.Value("U");
						}
						else
						{
							((LabelIconTooltip)val6).label = default(LocalizedString);
						}
					}
				}
				else
				{
					((IconTooltip)val6).icon = "Media/Glyphs/Angle.svg";
					((NumberTooltip<float>)(object)val6).value = val2.m_IntValue;
					((NumberTooltip<float>)(object)val6).unit = "angle";
				}
				AddGroup(value, val4);
			}
			return false;
		}

		private static void AddGroup(TooltipUISystem tooltipUISystem, TooltipGroup group)
		{
			//IL_0014: 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_004e: Unknown result type (might be due to invalid IL or missing references)
			if (((Widget)group).path != PathSegment.Empty && tooltipUISystem.groups.Any((TooltipGroup g) => ((Widget)g).path == ((Widget)group).path))
			{
				Debug.LogError((object)$"Trying to add tooltip group with duplicate path '{((Widget)group).path}'");
			}
			else
			{
				tooltipUISystem.groups.Add(group);
			}
		}

		private static float2 WorldToTooltipPos(Vector3 worldPos)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			float3 val = float3.op_Implicit(Camera.main.WorldToScreenPoint(worldPos));
			float2 xy = ((float3)(ref val)).xy;
			xy.y = (float)Screen.height - xy.y;
			return xy;
		}
	}
	[HarmonyPatch(typeof(InfoviewPrefab), "Initialize")]
	internal class InfoviewPrefab_ConstructorPatch
	{
		private static ZoneColourSystem _zoneColourSystem;

		private static void Prefix(InfoviewPrefab __instance)
		{
			LegacyFlavourSystem.EnsureModUIFolder();
			if (_zoneColourSystem == null)
			{
				World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged<LegacyFlavourSystem>();
				_zoneColourSystem = World.DefaultGameObjectInjectionWorld.GetExistingSystemManaged<ZoneColourSystem>();
			}
			string iconPath = __instance.m_IconPath;
			if (_zoneColourSystem != null && iconPath.Contains("Media/Game/Icons/"))
			{
				DynamicZoneIcons dynamicZoneIcons = _zoneColourSystem.DynamicZoneIcons;
				if (dynamicZoneIcons != null && dynamicZoneIcons.CheckForReplacement(iconPath, out var parsedUrl))
				{
					__instance.m_IconPath = parsedUrl;
					DynamicZoneIcons._infoViewReplacements.Add((__instance, iconPath));
				}
			}
		}
	}
	[HarmonyPatch(typeof(NetCourseTooltipSystem), "OnUpdate")]
	internal class NetCourseTooltipSystem_OnUpdatePatch
	{
		private static LegacyFlavourUpdateSystem _updateSystem;

		private static void Postfix(NetCourseTooltipSystem __instance)
		{
			//IL_0092: 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_0074: Unknown result type (might be due to invalid IL or missing references)
			if (_updateSystem == null)
			{
				_updateSystem = World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged<LegacyFlavourUpdateSystem>();
			}
			FloatTooltip value = Traverse.Create((object)__instance).Field("m_Length").GetValue<FloatTooltip>();
			if (value != null)
			{
				if (_updateSystem.Config.UseUnits)
				{
					((NumberTooltip<float>)(object)value).value = ((NumberTooltip<float>)(object)value).value / 8f;
					((NumberTooltip<float>)(object)value).unit = "floatTwoFractions";
					((LabelIconTooltip)value).label = LocalizedString.Value("U");
				}
				else
				{
					((NumberTooltip<float>)(object)value).unit = "length";
					((LabelIconTooltip)value).label = default(LocalizedString);
				}
			}
		}
	}
	[HarmonyPatch(typeof(SystemOrder))]
	public static class SystemOrderPatch
	{
		[HarmonyPatch("Initialize")]
		[HarmonyPostfix]
		public static void Postfix(UpdateSystem updateSystem)
		{
			updateSystem.UpdateAt<LegacyFlavourUpdateSystem>((SystemUpdatePhase)0);
			updateSystem.UpdateAt<LegacyFlavourUISystem>((SystemUpdatePhase)22);
			updateSystem.UpdateAt<LegacyFlavourSystem>((SystemUpdatePhase)14);
		}
	}
	[HarmonyPatch(typeof(ToolSystem), "UpdateInfoviewColors")]
	internal class ToolSystem_UpdateInfoviewColorsPatch
	{
		private static LegacyFlavourUpdateSystem _updateSystem;

		private static void Postfix(ToolSystem __instance)
		{
			if (_updateSystem == null)
			{
				_updateSystem = World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged<LegacyFlavourUpdateSystem>();
			}
			LegacyFlavourConfig config = _updateSystem.Config;
			if (config.UseStickyWhiteness)
			{
				InfoviewPrefab activeInfoview = __instance.activeInfoview;
				if (activeInfoview != null && ((ComponentBase)activeInfoview).active)
				{
					Shader.SetGlobalInt("colossal_InfoviewOn", config.WhitenessToggle ? 1 : 0);
				}
			}
		}
	}
	[HarmonyPatch(typeof(UIObject), "LateInitialize")]
	internal class UIObject_ConstructorPatch
	{
		private static ZoneColourSystem _zoneColourSystem;

		private static void Postfix(UIObject __instance)
		{
			LegacyFlavourSystem.EnsureModUIFolder();
			if (_zoneColourSystem == null)
			{
				World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged<LegacyFlavourSystem>();
				_zoneColourSystem = World.DefaultGameObjectInjectionWorld.GetExistingSystemManaged<ZoneColourSystem>();
			}
			string icon = __instance.m_Icon;
			if (_zoneColourSystem != null && icon.Contains("Media/Game/Icons/"))
			{
				DynamicZoneIcons dynamicZoneIcons = _zoneColourSystem.DynamicZoneIcons;
				if (dynamicZoneIcons != null && dynamicZoneIcons.CheckForReplacement(icon, out var parsedUrl))
				{
					__instance.m_Icon = parsedUrl;
					DynamicZoneIcons._replacements.Add((__instance, icon));
				}
			}
		}
	}
	[HarmonyPatch(typeof(ZoneSystem), "OnCreate")]
	internal class ZoneSystem_OnCreatePatch
	{
		private static void Postfix(ZoneSystem __instance)
		{
			((ComponentSystemBase)__instance).World.GetOrCreateSystemManaged<ZoneColourSystem>();
		}
	}
	[HarmonyPatch(typeof(ZoneSystem), "OnUpdate")]
	internal class ZoneSystem_UpdatePatch
	{
		private static ZoneColourSystem _zoneColourSystem;

		private static void Postfix(ZoneSystem __instance)
		{
			if (_zoneColourSystem == null)
			{
				_zoneColourSystem = ((ComponentSystemBase)__instance).World.GetOrCreateSystemManaged<ZoneColourSystem>();
			}
		}
	}
	[HarmonyPatch(typeof(ZoneSystem), "UpdateZoneColors", new Type[]
	{
		typeof(ZonePrefab),
		typeof(ZoneData)
	})]
	internal class ZoneSystem_UpdateZoneColorsPatch
	{
		private static ZoneColourSystem _zoneColourSystem;

		private static bool Prefix(ZoneSystem __instance, ZonePrefab zonePrefab, ZoneData zoneData)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (_zoneColourSystem == null)
			{
				_zoneColourSystem = ((ComponentSystemBase)__instance).World.GetOrCreateSystemManaged<ZoneColourSystem>();
			}
			return _zoneColourSystem.UpdateZones(zonePrefab, zoneData);
		}
	}
}
namespace LegacyFlavour.MonoBehaviours
{
	public class SnowDetector : MonoBehaviour
	{
		public Action<float> OnUpdate;

		private ComputeShader snowCoverageShader;

		private ComputeBuffer resultBuffer;

		private RenderTexture inputTexture;

		private const float RUN_FREQUENCY = 15f;

		private bool isRunning;

		private float endTime;

		private float lastSnowPercent;

		public bool Disable { get; set; }

		private void Start()
		{
			snowCoverageShader = LoadFromAssetBundle();
		}

		private void Update()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			if (!Disable && GameModeExtensions.IsGame(GameManager.instance.gameMode) && TryGetSnowTexture() && !isRunning && Time.time >= endTime + 15f)
			{
				Run();
			}
		}

		private bool TryGetSnowTexture()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			if ((Object)(object)inputTexture != (Object)null)
			{
				return true;
			}
			inputTexture = (RenderTexture)Shader.GetGlobalTexture("_SnowMap");
			return (Object)(object)inputTexture != (Object)null;
		}

		private void Run()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			resultBuffer = new ComputeBuffer(2, 4, (ComputeBufferType)0);
			int num = snowCoverageShader.FindKernel("CSMain");
			snowCoverageShader.SetTexture(num, "InputTexture", (Texture)(object)inputTexture);
			snowCoverageShader.SetBuffer(num, "Result", resultBuffer);
			snowCoverageShader.Dispatch(num, ((Texture)inputTexture).width / 8, ((Texture)inputTexture).height / 8, 1);
			AsyncGPUReadback.Request(resultBuffer, (Action<AsyncGPUReadbackRequest>)OnCompleteReadback);
			isRunning = true;
		}

		private void OnCompleteReadback(AsyncGPUReadbackRequest request)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			if (((AsyncGPUReadbackRequest)(ref request)).hasError)
			{
				Debug.LogError((object)"GPU readback error detected.");
				return;
			}
			uint[] array = ((AsyncGPUReadbackRequest)(ref request)).GetData<uint>(0).ToArray();
			float num = (float)array[0] / ((float)(((Texture)inputTexture).width * ((Texture)inputTexture).height) * 100f) * 100f;
			if (num != lastSnowPercent)
			{
				lastSnowPercent = num;
				OnUpdate?.Invoke(num);
			}
			resultBuffer.Release();
			isRunning = false;
			endTime = Time.time;
		}

		private ComputeShader LoadFromAssetBundle()
		{
			using Stream stream = typeof(SnowDetector).Assembly.GetManifestResourceStream("LegacyFlavour.Resources.calculatesnow");
			if (stream == null)
			{
				Debug.LogError((object)"Failed to load embedded resource.");
				return null;
			}
			byte[] array = new byte[stream.Length];
			stream.Read(array, 0, array.Length);
			AssetBundle val = AssetBundle.LoadFromMemory(array);
			if ((Object)(object)val == (Object)null)
			{
				Debug.LogError((object)"Failed to load AssetBundle from memory.");
				return null;
			}
			ComputeShader val2 = val.LoadAsset<ComputeShader>("assets/compute/calculatesnow.compute");
			if ((Object)(object)val2 == (Object)null)
			{
				Debug.LogError((object)"Failed to load the compute shader from the AssetBundle.");
				return null;
			}
			val.Unload(false);
			return val2;
		}

		public static SnowDetector Create()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			GameObject val = GameObject.Find("LegacyFlavour_SnowDetector");
			if ((Object)(object)val != (Object)null)
			{
				return val.GetComponent<SnowDetector>();
			}
			GameObject val2 = new GameObject("LegacyFlavour_SnowDetector");
			SnowDetector result = val2.AddComponent<SnowDetector>();
			Object.DontDestroyOnLoad((Object)(object)val2);
			return result;
		}
	}
}
namespace LegacyFlavour.Helpers
{
	public static class ColourHelpers
	{
		public static Color HexToColor(string hex)
		{
			//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_000d: 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)
			Color result = default(Color);
			if (ColorUtility.TryParseHtmlString(hex, ref result))
			{
				return result;
			}
			return Color.white;
		}

		public static string ColorToHex(Color color)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return "#" + ColorUtility.ToHtmlStringRGB(color);
		}

		public static Color RGBAToColourVar(string rgbaString, out string alpha)
		{
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			alpha = null;
			string pattern = "rgba\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(.*?)\\s*\\)$";
			Regex regex = new Regex(pattern);
			Match match = regex.Match(rgbaString);
			if (match.Success)
			{
				float num = float.Parse(match.Groups[1].Value) / 255f;
				float num2 = float.Parse(match.Groups[2].Value) / 255f;
				float num3 = float.Parse(match.Groups[3].Value) / 255f;
				alpha = match.Groups[4].Value;
				return new Color(num, num2, num3, 1f);
			}
			throw new ArgumentException("Invalid RGBA string format.");
		}

		public static Color Darken(Color originalColor, float darkenAmount)
		{
			//IL_0001: 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_0022: Unknown result type (might be due to invalid IL or missing references)
			float num = default(float);
			float num2 = default(float);
			float num3 = default(float);
			Color.RGBToHSV(originalColor, ref num, ref num2, ref num3);
			num3 = Mathf.Clamp01(num3 - darkenAmount);
			return Color.HSVToRGB(num, num2, num3);
		}

		public static Color SetAlpha(Color originalColor, float opacity)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: 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_001c: Unknown result type (might be due to invalid IL or missing references)
			return new Color(originalColor.r, originalColor.g, originalColor.b, opacity);
		}

		public static string MatchHue(string originalHex, string targetHex)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			Color val = default(Color);
			ColorUtility.TryParseHtmlString(originalHex, ref val);
			Color val2 = default(Color);
			ColorUtility.TryParseHtmlString(targetHex, ref val2);
			float num = default(float);
			float num2 = default(float);
			float num3 = default(float);
			Color.RGBToHSV(val, ref num, ref num2, ref num3);
			float num4 = default(float);
			float num5 = default(float);
			Color.RGBToHSV(val2, ref num4, ref num5, ref num2);
			Color val3 = Color.HSVToRGB(num4, num5, num3);
			string text = ColorUtility.ToHtmlStringRGB(val3);
			return "#" + text;
		}

		public static string MatchHueOrMultiply(string originalHex, string targetHex)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			Color val = default(Color);
			ColorUtility.TryParseHtmlString(originalHex, ref val);
			Color val2 = default(Color);
			ColorUtility.TryParseHtmlString(targetHex, ref val2);
			float num = default(float);
			float num2 = default(float);
			float num3 = default(float);
			Color.RGBToHSV(val, ref num, ref num2, ref num3);
			float num4 = default(float);
			float num5 = default(float);
			Color.RGBToHSV(val2, ref num4, ref num5, ref num2);
			string text = ColorUtility.ToHtmlStringRGB(Color.HSVToRGB(num4, num5, num3));
			return "#" + text;
		}

		public static string MatchHueRGBAVar(Color originalColour, string targetHex, string alpha)
		{
			//IL_000a: 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_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_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			Color val = default(Color);
			ColorUtility.TryParseHtmlString(targetHex, ref val);
			float num = default(float);
			float num2 = default(float);
			float num3 = default(float);
			Color.RGBToHSV(originalColour, ref num, ref num2, ref num3);
			float num4 = default(float);
			float num5 = default(float);
			Color.RGBToHSV(val, ref num4, ref num5, ref num2);
			Color val2 = Color.HSVToRGB(num4, num5, num3);
			return $"rgba({val2.r * 255f:0}, {val2.g * 255f:0}, {val2.b * 255f:0}, {alpha})";
		}

		public static string MatchHueOrMultiplyRGBAVar(Color originalColour, string targetHex, string alpha)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return MatchHueRGBAVar(originalColour, targetHex, alpha);
		}

		public static string HexToRGBA(string hex, string alpha)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			Color val = default(Color);
			ColorUtility.TryParseHtmlString(hex, ref val);
			return $"rgba({val.r * 255f:0}, {val.g * 255f:0}, {val.b * 255f:0}, {alpha})";
		}
	}
	public class DynamicZoneIcons
	{
		private static string AssemblyPath = Path.GetDirectoryName(typeof(DynamicZoneIcons).Assembly.Location);

		private static string UIPath = AssemblyPath + "\\UI\\";

		private static string IconsPath = Application.streamingAssetsPath.Replace("/", "\\") + "\\~UI~\\GameUI\\Media\\Game\\Icons";

		private static string ModIconsPath = UIPath + "\\Icons";

		private static Dictionary<string, string[]> ZoneColours = new Dictionary<string, string[]>
		{
			{
				"Commercial",
				new string[17]
				{
					"#00c1ff", "#0089cf", "#0071a9", "#73e0fc", "#3ed2ff", "#005f95", "#03243e", "#001209", "#73d0ff", "#067cb9",
					"#024263", "#032f47", "#021c29", "#9edeff", "#24b5ff", "#05a3f4", "#034464"
				}
			},
			{
				"Industrial",
				new string[8] { "#ffdc00", "#d6a900", "#a48700", "#fff69f", "#f29d00", "#504200", "#8a6d00", "#f1bf00" }
			},
			{
				"Residential",
				new string[23]
				{
					"#023b0a", "#00b41a", "#004b12", "#02ff26", "#00580d", "#00ce1e", "#9dffab", "#00ff25", "#7cff62", "#03d321",
					"#006117", "#008620", "#008f15", "#08961c", "#024412", "#00c1ff", "#0089cf", "#0071a9", "#03243e", "#73d0ff",
					"#002612", "#065b12", "#01cf1e"
				}
			},
			{
				"Office",
				new string[8] { "#b400ff", "#9a0ad6", "#7902ab", "#d078f5", "#64028d", "#310146", "#660090", "#c65af3" }
			}
		};

		private static FieldInfo toolbarUI_statusUpdate = typeof(ToolbarUISystem).GetField("m_UniqueAssetStatusChanged", BindingFlags.Instance | BindingFlags.NonPublic);

		private static FieldInfo infoViewUI_statusUpdate = typeof(InfoviewsUISystem).GetField("m_InfoviewChanged", BindingFlags.Instance | BindingFlags.NonPublic);

		private static MethodInfo infoViewUI_OnGameLoaded = typeof(InfoviewsUISystem).GetMethod("OnGameLoaded", BindingFlags.Instance | BindingFlags.NonPublic);

		public static List<(UIObject Instance, string Original)> _replacements = new List<(UIObject, string)>();

		public static List<(InfoviewPrefab Instance, string Original)> _infoViewReplacements = new List<(InfoviewPrefab, string)>();

		private static readonly string[] MANUAL_ICONS = new string[4] { "ZoneResidential", "ZoneCommercial", "ZoneOffice", "ZoneIndustrial" };

		private readonly ZoneColourSystem _zoneColourSystem;

		private readonly LegacyFlavourConfig _config;

		private List<string> IconNames { get; set; } = new List<string>();


		private List<string> ReplacedIcons { get; set; } = new List<string>();


		public DynamicZoneIcons()
		{
			World defaultGameObjectInjectionWorld = World.DefaultGameObjectInjectionWorld;
			_zoneColourSystem = defaultGameObjectInjectionWorld.GetExistingSystemManaged<ZoneColourSystem>();
			_config = defaultGameObjectInjectionWorld.GetExistingSystemManaged<LegacyFlavourUpdateSystem>().Config;
			ScanDirectory();
		}

		private void ScanDirectory()
		{
			if (!Directory.Exists(ModIconsPath))
			{
				Directory.CreateDirectory(ModIconsPath);
			}
			Debug.Log((object)("LegacyUI Scanning Zone Icons: " + IconsPath));
			string[] files = Directory.GetFiles(IconsPath, "*.svg");
			string[] array = files;
			foreach (string path in array)
			{
				string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(path);
				if (fileNameWithoutExtension.StartsWith("Zone") || fileNameWithoutExtension.StartsWith("Zoning"))
				{
					IconNames.Add(fileNameWithoutExtension);
				}
			}
			ModifyBasedOnColours(invalidateCache: true);
		}

		public void ModifyBasedOnColours(bool invalidateCache = false)
		{
			ReplacedIcons.Clear();
			if (invalidateCache)
			{
				_config.IconsID = Guid.NewGuid().ToString().Replace("-", "");
				_config.Save();
				string[] directories = Directory.GetDirectories(ModIconsPath);
				if (directories != null && directories.Length != 0)
				{
					string[] array = directories;
					foreach (string path in array)
					{
						Directory.Delete(path, recursive: true);
					}
				}
				string[] files = Directory.GetFiles(ModIconsPath);
				if (files != null && files.Length != 0)
				{
					string[] array2 = files;
					foreach (string path2 in array2)
					{
						File.Delete(path2);
					}
				}
				(ColourBlindness, Dictionary<string, Color>)[] allColours = _zoneColourSystem.AllColours;
				for (int k = 0; k < allColours.Length; k++)
				{
					(ColourBlindness, Dictionary<string, Color>) tuple = allColours[k];
					ProcessColours(tuple.Item1, tuple.Item2);
				}
			}
			else
			{
				ProcessColours(_zoneColourSystem.colourBlindness, _zoneColourSystem.Colours);
			}
			UpdateReplacementIcons();
		}

		private void ProcessColours(ColourBlindness mode, Dictionary<string, Color> colours, bool invalidateCache = false)
		{
			Dictionary<string, string> workingSVG = IconNames.ToDictionary((string i) => i, (string i) => string.Empty);
			foreach (string iconName2 in IconNames)
			{
				ProcessIcon(mode, workingSVG, colours, iconName2, invalidateCache);
			}
			string[] mANUAL_ICONS = MANUAL_ICONS;
			foreach (string iconName in mANUAL_ICONS)
			{
				ProcessIcon(mode, workingSVG, colours, iconName, invalidateCache, isRootIcon: true);
			}
		}

		private void UpdateReplacementIcons()
		{
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			List<(UIObject, string)> replacements = _replacements;
			if (replacements != null && replacements.Count > 0)
			{
				foreach (var item in replacements)
				{
					var (val, _) = item;
					if (!((Object)(object)val == (Object)null) && CheckForReplacement(item.Item2, out var parsedUrl))
					{
						val.m_Icon = parsedUrl;
					}
				}
			}
			List<(InfoviewPrefab, string)> infoViewReplacements = _infoViewReplacements;
			if (infoViewReplacements != null && infoViewReplacements.Count > 0)
			{
				foreach (var item2 in infoViewReplacements)
				{
					var (val2, _) = item2;
					if (!((Object)(object)val2 == (Object)null) && CheckForReplacement(item2.Item2, out var parsedUrl2))
					{
						val2.m_IconPath = parsedUrl2;
					}
				}
			}
			ToolbarUISystem existingSystemManaged = World.DefaultGameObjectInjectionWorld.GetExistingSystemManaged<ToolbarUISystem>();
			if (existingSystemManaged != null)
			{
				toolbarUI_statusUpdate.SetValue(existingSystemManaged, true);
			}
			InfoviewsUISystem existingSystemManaged2 = World.DefaultGameObjectInjectionWorld.GetExistingSystemManaged<InfoviewsUISystem>();
			if (existingSystemManaged2 != null)
			{
				infoViewUI_statusUpdate.SetValue(existingSystemManaged2, true);
				infoViewUI_OnGameLoaded.Invoke(existingSystemManaged2, new object[1] { (object)default(Context) });
			}
		}

		private void ProcessIcon(ColourBlindness mode, Dictionary<string, string> workingSVG, Dictionary<string, Color> colours, string iconName, bool invalidateCache = false, bool isRootIcon = false)
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			string text = ((!isRootIcon) ? colours.Keys.FirstOrDefault((string k) => "Zone" + k.Replace(" ", "") == iconName) : colours.Keys.FirstOrDefault((string k) => ("Zone" + k.Replace(" ", "")).StartsWith(iconName)));
			if (string.IsNullOrEmpty(text))
			{
				return;
			}
			Color val = colours[text];
			string text2 = ModIconsPath + "\\" + _config.IconsID + "\\" + iconName + "_" + mode.ToString() + ".svg";
			Directory.CreateDirectory(ModIconsPath + "\\" + _config.IconsID);
			if (invalidateCache || !File.Exists(text2))
			{
				string path = IconsPath + "\\" + iconName + ".svg";
				workingSVG[iconName] = File.ReadAllText(path);
				string svg = workingSVG[iconName];
				if (_config.OverrideIcons)
				{
					ConvertSVG(iconName, "#" + ColorUtility.ToHtmlStringRGB(val), ref svg);
				}
				workingSVG[iconName] = svg;
				SaveSVG(iconName, text2, svg);
			}
			else
			{
				workingSVG[iconName] = File.ReadAllText(text2);
				ReplacedIcons.Add(iconName);
			}
		}

		private void SaveSVG(string key, string filePath, string svg)
		{
			if (!string.IsNullOrEmpty(svg))
			{
				File.WriteAllText(filePath, svg, Encoding.UTF8);
				ReplacedIcons.Add(key);
			}
		}

		private void ConvertSVG(string iconName, string targetHex, ref string svg)
		{
			foreach (KeyValuePair<string, string[]> zoneColour in ZoneColours)
			{
				if (iconName.StartsWith("Zone" + zoneColour.Key) && zoneColour.Value != null && zoneColour.Value.Length != 0)
				{
					string[] value = zoneColour.Value;
					foreach (string text in value)
					{
						string newValue = ColourHelpers.MatchHue(text, targetHex);
						svg = svg.Replace(text, newValue);
					}
				}
			}
		}

		public bool CheckForReplacement(string url, out string parsedUrl)
		{
			parsedUrl = url;
			string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(url);
			string text = _zoneColourSystem.colourBlindness.ToString();
			foreach (string replacedIcon in ReplacedIcons)
			{
				if (fileNameWithoutExtension != replacedIcon)
				{
					continue;
				}
				if (!_config.Enabled)
				{
					return true;
				}
				parsedUrl = "coui://legacyflavourui/Icons/" + _config.IconsID + "/" + replacedIcon + "_" + text + ".svg";
				return true;
			}
			return false;
		}
	}
}
namespace LegacyFlavour.Configuration
{
	public abstract class ConfigBase : ModelWriter
	{
		private static readonly JsonSerializerSettings _serializerSettings = new JsonSerializerSettings
		{
			NullValueHandling = (NullValueHandling)1,
			Formatting = (Formatting)1
		};

		public static Action OnUpdated;

		protected abstract string ConfigFileName { get; }

		public virtual void Save()
		{
			string contents = JsonConvert.SerializeObject((object)this, _serializerSettings);
			string path = Path.Combine(GetAssemblyDirectory(), ConfigFileName);
			File.WriteAllText(path, contents);
			OnUpdated?.Invoke();
		}

		public static T Load<T>(bool useDefaultAsTemplate = true) where T : ConfigBase, new()
		{
			T val = new T();
			string path = Path.Combine(GetAssemblyDirectory(), val.ConfigFileName);
			string text = "";
			if (File.Exists(path))
			{
				text = File.ReadAllText(path);
			}
			else
			{
				if (!useDefaultAsTemplate)
				{
					return new T();
				}
				text = LoadDefaultAndSave<T>();
			}
			return (T)JsonConvert.DeserializeObject(text, typeof(T), _serializerSettings);
		}

		public static T LoadDefault<T>() where T : ConfigBase, new()
		{
			T val = new T();
			string text = val.LoadDefaultJson();
			return JsonConvert.DeserializeObject<T>(text, _serializerSettings);
		}

		private static string LoadDefaultAndSave<T>() where T : ConfigBase, new()
		{
			T val = new T();
			string text = val.LoadDefaultJson();
			string path = Path.Combine(GetAssemblyDirectory(), val.ConfigFileName);
			File.WriteAllText(path, text);
			return text;
		}

		protected static string GetAssemblyDirectory()
		{
			return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
		}

		protected virtual string LoadDefaultJson()
		{
			string text = "LegacyFlavour.Resources.default" + UppercaseFirst(ConfigFileName);
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			using Stream stream = executingAssembly.GetManifestResourceStream(text);
			if (stream == null)
			{
				Debug.LogError((object)("Embedded default config not found: " + text));
				return null;
			}
			using StreamReader streamReader = new StreamReader(stream);
			return streamReader.ReadToEnd();
		}

		private static string UppercaseFirst(string s)
		{
			if (string.IsNullOrEmpty(s))
			{
				return string.Empty;
			}
			return char.ToUpper(s[0]) + s.Substring(1);
		}
	}
	public class LegacyFlavourConfig : ConfigBase
	{
		public static readonly LegacyFlavourConfig Default = ConfigBase.LoadDefault<LegacyFlavourConfig>();

		protected override string ConfigFileName => "config.json";

		public bool Enabled { get; set; }

		public bool UseStickyWhiteness { get; set; } = false;


		public bool WhitenessToggle { get; set; }

		public bool UseUnits { get; set; } = true;


		public bool UseDynamicCellBorders { get; set; } = true;


		public decimal CellOpacity { get; set; } = 0.9m;


		public decimal CellBorderOpacity { get; set; } = 0.9m;


		public decimal EmptyCellOpacity { get; set; } = default(decimal);


		public decimal EmptyCellBorderOpacity { get; set; } = 0.2m;


		public ColourBlindness Mode { get; set; } = ColourBlindness.None;


		public TimeOfDayOverride TimeOfDay { get; set; } = TimeOfDayOverride.Off;


		public bool FreezeVisualTime { get; set; }

		public WeatherOverride Weather { get; set; } = WeatherOverride.Off;


		public List<ZoneColourConfig> Zones { get; set; }

		public bool OverrideIcons { get; set; } = true;


		public string IconsID { get; set; }
	}
	public class ZoneColourConfig
	{
		public string Name { get; set; }

		public string Colour { get; set; }

		public string Deuteranopia { get; set; }

		public string Protanopia { get; set; }

		public string Tritanopia { get; set; }

		public string Custom { get; set; }
	}
	public class LocaleConfig : ConfigBase
	{
		public static readonly LocaleConfig Default = ConfigBase.LoadDefault<LocaleConfig>();

		public List<LocaleGroup> Locales { get; set; }

		protected override string ConfigFileName => "locale.json";
	}
	public class LocaleGroup : ModelWriter
	{
		public List<string> IDs { get; set; }

		public Dictionary<string, string> Entries { get; set; }
	}
}