Decompiled source of StockAlert v1.2.3

StockAlert.dll

Decompiled 4 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Eremite;
using Eremite.Buildings;
using Eremite.Buildings.UI;
using Eremite.Characters;
using Eremite.Characters.Villagers;
using Eremite.MapObjects;
using Eremite.MapObjects.UI;
using Eremite.Model;
using Eremite.Model.Configs;
using Eremite.Model.Effects;
using Eremite.Model.Meta;
using Eremite.Model.State;
using Eremite.Services;
using Eremite.Services.Monitors;
using Eremite.View;
using Eremite.View.HUD;
using Eremite.View.HUD.Conditions;
using Eremite.View.HUD.Monitors;
using Eremite.View.HUD.Perks;
using Eremite.View.HUD.Rainpunk;
using Eremite.View.HUD.TradeRoutes;
using Eremite.View.Menu.Pick;
using Eremite.View.UI;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using StockAlert.Config;
using StockAlert.Core.Models;
using StockAlert.Game;
using StockAlert.Game.Discovery;
using StockAlert.Infrastructure.Bootstrap;
using StockAlert.Infrastructure.Plugin;
using StockAlert.UI.HUD;
using StockAlert.UI.Panels;
using StockAlert.UI.World;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("StockAlert")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+80d77746eb4dc12072e6c64cab0a6bf4c3c932da")]
[assembly: AssemblyProduct("StockAlert")]
[assembly: AssemblyTitle("StockAlert")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[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 StockAlert
{
	public static class StockAlertInfo
	{
		public const string Id = "com.stockalert.ats";

		public const string Name = "StockAlert";

		public const string Version = "1.2.3";
	}
}
namespace StockAlert.UI.World
{
	internal static class BuilderStatusIndicators
	{
		public readonly struct BuilderDemandCounts
		{
			public int OpenSlots { get; }

			public int ConstructionSites { get; }

			public BuilderDemandCounts(int openSlots, int constructionSites)
			{
				OpenSlots = openSlots;
				ConstructionSites = constructionSites;
			}
		}

		private sealed class BuilderIndicator
		{
			private readonly GameObject _iconObject;

			private readonly SpriteRenderer _renderer;

			private readonly Transform _transform;

			public BuilderIndicator(Villager villager)
			{
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Expected O, but got Unknown
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				//IL_0041: Expected O, but got Unknown
				//IL_0097: 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)
				_iconObject = new GameObject("BuilderStatusIcon");
				_renderer = _iconObject.AddComponent<SpriteRenderer>();
				((Renderer)_renderer).material = new Material(Shader.Find("Sprites/Default"));
				((Renderer)_renderer).sortingLayerName = "UI";
				((Renderer)_renderer).sortingOrder = 5000;
				_iconObject.transform.SetParent(((Component)((Actor)villager).ActorView).transform, false);
				_iconObject.transform.localPosition = new Vector3(0f, 1.6f, 0f);
				_transform = _iconObject.transform;
				_transform.localScale = Vector3.one;
				_iconObject.AddComponent<BillboardToCamera>();
			}

			public void Show(Sprite sprite)
			{
				if (!((Object)(object)_renderer == (Object)null) && !((Object)(object)sprite == (Object)null))
				{
					if ((Object)(object)_renderer.sprite != (Object)(object)sprite)
					{
						_renderer.sprite = sprite;
					}
					UpdateScale(sprite);
					if (!((Renderer)_renderer).enabled)
					{
						((Renderer)_renderer).enabled = true;
					}
				}
			}

			private void UpdateScale(Sprite sprite)
			{
				//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_0021: Unknown result type (might be due to invalid IL or missing references)
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: 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_0060: Unknown result type (might be due to invalid IL or missing references)
				//IL_0066: Unknown result type (might be due to invalid IL or missing references)
				//IL_0047: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)_transform == (Object)null) && !((Object)(object)sprite == (Object)null))
				{
					Bounds bounds = sprite.bounds;
					Vector3 size = ((Bounds)(ref bounds)).size;
					float num = Mathf.Max(size.x, size.y);
					if (num <= 0.001f)
					{
						_transform.localScale = Vector3.one;
						return;
					}
					float num2 = 0.5f / num;
					_transform.localScale = Vector3.one * num2;
				}
			}

			public void Destroy()
			{
				if ((Object)(object)_iconObject != (Object)null)
				{
					Object.Destroy((Object)(object)_iconObject);
				}
			}
		}

		private sealed class BillboardToCamera : MonoBehaviour
		{
			private void LateUpdate()
			{
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				Camera main = Camera.main;
				if ((Object)(object)main != (Object)null)
				{
					((Component)this).transform.forward = ((Component)main).transform.forward;
				}
			}
		}

		private static readonly Dictionary<int, BuilderIndicator> ActiveIndicators = new Dictionary<int, BuilderIndicator>();

		private static PropertyInfo _piVillagersService;

		private static PropertyInfo _piVillagers;

		private static FieldInfo _fiActorBrain;

		private static FieldInfo _fiBrainStack;

		private static Sprite _idleSprite;

		private static Sprite _builderSprite;

		public static void Refresh()
		{
			if (!ConfigManager.ShowBuilderStatusIcons || !GameAPI.IsGameActive())
			{
				Clear();
			}
			else
			{
				if (!EnsureSprites())
				{
					return;
				}
				HashSet<int> seenVillagers = new HashSet<int>();
				foreach (Villager builderVillager in GetBuilderVillagers())
				{
					if ((Object)(object)builderVillager == (Object)null || !builderVillager.IsAlive() || (Object)(object)((Actor)builderVillager).ActorView == (Object)null)
					{
						continue;
					}
					Sprite statusSprite = GetStatusSprite(IsVillagerIdle(builderVillager));
					if (!((Object)(object)statusSprite == (Object)null))
					{
						seenVillagers.Add(((Actor)builderVillager).Id);
						if (!ActiveIndicators.TryGetValue(((Actor)builderVillager).Id, out var value))
						{
							value = new BuilderIndicator(builderVillager);
							ActiveIndicators[((Actor)builderVillager).Id] = value;
						}
						value.Show(statusSprite);
					}
				}
				foreach (int item in ActiveIndicators.Keys.Where((int id) => !seenVillagers.Contains(id)).ToList())
				{
					ActiveIndicators[item].Destroy();
					ActiveIndicators.Remove(item);
				}
			}
		}

		private static Sprite GetStatusSprite(bool isIdle)
		{
			if (isIdle)
			{
				if (!ConfigManager.ShowIdleBuilderStatusIcons)
				{
					return null;
				}
				return _idleSprite;
			}
			if (!ConfigManager.ShowBusyBuilderStatusIcons)
			{
				return null;
			}
			return _builderSprite;
		}

		public static void Clear()
		{
			foreach (BuilderIndicator value in ActiveIndicators.Values)
			{
				value.Destroy();
			}
			ActiveIndicators.Clear();
		}

		public static int GetIdleBuilderCount()
		{
			return GetBuilderVillagers().Count((Villager villager) => (Object)(object)villager != (Object)null && villager.IsAlive() && IsVillagerIdle(villager));
		}

		public static BuilderDemandCounts GetBuilderDemandCounts()
		{
			int num = 0;
			int num2 = 0;
			foreach (Building constructionBuilding in GameAPI.GetConstructionBuildings())
			{
				if (((constructionBuilding != null) ? constructionBuilding.BuildingState : null) == null || (Object)(object)constructionBuilding.BuildingModel == (Object)null || constructionBuilding.IsFinished() || constructionBuilding.HasInternalBuilders)
				{
					continue;
				}
				BuildingState buildingState = constructionBuilding.BuildingState;
				int maxBuilders = constructionBuilding.BuildingModel.maxBuilders;
				if (maxBuilders > 0)
				{
					int num3 = maxBuilders - Math.Max(0, buildingState.builders);
					if (num3 > 0)
					{
						num2++;
						num += num3;
					}
				}
			}
			return new BuilderDemandCounts(num, num2);
		}

		public static bool HasIdleBuilderOfRace(string raceName)
		{
			if (string.IsNullOrWhiteSpace(raceName))
			{
				return false;
			}
			return GetIdleBuilderRaceIds().Contains(raceName);
		}

		public static bool HasIdleBuilderOfRace(RaceModel race)
		{
			if ((Object)(object)race == (Object)null || string.IsNullOrWhiteSpace(((SO)race).Name))
			{
				return false;
			}
			return GetIdleBuilderRaceIds().Contains(((SO)race).Name);
		}

		public static Sprite GetIdleBuilderSprite()
		{
			EnsureSprites();
			return _idleSprite;
		}

		public static IReadOnlyList<string> GetIdleBuilderRaceSummaries()
		{
			return (from villager in GetBuilderVillagers()
				where (Object)(object)villager != (Object)null && villager.IsAlive() && IsVillagerIdle(villager)
				group villager by villager.Race into @group
				orderby GetRaceDisplayName(@group.First(), @group.Count())
				select $"{GetRaceDisplayName(@group.First(), 1)}: {@group.Count()}").ToList();
		}

		private static HashSet<string> GetIdleBuilderRaceIds()
		{
			HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			foreach (Villager builderVillager in GetBuilderVillagers())
			{
				if (!((Object)(object)builderVillager == (Object)null) && builderVillager.IsAlive() && IsVillagerIdle(builderVillager))
				{
					if (!string.IsNullOrWhiteSpace(builderVillager.Race))
					{
						hashSet.Add(builderVillager.Race);
					}
					RaceModel raceModel = builderVillager.raceModel;
					if (!string.IsNullOrWhiteSpace((raceModel != null) ? ((SO)raceModel).Name : null))
					{
						hashSet.Add(((SO)builderVillager.raceModel).Name);
					}
				}
			}
			return hashSet;
		}

		private static string GetRaceDisplayName(Villager villager, int count)
		{
			if (!((Object)(object)villager.raceModel != (Object)null))
			{
				return villager.Race;
			}
			return villager.raceModel.GetDisplayNameFor(count);
		}

		private static IEnumerable<Villager> GetBuilderVillagers()
		{
			Settings settings = GameAPI.GetSettings();
			object obj;
			if (settings == null)
			{
				obj = null;
			}
			else
			{
				ProfessionModel defaultProfession = settings.DefaultProfession;
				obj = ((defaultProfession != null) ? ((SO)defaultProfession).Name : null);
			}
			string builderProfession = (string)obj;
			if (string.IsNullOrWhiteSpace(builderProfession))
			{
				yield break;
			}
			if (_piVillagersService == null)
			{
				_piVillagersService = typeof(GameMB).GetProperty("VillagersService", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			}
			object obj2 = _piVillagersService?.GetValue(null, null);
			if (obj2 == null)
			{
				yield break;
			}
			if ((object)_piVillagers == null)
			{
				_piVillagers = obj2.GetType().GetProperty("Villagers", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			}
			if (!(_piVillagers?.GetValue(obj2, null) is IDictionary dictionary))
			{
				yield break;
			}
			foreach (DictionaryEntry item in dictionary)
			{
				object? value = item.Value;
				Villager val = (Villager)((value is Villager) ? value : null);
				if (val != null && string.Equals(((Actor)val).Profession, builderProfession, StringComparison.OrdinalIgnoreCase))
				{
					yield return val;
				}
			}
		}

		private static bool IsVillagerIdle(Villager villager)
		{
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Invalid comparison between Unknown and I4
			try
			{
				if ((object)_fiActorBrain == null)
				{
					_fiActorBrain = typeof(Actor).GetField("brain", BindingFlags.Instance | BindingFlags.NonPublic);
				}
				object obj = _fiActorBrain?.GetValue(villager);
				if (obj == null)
				{
					return false;
				}
				if ((object)_fiBrainStack == null)
				{
					_fiBrainStack = obj.GetType().GetField("stack", BindingFlags.Instance | BindingFlags.NonPublic);
				}
				if (!(_fiBrainStack?.GetValue(obj) is Stack<ActorTask> stack) || stack.Count == 0)
				{
					return false;
				}
				ActorTask val = stack.Peek();
				return val != null && (int)val.WorkStatus == 0;
			}
			catch (Exception)
			{
				return false;
			}
		}

		private static bool EnsureSprites()
		{
			if ((Object)(object)_idleSprite == (Object)null)
			{
				_idleSprite = FindHudSprite("/HUD/GoodsHUD/SacrificeMarker/Content") ?? GameAPI.GetSettings()?.monitorsConfig?.noBuildersIcon;
			}
			if ((Object)(object)_builderSprite == (Object)null)
			{
				_builderSprite = FindBuilderHudSprite() ?? GameAPI.GetSettings()?.monitorsConfig?.noBuildersIcon;
			}
			if ((Object)(object)_idleSprite != (Object)null)
			{
				return (Object)(object)_builderSprite != (Object)null;
			}
			return false;
		}

		private static Sprite FindBuilderHudSprite()
		{
			RacesStatsHUD val = Object.FindObjectOfType<RacesStatsHUD>();
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			Transform val2 = FindDescendantByName(((Component)val).transform, "BuildersIcon");
			if ((Object)(object)val2 == (Object)null)
			{
				return null;
			}
			Image componentInChildren = ((Component)val2).GetComponentInChildren<Image>(true);
			if (componentInChildren == null)
			{
				return null;
			}
			return componentInChildren.sprite;
		}

		private static Sprite FindHudSprite(string path)
		{
			if (string.IsNullOrWhiteSpace(path))
			{
				return null;
			}
			GameObject val = GameObject.Find(path);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			Image component = val.GetComponent<Image>();
			if ((Object)(object)component != (Object)null && (Object)(object)component.sprite != (Object)null)
			{
				return component.sprite;
			}
			Image componentInChildren = val.GetComponentInChildren<Image>(true);
			if (componentInChildren == null)
			{
				return null;
			}
			return componentInChildren.sprite;
		}

		private static Transform FindDescendantByName(Transform root, string name)
		{
			if ((Object)(object)root == (Object)null)
			{
				return null;
			}
			for (int i = 0; i < root.childCount; i++)
			{
				Transform child = root.GetChild(i);
				if (string.Equals(((Object)child).name, name, StringComparison.Ordinal))
				{
					return child;
				}
				Transform val = FindDescendantByName(child, name);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			return null;
		}
	}
	internal static class BuildingAlertIndicators
	{
		private readonly struct IndicatorSnapshot : IEquatable<IndicatorSnapshot>
		{
			public bool Active { get; }

			public Color Color { get; }

			public bool ShowProductIcons { get; }

			public float ProductIconScale { get; }

			public string ProductGoodsKey { get; }

			public IndicatorSnapshot(bool active, Color color, IReadOnlyList<string> productGoodIds)
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				Active = active;
				Color = color;
				ShowProductIcons = ConfigManager.ShowBuildingSpecificItemIndicators;
				ProductIconScale = ConfigManager.BuildingShortageIconScale;
				ProductGoodsKey = ((productGoodIds == null || productGoodIds.Count == 0) ? string.Empty : string.Join("|", productGoodIds.Select(BuildProductGoodsKey)));
			}

			public bool Equals(IndicatorSnapshot other)
			{
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_0015: 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)
				if (Active == other.Active)
				{
					Color color = Color;
					if (((Color)(ref color)).Equals(other.Color) && ShowProductIcons == other.ShowProductIcons && Mathf.Approximately(ProductIconScale, other.ProductIconScale))
					{
						return string.Equals(ProductGoodsKey, other.ProductGoodsKey, StringComparison.Ordinal);
					}
				}
				return false;
			}

			private static string BuildProductGoodsKey(string goodId)
			{
				GoodInfo goodInfo = Discovery.Goods.FirstOrDefault((GoodInfo g) => string.Equals(g.Id, goodId, StringComparison.OrdinalIgnoreCase));
				return goodId + ((goodInfo != null && goodInfo.IsIngredientBlocked) ? ":blocked" : ":normal");
			}
		}

		private const int MaxProductIcons = 4;

		private const int ProductIconGridRows = 2;

		private const int ProductIconSortingOrderOffset = 100;

		private const float ProductIconForwardOffset = -0.05f;

		private const float ProductIconBorderThicknessScale = 0.08f;

		private const string ProductIconBorderRootName = "IngredientBlockedBorder";

		private const string ProductIconsRootName = "StockAlertProductIcons";

		private static readonly Color WhiteColor = Color.white;

		private static readonly Color RedColor = new Color(1f, 0.25f, 0.25f, 1f);

		private static readonly Color YellowColor = new Color(1f, 0.85f, 0.2f, 1f);

		private static readonly Color GreyColor = new Color(0.48f, 0.48f, 0.48f, 1f);

		private static readonly Color BorderRedColor = new Color(0.62f, 0.04f, 0.04f, 1f);

		private static readonly Dictionary<int, IndicatorSnapshot> LastApplied = new Dictionary<int, IndicatorSnapshot>();

		private static Sprite _solidSprite;

		public static void Refresh()
		{
			if (!ConfigManager.ShowBuildingAlertIndicators)
			{
				RestoreVanilla();
				return;
			}
			Settings settings = GameAPI.GetSettings();
			HashSet<string> lowGoods = new HashSet<string>(from g in Discovery.Goods
				where g.IsBelowThreshold
				select g.Id, StringComparer.OrdinalIgnoreCase);
			HashSet<string> blockedIngredientGoods = new HashSet<string>(Discovery.BlockedIngredientGoods, StringComparer.OrdinalIgnoreCase);
			HashSet<int> seenBuildings = new HashSet<int>();
			foreach (IWorkshop recipeBuilding in GetRecipeBuildings())
			{
				ProductionBuilding @base = recipeBuilding.Base;
				if (!((Object)(object)@base == (Object)null))
				{
					seenBuildings.Add(((Building)@base).Id);
					ApplyIndicatorState(@base, recipeBuilding, lowGoods, blockedIngredientGoods, settings);
				}
			}
			foreach (ProductionBuilding gatheringSourceBuilding in GameAPI.GetGatheringSourceBuildings())
			{
				if (!((Object)(object)gatheringSourceBuilding == (Object)null))
				{
					seenBuildings.Add(((Building)gatheringSourceBuilding).Id);
					ApplyGatheringIndicatorState(gatheringSourceBuilding, blockedIngredientGoods);
				}
			}
			foreach (Farm farmBuilding in GameAPI.GetFarmBuildings())
			{
				if (!((Object)(object)farmBuilding == (Object)null))
				{
					seenBuildings.Add(((Building)farmBuilding).Id);
					ApplyFarmIndicatorState(farmBuilding);
				}
			}
			foreach (int item in LastApplied.Keys.Where((int id) => !seenBuildings.Contains(id)).ToList())
			{
				RemoveProductIcons(item);
				LastApplied.Remove(item);
			}
		}

		public static void RefreshForView(ProductionBuildingView buildingView)
		{
			if (!ConfigManager.ShowBuildingAlertIndicators || (Object)(object)buildingView == (Object)null)
			{
				return;
			}
			IWorkshop val = GetRecipeBuildings().FirstOrDefault((Func<IWorkshop, bool>)delegate(IWorkshop w)
			{
				object obj;
				if (w == null)
				{
					obj = null;
				}
				else
				{
					ProductionBuilding @base = w.Base;
					obj = ((@base != null) ? ((Building)@base).BuildingView : null);
				}
				return obj == buildingView;
			});
			if (!((Object)(object)((val != null) ? val.Base : null) == (Object)null))
			{
				Settings settings = GameAPI.GetSettings();
				HashSet<string> lowGoods = new HashSet<string>(from g in Discovery.Goods
					where g.IsBelowThreshold
					select g.Id, StringComparer.OrdinalIgnoreCase);
				HashSet<string> blockedIngredientGoods = new HashSet<string>(Discovery.BlockedIngredientGoods, StringComparer.OrdinalIgnoreCase);
				ApplyIndicatorState(val.Base, val, lowGoods, blockedIngredientGoods, settings);
			}
		}

		public static void RestoreVanilla()
		{
			HashSet<int> hashSet = new HashSet<int>();
			foreach (IWorkshop recipeBuilding in GetRecipeBuildings())
			{
				ProductionBuilding @base = recipeBuilding.Base;
				if (!((Object)(object)@base == (Object)null) && hashSet.Add(((Building)@base).Id))
				{
					RestoreVanillaFor(@base);
				}
			}
			foreach (ProductionBuilding gatheringSourceBuilding in GameAPI.GetGatheringSourceBuildings())
			{
				if ((Object)(object)gatheringSourceBuilding != (Object)null && hashSet.Add(((Building)gatheringSourceBuilding).Id))
				{
					RestoreVanillaFor(gatheringSourceBuilding);
				}
			}
			foreach (Farm farmBuilding in GameAPI.GetFarmBuildings())
			{
				if ((Object)(object)farmBuilding != (Object)null && hashSet.Add(((Building)farmBuilding).Id))
				{
					RestoreVanillaFor((ProductionBuilding)(object)farmBuilding);
				}
			}
			LastApplied.Clear();
		}

		private static IEnumerable<IWorkshop> GetRecipeBuildings()
		{
			foreach (IWorkshop recipeBuilding in GameAPI.GetRecipeBuildings())
			{
				yield return recipeBuilding;
			}
		}

		private static void ApplyIndicatorState(ProductionBuilding building, IWorkshop workshop, HashSet<string> lowGoods, HashSet<string> blockedIngredientGoods, Settings settings)
		{
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: 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_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: 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_0113: Unknown result type (might be due to invalid IL or missing references)
			BuildingView buildingView = ((Building)building).BuildingView;
			object obj;
			if (buildingView == null)
			{
				obj = null;
			}
			else
			{
				Transform transform = ((Component)buildingView).transform;
				if (transform == null)
				{
					obj = null;
				}
				else
				{
					Transform obj2 = transform.Find("ToRotate/UI/NoWorkersIcon");
					obj = ((obj2 != null) ? ((Component)obj2).gameObject : null);
				}
			}
			GameObject val = (GameObject)obj;
			if (!((Object)(object)val == (Object)null))
			{
				MakeIconClickThrough(val);
				int num = building.CountWorkers();
				WorkplaceModel[] workplaces = building.Workplaces;
				int num2 = ((workplaces != null) ? workplaces.Length : 0);
				List<string> enabledLowRecipeGoods = GetEnabledLowRecipeGoods(workshop, lowGoods);
				bool flag = enabledLowRecipeGoods.Count > 0;
				bool flag2 = flag && HasCraftableEnabledLowRecipe(workshop, lowGoods, settings);
				bool flag3 = workshop.Recipes.Any((WorkshopRecipeState r) => IsEnabledGatheringSupplyRecipe(r, blockedIngredientGoods, settings));
				bool flag4 = flag || flag3;
				bool flag5 = flag && !flag2 && !flag3;
				bool flag6 = false;
				Color color = WhiteColor;
				if (num == 0)
				{
					flag6 = true;
					color = (flag5 ? GreyColor : (flag4 ? RedColor : WhiteColor));
				}
				else if (flag4 && num < num2)
				{
					flag6 = true;
					color = (flag5 ? GreyColor : YellowColor);
				}
				ApplySnapshot(((Building)building).Id, val, flag6, color, (flag6 && flag && ConfigManager.ShowBuildingSpecificItemIndicators) ? enabledLowRecipeGoods : null);
			}
		}

		private static void ApplyGatheringIndicatorState(ProductionBuilding building, HashSet<string> blockedIngredientGoods)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: 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)
			BuildingView buildingView = ((Building)building).BuildingView;
			object obj;
			if (buildingView == null)
			{
				obj = null;
			}
			else
			{
				Transform transform = ((Component)buildingView).transform;
				if (transform == null)
				{
					obj = null;
				}
				else
				{
					Transform obj2 = transform.Find("ToRotate/UI/NoWorkersIcon");
					obj = ((obj2 != null) ? ((Component)obj2).gameObject : null);
				}
			}
			GameObject val = (GameObject)obj;
			if (!((Object)(object)val == (Object)null))
			{
				MakeIconClickThrough(val);
				int num = building.CountWorkers();
				WorkplaceModel[] workplaces = building.Workplaces;
				int num2 = ((workplaces != null) ? workplaces.Length : 0);
				bool flag = HasRelevantGatheringRecipe(building, blockedIngredientGoods);
				bool active = false;
				Color color = WhiteColor;
				if (num == 0)
				{
					active = true;
					color = (flag ? RedColor : WhiteColor);
				}
				else if (flag && num < num2)
				{
					active = true;
					color = YellowColor;
				}
				ApplySnapshot(((Building)building).Id, val, active, color, null);
			}
		}

		private static void ApplyFarmIndicatorState(Farm farm)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			BuildingView buildingView = ((Building)farm).BuildingView;
			object obj;
			if (buildingView == null)
			{
				obj = null;
			}
			else
			{
				Transform transform = ((Component)buildingView).transform;
				if (transform == null)
				{
					obj = null;
				}
				else
				{
					Transform obj2 = transform.Find("ToRotate/UI/NoWorkersIcon");
					obj = ((obj2 != null) ? ((Component)obj2).gameObject : null);
				}
			}
			GameObject val = (GameObject)obj;
			if (!((Object)(object)val == (Object)null))
			{
				MakeIconClickThrough(val);
				int num = ((ProductionBuilding)farm).CountWorkers();
				WorkplaceModel[] workplaces = ((ProductionBuilding)farm).Workplaces;
				int num2 = ((workplaces != null) ? workplaces.Length : 0);
				bool flag = GameAPI.HasFarmFieldWork(farm);
				bool active = false;
				Color color = WhiteColor;
				if (num == 0)
				{
					active = true;
					color = (flag ? RedColor : WhiteColor);
				}
				else if (flag && num < num2)
				{
					active = true;
					color = YellowColor;
				}
				ApplySnapshot(((Building)farm).Id, val, active, color, null);
			}
		}

		private static bool HasRelevantGatheringRecipe(ProductionBuilding building, HashSet<string> blockedIngredientGoods)
		{
			if ((Object)(object)((building != null) ? ((Building)building).BuildingModel : null) == (Object)null || blockedIngredientGoods == null || blockedIngredientGoods.Count == 0)
			{
				return false;
			}
			List<RecipeState> recipeStates = GetRecipeStates(building);
			if (recipeStates == null || recipeStates.Count == 0)
			{
				return false;
			}
			foreach (string blockedIngredientGood in blockedIngredientGoods)
			{
				if (string.IsNullOrWhiteSpace(blockedIngredientGood))
				{
					continue;
				}
				Settings settings = GameAPI.GetSettings();
				GoodModel val = ((settings != null) ? settings.GetGood(blockedIngredientGood) : null);
				if ((Object)(object)val == (Object)null || !((Building)building).BuildingModel.IsSourceOf(val))
				{
					continue;
				}
				foreach (RecipeState item in recipeStates)
				{
					if (item != null && item.active && RecipeProducesGood(building, item, blockedIngredientGood))
					{
						return true;
					}
				}
			}
			return false;
		}

		private static List<RecipeState> GetRecipeStates(ProductionBuilding building)
		{
			GathererHut val = (GathererHut)(object)((building is GathererHut) ? building : null);
			if (val == null)
			{
				return ((Camp)(((building is Camp) ? building : null)?)).state?.recipes;
			}
			return val.state?.recipes;
		}

		private static bool RecipeProducesGood(ProductionBuilding building, RecipeState recipeState, string blockedGood)
		{
			GathererHut val = (GathererHut)(object)((building is GathererHut) ? building : null);
			if (val == null)
			{
				Camp val2 = (Camp)(object)((building is Camp) ? building : null);
				if (val2 != null)
				{
					CampRecipeModel recipeModel = val2.GetRecipeModel(recipeState);
					return string.Equals((recipeModel != null) ? ((RecipeModel)recipeModel).GetProducedGood() : null, blockedGood, StringComparison.OrdinalIgnoreCase);
				}
				return false;
			}
			GathererHutRecipeModel recipeModel2 = val.GetRecipeModel(recipeState);
			return string.Equals((recipeModel2 != null) ? ((RecipeModel)recipeModel2).GetProducedGood() : null, blockedGood, StringComparison.OrdinalIgnoreCase);
		}

		private static void ApplySnapshot(int buildingId, GameObject icon, bool active, Color color, IReadOnlyList<string> productGoodIds)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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_0037: 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)
			IndicatorSnapshot indicatorSnapshot = new IndicatorSnapshot(active, color, productGoodIds);
			bool activeSelf = icon.activeSelf;
			Color currentIconColor = GetCurrentIconColor(icon);
			if (LastApplied.TryGetValue(buildingId, out var value) && value.Equals(indicatorSnapshot) && activeSelf == active && ColorsEqual(currentIconColor, color))
			{
				if (active && productGoodIds != null && productGoodIds.Count > 0)
				{
					RefreshProductIconRenderOrder(icon);
				}
				return;
			}
			icon.SetActive(active);
			foreach (SpriteRenderer baseIconRenderer in GetBaseIconRenderers(icon))
			{
				baseIconRenderer.color = color;
			}
			ApplyProductIcons(buildingId, icon, active ? productGoodIds : null);
			LastApplied[buildingId] = indicatorSnapshot;
		}

		private static Color GetCurrentIconColor(GameObject icon)
		{
			//IL_0009: 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_0024: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)icon == (Object)null)
			{
				return Color.clear;
			}
			SpriteRenderer val = GetBaseIconRenderers(icon).FirstOrDefault();
			if (!((Object)(object)val != (Object)null))
			{
				return Color.clear;
			}
			return val.color;
		}

		private static List<string> GetEnabledLowRecipeGoods(IWorkshop workshop, HashSet<string> lowGoods)
		{
			List<string> list = new List<string>();
			if (((workshop != null) ? workshop.Recipes : null) == null || lowGoods == null || lowGoods.Count == 0)
			{
				return list;
			}
			foreach (WorkshopRecipeState recipe in workshop.Recipes)
			{
				if (IsEnabledLowRecipe(recipe, lowGoods) && !list.Any((string g) => string.Equals(g, recipe.productName, StringComparison.OrdinalIgnoreCase)))
				{
					list.Add(recipe.productName);
					if (list.Count >= 4)
					{
						break;
					}
				}
			}
			return list;
		}

		private static bool HasCraftableEnabledLowRecipe(IWorkshop workshop, HashSet<string> lowGoods, Settings settings)
		{
			if (((workshop != null) ? workshop.Recipes : null) == null || lowGoods == null || lowGoods.Count == 0 || (Object)(object)settings == (Object)null)
			{
				return false;
			}
			foreach (WorkshopRecipeState recipe in workshop.Recipes)
			{
				if (IsEnabledLowRecipe(recipe, lowGoods))
				{
					WorkshopRecipeModel workshopRecipe = settings.GetWorkshopRecipe(((RecipeState)recipe).model);
					if ((Object)(object)workshopRecipe != (Object)null && Discovery.CanRecipeContinue(workshop, workshopRecipe))
					{
						return true;
					}
				}
			}
			return false;
		}

		private static void ApplyProductIcons(int buildingId, GameObject icon, IReadOnlyList<string> productGoodIds)
		{
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: 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_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)icon == (Object)null || productGoodIds == null || productGoodIds.Count == 0)
			{
				DestroyProductIcons(icon);
				return;
			}
			SpriteRenderer val = GetBaseIconRenderers(icon).FirstOrDefault((Func<SpriteRenderer, bool>)((SpriteRenderer r) => (Object)(object)((r != null) ? r.sprite : null) != (Object)null));
			if ((Object)(object)val == (Object)null)
			{
				DestroyProductIcons(icon);
				return;
			}
			GameObject orCreateProductIconsRoot = GetOrCreateProductIconsRoot(icon);
			if ((Object)(object)orCreateProductIconsRoot == (Object)null)
			{
				return;
			}
			Vector2 rendererSizeInIconSpace = GetRendererSizeInIconSpace(icon.transform, val);
			float num = Mathf.Max(0.01f, rendererSizeInIconSpace.y * ConfigManager.BuildingShortageIconScale) / 2.08f;
			float num2 = num * 0.08f;
			float num3 = Mathf.Max(rendererSizeInIconSpace.x * 0.55f + num * 0.5f, num * 1.15f);
			int num4 = 0;
			int i;
			for (i = 0; i < productGoodIds.Count; i++)
			{
				GoodInfo goodInfo = Discovery.Goods.FirstOrDefault((GoodInfo g) => string.Equals(g.Id, productGoodIds[i], StringComparison.OrdinalIgnoreCase));
				Sprite val2 = goodInfo?.Icon;
				if (!((Object)(object)val2 == (Object)null))
				{
					GameObject orCreateProductIcon = GetOrCreateProductIcon(orCreateProductIconsRoot, num4);
					SpriteRenderer component = orCreateProductIcon.GetComponent<SpriteRenderer>();
					if (!((Object)(object)component == (Object)null))
					{
						component.sprite = val2;
						component.color = WhiteColor;
						ConfigureProductIconRenderer(component, val, 1);
						ApplyProductIconBorder(orCreateProductIcon, val2, goodInfo.IsIngredientBlocked, val);
						int num5 = num4 % 2;
						int num6 = num4 / 2;
						float num7 = ((num5 == 0) ? ((num + num2) * 0.5f) : ((0f - (num + num2)) * 0.5f));
						orCreateProductIcon.transform.localPosition = new Vector3(num3 + (float)num6 * (num + num2), num7, 0f);
						orCreateProductIcon.transform.localRotation = Quaternion.identity;
						orCreateProductIcon.transform.localScale = Vector3.one * GetScaleForHeight(val2, num);
						orCreateProductIcon.SetActive(true);
						num4++;
					}
				}
			}
			for (int j = num4; j < orCreateProductIconsRoot.transform.childCount; j++)
			{
				((Component)orCreateProductIconsRoot.transform.GetChild(j)).gameObject.SetActive(false);
			}
			orCreateProductIconsRoot.SetActive(num4 > 0);
			if (num4 == 0)
			{
				DestroyProductIcons(icon);
				LastApplied.Remove(buildingId);
			}
		}

		private static GameObject GetOrCreateProductIconsRoot(GameObject icon)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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_005c: 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_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected O, but got Unknown
			Transform val = icon.transform.Find("StockAlertProductIcons");
			if ((Object)(object)val != (Object)null)
			{
				return ((Component)val).gameObject;
			}
			GameObject val2 = new GameObject("StockAlertProductIcons");
			val2.transform.SetParent(icon.transform, false);
			val2.transform.localPosition = new Vector3(0f, 0f, -0.05f);
			val2.transform.localRotation = Quaternion.identity;
			val2.transform.localScale = Vector3.one;
			return val2;
		}

		private static GameObject GetOrCreateProductIcon(GameObject root, int index)
		{
			//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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			while (root.transform.childCount <= index)
			{
				GameObject val = new GameObject("ProductIcon");
				val.transform.SetParent(root.transform, false);
				((Renderer)val.AddComponent<SpriteRenderer>()).material = new Material(Shader.Find("Sprites/Default"));
			}
			return ((Component)root.transform.GetChild(index)).gameObject;
		}

		private static void RefreshProductIconRenderOrder(GameObject icon)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			SpriteRenderer val = GetBaseIconRenderers(icon).FirstOrDefault((Func<SpriteRenderer, bool>)((SpriteRenderer r) => (Object)(object)((r != null) ? r.sprite : null) != (Object)null));
			object obj;
			if (icon == null)
			{
				obj = null;
			}
			else
			{
				Transform transform = icon.transform;
				obj = ((transform != null) ? transform.Find("StockAlertProductIcons") : null);
			}
			Transform val2 = (Transform)obj;
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null))
			{
				val2.localPosition = new Vector3(val2.localPosition.x, val2.localPosition.y, -0.05f);
				SpriteRenderer[] componentsInChildren = ((Component)val2).GetComponentsInChildren<SpriteRenderer>(true);
				foreach (SpriteRenderer obj2 in componentsInChildren)
				{
					int offset = ((!IsBorderPart(((Component)obj2).transform)) ? 1 : 2);
					ConfigureProductIconRenderer(obj2, val, offset);
				}
			}
		}

		private static void ApplyProductIconBorder(GameObject productIcon, Sprite sprite, bool active, SpriteRenderer baseRenderer)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			GameObject orCreateProductIconBorder = GetOrCreateProductIconBorder(productIcon);
			if (!((Object)(object)orCreateProductIconBorder == (Object)null))
			{
				orCreateProductIconBorder.SetActive(active);
				if (active && !((Object)(object)sprite == (Object)null))
				{
					Bounds bounds = sprite.bounds;
					Vector3 size = ((Bounds)(ref bounds)).size;
					float num = Mathf.Max(size.y * 0.08f, 0.01f);
					float num2 = size.x + num * 2f;
					float num3 = size.y + num * 2f;
					Transform obj = orCreateProductIconBorder.transform.Find("Top");
					ConfigureBorderPart((obj != null) ? ((Component)obj).GetComponent<SpriteRenderer>() : null, 0f, num3 * 0.5f - num * 0.5f, num2, num, baseRenderer);
					Transform obj2 = orCreateProductIconBorder.transform.Find("Bottom");
					ConfigureBorderPart((obj2 != null) ? ((Component)obj2).GetComponent<SpriteRenderer>() : null, 0f, (0f - num3) * 0.5f + num * 0.5f, num2, num, baseRenderer);
					Transform obj3 = orCreateProductIconBorder.transform.Find("Left");
					ConfigureBorderPart((obj3 != null) ? ((Component)obj3).GetComponent<SpriteRenderer>() : null, (0f - num2) * 0.5f + num * 0.5f, 0f, num, num3, baseRenderer);
					Transform obj4 = orCreateProductIconBorder.transform.Find("Right");
					ConfigureBorderPart((obj4 != null) ? ((Component)obj4).GetComponent<SpriteRenderer>() : null, num2 * 0.5f - num * 0.5f, 0f, num, num3, baseRenderer);
				}
			}
		}

		private static GameObject GetOrCreateProductIconBorder(GameObject productIcon)
		{
			//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_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: 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_00a8: 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_00c0: Expected O, but got Unknown
			if ((Object)(object)productIcon == (Object)null)
			{
				return null;
			}
			Transform val = productIcon.transform.Find("IngredientBlockedBorder");
			if ((Object)(object)val != (Object)null)
			{
				return ((Component)val).gameObject;
			}
			GameObject val2 = new GameObject("IngredientBlockedBorder");
			val2.transform.SetParent(productIcon.transform, false);
			val2.transform.localPosition = Vector3.zero;
			val2.transform.localRotation = Quaternion.identity;
			val2.transform.localScale = Vector3.one;
			CreateBorderPart(val2.transform, "Top");
			CreateBorderPart(val2.transform, "Bottom");
			CreateBorderPart(val2.transform, "Left");
			CreateBorderPart(val2.transform, "Right");
			val2.SetActive(false);
			return val2;
		}

		private static void CreateBorderPart(Transform parent, string name)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			SpriteRenderer obj = val.AddComponent<SpriteRenderer>();
			obj.sprite = GetSolidSprite();
			((Renderer)obj).material = new Material(Shader.Find("Sprites/Default"));
		}

		private static void ConfigureBorderPart(SpriteRenderer renderer, float x, float y, float width, float height, SpriteRenderer baseRenderer)
		{
			//IL_000b: 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_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)renderer == (Object)null))
			{
				renderer.color = BorderRedColor;
				ConfigureProductIconRenderer(renderer, baseRenderer, 2);
				((Component)renderer).transform.localPosition = new Vector3(x, y, 0f);
				((Component)renderer).transform.localRotation = Quaternion.identity;
				((Component)renderer).transform.localScale = new Vector3(width, height, 1f);
			}
		}

		private static void ConfigureProductIconRenderer(SpriteRenderer renderer, SpriteRenderer baseRenderer, int offset)
		{
			if (!((Object)(object)renderer == (Object)null) && !((Object)(object)baseRenderer == (Object)null))
			{
				if ((Object)(object)((Renderer)baseRenderer).sharedMaterial != (Object)null)
				{
					((Renderer)renderer).sharedMaterial = ((Renderer)baseRenderer).sharedMaterial;
				}
				((Renderer)renderer).sortingLayerID = ((Renderer)baseRenderer).sortingLayerID;
				((Renderer)renderer).sortingOrder = ((Renderer)baseRenderer).sortingOrder + 100 + offset;
			}
		}

		private static bool IsBorderPart(Transform transform)
		{
			if ((Object)(object)((transform != null) ? transform.parent : null) != (Object)null)
			{
				return string.Equals(((Object)transform.parent).name, "IngredientBlockedBorder", StringComparison.Ordinal);
			}
			return false;
		}

		private static Vector2 GetRendererSizeInIconSpace(Transform iconTransform, SpriteRenderer renderer)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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_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_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)iconTransform == (Object)null || (Object)(object)((renderer != null) ? renderer.sprite : null) == (Object)null)
			{
				return Vector2.one;
			}
			Bounds bounds = renderer.sprite.bounds;
			Vector3 size = ((Bounds)(ref bounds)).size;
			Vector3 val = iconTransform.InverseTransformVector(((Component)renderer).transform.TransformVector(new Vector3(size.x, 0f, 0f)));
			float magnitude = ((Vector3)(ref val)).magnitude;
			val = iconTransform.InverseTransformVector(((Component)renderer).transform.TransformVector(new Vector3(0f, size.y, 0f)));
			float magnitude2 = ((Vector3)(ref val)).magnitude;
			return new Vector2(Mathf.Max(0.01f, magnitude), Mathf.Max(0.01f, magnitude2));
		}

		private static float GetScaleForHeight(Sprite sprite, float targetHeight)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			float num;
			if (sprite == null)
			{
				num = 0f;
			}
			else
			{
				Bounds bounds = sprite.bounds;
				num = ((Bounds)(ref bounds)).size.y;
			}
			float num2 = num;
			if (!(num2 > 0.001f))
			{
				return 1f;
			}
			return targetHeight / num2;
		}

		private static Sprite GetSolidSprite()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			if ((Object)(object)_solidSprite != (Object)null)
			{
				return _solidSprite;
			}
			Texture2D val = new Texture2D(4, 4, (TextureFormat)5, false)
			{
				filterMode = (FilterMode)0,
				wrapMode = (TextureWrapMode)1,
				hideFlags = (HideFlags)61
			};
			val.SetPixels(Enumerable.Repeat<Color>(Color.white, 16).ToArray());
			val.Apply(false, true);
			_solidSprite = Sprite.Create(val, new Rect(0f, 0f, 4f, 4f), new Vector2(0.5f, 0.5f), 4f);
			return _solidSprite;
		}

		private static IEnumerable<SpriteRenderer> GetBaseIconRenderers(GameObject icon)
		{
			return from r in icon.GetComponentsInChildren<SpriteRenderer>(true)
				where (Object)(object)r != (Object)null && !IsProductIconTransform(((Component)r).transform)
				select r;
		}

		private static bool IsProductIconTransform(Transform transform)
		{
			while ((Object)(object)transform != (Object)null)
			{
				if (string.Equals(((Object)transform).name, "StockAlertProductIcons", StringComparison.Ordinal))
				{
					return true;
				}
				transform = transform.parent;
			}
			return false;
		}

		private static void RemoveProductIcons(int buildingId)
		{
			foreach (IWorkshop recipeBuilding in GetRecipeBuildings())
			{
				if (recipeBuilding == null)
				{
					continue;
				}
				ProductionBuilding @base = recipeBuilding.Base;
				if (((@base != null) ? new int?(((Building)@base).Id) : null) != buildingId)
				{
					continue;
				}
				BuildingView buildingView = ((Building)recipeBuilding.Base).BuildingView;
				object icon;
				if (buildingView == null)
				{
					icon = null;
				}
				else
				{
					Transform transform = ((Component)buildingView).transform;
					if (transform == null)
					{
						icon = null;
					}
					else
					{
						Transform obj = transform.Find("ToRotate/UI/NoWorkersIcon");
						icon = ((obj != null) ? ((Component)obj).gameObject : null);
					}
				}
				DestroyProductIcons((GameObject)icon);
				return;
			}
			foreach (Farm farmBuilding in GameAPI.GetFarmBuildings())
			{
				if (farmBuilding == null || ((Building)farmBuilding).Id != buildingId)
				{
					continue;
				}
				BuildingView buildingView2 = ((Building)farmBuilding).BuildingView;
				object icon2;
				if (buildingView2 == null)
				{
					icon2 = null;
				}
				else
				{
					Transform transform2 = ((Component)buildingView2).transform;
					if (transform2 == null)
					{
						icon2 = null;
					}
					else
					{
						Transform obj2 = transform2.Find("ToRotate/UI/NoWorkersIcon");
						icon2 = ((obj2 != null) ? ((Component)obj2).gameObject : null);
					}
				}
				DestroyProductIcons((GameObject)icon2);
				break;
			}
		}

		private static void DestroyProductIcons(GameObject icon)
		{
			object obj;
			if (icon == null)
			{
				obj = null;
			}
			else
			{
				Transform transform = icon.transform;
				obj = ((transform != null) ? transform.Find("StockAlertProductIcons") : null);
			}
			Transform val = (Transform)obj;
			if ((Object)(object)val != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)val).gameObject);
			}
		}

		private static void RestoreVanillaFor(ProductionBuilding building)
		{
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			BuildingView buildingView = ((Building)building).BuildingView;
			object obj;
			if (buildingView == null)
			{
				obj = null;
			}
			else
			{
				Transform transform = ((Component)buildingView).transform;
				if (transform == null)
				{
					obj = null;
				}
				else
				{
					Transform obj2 = transform.Find("ToRotate/UI/NoWorkersIcon");
					obj = ((obj2 != null) ? ((Component)obj2).gameObject : null);
				}
			}
			GameObject val = (GameObject)obj;
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			MakeIconClickThrough(val);
			bool active = ((Building)building).BuildingState != null && ((Building)building).BuildingState.finished && !((Building)building).BuildingState.isSleeping && building.CountWorkers() == 0;
			val.SetActive(active);
			foreach (SpriteRenderer baseIconRenderer in GetBaseIconRenderers(val))
			{
				baseIconRenderer.color = WhiteColor;
			}
			DestroyProductIcons(val);
		}

		private static bool ColorsEqual(Color a, Color b)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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_0039: 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)
			if (Mathf.Approximately(a.r, b.r) && Mathf.Approximately(a.g, b.g) && Mathf.Approximately(a.b, b.b))
			{
				return Mathf.Approximately(a.a, b.a);
			}
			return false;
		}

		private static void MakeIconClickThrough(GameObject icon)
		{
			if ((Object)(object)icon == (Object)null)
			{
				return;
			}
			Graphic[] componentsInChildren = icon.GetComponentsInChildren<Graphic>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].raycastTarget = false;
			}
			Selectable[] componentsInChildren2 = icon.GetComponentsInChildren<Selectable>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				componentsInChildren2[i].interactable = false;
			}
			GraphicRaycaster[] componentsInChildren3 = icon.GetComponentsInChildren<GraphicRaycaster>(true);
			for (int i = 0; i < componentsInChildren3.Length; i++)
			{
				((Behaviour)componentsInChildren3[i]).enabled = false;
			}
			EventTrigger[] componentsInChildren4 = icon.GetComponentsInChildren<EventTrigger>(true);
			for (int i = 0; i < componentsInChildren4.Length; i++)
			{
				((Behaviour)componentsInChildren4[i]).enabled = false;
			}
			Component[] componentsInChildren5 = icon.GetComponentsInChildren<Component>(true);
			foreach (Component val in componentsInChildren5)
			{
				Type type = ((object)val)?.GetType();
				if (!(type == null) && type.Name.IndexOf("Collider", StringComparison.Ordinal) >= 0)
				{
					PropertyInfo property = type.GetProperty("enabled");
					if (property != null && property.CanWrite)
					{
						property.SetValue(val, false, null);
					}
				}
			}
		}

		private static bool IsEnabledLowRecipe(WorkshopRecipeState recipeState, HashSet<string> lowGoods)
		{
			if (recipeState == null || !((RecipeState)recipeState).active || string.IsNullOrWhiteSpace(recipeState.productName) || !lowGoods.Contains(recipeState.productName))
			{
				return false;
			}
			return true;
		}

		private static bool IsEnabledGatheringSupplyRecipe(WorkshopRecipeState recipeState, HashSet<string> blockedIngredientGoods, Settings settings)
		{
			if (recipeState == null || !((RecipeState)recipeState).active || blockedIngredientGoods == null || blockedIngredientGoods.Count == 0 || string.IsNullOrWhiteSpace(recipeState.productName) || !blockedIngredientGoods.Contains(recipeState.productName))
			{
				return false;
			}
			WorkshopRecipeModel val = ((settings != null) ? settings.GetWorkshopRecipe(((RecipeState)recipeState).model) : null);
			if (val?.requiredGoods != null)
			{
				return val.requiredGoods.Length == 0;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(ProductionBuildingView), "ShowWorkers")]
	internal static class BuildingAlertIndicatorsViewPatch
	{
		[HarmonyPostfix]
		private static void ShowWorkersPostfix(ProductionBuildingView __instance)
		{
			if (!((Object)(object)__instance == (Object)null) && GameAPI.IsGameActive())
			{
				BuildingAlertIndicators.RefreshForView(__instance);
			}
		}
	}
	internal sealed class IdleBuilderRaceMenuMarker : MonoBehaviour
	{
		private RacesMenuSlot _slot;

		private GameObject _markerObject;

		private Image _markerImage;

		private float _nextRefreshTime;

		public static void Attach(RacesMenuSlot slot)
		{
			if (!((Object)(object)slot == (Object)null))
			{
				IdleBuilderRaceMenuMarker component = ((Component)slot).GetComponent<IdleBuilderRaceMenuMarker>();
				if ((Object)(object)component == (Object)null)
				{
					component = ((Component)slot).gameObject.AddComponent<IdleBuilderRaceMenuMarker>();
					component.Initialize(slot);
				}
				else
				{
					component.Initialize(slot);
				}
			}
		}

		private void Initialize(RacesMenuSlot slot)
		{
			_slot = slot;
			CleanupLegacyMarkers();
			Refresh();
		}

		private void OnEnable()
		{
			Refresh();
		}

		private void Update()
		{
			if (!(Time.unscaledTime < _nextRefreshTime))
			{
				_nextRefreshTime = Time.unscaledTime + 0.25f;
				Refresh();
			}
		}

		private void Refresh()
		{
			if ((Object)(object)_slot == (Object)null || !ConfigManager.ShowBuilderStatusIcons || !ConfigManager.ShowIdleBuilderStatusIcons)
			{
				Hide();
				return;
			}
			RaceModel race = _slot.GetRace();
			if ((Object)(object)race == (Object)null || !BuilderStatusIndicators.HasIdleBuilderOfRace(race))
			{
				Hide();
				return;
			}
			Sprite idleBuilderSprite = BuilderStatusIndicators.GetIdleBuilderSprite();
			if ((Object)(object)idleBuilderSprite == (Object)null)
			{
				Hide();
				return;
			}
			EnsureMarker();
			if (!((Object)(object)_markerImage == (Object)null))
			{
				_markerImage.sprite = idleBuilderSprite;
				_markerObject.SetActive(true);
			}
		}

		private void EnsureMarker()
		{
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_markerObject != (Object)null) && !((Object)(object)_slot == (Object)null))
			{
				Transform obj = ((Component)_slot).transform.Find("Content");
				RectTransform val = (RectTransform)(object)((obj is RectTransform) ? obj : null);
				if ((Object)(object)val == (Object)null)
				{
					val = ((Component)_slot).GetComponent<RectTransform>();
				}
				if (!((Object)(object)val == (Object)null))
				{
					_markerObject = new GameObject("StockAlertIdleBuilderRaceMarker", new Type[3]
					{
						typeof(RectTransform),
						typeof(CanvasRenderer),
						typeof(Image)
					});
					_markerObject.transform.SetParent((Transform)(object)val, false);
					_markerImage = _markerObject.GetComponent<Image>();
					((Graphic)_markerImage).raycastTarget = false;
					_markerImage.preserveAspect = true;
					RectTransform component = _markerObject.GetComponent<RectTransform>();
					component.anchorMin = new Vector2(0f, 0.5f);
					component.anchorMax = new Vector2(0f, 0.5f);
					component.pivot = new Vector2(0.5f, 0.5f);
					component.sizeDelta = new Vector2(22f, 22f);
					component.anchoredPosition = new Vector2(-2f, 0f);
					_markerObject.transform.SetAsLastSibling();
					_markerObject.SetActive(false);
				}
			}
		}

		private void CleanupLegacyMarkers()
		{
			if (!((Object)(object)_slot == (Object)null))
			{
				Transform val = ((Component)_slot).transform.Find("Content");
				if (!((Object)(object)val == (Object)null))
				{
					DestroyChild(val, "IdleBuilderRaceMarker");
					DestroyChild(val, "StockAlertIdleBuilderRaceMarker");
					_markerObject = null;
					_markerImage = null;
				}
			}
		}

		private static void DestroyChild(Transform parent, string childName)
		{
			Transform val = parent.Find(childName);
			if ((Object)(object)val != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)val).gameObject);
			}
		}

		private void Hide()
		{
			if ((Object)(object)_markerObject != (Object)null)
			{
				_markerObject.SetActive(false);
			}
		}
	}
	internal static class IdleBuildersAlert
	{
		public const string AlertPrefix = "You have idle builders:";

		private static News _activeNews;

		private static string _lastContent;

		public static void Refresh()
		{
			if (!ConfigManager.ShowIdleBuildersAlert || !GameAPI.IsGameActive())
			{
				Clear();
				return;
			}
			int idleBuilderCount = BuilderStatusIndicators.GetIdleBuilderCount();
			if (idleBuilderCount <= 0)
			{
				Clear();
				return;
			}
			string content = BuildContent(idleBuilderCount);
			List<News> currentNews = GameAPI.GetCurrentNews();
			News val = ((IEnumerable<News>)currentNews).FirstOrDefault((Func<News, bool>)((News news) => news != null && news.content == content));
			if (val != null)
			{
				_activeNews = val;
				_lastContent = content;
				return;
			}
			if (_activeNews != null)
			{
				GameAPI.RemoveNews(_activeNews);
				_activeNews = null;
			}
			if (!(_lastContent == content) || !currentNews.Any((News news) => news != null && news.content != null && news.content.StartsWith("You have idle builders:")))
			{
				_activeNews = GameAPI.PublishNews(content, null, (AlertSeverity)1);
				_lastContent = content;
			}
		}

		public static void Clear()
		{
			if (_activeNews != null)
			{
				GameAPI.RemoveNews(_activeNews);
				_activeNews = null;
			}
			_lastContent = null;
		}

		private static string BuildContent(int count)
		{
			IReadOnlyList<string> idleBuilderRaceSummaries = BuilderStatusIndicators.GetIdleBuilderRaceSummaries();
			if (idleBuilderRaceSummaries.Count == 0)
			{
				return string.Format("{0} {1}", "You have idle builders:", count);
			}
			string arg = string.Join("\n", idleBuilderRaceSummaries);
			return string.Format("{0} {1}\n{2}", "You have idle builders:", count, arg);
		}
	}
	internal static class ItemLocatorOverlay
	{
		private const float MarkerHeightOffset = 0.55f;

		private static readonly Dictionary<string, GameObject> Markers = new Dictionary<string, GameObject>(StringComparer.OrdinalIgnoreCase);

		private static string _trackedGoodId;

		private static GameObject _template;

		private static string _lastToggledGoodId;

		private static int _lastToggleFrame = -1;

		public static bool IsTracking => !string.IsNullOrWhiteSpace(_trackedGoodId);

		public static void Toggle(string goodId)
		{
			if (!string.IsNullOrWhiteSpace(goodId) && (_lastToggleFrame != Time.frameCount || !string.Equals(_lastToggledGoodId, goodId, StringComparison.OrdinalIgnoreCase)))
			{
				_lastToggleFrame = Time.frameCount;
				_lastToggledGoodId = goodId;
				if (string.Equals(_trackedGoodId, goodId, StringComparison.OrdinalIgnoreCase))
				{
					Clear();
					return;
				}
				_trackedGoodId = goodId;
				Refresh();
			}
		}

		public static void Clear()
		{
			_trackedGoodId = null;
			foreach (GameObject value in Markers.Values)
			{
				if ((Object)(object)value != (Object)null)
				{
					Object.Destroy((Object)(object)value);
				}
			}
			Markers.Clear();
		}

		public static void Refresh()
		{
			if (!GameAPI.IsGameActive() || string.IsNullOrWhiteSpace(_trackedGoodId))
			{
				Clear();
				return;
			}
			Settings settings = GameAPI.GetSettings();
			Sprite val = ((settings != null) ? settings.GetGood(_trackedGoodId) : null)?.icon;
			if ((Object)(object)val == (Object)null)
			{
				Clear();
				return;
			}
			GameObject val2 = ResolveTemplate();
			if ((Object)(object)val2 == (Object)null)
			{
				Clear();
				return;
			}
			List<TrackedItemLocation> trackedItemLocations = GameAPI.GetTrackedItemLocations(_trackedGoodId);
			HashSet<string> seen = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			foreach (TrackedItemLocation item in trackedItemLocations.Where((TrackedItemLocation l) => l != null && !string.IsNullOrWhiteSpace(l.Key)))
			{
				UpsertMarker(item, val, val2);
				seen.Add(item.Key);
			}
			foreach (string item2 in Markers.Keys.Where((string key) => !seen.Contains(key)).ToList())
			{
				if (Markers.TryGetValue(item2, out var value) && (Object)(object)value != (Object)null)
				{
					Object.Destroy((Object)(object)value);
				}
				Markers.Remove(item2);
			}
		}

		private static void UpsertMarker(TrackedItemLocation location, Sprite icon, GameObject template)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			Vector3 markerWorldPosition = GetMarkerWorldPosition(location);
			if (!Markers.TryGetValue(location.Key, out var value) || (Object)(object)value == (Object)null)
			{
				value = Object.Instantiate<GameObject>(template, template.transform.parent);
				((Object)value).name = "StockAlertItemLocator_" + location.Key;
				Markers[location.Key] = value;
			}
			ApplyVisuals(value, icon, location);
			ApplyTarget(value, markerWorldPosition);
			value.SetActive(true);
		}

		private static void ApplyVisuals(GameObject marker, Sprite icon, TrackedItemLocation location)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			Transform obj = marker.transform.Find("Icon");
			object obj2 = ((obj != null) ? ((Component)obj).GetComponent<Image>() : null);
			if (obj2 == null)
			{
				Transform obj3 = marker.transform.Find("Mask/Icon");
				obj2 = ((obj3 != null) ? ((Component)obj3).GetComponent<Image>() : null);
			}
			Image val = (Image)obj2;
			if ((Object)(object)val != (Object)null)
			{
				val.sprite = icon;
				val.preserveAspect = true;
				((Graphic)val).color = Color.white;
				((Graphic)val).raycastTarget = false;
			}
			Transform val2 = marker.transform.Find("Grade");
			if ((Object)(object)val2 != (Object)null)
			{
				((Component)val2).gameObject.SetActive(false);
			}
			Transform obj4 = marker.transform.Find("BG");
			Image val3 = ((obj4 != null) ? ((Component)obj4).GetComponent<Image>() : null);
			if ((Object)(object)val3 != (Object)null)
			{
				((Graphic)val3).raycastTarget = false;
			}
			Image[] componentsInChildren = marker.GetComponentsInChildren<Image>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				((Graphic)componentsInChildren[i]).raycastTarget = false;
			}
			ApplyAmountBadge(marker, location);
		}

		private static void ApplyAmountBadge(GameObject marker, TrackedItemLocation location)
		{
			GameObject orCreateAmountBadge = GetOrCreateAmountBadge(marker);
			if ((Object)(object)orCreateAmountBadge == (Object)null)
			{
				return;
			}
			bool flag = location != null && location.Amount > 0 && location.Key.StartsWith("building:", StringComparison.OrdinalIgnoreCase);
			orCreateAmountBadge.SetActive(flag);
			if (flag)
			{
				TextMeshProUGUI componentInChildren = orCreateAmountBadge.GetComponentInChildren<TextMeshProUGUI>(true);
				if ((Object)(object)componentInChildren != (Object)null)
				{
					((TMP_Text)componentInChildren).text = location.Amount.ToString();
				}
			}
		}

		private static GameObject GetOrCreateAmountBadge(GameObject marker)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: 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_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: 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_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			Transform val = marker.transform.Find("StockAlertAmountBadge");
			if ((Object)(object)val != (Object)null)
			{
				return ((Component)val).gameObject;
			}
			RectTransform val2 = marker.GetComponent<RectTransform>() ?? marker.GetComponentInChildren<RectTransform>(true);
			if ((Object)(object)val2 == (Object)null)
			{
				return null;
			}
			GameObject val3 = new GameObject("StockAlertAmountBadge", new Type[1] { typeof(RectTransform) });
			RectTransform component = val3.GetComponent<RectTransform>();
			((Transform)component).SetParent((Transform)(object)val2, false);
			component.anchorMin = new Vector2(1f, 0f);
			component.anchorMax = new Vector2(1f, 0f);
			component.pivot = new Vector2(1f, 0f);
			component.anchoredPosition = new Vector2(8f, -8f);
			component.sizeDelta = new Vector2(32f, 20f);
			GameObject val4 = new GameObject("Text", new Type[2]
			{
				typeof(RectTransform),
				typeof(TextMeshProUGUI)
			});
			RectTransform component2 = val4.GetComponent<RectTransform>();
			((Transform)component2).SetParent((Transform)(object)component, false);
			component2.anchorMin = Vector2.zero;
			component2.anchorMax = Vector2.one;
			component2.offsetMin = Vector2.zero;
			component2.offsetMax = Vector2.zero;
			TextMeshProUGUI component3 = val4.GetComponent<TextMeshProUGUI>();
			((TMP_Text)component3).font = TMP_Settings.defaultFontAsset;
			((TMP_Text)component3).fontSize = 15f;
			((TMP_Text)component3).enableAutoSizing = false;
			((TMP_Text)component3).fontStyle = (FontStyles)1;
			((TMP_Text)component3).alignment = (TextAlignmentOptions)514;
			((Graphic)component3).color = new Color(1f, 0.99f, 0.9f, 1f);
			((Graphic)component3).raycastTarget = false;
			((TMP_Text)component3).margin = new Vector4(1f, 0f, 1f, 0f);
			((TMP_Text)component3).fontSharedMaterial = ((TMP_Text)component3).fontMaterial;
			((TMP_Text)component3).outlineWidth = 0.25f;
			((TMP_Text)component3).outlineColor = Color32.op_Implicit(new Color(0.05f, 0.05f, 0.05f, 1f));
			return val3;
		}

		private static void ApplyTarget(GameObject marker, Vector3 worldPosition)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			WorldIndicator val = marker.GetComponent<WorldIndicator>();
			if ((Object)(object)val == (Object)null)
			{
				val = marker.GetComponentInChildren<WorldIndicator>(true);
			}
			if (val != null)
			{
				val.SetTarget(worldPosition);
			}
		}

		private static Vector3 GetMarkerWorldPosition(TrackedItemLocation location)
		{
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: 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_0087: 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_00a3: Unknown result type (might be due to invalid IL or missing references)
			Object source = location.Source;
			Component val = (Component)(object)((source is Component) ? source : null);
			if (val != null && (Object)(object)val != (Object)null)
			{
				Renderer[] array = (from renderer in val.GetComponentsInChildren<Renderer>(true)
					where (Object)(object)renderer != (Object)null && !IsLocatorRenderer(((Component)renderer).transform)
					select renderer).ToArray();
				if (array.Length != 0)
				{
					Bounds bounds = array[0].bounds;
					for (int i = 1; i < array.Length; i++)
					{
						((Bounds)(ref bounds)).Encapsulate(array[i].bounds);
					}
					return new Vector3(((Bounds)(ref bounds)).center.x, ((Bounds)(ref bounds)).max.y + 0.55f, ((Bounds)(ref bounds)).center.z);
				}
			}
			return location.FallbackPosition + new Vector3(0f, 0.55f, 0f);
		}

		private static bool IsLocatorRenderer(Transform transform)
		{
			while ((Object)(object)transform != (Object)null)
			{
				if (((Object)transform).name.StartsWith("StockAlertItemLocator_", StringComparison.Ordinal))
				{
					return true;
				}
				transform = transform.parent;
			}
			return false;
		}

		private static GameObject ResolveTemplate()
		{
			if ((Object)(object)_template != (Object)null)
			{
				return _template;
			}
			DepositIndicator? obj = ((IEnumerable<DepositIndicator>)Resources.FindObjectsOfTypeAll<DepositIndicator>()).FirstOrDefault((Func<DepositIndicator, bool>)IsSceneObject);
			object obj2 = ((obj != null) ? ((Component)obj).gameObject : null);
			if (obj2 == null)
			{
				LakeIndicator? obj3 = ((IEnumerable<LakeIndicator>)Resources.FindObjectsOfTypeAll<LakeIndicator>()).FirstOrDefault((Func<LakeIndicator, bool>)IsSceneObject);
				obj2 = ((obj3 != null) ? ((Component)obj3).gameObject : null);
				if (obj2 == null)
				{
					OreIndicator? obj4 = ((IEnumerable<OreIndicator>)Resources.FindObjectsOfTypeAll<OreIndicator>()).FirstOrDefault((Func<OreIndicator, bool>)IsSceneObject);
					obj2 = ((obj4 != null) ? ((Component)obj4).gameObject : null);
					if (obj2 == null)
					{
						BuildingIndicator? obj5 = ((IEnumerable<BuildingIndicator>)Resources.FindObjectsOfTypeAll<BuildingIndicator>()).FirstOrDefault((Func<BuildingIndicator, bool>)IsSceneObject);
						obj2 = ((obj5 != null) ? ((Component)obj5).gameObject : null);
					}
				}
			}
			_template = (GameObject)obj2;
			return _template;
		}

		private static bool IsSceneObject(Component component)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)component != (Object)null)
			{
				Scene scene = component.gameObject.scene;
				return ((Scene)(ref scene)).IsValid();
			}
			return false;
		}
	}
	internal sealed class QueuedWorkerSlotCompanion : MonoBehaviour
	{
		private static readonly List<QueuedWorkerSlotCompanion> Instances = new List<QueuedWorkerSlotCompanion>();

		private static FieldInfo _fiBuilding;

		private static FieldInfo _fiWorkplace;

		private static FieldInfo _fiRaceIcon;

		private static PropertyInfo _piIsRemoved;

		private static PropertyInfo _piReactiveValue;

		private BuildingWorkerSlot _slot;

		private GameObject _queuedIconObject;

		private Image _queuedIconImage;

		private Button _queuedIconButton;

		private float _nextRefreshTime;

		public static void Attach(BuildingWorkerSlot slot)
		{
			if (!((Object)(object)slot == (Object)null) && !((Object)(object)((Component)slot).GetComponent<QueuedWorkerSlotCompanion>() != (Object)null))
			{
				((Component)slot).gameObject.AddComponent<QueuedWorkerSlotCompanion>().Initialize(slot);
			}
		}

		public static void ClearAll()
		{
			QueuedWorkerSlotCompanion[] array = Instances.ToArray();
			for (int i = 0; i < array.Length; i++)
			{
				array[i]?.Hide();
			}
		}

		private void Initialize(BuildingWorkerSlot slot)
		{
			_slot = slot;
			Instances.Add(this);
			EnsureUi();
			Refresh();
		}

		private void OnDestroy()
		{
			Instances.Remove(this);
		}

		private void Update()
		{
			if (!(Time.unscaledTime < _nextRefreshTime))
			{
				_nextRefreshTime = Time.unscaledTime + 0.25f;
				Refresh();
			}
		}

		private void Refresh()
		{
			if ((Object)(object)_slot == (Object)null)
			{
				Hide();
				return;
			}
			if (!ConfigManager.EnableQueuedWorkerAssignments)
			{
				Hide();
				return;
			}
			if (!TryGetContext(out var building, out var _, out var workplaceIndex))
			{
				Hide();
				return;
			}
			if (IsBuildingRemoved(building))
			{
				WorkerAssignmentQueue.ClearQueuedRace(building, workplaceIndex);
				Hide();
				return;
			}
			RaceModel queuedRace = WorkerAssignmentQueue.GetQueuedRace(building, workplaceIndex);
			if ((Object)(object)queuedRace == (Object)null)
			{
				Hide();
				return;
			}
			EnsureUi();
			_queuedIconImage.sprite = queuedRace.roundIcon;
			((Graphic)_queuedIconImage).material = null;
			_queuedIconObject.SetActive(true);
		}

		private bool TryGetContext(out ProductionBuilding building, out WorkplaceModel workplace, out int workplaceIndex)
		{
			building = null;
			workplace = null;
			workplaceIndex = -1;
			if ((Object)(object)_slot == (Object)null)
			{
				return false;
			}
			if ((object)_fiBuilding == null)
			{
				_fiBuilding = typeof(BuildingWorkerSlot).GetField("building", BindingFlags.Instance | BindingFlags.NonPublic);
			}
			if ((object)_fiWorkplace == null)
			{
				_fiWorkplace = typeof(BuildingWorkerSlot).GetField("workplace", BindingFlags.Instance | BindingFlags.NonPublic);
			}
			object? obj = _fiBuilding?.GetValue(_slot);
			building = (ProductionBuilding)((obj is ProductionBuilding) ? obj : null);
			object? obj2 = _fiWorkplace?.GetValue(_slot);
			workplace = (WorkplaceModel)((obj2 is WorkplaceModel) ? obj2 : null);
			if ((Object)(object)building == (Object)null || workplace == null)
			{
				return false;
			}
			workplaceIndex = building.GetIndexOf(workplace);
			return workplaceIndex >= 0;
		}

		private void EnsureUi()
		{
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Expected O, but got Unknown
			//IL_00ff: 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_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			if ((Object)(object)_queuedIconObject != (Object)null)
			{
				return;
			}
			if ((object)_fiRaceIcon == null)
			{
				_fiRaceIcon = typeof(BuildingWorkerSlot).GetField("raceIcon", BindingFlags.Instance | BindingFlags.NonPublic);
			}
			object? obj = _fiRaceIcon?.GetValue(_slot);
			Image val = (Image)((obj is Image) ? obj : null);
			if (!((Object)(object)val == (Object)null))
			{
				_queuedIconObject = Object.Instantiate<GameObject>(((Component)val).gameObject, ((Component)val).transform.parent, false);
				((Object)_queuedIconObject).name = "QueuedWorkerIcon";
				_queuedIconImage = _queuedIconObject.GetComponent<Image>();
				_queuedIconButton = _queuedIconObject.GetComponent<Button>();
				if ((Object)(object)_queuedIconButton == (Object)null)
				{
					_queuedIconButton = _queuedIconObject.AddComponent<Button>();
				}
				((UnityEventBase)_queuedIconButton.onClick).RemoveAllListeners();
				((UnityEvent)_queuedIconButton.onClick).AddListener(new UnityAction(OpenQueueMenu));
				RectTransform component = _queuedIconObject.GetComponent<RectTransform>();
				Rect rect = component.rect;
				float num;
				if (!(((Rect)(ref rect)).width > 0f))
				{
					num = Mathf.Max(32f, component.sizeDelta.x);
				}
				else
				{
					rect = component.rect;
					num = ((Rect)(ref rect)).width;
				}
				float num2 = num;
				component.anchoredPosition += new Vector2(0f - (num2 + 8f), 0f);
				_queuedIconObject.SetActive(false);
			}
		}

		private void OpenQueueMenu()
		{
			if (!ConfigManager.EnableQueuedWorkerAssignments || !TryGetContext(out var building, out var workplace, out var _))
			{
				return;
			}
			RacesMenu val = FindRacesMenu();
			if (!((Object)(object)val == (Object)null))
			{
				val.SetUp(_queuedIconObject.GetComponent<RectTransform>(), (Building)(object)building, (Action<RaceModel>)delegate(RaceModel race)
				{
					WorkerAssignmentQueue.SetQueuedRace(building, workplace, race);
				}, (Action)delegate
				{
					WorkerAssignmentQueue.ClearQueuedRace(building, workplace);
				});
			}
		}

		private static RacesMenu FindRacesMenu()
		{
			return ((IEnumerable<RacesMenu>)Resources.FindObjectsOfTypeAll<RacesMenu>()).FirstOrDefault((Func<RacesMenu, bool>)delegate(RacesMenu menu)
			{
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)menu != (Object)null)
				{
					Scene scene = ((Component)menu).gameObject.scene;
					return ((Scene)(ref scene)).IsValid();
				}
				return false;
			});
		}

		private static bool IsBuildingRemoved(ProductionBuilding building)
		{
			try
			{
				if ((object)_piIsRemoved == null)
				{
					_piIsRemoved = typeof(Building).GetProperty("IsRemoved", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				}
				object obj = _piIsRemoved?.GetValue(building, null);
				if (obj == null)
				{
					return false;
				}
				if ((object)_piReactiveValue == null)
				{
					_piReactiveValue = obj.GetType().GetProperty("Value", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				}
				object obj2 = _piReactiveValue?.GetValue(obj, null);
				bool flag = default(bool);
				int num;
				if (obj2 is bool)
				{
					flag = (bool)obj2;
					num = 1;
				}
				else
				{
					num = 0;
				}
				return (byte)((uint)num & (flag ? 1u : 0u)) != 0;
			}
			catch (Exception)
			{
				return false;
			}
		}

		private void Hide()
		{
			if ((Object)(object)_queuedIconObject != (Object)null)
			{
				_queuedIconObject.SetActive(false);
			}
		}
	}
	internal sealed class TrackedGoodClickTarget : MonoBehaviour, IPointerClickHandler, IEventSystemHandler
	{
		public string GoodId;

		public static void Attach(Component target, string goodId)
		{
			if (!((Object)(object)target == (Object)null) && !string.IsNullOrWhiteSpace(goodId))
			{
				TrackedGoodClickTarget trackedGoodClickTarget = target.GetComponent<TrackedGoodClickTarget>();
				if ((Object)(object)trackedGoodClickTarget == (Object)null)
				{
					trackedGoodClickTarget = target.gameObject.AddComponent<TrackedGoodClickTarget>();
				}
				trackedGoodClickTarget.GoodId = goodId;
			}
		}

		public void OnPointerClick(PointerEventData eventData)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			if (eventData != null && (int)eventData.button == 0 && IsModifierPressed() && !string.IsNullOrWhiteSpace(GoodId))
			{
				ItemLocatorOverlay.Toggle(GoodId);
				((AbstractEventData)eventData).Use();
			}
		}

		private static bool IsModifierPressed()
		{
			Keyboard current = Keyboard.current;
			if (current != null)
			{
				if (!((ButtonControl)current.leftCtrlKey).isPressed && !((ButtonControl)current.rightCtrlKey).isPressed)
				{
					return current.ctrlKey.isPressed;
				}
				return true;
			}
			if (!Input.GetKey((KeyCode)306))
			{
				return Input.GetKey((KeyCode)305);
			}
			return true;
		}
	}
	internal static class WarehouseHaulerIndicators
	{
		private sealed class WarehouseHaulerIndicator
		{
			private const float MarkerHeightOffset = 0.45f;

			private readonly Storage _storage;

			private readonly GameObject _root;

			private readonly SpriteRenderer _iconRenderer;

			private readonly TextMeshPro _countText;

			public WarehouseHaulerIndicator(Storage storage)
			{
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: Expected O, but got Unknown
				//IL_0028: 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_004d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0053: Expected O, but got Unknown
				//IL_007f: Unknown result type (might be due to invalid IL or missing references)
				//IL_008f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0099: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c9: Expected O, but got Unknown
				//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
				//IL_0104: Expected O, but got Unknown
				//IL_0130: Unknown result type (might be due to invalid IL or missing references)
				//IL_0194: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
				_storage = storage;
				_root = new GameObject("StockAlertWarehouseHaulers");
				_root.transform.localScale = Vector3.one * 0.62f;
				_root.AddComponent<BillboardToCamera>();
				GameObject val = new GameObject("Icon");
				val.transform.SetParent(_root.transform, false);
				val.transform.localPosition = new Vector3(-0.12f, 0f, 0f);
				val.transform.localScale = Vector3.one * 1.5f;
				_iconRenderer = val.AddComponent<SpriteRenderer>();
				((Renderer)_iconRenderer).material = new Material(Shader.Find("Sprites/Default"));
				_iconRenderer.sprite = GetHaulerSprite();
				((Renderer)_iconRenderer).sortingLayerName = "UI";
				((Renderer)_iconRenderer).sortingOrder = 5100;
				GameObject val2 = new GameObject("Count");
				val2.transform.SetParent(_root.transform, false);
				val2.transform.localPosition = new Vector3(0.26f, -0.03f, 0f);
				_countText = val2.AddComponent<TextMeshPro>();
				((TMP_Text)_countText).font = TMP_Settings.defaultFontAsset;
				((TMP_Text)_countText).alignment = (TextAlignmentOptions)514;
				((TMP_Text)_countText).textWrappingMode = (TextWrappingModes)0;
				((TMP_Text)_countText).fontSize = 5f;
				((TMP_Text)_countText).fontStyle = (FontStyles)1;
				((Graphic)_countText).color = Color.white;
				((TMP_Text)_countText).outlineColor = Color32.op_Implicit(Color.black);
				((TMP_Text)_countText).outlineWidth = 0.25f;
				_countText.renderer.sortingLayerName = "UI";
				_countText.renderer.sortingOrder = 5101;
			}

			public void Show(int haulers)
			{
				//IL_006a: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)_root == (Object)null))
				{
					if ((Object)(object)_countText != (Object)null)
					{
						((TMP_Text)_countText).text = haulers.ToString();
						((Behaviour)_countText).enabled = true;
					}
					if ((Object)(object)_iconRenderer != (Object)null)
					{
						_iconRenderer.sprite = GetHaulerSprite();
					}
					_root.transform.position = GetMarkerWorldPosition(_storage);
					if (!_root.activeSelf)
					{
						_root.SetActive(true);
					}
				}
			}

			private static Vector3 GetMarkerWorldPosition(Storage storage)
			{
				//IL_0034: 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_00db: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fb: 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_0119: Unknown result type (might be due to invalid IL or missing references)
				//IL_0123: 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_00c8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
				object obj;
				if (storage == null)
				{
					obj = null;
				}
				else
				{
					BuildingView buildingView = ((Building)storage).BuildingView;
					if (buildingView == null)
					{
						obj = null;
					}
					else
					{
						Transform transform = ((Component)buildingView).transform;
						obj = ((transform != null) ? transform.Find("ToRotate/UI/NoWorkersIcon") : null);
					}
				}
				Transform val = (Transform)obj;
				if ((Object)(object)val != (Object)null)
				{
					return val.position;
				}
				Renderer[] array = (((Object)(object)((storage != null) ? ((Building)storage).BuildingView : null) != (Object)null) ? (from renderer in ((Component)((Building)storage).BuildingView).GetComponentsInChildren<Renderer>(true)
					where (Object)(object)renderer != (Object)null && !IsHaulerIndicatorRenderer(((Component)renderer).transform)
					select renderer).ToArray() : Array.Empty<Renderer>());
				if (array.Length == 0)
				{
					if (!((Object)(object)((storage != null) ? ((Building)storage).BuildingView : null) != (Object)null))
					{
						return Vector3.zero;
					}
					return ((Component)((Building)storage).BuildingView).transform.position + new Vector3(0f, 2.4f, 0f);
				}
				Bounds bounds = array[0].bounds;
				for (int i = 1; i < array.Length; i++)
				{
					((Bounds)(ref bounds)).Encapsulate(array[i].bounds);
				}
				return new Vector3(((Bounds)(ref bounds)).center.x, ((Bounds)(ref bounds)).max.y + 0.45f, ((Bounds)(ref bounds)).center.z);
			}

			private static bool IsHaulerIndicatorRenderer(Transform transform)
			{
				while ((Object)(object)transform != (Object)null)
				{
					if (string.Equals(((Object)transform).name, "StockAlertWarehouseHaulers", StringComparison.Ordinal))
					{
						return true;
					}
					transform = transform.parent;
				}
				return false;
			}

			public void Destroy()
			{
				if ((Object)(object)_root != (Object)null)
				{
					Object.Destroy((Object)(object)_root);
				}
			}
		}

		private sealed class BillboardToCamera : MonoBehaviour
		{
			private void LateUpdate()
			{
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				Camera main = Camera.main;
				if ((Object)(object)main != (Object)null)
				{
					((Component)this).transform.forward = ((Component)main).transform.forward;
				}
			}
		}

		private static readonly Dictionary<int, WarehouseHaulerIndicator> ActiveIndicators = new Dictionary<int, WarehouseHaulerIndicator>();

		private static readonly FieldInfo LakePanelRetrieveButtonField = typeof(LakePanel).GetField("retrieveButton", BindingFlags.Instance | BindingFlags.NonPublic);

		private static Sprite _haulerSprite;

		private static Sprite _fallbackHaulerSprite;

		public static void Refresh()
		{
			if (!GameAPI.IsGameActive())
			{
				Clear();
				return;
			}
			HashSet<int> seenStorages = new HashSet<int>();
			foreach (Storage storageBuilding in GameAPI.GetStorageBuildings())
			{
				if ((Object)(object)((storageBuilding != null) ? ((Building)storageBuilding).BuildingView : null) == (Object)null || ((Building)storageBuilding).BuildingState == null || !((Building)storageBuilding).BuildingState.finished || ((Building)storageBuilding).BuildingState.isSleeping)
				{
					continue;
				}
				int num = ((ProductionBuilding)storageBuilding).CountWorkers();
				if (num > 0)
				{
					seenStorages.Add(((Building)storageBuilding).Id);
					if (!ActiveIndicators.TryGetValue(((Building)storageBuilding).Id, out var value))
					{
						value = new WarehouseHaulerIndicator(storageBuilding);
						ActiveIndicators[((Building)storageBuilding).Id] = value;
					}
					value.Show(num);
				}
			}
			foreach (int item in ActiveIndicators.Keys.Where((int id) => !seenStorages.Contains(id)).ToList())
			{
				ActiveIndicators[item].Destroy();
				ActiveIndicators.Remove(item);
			}
		}

		public static void Clear()
		{
			foreach (WarehouseHaulerIndicator value in ActiveIndicators.Values)
			{
				value.Destroy();
			}
			ActiveIndicators.Clear();
		}

		private static Sprite GetHaulerSprite()
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Expected O, but got Unknown
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Expected O, but got Unknown
			if ((Object)(object)_haulerSprite != (Object)null)
			{
				return _haulerSprite;
			}
			_haulerSprite = TryGetPondNetsSprite();
			if ((Object)(object)_haulerSprite != (Object)null)
			{
				return _haulerSprite;
			}
			if ((Object)(object)_fallbackHaulerSprite != (Object)null)
			{
				return _fallbackHaulerSprite;
			}
			Texture2D val = new Texture2D(64, 64, (TextureFormat)5, false)
			{
				filterMode = (FilterMode)1,
				wrapMode = (TextureWrapMode)1,
				hideFlags = (HideFlags)61
			};
			Color element = default(Color);
			((Color)(ref element))..ctor(0f, 0f, 0f, 0f);
			val.SetPixels(Enumerable.Repeat<Color>(element, 4096).ToArray());
			DrawHaulerIcon(val);
			val.Apply(false, true);
			_fallbackHaulerSprite = Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f), 64f);
			return _fallbackHaulerSprite;
		}

		private static Sprite TryGetPondNetsSprite()
		{
			try
			{
				LakePanel instance = LakePanel.Instance;
				object? obj = LakePanelRetrieveButtonField?.GetValue(instance);
				Button val = (Button)((obj is Button) ? obj : null);
				if ((Object)(object)val == (Object)null)
				{
					return null;
				}
				Transform obj2 = ((Component)val).transform.Find("Icon");
				object obj3 = ((obj2 != null) ? ((Component)obj2).GetComponent<Image>() : null);
				if (obj3 == null)
				{
					Transform obj4 = ((Component)val).transform.Find("Mask/Icon");
					obj3 = ((obj4 != null) ? ((Component)obj4).GetComponent<Image>() : null);
				}
				Image val2 = (Image)obj3;
				if ((Object)(object)((val2 != null) ? val2.sprite : null) != (Object)null)
				{
					return val2.sprite;
				}
				Image[] componentsInChildren = ((Component)val).GetComponentsInChildren<Image>(true);
				foreach (Image val3 in componentsInChildren)
				{
					if ((Object)(object)val3 != (Object)null && (Object)(object)val3 != (Object)(object)((Selectable)val).image && (Object)(object)val3.sprite != (Object)null && ((Object)val3).name.IndexOf("icon", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						return val3.sprite;
					}
				}
				return ((Object)(object)((Selectable)val).image != (Object)null) ? ((Selectable)val).image.sprite : null;
			}
			catch
			{
				return null;
			}
		}

		private static void DrawHaulerIcon(Texture2D texture)
		{
			//IL_008d: 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_00a8: 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_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: 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_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: 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_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)
			Color color = default(Color);
			((Color)(ref color))..ctor(0.03f, 0.02f, 0.015f, 1f);
			Color color2 = default(Color);
			((Color)(ref color2))..ctor(1f, 0.82f, 0.48f, 1f);
			Color color3 = default(Color);
			((Color)(ref color3))..ctor(0.98f, 0.62f, 0.13f, 1f);
			Color color4 = default(Color);
			((Color)(ref color4))..ctor(0.84f, 0.56f, 0.27f, 1f);
			Color color5 = default(Color);
			((Color)(ref color5))..ctor(1f, 0.92f, 0.52f, 1f);
			FillCircle(texture, 28, 44, 7, color);
			FillCircle(texture, 28, 44, 5, color2);
			FillEllipse(texture, 38, 41, 12, 9, color);
			FillEllipse(texture, 39, 42, 9, 7, color4);
			FillCircle(texture, 35, 45, 2, color5);
			DrawLine(texture, 30, 38, 22, 24, 8, color);
			DrawLine(texture, 30, 38, 22, 24, 5, color3);
			DrawLine(texture, 24, 34, 38, 40, 5, color);
			DrawLine(texture, 25, 35, 37, 40, 3, color2);
			DrawLine(texture, 23, 25, 14, 11, 5, color);
			DrawLine(texture, 23, 25, 14, 11, 3, color3);
			DrawLine(texture, 23, 25, 32, 11, 5, color);
			DrawLine(texture, 23, 25, 32, 11, 3, color3);
			DrawLine(texture, 14, 11, 9, 8, 4, color);
			DrawLine(texture, 32, 11, 38, 8, 4, color);
		}

		private static void FillCircle(Texture2D texture, int centerX, int centerY, int radius, Color color)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			FillEllipse(texture, centerX, centerY, radius, radius, color);
		}

		private static void FillEllipse(Texture2D texture, int centerX, int centerY, int radiusX, int radiusY, Color color)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			for (int i = centerY - radiusY; i <= centerY + radiusY; i++)
			{
				for (int j = centerX - radiusX; j <= centerX + radiusX; j++)
				{
					float num = (float)(j - centerX) / (float)radiusX;
					float num2 = (float)(i - centerY) / (float)radiusY;
					if (num * num + num2 * num2 <=