Decompiled source of StockAlert v1.2.4
StockAlert.dll
Decompiled 4 days ago
The result has been truncated due to the large size, download it to view full contents!
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.Orders; 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.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyCompany("StockAlert")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+d3ea5b21dc2e5f81c74dbea46e19dbb07e087adc")] [assembly: AssemblyProduct("StockAlert")] [assembly: AssemblyTitle("StockAlert")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] internal sealed class IsReadOnlyAttribute : Attribute { } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace StockAlert { public static class StockAlertInfo { public const string Id = "com.stockalert.ats"; public const string Name = "StockAlert"; public const string Version = "1.2.4"; } } 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_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown //IL_009d: 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) _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_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_002a: 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_0030: 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_0075: 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_005a: 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_001f: 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()) { continue; } ActorView actorView = ((Actor)builderVillager).ActorView; if ((Object)(object)actorView == (Object)null) { continue; } bool isIdle = IsVillagerIdle(builderVillager); Sprite statusSprite = GetStatusSprite(isIdle); 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); } } List<int> list = ActiveIndicators.Keys.Where((int id) => !seenVillagers.Contains(id)).ToList(); foreach (int item in list) { ActiveIndicators[item].Destroy(); ActiveIndicators.Remove(item); } } } private static Sprite GetStatusSprite(bool isIdle) { if (isIdle) { return ConfigManager.ShowIdleBuilderStatusIcons ? _idleSprite : null; } return ConfigManager.ShowBusyBuilderStatusIcons ? _builderSprite : null; } 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 || !GameAPI.CanConstructionUseBuilders(constructionBuilding)) { 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) { return ((Object)(object)villager.raceModel != (Object)null) ? villager.raceModel.GetDisplayNameFor(count) : villager.Race; } 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 villagersService = _piVillagersService?.GetValue(null, null); if (villagersService == null) { yield break; } if ((object)_piVillagers == null) { _piVillagers = villagersService.GetType().GetProperty("Villagers", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } if (!(_piVillagers?.GetValue(villagersService, null) is IDictionary villagers)) { yield break; } foreach (DictionaryEntry item in villagers) { object value = item.Value; Villager villager = (Villager)((value is Villager) ? value : null); if (villager != null && string.Equals(((Actor)villager).Profession, builderProfession, StringComparison.OrdinalIgnoreCase)) { yield return villager; } } } private static bool IsVillagerIdle(Villager villager) { //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: 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> { Count: not 0 } stack)) { 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; } return (Object)(object)_idleSprite != (Object)null && (Object)(object)_builderSprite != (Object)null; } 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); return (componentInChildren != null) ? componentInChildren.sprite : null; } 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); return (componentInChildren != null) ? componentInChildren.sprite : null; } 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_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) 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_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) int result; if (Active == other.Active) { Color color = Color; if (((Color)(ref color)).Equals(other.Color) && ShowProductIcons == other.ShowProductIcons && Mathf.Approximately(ProductIconScale, other.ProductIconScale)) { result = (string.Equals(ProductGoodsKey, other.ProductGoodsKey, StringComparison.Ordinal) ? 1 : 0); goto IL_0060; } } result = 0; goto IL_0060; IL_0060: return (byte)result != 0; } 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 val = recipeBuilding.Base; if (!((Object)(object)val == (Object)null)) { seenBuildings.Add(((Building)val).Id); ApplyIndicatorState(val, 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 (RainCatcher rainCatcherBuilding in GameAPI.GetRainCatcherBuildings()) { if (!((Object)(object)rainCatcherBuilding == (Object)null)) { seenBuildings.Add(((Building)rainCatcherBuilding).Id); ApplyRainCatcherIndicatorState(rainCatcherBuilding); } } List<int> list = LastApplied.Keys.Where((int id) => !seenBuildings.Contains(id)).ToList(); foreach (int item in list) { 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 obj2 = w.Base; obj = ((obj2 != null) ? ((Building)obj2).BuildingView : null); } return obj == buildingView; }); if ((Object)(object)((val != null) ? val.Base : null) == (Object)null) { RainCatcher val2 = ((IEnumerable<RainCatcher>)GameAPI.GetRainCatcherBuildings()).FirstOrDefault((Func<RainCatcher, bool>)((RainCatcher b) => (object)((b != null) ? ((Building)b).BuildingView : null) == buildingView)); if ((Object)(object)val2 != (Object)null) { ApplyRainCatcherIndicatorState(val2); } 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); ApplyIndicatorState(val.Base, val, lowGoods, blockedIngredientGoods, settings); } public static void RestoreVanilla() { HashSet<int> hashSet = new HashSet<int>(); foreach (IWorkshop recipeBuilding in GetRecipeBuildings()) { ProductionBuilding val = recipeBuilding.Base; if (!((Object)(object)val == (Object)null) && hashSet.Add(((Building)val).Id)) { RestoreVanillaFor(val); } } 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); } } foreach (RainCatcher rainCatcherBuilding in GameAPI.GetRainCatcherBuildings()) { if ((Object)(object)rainCatcherBuilding != (Object)null && hashSet.Add(((Building)rainCatcherBuilding).Id)) { RestoreVanillaFor((ProductionBuilding)(object)rainCatcherBuilding); } } 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_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: 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_013d: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0131: 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_006d: 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_0085: 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_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) 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_0069: 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_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0081: 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_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: 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 void ApplyRainCatcherIndicatorState(RainCatcher rainCatcher) { //IL_0069: 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_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0081: 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_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) BuildingView buildingView = ((Building)rainCatcher).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)rainCatcher).CountWorkers(); WorkplaceModel[] workplaces = ((ProductionBuilding)rainCatcher).Workplaces; int num2 = ((workplaces != null) ? workplaces.Length : 0); bool flag = GameAPI.CanRainCatcherFillWaterTank(rainCatcher); 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)rainCatcher).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)) { continue; } 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_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0091: 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_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: 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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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(); return ((Object)(object)val != (Object)null) ? val.color : Color.clear; } 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_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: 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_00db: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_022d: 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); float num2 = num / 2.08f; float num3 = num2 * 0.08f; float num4 = Mathf.Max(rendererSizeInIconSpace.x * 0.55f + num2 * 0.5f, num2 * 1.15f); int num5 = 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, num5); 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 num6 = num5 % 2; int num7 = num5 / 2; float num8 = ((num6 == 0) ? ((num2 + num3) * 0.5f) : ((0f - (num2 + num3)) * 0.5f)); orCreateProductIcon.transform.localPosition = new Vector3(num4 + (float)num7 * (num2 + num3), num8, 0f); orCreateProductIcon.transform.localRotation = Quaternion.identity; orCreateProductIcon.transform.localScale = Vector3.one * GetScaleForHeight(val2, num2); orCreateProductIcon.SetActive(true); num5++; } } } for (int num9 = num5; num9 < orCreateProductIconsRoot.transform.childCount; num9++) { ((Component)orCreateProductIconsRoot.transform.GetChild(num9)).gameObject.SetActive(false); } orCreateProductIconsRoot.SetActive(num5 > 0); if (num5 == 0) { DestroyProductIcons(icon); LastApplied.Remove(buildingId); } } private static GameObject GetOrCreateProductIconsRoot(GameObject icon) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) 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_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown while (root.transform.childCount <= index) { GameObject val = new GameObject("ProductIcon"); val.transform.SetParent(root.transform, false); SpriteRenderer val2 = val.AddComponent<SpriteRenderer>(); ((Renderer)val2).material = new Material(Shader.Find("Sprites/Default")); } return ((Component)root.transform.GetChild(index)).gameObject; } private static void RefreshProductIconRenderOrder(GameObject icon) { //IL_0066: 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_0080: 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 val3 in componentsInChildren) { int offset = ((!IsBorderPart(((Component)val3).transform)) ? 1 : 2); ConfigureProductIconRenderer(val3, val, offset); } } } private static void ApplyProductIconBorder(GameObject productIcon, Sprite sprite, bool active, SpriteRenderer baseRenderer) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_0063: 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_0085: Unknown result type (might be due to invalid IL or missing references) 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_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown GameObject val = new GameObject(name); val.transform.SetParent(parent, false); SpriteRenderer val2 = val.AddComponent<SpriteRenderer>(); val2.sprite = GetSolidSprite(); ((Renderer)val2).material = new Material(Shader.Find("Sprites/Default")); } private static void ConfigureBorderPart(SpriteRenderer renderer, float x, float y, float width, float height, SpriteRenderer baseRenderer) { //IL_0010: 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_0043: 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) 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) { return (Object)(object)((transform != null) ? transform.parent : null) != (Object)null && string.Equals(((Object)transform.parent).name, "IngredientBlockedBorder", StringComparison.Ordinal); } private static Vector2 GetRendererSizeInIconSpace(Transform iconTransform, SpriteRenderer renderer) { //IL_0036: 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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004c: 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_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_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0081: 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_0096: 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_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_00c4: 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_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) float num; if (sprite == null) { num = 0f; } else { Bounds bounds = sprite.bounds; num = ((Bounds)(ref bounds)).size.y; } float num2 = num; return (num2 > 0.001f) ? (targetHeight / num2) : 1f; } private static Sprite GetSolidSprite() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) 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 obj = recipeBuilding.Base; if (((obj != null) ? new int?(((Building)obj).Id) : ((int?)null)) != buildingId) { continue; } BuildingView buildingView = ((Building)recipeBuilding.Base).BuildingView; object obj2; if (buildingView == null) { obj2 = null; } else { Transform transform = ((Component)buildingView).transform; if (transform == null) { obj2 = null; } else { Transform obj3 = transform.Find("ToRotate/UI/NoWorkersIcon"); obj2 = ((obj3 != null) ? ((Component)obj3).gameObject : null); } } GameObject icon = (GameObject)obj2; DestroyProductIcons(icon); return; } foreach (Farm farmBuilding in GameAPI.GetFarmBuildings()) { if (farmBuilding == null || ((Building)farmBuilding).Id != buildingId) { continue; } BuildingView buildingView2 = ((Building)farmBuilding).BuildingView; object obj4; if (buildingView2 == null) { obj4 = null; } else { Transform transform2 = ((Component)buildingView2).transform; if (transform2 == null) { obj4 = null; } else { Transform obj5 = transform2.Find("ToRotate/UI/NoWorkersIcon"); obj4 = ((obj5 != null) ? ((Component)obj5).gameObject : null); } } GameObject icon2 = (GameObject)obj4; DestroyProductIcons(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_009a: 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_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_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_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) return Mathf.Approximately(a.r, b.r) && Mathf.Approximately(a.g, b.g) && Mathf.Approximately(a.b, b.b) && Mathf.Approximately(a.a, b.a); } private static void MakeIconClickThrough(GameObject icon) { if ((Object)(object)icon == (Object)null) { return; } Graphic[] componentsInChildren = icon.GetComponentsInChildren<Graphic>(true); foreach (Graphic val in componentsInChildren) { val.raycastTarget = false; } Selectable[] componentsInChildren2 = icon.GetComponentsInChildren<Selectable>(true); foreach (Selectable val2 in componentsInChildren2) { val2.interactable = false; } GraphicRaycaster[] componentsInChildren3 = icon.GetComponentsInChildren<GraphicRaycaster>(true); foreach (GraphicRaycaster val3 in componentsInChildren3) { ((Behaviour)val3).enabled = false; } EventTrigger[] componentsInChildren4 = icon.GetComponentsInChildren<EventTrigger>(true); foreach (EventTrigger val4 in componentsInChildren4) { ((Behaviour)val4).enabled = false; } Component[] componentsInChildren5 = icon.GetComponentsInChildren<Component>(true); foreach (Component val5 in componentsInChildren5) { Type type = ((object)val5)?.GetType(); if (type == null) { continue; } string name = type.Name; if (name.IndexOf("Collider", StringComparison.Ordinal) >= 0) { PropertyInfo property = type.GetProperty("enabled"); if (property != null && property.CanWrite) { property.SetValue(val5, 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); return val?.requiredGoods == null || val.requiredGoods.Length == 0; } } [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_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Expected O, but got Unknown //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0117: 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_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) 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); } List<string> list = Markers.Keys.Where((string key) => !seen.Contains(key)).ToList(); foreach (string item2 in list) { 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_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0071: 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_005b: 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); foreach (Image val4 in componentsInChildren) { ((Graphic)val4).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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Expected O, but got Unknown //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_0228: 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_0023: 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_00c7: 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_00e0: 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_00e9: 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_0065: 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_0094: 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_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) 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 num = 1; num < array.Length; num++) { ((Bounds)(ref bounds)).Encapsulate(array[num].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_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) int result; if ((Object)(object)component != (Object)null) { Scene scene = component.gameObject.scene; result = (((Scene)(ref scene)).IsValid() ? 1 : 0); } else { result = 0; } return (byte)result != 0; } } 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_0101: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Expected O, but got Unknown //IL_0119: 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_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016e: 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) int result; if ((Object)(object)menu != (Object)null) { Scene scene = ((Component)menu).gameObject.scene; result = (((Scene)(ref scene)).IsValid() ? 1 : 0); } else { result = 0; } return (byte)result != 0; }); } 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 static class TimedOrdersAlert { private const int OneMinuteThreshold = 60; private const int ThirtySecondsThreshold = 30; private static readonly HashSet<string> FiredAlerts = new HashSet<string>(StringComparer.Ordinal); private static readonly Dictionary<string, News> ActiveNews = new Dictionary<string, News>(StringComparer.Ordinal); public static void Refresh() { if (!ConfigManager.TimedOrdersAlert || !GameAPI.IsGameActive()) { Clear(); return; } List<GameAPI.TimedOrderInfo> activeTimedOrders = GameAPI.GetActiveTimedOrders(); HashSet<int> activeOrderIds = new HashSet<int>(activeTimedOrders.Select((GameAPI.TimedOrderInfo order) => order.Id)); ClearInactive(activeOrderIds); foreach (GameAPI.TimedOrderInfo item in activeTimedOrders) { if (item.TimeLeft <= 30f) { Fire(item, 30, "30 seconds", (AlertSeverity)3); } else if (item.TimeLeft <= 60f) { Fire(item, 60, "1 minute", (AlertSeverity)2); } } } public static void Clear() { foreach (News item in ActiveNews.Values.ToList()) { GameAPI.RemoveNews(item); } ActiveNews.Clear(); FiredAlerts.Clear(); } private static void Fire(GameAPI.TimedOrderInfo order, int threshold, string label, AlertSeverity severity) { //IL_007a: Unknown result type (might be due to invalid IL or missing references) string key = GetKey(order.Id, threshold); if (FiredAlerts.Add(key)) { if (threshold == 30) { RemoveNews(GetKey(order.Id, 60)); } string content = "Timed order: " + order.DisplayName + " has " + label + " left."; ActiveNews[key] = GameAPI.PublishNews(content, null, severity); } } private static void ClearInactive(HashSet<int> activeOrderIds) { foreach (string item in ActiveNews.Keys.ToList()) { if (!TryGetOrderId(item, out var orderId) || !activeOrderIds.Contains(orderId)) { RemoveNews(item); } } FiredAlerts.RemoveWhere((string key) => !TryGetOrderId(key, out var orderId2) || !activeOrderIds.Contains(orderId2)); } private static void RemoveNews(string key) { if (ActiveNews.TryGetValue(key, out var value)) { GameAPI.RemoveNews(value); ActiveNews.Remove(key); } } private static string GetKey(int orderId, int threshold) { return orderId + ":" + threshold; } private static bool TryGetOrderId(string key, out int orderId) { orderId = 0; int num = key?.IndexOf(':') ?? (-1); return num > 0 && int.TryParse(key.Substring(0, num), out orderId); } } 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_0005: 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) { return ((ButtonControl)current.leftCtrlKey).isPressed || ((ButtonControl)current.rightCtrlKey).isPressed || current.ctrlKey.isPressed; } return Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)305); } } 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_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_002a: 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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Expected O, but got Unknown //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Expected O, but got Unknown //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: 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_007d: 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_0038: 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_0150: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: 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_011f: 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_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: 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_00e0: 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_00e5: 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) { return ((Object)(object)((storage != null) ? ((Building)storage).BuildingView : null) != (Object)null) ? (((Component)((Building)storage).BuildingView).transform.position + new Vector3(0f, 2.4f, 0f)) : Vector3.zero; } Bounds bounds = array[0].bounds; for (int num = 1; num < array.Length; num++) { ((Bounds)(ref bounds)).Encapsulate(array[num].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_001f: 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); } } List<int> list = ActiveIndicators.Keys.Where((int id) => !seenStorages.Contains(id)).ToList(); foreach (int item in list) { 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_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0073: 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_0085: Expected O, but got Unknown //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_haulerSprite != (Object)null) { return _haulerSprite; } _haulerSprite = TryGetPondNetsSprite(); if ((Obje