Decompiled source of Stellogistics v2.0.1
Stellogistics.dll
Decompiled an hour ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("Stellogistics")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Shows combined Interplanetary Logistics (ILS) imports and exports per planet and star system on the Starmap.")] [assembly: AssemblyFileVersion("2.0.1.0")] [assembly: AssemblyInformationalVersion("2.0.1+6c5172b636f7a533ad8af5edcb994e655db816c8")] [assembly: AssemblyProduct("Stellogistics")] [assembly: AssemblyTitle("Stellogistics")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.0.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [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 Stellogistics { public static class LogisticsAggregator { private struct SupplyAvailability { public int HealthySupplierPlanetCount; public int SingleSupplierPlanetId; public int SingleSupplierStarId; public bool MultipleStarSystems; } private const double OneLightYearMeters = 2390000.0; private const int WarperItemId = 1210; public static LogisticsSummary AggregatePlanet(PlanetData planet, StellogisticsConfig config) { int galaxySeed = ((GameMain.galaxy != null) ? GameMain.galaxy.seed : 0); int num = ((planet != null) ? planet.astroId : 0); EItemCategoryFilter filterForAstro = config.GetFilterForAstro(galaxySeed, num); LogisticsSummary logisticsSummary = new LogisticsSummary { IsStarSystem = false, TargetAstroId = num, GalaxySeed = galaxySeed, ActiveCategoryFilter = filterForAstro, TargetName = ((planet != null) ? planet.displayName : "Unknown Planet") }; if (planet == null || GameMain.data == null) { return logisticsSummary; } Dictionary<int, CombinedLogisticsItem> exportsByItem = new Dictionary<int, CombinedLogisticsItem>(); Dictionary<int, CombinedLogisticsItem> importsByItem = new Dictionary<int, CombinedLogisticsItem>(); StationComponent[] gStationPool = GameMain.data.galacticTransport?.stationPool; int starId = ((planet.star != null) ? planet.star.id : (planet.id / 100)); AggregatePlanetStations(planet, starId, config.IncludeOrbitalCollectors.Value, EStarFilterMode.AllRemoteSlots, gStationPool, exportsByItem, importsByItem, null, null, ref logisticsSummary.TotalIlsCount, ref logisticsSummary.TotalCollectorCount, ref logisticsSummary.TotalWarperCount, ref logisticsSummary.TotalIdleShips, ref logisticsSummary.TotalWorkShips); logisticsSummary.ColonizedPlanetCount = (logisticsSummary.HasAnyStations ? 1 : 0); LinkHubItems(exportsByItem, importsByItem); FinalizeSummary(logisticsSummary, exportsByItem, importsByItem, config, planet.id, 0); string arg = ((logisticsSummary.TotalCollectorCount > 0) ? $", {logisticsSummary.TotalCollectorCount} OC" : ""); logisticsSummary.TargetSubtitle = $"Planet • {logisticsSummary.TotalIlsCount} ILS{arg}"; return logisticsSummary; } public static LogisticsSummary AggregateStar(StarData star, StellogisticsConfig config) { int galaxySeed = ((GameMain.galaxy != null) ? GameMain.galaxy.seed : 0); int num = ((star != null) ? star.astroId : 0); EItemCategoryFilter filterForAstro = config.GetFilterForAstro(galaxySeed, num); LogisticsSummary logisticsSummary = new LogisticsSummary { IsStarSystem = true, TargetAstroId = num, GalaxySeed = galaxySeed, ActiveCategoryFilter = filterForAstro, TargetName = ((star != null) ? (star.displayName + " System") : "Unknown System") }; if (star == null || star.planets == null || GameMain.data == null) { return logisticsSummary; } Dictionary<int, CombinedLogisticsItem> exportsByItem = new Dictionary<int, CombinedLogisticsItem>(); Dictionary<int, CombinedLogisticsItem> importsByItem = new Dictionary<int, CombinedLogisticsItem>(); Dictionary<int, HashSet<int>> exportPlanetsByItem = new Dictionary<int, HashSet<int>>(); Dictionary<int, HashSet<int>> importPlanetsByItem = new Dictionary<int, HashSet<int>>(); StationComponent[] gStationPool = GameMain.data.galacticTransport?.stationPool; EStarFilterMode value = config.StarSystemFilterMode.Value; bool value2 = config.IncludeOrbitalCollectors.Value; for (int i = 0; i < star.planets.Length; i++) { PlanetData val = star.planets[i]; if (val != null) { int totalIlsCount = logisticsSummary.TotalIlsCount; int totalCollectorCount = logisticsSummary.TotalCollectorCount; AggregatePlanetStations(val, star.id, value2, value, gStationPool, exportsByItem, importsByItem, exportPlanetsByItem, importPlanetsByItem, ref logisticsSummary.TotalIlsCount, ref logisticsSummary.TotalCollectorCount, ref logisticsSummary.TotalWarperCount, ref logisticsSummary.TotalIdleShips, ref logisticsSummary.TotalWorkShips); if (logisticsSummary.TotalIlsCount > totalIlsCount || logisticsSummary.TotalCollectorCount > totalCollectorCount) { logisticsSummary.ColonizedPlanetCount++; } } } switch (value) { case EStarFilterMode.InterstellarSmart: ApplyInterstellarSmartFilter(exportsByItem, importsByItem); break; case EStarFilterMode.NetOutIntraSystem: ApplyNetOutIntraSystemFilter(exportsByItem, importsByItem); break; } LinkHubItems(exportsByItem, importsByItem); FinalizeSummary(logisticsSummary, exportsByItem, importsByItem, config, 0, star.id); string text = value switch { EStarFilterMode.InterstellarSmart => "Interstellar", EStarFilterMode.NetOutIntraSystem => "Netted", _ => "All Remote", }; string text2 = ((logisticsSummary.TotalCollectorCount > 0) ? $" +{logisticsSummary.TotalCollectorCount} OC" : ""); logisticsSummary.TargetSubtitle = $"{text} • {logisticsSummary.ColonizedPlanetCount}/{star.planets.Length} Planets • {logisticsSummary.TotalIlsCount} ILS{text2}"; return logisticsSummary; } private static void AggregatePlanetStations(PlanetData planet, int starId, bool includeCollectors, EStarFilterMode filterMode, StationComponent[] gStationPool, Dictionary<int, CombinedLogisticsItem> exportsByItem, Dictionary<int, CombinedLogisticsItem> importsByItem, Dictionary<int, HashSet<int>> exportPlanetsByItem, Dictionary<int, HashSet<int>> importPlanetsByItem, ref int totalIlsCount, ref int totalCollectorCount, ref int totalWarperCount, ref int totalIdleShips, ref int totalWorkShips) { //IL_0142: 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_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Invalid comparison between Unknown and I4 //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Invalid comparison between Unknown and I4 //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Invalid comparison between Unknown and I4 StationComponent[] array = planet.factory?.transport?.stationPool; int num = ((planet.factory?.transport != null) ? planet.factory.transport.stationCursor : 0); if (array == null || num <= 0) { return; } for (int i = 1; i < num; i++) { StationComponent val = array[i]; if (val == null || val.id != i || !val.isStellar) { continue; } if (val.isCollector) { if (!includeCollectors) { continue; } totalCollectorCount++; } else { totalIlsCount++; totalWarperCount += val.warperCount; totalIdleShips += val.idleShipCount; totalWorkShips += val.workShipCount; } StationStore[] storage = val.storage; if (storage == null) { continue; } bool flag = val.isCollector || val.tripRangeShips >= 2390000.0; bool flag2 = !val.isCollector && val.idleShipCount + val.workShipCount > 0 && flag && (!val.warperNecessary || val.warperCount > 0 || val.warperFree || HasWarperSlot(storage)); for (int j = 0; j < storage.Length; j++) { StationStore val2 = storage[j]; if (val2.itemId <= 0 || (int)val2.remoteLogic == 0) { continue; } bool hasExternalPair = false; bool hasInternalPair = false; if (filterMode == EStarFilterMode.InterstellarSmart && gStationPool != null) { InspectSlotRemotePairs(val, j, starId, gStationPool, out hasExternalPair, out hasInternalPair); if ((hasInternalPair && !hasExternalPair && !flag2) || ((int)val2.remoteLogic == 2 && !flag && !hasExternalPair)) { continue; } } if ((int)val2.remoteLogic == 1) { AccumulateSlot(exportsByItem, exportPlanetsByItem, planet.id, val2, val.isCollector, hasExternalPair, flag2); } else if ((int)val2.remoteLogic == 2) { AccumulateSlot(importsByItem, importPlanetsByItem, planet.id, val2, val.isCollector, hasExternalPair, flag2); } } } } private static bool HasWarperSlot(StationStore[] storage) { for (int i = 0; i < storage.Length; i++) { if (storage[i].itemId == 1210 && storage[i].count > 0) { return true; } } return false; } private static void InspectSlotRemotePairs(StationComponent station, int slotIndex, int starId, StationComponent[] gStationPool, out bool hasExternalPair, out bool hasInternalPair) { //IL_0032: 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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) hasExternalPair = false; hasInternalPair = false; SupplyDemandPair[] remotePairs = station.remotePairs; if (remotePairs == null) { return; } int num = Math.Min(station.remotePairTotalCount, remotePairs.Length); int gid = station.gid; for (int i = 0; i < num; i++) { SupplyDemandPair val = remotePairs[i]; int num2 = -1; if (val.supplyId == gid && val.supplyIndex == slotIndex) { num2 = val.demandId; } else if (val.demandId == gid && val.demandIndex == slotIndex) { num2 = val.supplyId; } if (num2 <= 0 || num2 >= gStationPool.Length) { continue; } StationComponent val2 = gStationPool[num2]; if (val2 != null && val2.gid == num2) { if (val2.planetId / 100 != starId) { hasExternalPair = true; } else { hasInternalPair = true; } } } } private static void AccumulateSlot(Dictionary<int, CombinedLogisticsItem> dict, Dictionary<int, HashSet<int>> planetsByItem, int planetId, StationStore store, bool isCollector, bool hasExternalPair, bool hasWarpCapableStation) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: 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_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) if (!dict.TryGetValue(store.itemId, out var value)) { ItemProto val = ((ProtoSet<ItemProto>)(object)LDB.items)?.Select(store.itemId); value = new CombinedLogisticsItem { ItemId = store.itemId, ItemName = ((val != null) ? ((Proto)val).name : $"Item #{store.itemId}"), Icon = ((val != null) ? val.iconSprite : null), Category = CombinedLogisticsItem.ClassifyItem(val), Logic = store.remoteLogic, PlanetCount = 1 }; dict[store.itemId] = value; } value.StoredCount += store.count; value.MaxCount += store.max; value.InTransitOrder += store.remoteOrder; value.SlotCount++; if (isCollector) { value.CollectorSlotCount++; } if (hasExternalPair) { value.HasExternalStarPair = true; } if (hasWarpCapableStation) { value.HasWarpCapableStation = true; } if (planetsByItem != null) { if (!planetsByItem.TryGetValue(store.itemId, out var value2)) { value2 = new HashSet<int>(); planetsByItem[store.itemId] = value2; } value2.Add(planetId); value.PlanetCount = value2.Count; } } private static void ApplyInterstellarSmartFilter(Dictionary<int, CombinedLogisticsItem> exportsByItem, Dictionary<int, CombinedLogisticsItem> importsByItem) { List<int> list = new List<int>(); foreach (int key2 in exportsByItem.Keys) { if (importsByItem.ContainsKey(key2)) { list.Add(key2); } } for (int i = 0; i < list.Count; i++) { int key = list[i]; CombinedLogisticsItem combinedLogisticsItem = exportsByItem[key]; CombinedLogisticsItem combinedLogisticsItem2 = importsByItem[key]; if (combinedLogisticsItem.HasExternalStarPair && !combinedLogisticsItem2.HasExternalStarPair) { importsByItem.Remove(key); } else if (combinedLogisticsItem2.HasExternalStarPair && !combinedLogisticsItem.HasExternalStarPair) { exportsByItem.Remove(key); } else if (!combinedLogisticsItem.HasExternalStarPair && !combinedLogisticsItem2.HasExternalStarPair) { exportsByItem.Remove(key); importsByItem.Remove(key); } } } private static void ApplyNetOutIntraSystemFilter(Dictionary<int, CombinedLogisticsItem> exportsByItem, Dictionary<int, CombinedLogisticsItem> importsByItem) { List<int> list = new List<int>(); foreach (int key2 in exportsByItem.Keys) { if (importsByItem.ContainsKey(key2)) { list.Add(key2); } } for (int i = 0; i < list.Count; i++) { int key = list[i]; CombinedLogisticsItem combinedLogisticsItem = exportsByItem[key]; CombinedLogisticsItem combinedLogisticsItem2 = importsByItem[key]; int num = combinedLogisticsItem.SlotCount - combinedLogisticsItem.CollectorSlotCount; if (num <= combinedLogisticsItem2.SlotCount && combinedLogisticsItem.CollectorSlotCount == 0) { exportsByItem.Remove(key); if (combinedLogisticsItem2.SlotCount <= num) { importsByItem.Remove(key); } } else { importsByItem.Remove(key); } } } private static void LinkHubItems(Dictionary<int, CombinedLogisticsItem> exportsByItem, Dictionary<int, CombinedLogisticsItem> importsByItem) { foreach (KeyValuePair<int, CombinedLogisticsItem> item in exportsByItem) { if (importsByItem.TryGetValue(item.Key, out var value)) { CombinedLogisticsItem value2 = item.Value; value2.IsHub = true; value2.HubCounterpartStored = value.StoredCount; value2.HubCounterpartMax = value.MaxCount; value2.HubCounterpartSlots = value.SlotCount; value.IsHub = true; value.HubCounterpartStored = value2.StoredCount; value.HubCounterpartMax = value2.MaxCount; value.HubCounterpartSlots = value2.SlotCount; } } } private static void RecordPlanetSupplyAvailability(Dictionary<int, SupplyAvailability> supplyByItem, int planetId, int starId, CombinedLogisticsItem expItem, CombinedLogisticsItem impItemOnSamePlanet, int critPct, int warnPct) { if (expItem == null || expItem.StoredCount <= 0) { return; } EHealthStatus healthStatus = expItem.GetHealthStatus(critPct, warnPct); if (impItemOnSamePlanet != null && impItemOnSamePlanet.GetHealthStatus(critPct, warnPct) != EHealthStatus.Healthy && impItemOnSamePlanet.MaxCount > expItem.MaxCount) { return; } long num = expItem.StoredCount + expItem.InTransitOrder; if (healthStatus != EHealthStatus.Healthy && num < 400) { return; } if (!supplyByItem.TryGetValue(expItem.ItemId, out var value)) { value.HealthySupplierPlanetCount = 1; value.SingleSupplierPlanetId = planetId; value.SingleSupplierStarId = starId; value.MultipleStarSystems = false; } else { if (value.HealthySupplierPlanetCount == 1 && value.SingleSupplierPlanetId != planetId) { value.HealthySupplierPlanetCount = 2; } else if (value.HealthySupplierPlanetCount > 1) { value.HealthySupplierPlanetCount++; } if (value.SingleSupplierStarId != starId) { value.MultipleStarSystems = true; } } supplyByItem[expItem.ItemId] = value; } private static bool HasExternalSupply(Dictionary<int, SupplyAvailability> supplyByItem, int itemId, int targetPlanetId, int targetStarId) { if (!supplyByItem.TryGetValue(itemId, out var value) || value.HealthySupplierPlanetCount <= 0) { return false; } if (targetPlanetId > 0) { if (value.HealthySupplierPlanetCount < 2) { return value.SingleSupplierPlanetId != targetPlanetId; } return true; } if (targetStarId > 0) { if (!value.MultipleStarSystems && value.SingleSupplierStarId == targetStarId) { return value.HealthySupplierPlanetCount >= 2; } return true; } return true; } private static void CollectGalaxySupplyAvailability(StellogisticsConfig config, int galaxySeed, int critPct, int warnPct, Dictionary<int, SupplyAvailability> outSupplyByItem) { outSupplyByItem.Clear(); if (GameMain.galaxy?.stars == null || GameMain.data == null) { return; } bool value = config.IncludeOrbitalCollectors.Value; Dictionary<int, CombinedLogisticsItem> dictionary = new Dictionary<int, CombinedLogisticsItem>(); Dictionary<int, CombinedLogisticsItem> dictionary2 = new Dictionary<int, CombinedLogisticsItem>(); StarData[] stars = GameMain.galaxy.stars; foreach (StarData val in stars) { if (val == null || val.planets == null) { continue; } for (int j = 0; j < val.planets.Length; j++) { PlanetData val2 = val.planets[j]; StationComponent[] obj = val2?.factory?.transport?.stationPool; int num = ((val2?.factory?.transport != null) ? val2.factory.transport.stationCursor : 0); if (obj == null || num <= 0 || config.IsPlanetOrStarIgnored(galaxySeed, val2)) { continue; } dictionary.Clear(); dictionary2.Clear(); int totalIlsCount = 0; int totalCollectorCount = 0; int totalWarperCount = 0; int totalIdleShips = 0; int totalWorkShips = 0; AggregatePlanetStations(val2, val.id, value, EStarFilterMode.AllRemoteSlots, null, dictionary, dictionary2, null, null, ref totalIlsCount, ref totalCollectorCount, ref totalWarperCount, ref totalIdleShips, ref totalWorkShips); foreach (CombinedLogisticsItem value3 in dictionary.Values) { dictionary2.TryGetValue(value3.ItemId, out var value2); RecordPlanetSupplyAvailability(outSupplyByItem, val2.id, val.id, value3, value2, critPct, warnPct); } } } } private static void EvaluateImportBottleneck(CombinedLogisticsItem impItem, EHealthStatus status, Dictionary<int, SupplyAvailability> supplyByItem, int planetId, int starId) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 if (impItem != null && (int)impItem.Logic == 2 && impItem.MaxCount > 0 && status != EHealthStatus.Healthy && impItem.FillRatio + impItem.InboundTransitRatio < 0.85f && HasExternalSupply(supplyByItem, impItem.ItemId, planetId, starId)) { impItem.HasLogisticsBottleneck = true; } } private static void FinalizeSummary(LogisticsSummary summary, Dictionary<int, CombinedLogisticsItem> exportsByItem, Dictionary<int, CombinedLogisticsItem> importsByItem, StellogisticsConfig config, int targetPlanetId, int targetStarId) { int value = config.CriticalThresholdPercent.Value; int value2 = config.WarningThresholdPercent.Value; int num = Mathf.Clamp(config.ExcludeFullThresholdPercent.Value, 40, 100); ESortOrder sortOrder = config.SortOrder.Value; bool exclude100PercentForAstro = config.GetExclude100PercentForAstro(summary.GalaxySeed, summary.TargetAstroId); Dictionary<int, SupplyAvailability> dictionary = null; foreach (CombinedLogisticsItem value3 in exportsByItem.Values) { bool flag = value3.DisplayPercent >= num; if (!config.IsItemVisibleForAstro(summary.GalaxySeed, summary.TargetAstroId, value3.ItemId, value3.Category) || (exclude100PercentForAstro && flag)) { summary.FilteredOutItemCount++; continue; } summary.Exports.Add(value3); switch (value3.GetHealthStatus(value, value2)) { case EHealthStatus.Critical: summary.CriticalExportCount++; break; case EHealthStatus.Warning: summary.WarningExportCount++; break; } } foreach (CombinedLogisticsItem value4 in importsByItem.Values) { bool flag2 = value4.DisplayPercent >= num; if (!config.IsItemVisibleForAstro(summary.GalaxySeed, summary.TargetAstroId, value4.ItemId, value4.Category) || (exclude100PercentForAstro && flag2)) { summary.FilteredOutItemCount++; continue; } summary.Imports.Add(value4); EHealthStatus healthStatus = value4.GetHealthStatus(value, value2); switch (healthStatus) { case EHealthStatus.Critical: summary.CriticalImportCount++; break; case EHealthStatus.Warning: summary.WarningImportCount++; break; } if (healthStatus != EHealthStatus.Healthy && value4.FillRatio + value4.InboundTransitRatio < 0.85f) { if (dictionary == null) { dictionary = new Dictionary<int, SupplyAvailability>(); CollectGalaxySupplyAvailability(config, summary.GalaxySeed, value, value2, dictionary); } EvaluateImportBottleneck(value4, healthStatus, dictionary, targetPlanetId, targetStarId); } } Comparison<CombinedLogisticsItem> comparison = delegate(CombinedLogisticsItem a, CombinedLogisticsItem b) { if (sortOrder == ESortOrder.ShortageFirst) { int num2 = a.DisplayPercent.CompareTo(b.DisplayPercent); if (num2 != 0) { return num2; } int num3 = a.FillRatio.CompareTo(b.FillRatio); if (num3 != 0) { return num3; } int num4 = b.MaxCount.CompareTo(a.MaxCount); if (num4 != 0) { return num4; } } else if (sortOrder == ESortOrder.StoredAmountDesc) { int num5 = b.DisplayPercent.CompareTo(a.DisplayPercent); if (num5 != 0) { return num5; } int num6 = b.FillRatio.CompareTo(a.FillRatio); if (num6 != 0) { return num6; } int num7 = b.StoredCount.CompareTo(a.StoredCount); if (num7 != 0) { return num7; } } return a.ItemId.CompareTo(b.ItemId); }; summary.Exports.Sort(comparison); summary.Imports.Sort(comparison); } public static void CollectStoredItemIds(HashSet<int> result) { //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_022b: 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) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) result.Clear(); GameData data = GameMain.data; if (data == null || data.factories == null) { return; } int num = Math.Min(data.factoryCount, data.factories.Length); for (int i = 0; i < num; i++) { PlanetFactory val = data.factories[i]; if (val == null) { continue; } PlanetTransport transport = val.transport; if (transport != null) { StationComponent[] stationPool = transport.stationPool; if (stationPool != null) { int num2 = Math.Min(transport.stationCursor, stationPool.Length); for (int j = 1; j < num2; j++) { StationComponent val2 = stationPool[j]; if (val2 == null || val2.id != j || val2.storage == null) { continue; } for (int k = 0; k < val2.storage.Length; k++) { int itemId = val2.storage[k].itemId; if (itemId > 0) { result.Add(itemId); } } } } DispenserComponent[] dispenserPool = transport.dispenserPool; if (dispenserPool != null) { int num3 = Math.Min(transport.dispenserCursor, dispenserPool.Length); for (int l = 1; l < num3; l++) { DispenserComponent val3 = dispenserPool[l]; if (val3 != null && val3.id == l && val3.filter > 0) { result.Add(val3.filter); } } } } FactoryStorage factoryStorage = val.factoryStorage; if (factoryStorage == null) { continue; } StorageComponent[] storagePool = factoryStorage.storagePool; if (storagePool != null) { int num4 = Math.Min(factoryStorage.storageCursor, storagePool.Length); for (int m = 1; m < num4; m++) { StorageComponent val4 = storagePool[m]; if (val4 == null || val4.id != m || val4.grids == null) { continue; } for (int n = 0; n < val4.grids.Length; n++) { int itemId2 = val4.grids[n].itemId; if (itemId2 > 0) { result.Add(itemId2); } int filter = val4.grids[n].filter; if (filter > 0) { result.Add(filter); } } } } TankComponent[] tankPool = factoryStorage.tankPool; if (tankPool == null) { continue; } int num5 = Math.Min(factoryStorage.tankCursor, tankPool.Length); for (int num6 = 1; num6 < num5; num6++) { TankComponent val5 = tankPool[num6]; if (val5.id == num6 && val5.fluidId > 0) { result.Add(val5.fluidId); } } } } public static GalaxyItemSearchSummary SearchGalaxyForItem(int itemId, StellogisticsConfig config) { //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Invalid comparison between Unknown and I4 //IL_02d0: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Invalid comparison between Unknown and I4 //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_0293: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_0329: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Unknown result type (might be due to invalid IL or missing references) //IL_0355: Unknown result type (might be due to invalid IL or missing references) //IL_0313: Unknown result type (might be due to invalid IL or missing references) ItemProto val = ((ProtoSet<ItemProto>)(object)LDB.items)?.Select(itemId); GalaxyItemSearchSummary galaxyItemSearchSummary = new GalaxyItemSearchSummary { ItemId = itemId, ItemName = ((val != null) ? ((Proto)val).name : $"Item #{itemId}"), Icon = ((val != null) ? val.iconSprite : null) }; if (itemId <= 0 || GameMain.galaxy == null || GameMain.galaxy.stars == null || GameMain.data == null) { return galaxyItemSearchSummary; } int seed = GameMain.galaxy.seed; bool value = config.IncludeOrbitalCollectors.Value; int value2 = config.CriticalThresholdPercent.Value; int value3 = config.WarningThresholdPercent.Value; int num = Mathf.Clamp(config.ExcludeFullThresholdPercent.Value, 40, 100); bool exclude100PercentForAstro = config.GetExclude100PercentForAstro(seed, 0); ESortOrder sortOrder = config.SortOrder.Value; StarData[] stars = GameMain.galaxy.stars; foreach (StarData val2 in stars) { if (val2 == null || val2.planets == null) { continue; } for (int j = 0; j < val2.planets.Length; j++) { PlanetData val3 = val2.planets[j]; StationComponent[] array = val3?.factory?.transport?.stationPool; int num2 = ((val3?.factory?.transport != null) ? val3.factory.transport.stationCursor : 0); if (array == null || num2 <= 0) { continue; } CombinedLogisticsItem combinedLogisticsItem = null; CombinedLogisticsItem combinedLogisticsItem2 = null; for (int k = 1; k < num2; k++) { StationComponent val4 = array[k]; if (val4 == null || val4.id != k || !val4.isStellar || val4.storage == null || (val4.isCollector && !value)) { continue; } StationStore[] storage = val4.storage; foreach (StationStore val5 in storage) { if (val5.itemId != itemId || (int)val5.remoteLogic == 0) { continue; } if ((int)val5.remoteLogic == 1) { if (combinedLogisticsItem == null) { combinedLogisticsItem = new CombinedLogisticsItem { ItemId = itemId, ItemName = galaxyItemSearchSummary.ItemName, Icon = galaxyItemSearchSummary.Icon, Category = CombinedLogisticsItem.ClassifyItem(val), Logic = (ELogisticStorage)1, PlanetCount = 1 }; } combinedLogisticsItem.StoredCount += val5.count; combinedLogisticsItem.MaxCount += val5.max; combinedLogisticsItem.InTransitOrder += val5.remoteOrder; combinedLogisticsItem.SlotCount++; if (val4.isCollector) { combinedLogisticsItem.CollectorSlotCount++; } } else if ((int)val5.remoteLogic == 2) { if (combinedLogisticsItem2 == null) { combinedLogisticsItem2 = new CombinedLogisticsItem { ItemId = itemId, ItemName = galaxyItemSearchSummary.ItemName, Icon = galaxyItemSearchSummary.Icon, Category = CombinedLogisticsItem.ClassifyItem(val), Logic = (ELogisticStorage)2, PlanetCount = 1 }; } combinedLogisticsItem2.StoredCount += val5.count; combinedLogisticsItem2.MaxCount += val5.max; combinedLogisticsItem2.InTransitOrder += val5.remoteOrder; combinedLogisticsItem2.SlotCount++; if (val4.isCollector) { combinedLogisticsItem2.CollectorSlotCount++; } } } } if (combinedLogisticsItem != null && combinedLogisticsItem2 != null) { combinedLogisticsItem.IsHub = true; combinedLogisticsItem.HubCounterpartStored = combinedLogisticsItem2.StoredCount; combinedLogisticsItem.HubCounterpartMax = combinedLogisticsItem2.MaxCount; combinedLogisticsItem.HubCounterpartSlots = combinedLogisticsItem2.SlotCount; combinedLogisticsItem2.IsHub = true; combinedLogisticsItem2.HubCounterpartStored = combinedLogisticsItem.StoredCount; combinedLogisticsItem2.HubCounterpartMax = combinedLogisticsItem.MaxCount; combinedLogisticsItem2.HubCounterpartSlots = combinedLogisticsItem.SlotCount; } bool flag = combinedLogisticsItem != null && (!exclude100PercentForAstro || combinedLogisticsItem.DisplayPercent < num); bool flag2 = combinedLogisticsItem2 != null && (!exclude100PercentForAstro || combinedLogisticsItem2.DisplayPercent < num); if ((flag || flag2) && config.IsPlanetOrStarIgnored(seed, val3)) { galaxyItemSearchSummary.IgnoredPlanetMatchCount++; continue; } if (flag) { galaxyItemSearchSummary.ExportingPlanets.Add(new PlanetItemLocationEntry { Planet = val3, Star = val2, PlanetId = val3.id, PlanetAstroId = val3.astroId, PlanetName = val3.displayName, StarName = val2.displayName, Item = combinedLogisticsItem }); switch (combinedLogisticsItem.GetHealthStatus(value2, value3)) { case EHealthStatus.Critical: galaxyItemSearchSummary.CriticalExportPlanetCount++; break; case EHealthStatus.Warning: galaxyItemSearchSummary.WarningExportPlanetCount++; break; } } if (flag2) { galaxyItemSearchSummary.ImportingPlanets.Add(new PlanetItemLocationEntry { Planet = val3, Star = val2, PlanetId = val3.id, PlanetAstroId = val3.astroId, PlanetName = val3.displayName, StarName = val2.displayName, Item = combinedLogisticsItem2 }); switch (combinedLogisticsItem2.GetHealthStatus(value2, value3)) { case EHealthStatus.Critical: galaxyItemSearchSummary.CriticalImportPlanetCount++; break; case EHealthStatus.Warning: galaxyItemSearchSummary.WarningImportPlanetCount++; break; } } } } Comparison<PlanetItemLocationEntry> comparison = delegate(PlanetItemLocationEntry a, PlanetItemLocationEntry b) { if (sortOrder == ESortOrder.ShortageFirst) { int num3 = a.Item.DisplayPercent.CompareTo(b.Item.DisplayPercent); if (num3 != 0) { return num3; } int num4 = a.Item.FillRatio.CompareTo(b.Item.FillRatio); if (num4 != 0) { return num4; } int num5 = b.Item.MaxCount.CompareTo(a.Item.MaxCount); if (num5 != 0) { return num5; } } else if (sortOrder == ESortOrder.StoredAmountDesc) { int num6 = b.Item.DisplayPercent.CompareTo(a.Item.DisplayPercent); if (num6 != 0) { return num6; } int num7 = b.Item.FillRatio.CompareTo(a.Item.FillRatio); if (num7 != 0) { return num7; } int num8 = b.Item.StoredCount.CompareTo(a.Item.StoredCount); if (num8 != 0) { return num8; } } return a.PlanetId.CompareTo(b.PlanetId); }; galaxyItemSearchSummary.ExportingPlanets.Sort(comparison); galaxyItemSearchSummary.ImportingPlanets.Sort(comparison); return galaxyItemSearchSummary; } public static GalaxyItemSearchSummary ScanGalaxyBottlenecks(StellogisticsConfig config) { return ScanGalaxyFinder(config, onlyBottlenecks: true); } public static GalaxyItemSearchSummary ScanGalaxyFinder(StellogisticsConfig config, bool onlyBottlenecks) { int galaxySeed = ((GameMain.galaxy != null) ? GameMain.galaxy.seed : 0); HashSet<int> hashSet = new HashSet<int>(); CollectStoredItemIds(hashSet); int num = 0; int num2 = -1; ItemProto val = null; foreach (int item in hashSet) { ItemProto val2 = ((ProtoSet<ItemProto>)(object)LDB.items)?.Select(item); if (val2 == null || ((Proto)val2).ID <= 0 || val2.GridIndex <= 0) { continue; } EItemCategoryFilter itemCategory = CombinedLogisticsItem.ClassifyItem(val2); if (config.IsItemVisibleForAstro(galaxySeed, 0, item, itemCategory)) { num++; if (num == 1) { num2 = item; val = val2; } else { num2 = -1; val = null; } } } string itemName = ((num == 0) ? "No Items Checked" : ((num2 > 0) ? ((val != null) ? ((Proto)val).name : $"Item #{num2}") : ((!onlyBottlenecks) ? ((num < hashSet.Count) ? $"{num} Items" : "All Items") : ((num < hashSet.Count) ? $"Bottlenecks ({num} Items)" : "Bottlenecks")))); GalaxyItemSearchSummary galaxyItemSearchSummary = new GalaxyItemSearchSummary { IsBottleneckScan = (num2 <= 0), CheckedItemCount = num, ItemId = num2, ItemName = itemName, Icon = ((val != null) ? val.iconSprite : null) }; if (num == 0 || GameMain.galaxy == null || GameMain.galaxy.stars == null || GameMain.data == null) { return galaxyItemSearchSummary; } bool value = config.IncludeOrbitalCollectors.Value; int value2 = config.CriticalThresholdPercent.Value; int value3 = config.WarningThresholdPercent.Value; int num3 = Mathf.Clamp(config.ExcludeFullThresholdPercent.Value, 40, 100); bool exclude100PercentForAstro = config.GetExclude100PercentForAstro(galaxySeed, 0); ESortOrder sortOrder = config.SortOrder.Value; Dictionary<int, CombinedLogisticsItem> dictionary = new Dictionary<int, CombinedLogisticsItem>(); Dictionary<int, CombinedLogisticsItem> dictionary2 = new Dictionary<int, CombinedLogisticsItem>(); Dictionary<int, SupplyAvailability> supplyByItem = new Dictionary<int, SupplyAvailability>(); StarData[] stars = GameMain.galaxy.stars; foreach (StarData val3 in stars) { if (val3 == null || val3.planets == null) { continue; } for (int j = 0; j < val3.planets.Length; j++) { PlanetData val4 = val3.planets[j]; StationComponent[] obj = val4?.factory?.transport?.stationPool; int num4 = ((val4?.factory?.transport != null) ? val4.factory.transport.stationCursor : 0); if (obj == null || num4 <= 0) { continue; } dictionary.Clear(); dictionary2.Clear(); int totalIlsCount = 0; int totalCollectorCount = 0; int totalWarperCount = 0; int totalIdleShips = 0; int totalWorkShips = 0; AggregatePlanetStations(val4, val3.id, value, EStarFilterMode.AllRemoteSlots, null, dictionary, dictionary2, null, null, ref totalIlsCount, ref totalCollectorCount, ref totalWarperCount, ref totalIdleShips, ref totalWorkShips); LinkHubItems(dictionary, dictionary2); bool flag = config.IsPlanetOrStarIgnored(galaxySeed, val4); bool flag2 = false; foreach (CombinedLogisticsItem value5 in dictionary.Values) { if (!flag) { dictionary2.TryGetValue(value5.ItemId, out var value4); RecordPlanetSupplyAvailability(supplyByItem, val4.id, val3.id, value5, value4, value2, value3); } if (!config.IsItemVisibleForAstro(galaxySeed, 0, value5.ItemId, value5.Category)) { continue; } EHealthStatus healthStatus = value5.GetHealthStatus(value2, value3); if (onlyBottlenecks) { if (healthStatus == EHealthStatus.Healthy) { continue; } } else if (exclude100PercentForAstro && value5.DisplayPercent >= num3) { continue; } if (flag) { flag2 = true; continue; } galaxyItemSearchSummary.ExportingPlanets.Add(new PlanetItemLocationEntry { Planet = val4, Star = val3, PlanetId = val4.id, PlanetAstroId = val4.astroId, PlanetName = val4.displayName, StarName = val3.displayName, Item = value5 }); switch (healthStatus) { case EHealthStatus.Critical: galaxyItemSearchSummary.CriticalExportPlanetCount++; break; case EHealthStatus.Warning: galaxyItemSearchSummary.WarningExportPlanetCount++; break; } } foreach (CombinedLogisticsItem value6 in dictionary2.Values) { if (!config.IsItemVisibleForAstro(galaxySeed, 0, value6.ItemId, value6.Category)) { continue; } EHealthStatus healthStatus2 = value6.GetHealthStatus(value2, value3); if (onlyBottlenecks) { if (healthStatus2 == EHealthStatus.Healthy) { continue; } } else if (exclude100PercentForAstro && value6.DisplayPercent >= num3) { continue; } if (flag) { flag2 = true; continue; } galaxyItemSearchSummary.ImportingPlanets.Add(new PlanetItemLocationEntry { Planet = val4, Star = val3, PlanetId = val4.id, PlanetAstroId = val4.astroId, PlanetName = val4.displayName, StarName = val3.displayName, Item = value6 }); switch (healthStatus2) { case EHealthStatus.Critical: galaxyItemSearchSummary.CriticalImportPlanetCount++; break; case EHealthStatus.Warning: galaxyItemSearchSummary.WarningImportPlanetCount++; break; } } if (flag2) { galaxyItemSearchSummary.IgnoredPlanetMatchCount++; } } } for (int k = 0; k < galaxyItemSearchSummary.ImportingPlanets.Count; k++) { PlanetItemLocationEntry planetItemLocationEntry = galaxyItemSearchSummary.ImportingPlanets[k]; EHealthStatus healthStatus3 = planetItemLocationEntry.Item.GetHealthStatus(value2, value3); int starId = ((planetItemLocationEntry.Star != null) ? planetItemLocationEntry.Star.id : (planetItemLocationEntry.PlanetId / 100)); EvaluateImportBottleneck(planetItemLocationEntry.Item, healthStatus3, supplyByItem, planetItemLocationEntry.PlanetId, starId); } Comparison<PlanetItemLocationEntry> comparison = delegate(PlanetItemLocationEntry a, PlanetItemLocationEntry b) { if (sortOrder == ESortOrder.ShortageFirst) { int num5 = a.Item.DisplayPercent.CompareTo(b.Item.DisplayPercent); if (num5 != 0) { return num5; } int num6 = a.Item.FillRatio.CompareTo(b.Item.FillRatio); if (num6 != 0) { return num6; } int num7 = b.Item.MaxCount.CompareTo(a.Item.MaxCount); if (num7 != 0) { return num7; } } else if (sortOrder == ESortOrder.StoredAmountDesc) { int num8 = b.Item.DisplayPercent.CompareTo(a.Item.DisplayPercent); if (num8 != 0) { return num8; } int num9 = b.Item.FillRatio.CompareTo(a.Item.FillRatio); if (num9 != 0) { return num9; } int num10 = b.Item.StoredCount.CompareTo(a.Item.StoredCount); if (num10 != 0) { return num10; } } int num11 = a.Item.ItemId.CompareTo(b.Item.ItemId); return (num11 != 0) ? num11 : a.PlanetId.CompareTo(b.PlanetId); }; galaxyItemSearchSummary.ExportingPlanets.Sort(comparison); galaxyItemSearchSummary.ImportingPlanets.Sort(comparison); return galaxyItemSearchSummary; } public static void CollectLogisticsPlanetsAndStars(StellogisticsConfig config, List<PlanetLogisticsFilterEntry> outEntries) { outEntries.Clear(); if (GameMain.galaxy == null || GameMain.galaxy.stars == null) { return; } int seed = GameMain.galaxy.seed; bool value = config.IncludeOrbitalCollectors.Value; List<PlanetLogisticsFilterEntry> list = new List<PlanetLogisticsFilterEntry>(); StarData[] stars = GameMain.galaxy.stars; foreach (StarData val in stars) { if (val == null || val.planets == null) { continue; } list.Clear(); int num = 0; int num2 = 0; for (int j = 0; j < val.planets.Length; j++) { PlanetData val2 = val.planets[j]; if (val2 == null) { continue; } int num3 = 0; int num4 = 0; StationComponent[] array = val2.factory?.transport?.stationPool; int num5 = ((val2.factory?.transport != null) ? val2.factory.transport.stationCursor : 0); if (array != null && num5 > 0) { for (int k = 1; k < num5; k++) { StationComponent val3 = array[k]; if (val3 == null || val3.id != k || !val3.isStellar) { continue; } if (val3.isCollector) { if (value) { num4++; } } else { num3++; } } } bool flag = config.IsAstroIgnored(seed, val2.astroId); if (num3 > 0 || num4 > 0 || flag) { num += num3; num2 += num4; string metaInfo = ((num3 > 0 && num4 > 0) ? $"{num3} ILS +{num4} OC" : ((num4 > 0) ? $"{num4} OC" : ((num3 <= 0) ? "0 ILS (Ignored)" : $"{num3} ILS"))); list.Add(new PlanetLogisticsFilterEntry { IsStarSystem = false, AstroId = val2.astroId, ParentStarAstroId = val.astroId, Star = val, Planet = val2, DisplayName = val2.displayName, MetaInfo = metaInfo, IlsCount = num3, CollectorCount = num4 }); } } bool flag2 = config.IsAstroIgnored(seed, val.astroId); if (list.Count > 0 || flag2) { string metaInfo2 = ((num2 > 0) ? $"System • {list.Count} Planets • {num} ILS +{num2} OC" : $"System • {list.Count} Planets • {num} ILS"); outEntries.Add(new PlanetLogisticsFilterEntry { IsStarSystem = true, AstroId = val.astroId, ParentStarAstroId = val.astroId, Star = val, Planet = null, DisplayName = "★ " + val.displayName, MetaInfo = metaInfo2, IlsCount = num, CollectorCount = num2 }); for (int l = 0; l < list.Count; l++) { outEntries.Add(list[l]); } } } } } public enum EHealthStatus { Critical, Warning, Healthy } public class CombinedLogisticsItem { public int ItemId; public string ItemName; public Sprite Icon; public EItemCategoryFilter Category; public ELogisticStorage Logic; public long StoredCount; public long MaxCount; public long InTransitOrder; public int SlotCount; public int CollectorSlotCount; public int PlanetCount; public bool HasExternalStarPair; public bool HasWarpCapableStation; public bool IsHub; public long HubCounterpartStored; public long HubCounterpartMax; public int HubCounterpartSlots; public bool HasLogisticsBottleneck; public float FillRatio { get { if (MaxCount <= 0) { if (StoredCount <= 0) { return 0f; } return 1f; } return Mathf.Clamp01((float)StoredCount / (float)MaxCount); } } public float InboundTransitRatio { get { if (MaxCount <= 0 || InTransitOrder <= 0) { return 0f; } float num = Mathf.Clamp01(1f - FillRatio); return Mathf.Clamp((float)InTransitOrder / (float)MaxCount, 0f, num); } } public int DisplayPercent { get { if (MaxCount <= 0) { if (StoredCount <= 0) { return 0; } return 100; } if (StoredCount <= 0) { return 0; } if (StoredCount >= MaxCount) { return 100; } return Mathf.Clamp(Mathf.RoundToInt((float)StoredCount / (float)MaxCount * 100f), 1, 99); } } public EHealthStatus GetHealthStatus(int criticalThresholdPct, int warningThresholdPct) { if (MaxCount <= 0) { if (StoredCount <= 0) { return EHealthStatus.Critical; } return EHealthStatus.Healthy; } int displayPercent = DisplayPercent; if (StoredCount <= 0 || displayPercent <= criticalThresholdPct) { return EHealthStatus.Critical; } if (displayPercent <= warningThresholdPct) { return EHealthStatus.Warning; } return EHealthStatus.Healthy; } public static EItemCategoryFilter ClassifyItem(ItemProto proto) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Invalid comparison between Unknown and I4 //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Invalid comparison between Unknown and I4 //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Invalid comparison between Unknown and I4 //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Invalid comparison between Unknown and I4 //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Invalid comparison between Unknown and I4 //IL_004b: 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_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected I4, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Invalid comparison between Unknown and I4 if (proto == null) { return EItemCategoryFilter.Materials; } if ((int)proto.Type == 11) { return EItemCategoryFilter.Matrices; } if (proto.CanBuild || (int)proto.Type == 5 || (int)proto.Type == 6 || (int)proto.Type == 7 || (int)proto.Type == 8 || (int)proto.Type == 9) { return EItemCategoryFilter.Buildings; } EItemType type = proto.Type; switch (type - 1) { default: if ((int)type == 10) { return EItemCategoryFilter.Materials; } return EItemCategoryFilter.Materials; case 0: return EItemCategoryFilter.RawResources; case 1: return EItemCategoryFilter.Materials; case 2: return EItemCategoryFilter.Components; case 3: return EItemCategoryFilter.ConsumablesAndPods; } } public static string FormatAmount(long amount) { long num = Math.Abs(amount); string arg = ((amount < 0) ? "-" : ""); if (num >= 1000000) { return $"{arg}{(double)num / 1000000.0:0.#}M"; } if (num >= 10000) { return $"{arg}{(double)num / 1000.0:0.#}k"; } if (num >= 1000) { return $"{arg}{(double)num / 1000.0:0.0}k"; } return $"{arg}{num}"; } } public class LogisticsSummary { public string TargetName = ""; public string TargetSubtitle = ""; public bool IsStarSystem; public int TargetAstroId; public int GalaxySeed; public EItemCategoryFilter ActiveCategoryFilter = EItemCategoryFilter.All; public int FilteredOutItemCount; public int TotalIlsCount; public int TotalCollectorCount; public int TotalWarperCount; public int TotalIdleShips; public int TotalWorkShips; public int ColonizedPlanetCount; public List<CombinedLogisticsItem> Exports = new List<CombinedLogisticsItem>(); public List<CombinedLogisticsItem> Imports = new List<CombinedLogisticsItem>(); public int CriticalExportCount; public int WarningExportCount; public int CriticalImportCount; public int WarningImportCount; public bool HasAnyStations { get { if (TotalIlsCount <= 0) { return TotalCollectorCount > 0; } return true; } } public bool HasAnySlots { get { if (Exports.Count <= 0) { return Imports.Count > 0; } return true; } } } public class PlanetItemLocationEntry { public PlanetData Planet; public StarData Star; public int PlanetId; public int PlanetAstroId; public string PlanetName = ""; public string StarName = ""; public CombinedLogisticsItem Item; } public class GalaxyItemSearchSummary { public bool IsBottleneckScan; public int CheckedItemCount; public int ItemId; public string ItemName = ""; public Sprite Icon; public List<PlanetItemLocationEntry> ExportingPlanets = new List<PlanetItemLocationEntry>(); public List<PlanetItemLocationEntry> ImportingPlanets = new List<PlanetItemLocationEntry>(); public int CriticalExportPlanetCount; public int WarningExportPlanetCount; public int CriticalImportPlanetCount; public int WarningImportPlanetCount; public int IgnoredPlanetMatchCount; public bool HasAnyLocations { get { if (ExportingPlanets.Count <= 0) { return ImportingPlanets.Count > 0; } return true; } } } public class PlanetLogisticsFilterEntry { public bool IsStarSystem; public int AstroId; public int ParentStarAstroId; public StarData Star; public PlanetData Planet; public string DisplayName = ""; public string MetaInfo = ""; public int IlsCount; public int CollectorCount; } public static class StarmapPatches { private static UIStarmapLogisticsPanel _panelInstance; private static bool _zoomBlockedThisFrame; private static double _savedDistWanted; private static float _savedFovWanted; public static bool IsPointerOverPanel() { if ((Object)(object)_panelInstance != (Object)null) { return _panelInstance.IsPointerOverUI(); } return false; } public static UIStarmapLogisticsPanel EnsurePanel(UIStarmap starmap) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_panelInstance != (Object)null) { return _panelInstance; } UIGame val = UIRoot.instance?.uiGame; if ((Object)(object)val == (Object)null || (Object)(object)starmap == (Object)null) { return null; } Transform transform = ((Component)starmap).transform; GameObject val2 = new GameObject("Stellogistics_StarmapPanel", new Type[1] { typeof(RectTransform) }); val2.transform.SetParent(transform, false); val2.SetActive(false); _panelInstance = val2.AddComponent<UIStarmapLogisticsPanel>(); _panelInstance.Initialize(val, StellogisticsPlugin.ModConfig); ManualLogSource log = StellogisticsPlugin.Log; if (log != null) { log.LogInfo((object)"Initialized Stellogistics Starmap sidebar panel."); } return _panelInstance; } public static void DestroyPanel() { if ((Object)(object)_panelInstance != (Object)null) { if ((Object)(object)((Component)_panelInstance).gameObject != (Object)null) { Object.Destroy((Object)(object)((Component)_panelInstance).gameObject); } _panelInstance = null; } } [HarmonyPostfix] [HarmonyPatch(typeof(UIStarmap), "_OnOpen")] public static void UIStarmap_OnOpen_Postfix(UIStarmap __instance) { UIStarmapLogisticsPanel uIStarmapLogisticsPanel = EnsurePanel(__instance); if ((Object)(object)uIStarmapLogisticsPanel != (Object)null) { uIStarmapLogisticsPanel.RequestImmediateRefresh(); uIStarmapLogisticsPanel.OnStarmapUpdate(__instance); } } [HarmonyPostfix] [HarmonyPatch(typeof(UIStarmap), "_OnUpdate")] public static void UIStarmap_OnUpdate_Postfix(UIStarmap __instance) { UIStarmapLogisticsPanel uIStarmapLogisticsPanel = EnsurePanel(__instance); if ((Object)(object)uIStarmapLogisticsPanel != (Object)null) { uIStarmapLogisticsPanel.OnStarmapUpdate(__instance); } } [HarmonyPostfix] [HarmonyPatch(typeof(UIStarmap), "_OnClose")] public static void UIStarmap_OnClose_Postfix() { if ((Object)(object)_panelInstance != (Object)null && ((Component)_panelInstance).gameObject.activeSelf) { ((Component)_panelInstance).gameObject.SetActive(false); } } [HarmonyPostfix] [HarmonyPatch(typeof(UIStarmap), "_OnDestroy")] public static void UIStarmap_OnDestroy_Postfix() { DestroyPanel(); } [HarmonyPostfix] [HarmonyPatch(typeof(UIPlanetDetail), "OnPlanetDataSet")] public static void UIPlanetDetail_OnPlanetDataSet_Postfix() { if ((Object)(object)_panelInstance != (Object)null) { _panelInstance.RequestImmediateRefresh(); } } [HarmonyPostfix] [HarmonyPatch(typeof(UIStarDetail), "OnStarDataSet")] public static void UIStarDetail_OnStarDataSet_Postfix() { if ((Object)(object)_panelInstance != (Object)null) { _panelInstance.RequestImmediateRefresh(); } } [HarmonyPostfix] [HarmonyPatch(typeof(VFInput), "UpdateGameStates")] public static void VFInput_UpdateGameStates_Postfix() { if (IsPointerOverPanel()) { VFInput.inScrollView = true; } } [HarmonyPostfix] [HarmonyPatch(/*Could not decode attribute arguments.*/)] public static void VFInput_CameraZoomIn_Postfix(ref float __result) { if (IsPointerOverPanel()) { __result = 0f; } } [HarmonyPostfix] [HarmonyPatch(/*Could not decode attribute arguments.*/)] public static void VFInput_CameraZoomOut_Postfix(ref float __result) { if (IsPointerOverPanel()) { __result = 0f; } } [HarmonyPrefix] [HarmonyPatch(typeof(StarmapCamera), "CameraControl")] public static void StarmapCamera_CameraControl_Prefix(StarmapCamera __instance) { if (IsPointerOverPanel()) { VFInput.inScrollView = true; _zoomBlockedThisFrame = true; _savedDistWanted = __instance.distWanted; _savedFovWanted = __instance.fovWanted; } else { _zoomBlockedThisFrame = false; } } [HarmonyPostfix] [HarmonyPatch(typeof(StarmapCamera), "CameraControl")] public static void StarmapCamera_CameraControl_Postfix(StarmapCamera __instance) { if (_zoomBlockedThisFrame) { __instance.distWanted = _savedDistWanted; __instance.fovWanted = _savedFovWanted; } } } public enum EStarFilterMode { InterstellarSmart, NetOutIntraSystem, AllRemoteSlots } public enum ESortOrder { ShortageFirst, ItemId, StoredAmountDesc } [Flags] public enum EItemCategoryFilter { None = 0, RawResources = 1, Materials = 2, Components = 4, Buildings = 8, ConsumablesAndPods = 0x10, Matrices = 0x20, All = 0x3F, Exclude100Percent = 0x40 } public class StellogisticsConfig { private readonly ConfigFile _configFile; public const float DefaultPosX = 82f; public const float DefaultPosY = -470f; public const float DefaultWidth = 310f; public const float DefaultMaxHeight = 460f; private readonly Dictionary<string, EItemCategoryFilter> _astroFilterCache = new Dictionary<string, EItemCategoryFilter>(); private readonly Dictionary<string, HashSet<int>> _astroItemOverridesCache = new Dictionary<string, HashSet<int>>(); private readonly Dictionary<int, HashSet<int>> _ignoredAstrosBySeed = new Dictionary<int, HashSet<int>>(); private const string GlobalFilterKey = "global"; public ConfigEntry<bool> EnableMod { get; } public ConfigEntry<bool> IncludeOrbitalCollectors { get; } public ConfigEntry<EStarFilterMode> StarSystemFilterMode { get; } public ConfigEntry<ESortOrder> SortOrder { get; } public ConfigEntry<bool> ShowOnHover { get; } public ConfigEntry<bool> ShowInTransitBar { get; } public ConfigEntry<int> CriticalThresholdPercent { get; } public ConfigEntry<int> WarningThresholdPercent { get; } public ConfigEntry<int> ExcludeFullThresholdPercent { get; } public ConfigEntry<float> PanelWidth { get; } public ConfigEntry<float> PanelMaxHeight { get; } public ConfigEntry<bool> UseCustomPosition { get; } public ConfigEntry<float> CustomPanelPosX { get; } public ConfigEntry<float> CustomPanelPosY { get; } public ConfigEntry<EItemCategoryFilter> DefaultCategoryFilter { get; } public ConfigEntry<string> SavedAstroFilters { get; } public ConfigEntry<string> SavedAstroItemOverrides { get; } public ConfigEntry<string> SavedIgnoredAstros { get; } public StellogisticsConfig(ConfigFile config) { //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Expected O, but got Unknown //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Expected O, but got Unknown //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Expected O, but got Unknown //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Expected O, but got Unknown //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Expected O, but got Unknown _configFile = config; EnableMod = config.Bind<bool>("General", "EnableMod", true, "Enable the Stellogistics import/export panel on the Starmap."); IncludeOrbitalCollectors = config.Bind<bool>("Logistics", "IncludeOrbitalCollectors", true, "Include Gas Giant Orbital Collectors (Hydrogen, Deuterium, Fire Ice) in Exports."); StarSystemFilterMode = config.Bind<EStarFilterMode>("Logistics", "StarSystemFilterMode", EStarFilterMode.InterstellarSmart, "How to filter intra-system trade when viewing an entire Star System:\nInterstellarSmart: Excludes slots restricted to intra-system range (<1 LY) and internal supply+demand pairs that have no external star routes.\nNetOutIntraSystem: Nets total Supply against total Demand within the same star system.\nAllRemoteSlots: Shows all Remote Supply and Remote Demand slots in the star system."); SortOrder = config.Bind<ESortOrder>("Display", "SortOrder", ESortOrder.ShortageFirst, "How combined items are sorted in the Exports and Imports lists:\nShortageFirst: Items running empty (Exports) or starved (Imports) appear at the top.\nItemId: Sorted by DSP item ID.\nStoredAmountDesc: Sorted by highest stored amount first."); ShowOnHover = config.Bind<bool>("Display", "ShowOnHover", true, "Show logistics when hovering a planet or star in the Starmap even if not clicked/selected."); ShowInTransitBar = config.Bind<bool>("Display", "ShowInTransitBar", true, "Show a hatched bar extension on item rows indicating inbound (+ in-transit) cargo on the way."); CriticalThresholdPercent = config.Bind<int>("Thresholds", "CriticalThresholdPercent", 15, new ConfigDescription("Storage fullness percentage at or below which an item is highlighted Red (Critical / Empty).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 50), Array.Empty<object>())); WarningThresholdPercent = config.Bind<int>("Thresholds", "WarningThresholdPercent", 40, new ConfigDescription("Storage fullness percentage at or below which an item is highlighted Orange (Low / Depleting).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 85), Array.Empty<object>())); ExcludeFullThresholdPercent = config.Bind<int>("Thresholds", "ExcludeFullThresholdPercent", 90, new ConfigDescription("Storage fullness percentage at or above which an item is excluded when the Exclude Full filter is enabled (90 = excludes 90%–100% including freshly tapped storages; 100 = only 100%; 41 = excludes all green >40% entries).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(40, 100), Array.Empty<object>())); PanelWidth = config.Bind<float>("UI", "PanelWidth", 310f, new ConfigDescription("Width of the Stellogistics panel in pixels.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(240f, 700f), Array.Empty<object>())); PanelMaxHeight = config.Bind<float>("UI", "PanelMaxHeight", 460f, new ConfigDescription("Maximum height of the scrollable list area in pixels.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(56f, 950f), Array.Empty<object>())); UseCustomPosition = config.Bind<bool>("UI", "UseCustomPosition", false, "True when the user has dragged the Stellogistics panel to a custom screen position."); CustomPanelPosX = config.Bind<float>("UI", "CustomPanelPosX", 82f, "Saved X anchoredPosition (from top-left) of the Stellogistics panel."); CustomPanelPosY = config.Bind<float>("UI", "CustomPanelPosY", -470f, "Saved Y anchoredPosition (from top-left) of the Stellogistics panel."); DefaultCategoryFilter = config.Bind<EItemCategoryFilter>("Filters", "DefaultCategoryFilter", EItemCategoryFilter.All, "Default item category filter for planets and star systems that do not have a custom per-body filter saved."); SavedAstroFilters = config.Bind<string>("Filters", "SavedAstroFilters", "", "Serialized per-star and per-planet item category filters (format: seed_astroId:mask,...)."); SavedAstroItemOverrides = config.Bind<string>("Filters", "SavedAstroItemOverrides", "", "Serialized per-star and per-planet individual item filter overrides (format: seed_astroId:id1|id2,...)."); SavedIgnoredAstros = config.Bind<string>("Filters", "SavedIgnoredAstros", "", "Serialized per-galaxy ignored planet and star system astroIds for the Finder (format: seed:astroId1|astroId2,...)."); ParseSavedAstroFilters(); ParseSavedAstroItemOverrides(); ParseSavedIgnoredAstros(); } private static string MakeAstroKey(int galaxySeed, int astroId) { return "global"; } private void ParseSavedAstroFilters() { _astroFilterCache.Clear(); string value = SavedAstroFilters.Value; if (string.IsNullOrEmpty(value)) { return; } string[] array = value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < array.Length; i++) { string[] array2 = array[i].Split(new char[1] { ':' }); if (array2.Length == 2 && int.TryParse(array2[1], out var result)) { _astroFilterCache[array2[0].Trim()] = (EItemCategoryFilter)(result & 0x7F); } } } private void FlushSavedAstroFilters() { StringBuilder stringBuilder = new StringBuilder(); foreach (KeyValuePair<string, EItemCategoryFilter> item in _astroFilterCache) { if (stringBuilder.Length > 0) { stringBuilder.Append(','); } stringBuilder.Append(item.Key).Append(':').Append((int)item.Value); } SavedAstroFilters.Value = stringBuilder.ToString(); _configFile.Save(); } private void ParseSavedAstroItemOverrides() { _astroItemOverridesCache.Clear(); string value = SavedAstroItemOverrides.Value; if (string.IsNullOrEmpty(value)) { return; } string[] array = value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < array.Length; i++) { string[] array2 = array[i].Split(new char[1] { ':' }); if (array2.Length != 2) { continue; } string key = array2[0].Trim(); string[] array3 = array2[1].Split(new char[1] { '|' }, StringSplitOptions.RemoveEmptyEntries); HashSet<int> hashSet = new HashSet<int>(); for (int j = 0; j < array3.Length; j++) { if (int.TryParse(array3[j], out var result) && result > 0) { hashSet.Add(result); } } if (hashSet.Count > 0) { _astroItemOverridesCache[key] = hashSet; } } } private void FlushSavedAstroItemOverrides() { StringBuilder stringBuilder = new StringBuilder(); foreach (KeyValuePair<string, HashSet<int>> item in _astroItemOverridesCache) { if (item.Value == null || item.Value.Count == 0) { continue; } if (stringBuilder.Length > 0) { stringBuilder.Append(','); } stringBuilder.Append(item.Key).Append(':'); bool flag = true; foreach (int item2 in item.Value) { if (!flag) { stringBuilder.Append('|'); } stringBuilder.Append(item2); flag = false; } } SavedAstroItemOverrides.Value = stringBuilder.ToString(); _configFile.Save(); } public EItemCategoryFilter GetFilterForAstro(int galaxySeed, int astroId) { if (_astroFilterCache.TryGetValue("global", out var value)) { return value; } return DefaultCategoryFilter.Value; } public bool GetExclude100PercentForAstro(int galaxySeed, int astroId) { return (GetFilterForAstro(galaxySeed, astroId) & EItemCategoryFilter.Exclude100Percent) != 0; } public void ToggleExclude100PercentForAstro(int galaxySeed, int astroId) { EItemCategoryFilter filterForAstro = GetFilterForAstro(galaxySeed, astroId); EItemCategoryFilter value = (((filterForAstro & EItemCategoryFilter.Exclude100Percent) != EItemCategoryFilter.None) ? (filterForAstro & ~EItemCategoryFilter.Exclude100Percent) : (filterForAstro | EItemCategoryFilter.Exclude100Percent)); _astroFilterCache["global"] = value; DefaultCategoryFilter.Value = value; FlushSavedAstroFilters(); } public bool HasCustomFilterForAstro(int galaxySeed, int astroId) { bool num = GetFilterForAstro(galaxySeed, astroId) != EItemCategoryFilter.All; HashSet<int> value; bool flag = _astroItemOverridesCache.TryGetValue("global", out value) && value.Count > 0; return num || flag; } private HashSet<int> GetOrInitHiddenItemsSet(int galaxySeed, int astroId) { if (!_astroItemOverridesCache.TryGetValue("global", out var value)) { value = new HashSet<int>(); EItemCategoryFilter eItemCategoryFilter = GetFilterForAstro(galaxySeed, astroId) & EItemCategoryFilter.All; if (eItemCategoryFilter != EItemCategoryFilter.All && (Object)(object)LDB.items != (Object)null && ((ProtoSet<ItemProto>)(object)LDB.items).dataArray != null) { ItemProto[] dataArray = ((ProtoSet<ItemProto>)(object)LDB.items).dataArray; foreach (ItemProto val in dataArray) { if (val != null && ((Proto)val).ID > 0) { EItemCategoryFilter eItemCategoryFilter2 = CombinedLogisticsItem.ClassifyItem(val); if ((eItemCategoryFilter & eItemCategoryFilter2) == 0) { value.Add(((Proto)val).ID); } } } } _astroItemOverridesCache["global"] = value; } return value; } public void SetFilterForAstro(int galaxySeed, int astroId, EItemCategoryFilter mask, EItemCategoryFilter? toggledCategories = null) { HashSet<int> orInitHiddenItemsSet = GetOrInitHiddenItemsSet(galaxySeed, astroId); EItemCategoryFilter eItemCategoryFilter = GetFilterForAstro(galaxySeed, astroId) & EItemCategoryFilter.Exclude100Percent; EItemCategoryFilter eItemCategoryFilter2 = (mask & EItemCategoryFilter.All) | eItemCategoryFilter; _astroFilterCache["global"] = eItemCategoryFilter2; DefaultCategoryFilter.Value = eItemCategoryFilter2; if (toggledCategories.HasValue && (Object)(object)LDB.items != (Object)null && ((ProtoSet<ItemProto>)(object)LDB.items).dataArray != null) { EItemCategoryFilter value = toggledCategories.Value; ItemProto[] dataArray = ((ProtoSet<ItemProto>)(object)LDB.items).dataArray; foreach (ItemProto val in dataArray) { if (val == null || ((Proto)val).ID <= 0) { continue; } EItemCategoryFilter eItemCategoryFilter3 = CombinedLogisticsItem.ClassifyItem(val); if ((value & eItemCategoryFilter3) != EItemCategoryFilter.None) { if ((eItemCategoryFilter2 & eItemCategoryFilter3) != EItemCategoryFilter.None) { orInitHiddenItemsSet.Remove(((Proto)val).ID); } else { orInitHiddenItemsSet.Add(((Proto)val).ID); } } } } FlushSavedAstroItemOverrides(); FlushSavedAstroFilters(); } public void SetCustomItemsAllVisible(int galaxySeed, int astroId, bool visible) { HashSet<int> orInitHiddenItemsSet = GetOrInitHiddenItemsSet(galaxySeed, astroId); if (visible) { orInitHiddenItemsSet.Clear(); } else if ((Object)(object)LDB.items != (Object)null && ((ProtoSet<ItemProto>)(object)LDB.items).dataArray != null) { ItemProto[] dataArray = ((ProtoSet<ItemProto>)(object)LDB.items).dataArray; foreach (ItemProto val in dataArray) { if (val != null && ((Proto)val).ID > 0) { orInitHiddenItemsSet.Add(((Proto)val).ID); } } } FlushSavedAstroItemOverrides(); } public void CopyHiddenItemsSnapshot(int galaxySeed, int astroId, HashSet<int> destination) { if (destination != null) { destination.Clear(); HashSet<int> orInitHiddenItemsSet = GetOrInitHiddenItemsSet(galaxySeed, astroId); destination.UnionWith(orInitHiddenItemsSet); } } public void RestoreHiddenItemsSnapshot(int galaxySeed, int astroId, HashSet<int> snapshot) { if (snapshot != null) { HashSet<int> orInitHiddenItemsSet = GetOrInitHiddenItemsSet(galaxySeed, astroId); orInitHiddenItemsSet.Clear(); orInitHiddenItemsSet.UnionWith(snapshot); FlushSavedAstroItemOverrides(); } } public void SetCustomSingleItemOnly(int galaxySeed, int astroId, int itemId) { if (itemId <= 0) { return; } HashSet<int> orInitHiddenItemsSet = GetOrInitHiddenItemsSet(galaxySeed, astroId); orInitHiddenItemsSet.Clear(); if ((Object)(object)LDB.items != (Object)null && ((ProtoSet<ItemProto>)(object)LDB.items).dataArray != null) { ItemProto[] dataArray = ((ProtoSet<ItemProto>)(object)LDB.items).dataArray; foreach (ItemProto val in dataArray) { if (val != null && ((Proto)val).ID > 0 && ((Proto)val).ID != itemId) { orInitHiddenItemsSet.Add(((Proto)val).ID); } } } FlushSavedAstroItemOverrides(); } public void ResetFilterForAstro(int galaxySeed, int astroId) { DefaultCategoryFilter.Value = EItemCategoryFilter.All; _astroFilterCache.Clear(); _astroItemOverridesCache.Clear(); FlushSavedAstroFilters(); FlushSavedAstroItemOverrides(); } public bool IsItemVisibleForAstro(int galaxySeed, int astroId, int itemId, EItemCategoryFilter itemCategory) { if (_astroItemOverridesCache.TryGetValue("global", out var value)) { return !value.Contains(itemId); } return (GetFilterForAstro(galaxySeed, astroId) & itemCategory) != 0; } public void ToggleItemOverrideForAstro(int galaxySeed, int astroId, int itemId) { if (itemId > 0) { HashSet<int> orInitHiddenItemsSet = GetOrInitHiddenItemsSet(galaxySeed, astroId); if (!orInitHiddenItemsSet.Remove(itemId)) { orInitHiddenItemsSet.Add(itemId); } FlushSavedAstroItemOverrides(); } } private void ParseSavedIgnoredAstros() { _ignoredAstrosBySeed.Clear(); string value = SavedIgnoredAstros.Value; if (string.IsNullOrEmpty(value)) { return; } string[] array = value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < array.Length; i++) { string[] array2 = array[i].Split(new char[1] { ':' }); if (array2.Length != 2 || !int.TryParse(array2[0].Trim(), out var result)) { continue; } string[] array3 = array2[1].Split(new char[1] { '|' }, StringSplitOptions.RemoveEmptyEntries); HashSet<int> hashSet = new HashSet<int>(); for (int j = 0; j < array3.Length; j++) { if (int.TryParse(array3[j], out var result2) && result2 > 0) { hashSet.Add(result2); } } if (hashSet.Count > 0) { _ignoredAstrosBySeed[result] = hashSet; } } } private void FlushSavedIgnoredAstros() { StringBuilder stringBuilder = new StringBuilder(); foreach (KeyValuePair<int, HashSet<int>> item in _ignoredAstrosBySeed) { if (item.Value == null || item.Value.Count == 0) { continue; } if (stringBuilder.Length > 0) { stringBuilder.Append(','); } stringBuilder.Append(item.Key).Append(':'); bool flag = true; foreach (int item2 in item.Value) { if (!flag) { stringBuilder.Append('|'); } stringBuilder.Append(item2); flag = false; } } SavedIgnoredAstros.Value = stringBuilder.ToString(); _configFile.Save(); } public bool IsAstroIgnored(int galaxySeed, int astroId) { if (astroId <= 0) { return false; } if (_ignoredAstrosBySeed.TryGetValue(galaxySeed, out var value)) { return value.Contains(astroId); } return false; } public bool IsPlanetOrStarIgnored(int galaxySeed, PlanetData planet) { if (planet == null) { return false; } if (IsAstroIgnored(galaxySeed, planet.astroId)) { return true; } if (planet.star != null && IsAstroIgnored(galaxySeed, planet.star.astroId)) { return true; } return false; } public void ToggleAstroIgnored(int galaxySeed, int astroId) { if (astroId > 0) { if (!_ignoredAstrosBySeed.TryGetValue(galaxySeed, out var value)) { value = new HashSet<int>(); _ignoredAstrosBySeed[galaxySeed] = value; } if (!value.Remove(astroId)) { value.Add(astroId); } FlushSavedIgnoredAstros(); } } public void SetAstroIgnored(int galaxySeed, int astroId, bool ignored) { if (astroId <= 0) { return; } if (!_ignoredAstrosBySeed.TryGetValue(galaxySeed, out var value)) { if (!ignored) { return; } value = new HashSet<int>(); _ignoredAstrosBySeed[galaxySeed] = value; } if (ignored ? value.Add(astroId) : value.Remove(astroId)) { FlushSavedIgnoredAstros(); } } public void ClearAllIgnoredAstros(int galaxySeed) { if (_ignoredAstrosBySeed.Remove(galaxySeed)) { FlushSavedIgnoredAstros(); } } public int GetIgnoredAstroCount(int galaxySeed) { if (!_ignoredAstrosBySeed.TryGetValue(galaxySeed, out var value)) { return 0; } return value.Count; } public void SaveCustomPanelPosition(float x, float y) { UseCustomPosition.Value = true; CustomPanelPosX.Value = x; CustomPanelPosY.Value = y; _configFile.Save(); } public void SavePanelSize(float width, float maxHeight) { PanelWidth.Value = width; PanelMaxHeight.Value = maxHeight; _configFile.Save(); } public void ResetPanelLayout() { UseCustomPosition.Value = false; CustomPanelPosX.Value = 82f; CustomPanelPosY.Value = -470f; PanelWidth.Value = 310f; PanelMaxHeight.Value = 460f; _configFile.Save(); } } [BepInPlugin("com.stellogistics.dsp", "Stellogistics", "2.0.1")] [BepInProcess("DSPGAME.exe")] public class StellogisticsPlugin : BaseUnityPlugin { public const string PluginGuid = "com.stellogistics.dsp"; public const string PluginName = "Stellogistics"; public const string PluginVersion = "2.0.1"; private Harmony _harmony; public static ManualLogSource Log { get; private set; } public static StellogisticsConfig ModConfig { get; private set; } private void Awake() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; ModConfig = new StellogisticsConfig(((BaseUnityPlugin)this).Config); _harmony = new Harmony("com.stellogistics.dsp"); _harmony.PatchAll(typeof(StarmapPatches)); Log.LogInfo((object)"Stellogistics v2.0.1 loaded."); } private void OnDestroy() { StarmapPatches.DestroyPanel(); Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } public class PointerHoverTracker : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler { public bool IsHovered { get; private set; } public void OnPointerEnter(PointerEventData eventData) { IsHovered = true; } public void OnPointerExit(PointerEventData eventData) { IsHovered = false; } private void OnDisable() { IsHovered = false; } } public class ItemCellHoverHandler : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler { public Action OnHoverEnter; public Action OnHoverExit; public void OnPointerEnter(PointerEventData eventData) { OnHoverEnter?.Invoke(); } public void OnPointerExit(PointerEventData eventData) { OnHoverExit?.Invoke(); } } public class PanelDragHandler : MonoBehaviour, IBeginDragHandler, IEventSystemHandler, IDragHandler, IEndDragHandler { public RectTransform TargetRect; public Action OnDragStarted; public Action<Vector2> OnDragFinished; private Canvas _canvas; public void OnBeginDrag(PointerEventData eventData) { if (!((Object)(object)TargetRect == (Object)null)) { if ((Object)(object)_canvas == (Object)null) { _canvas = ((Component)TargetRect).GetComponentInParent<Canvas>(); } OnDragStarted?.Invoke(); } } public void OnDrag(PointerEventData eventData) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)TargetRect == (Object)null)) { float num = (((Object)(object)_canvas != (Object)null && _canvas.scaleFactor > 0.01f) ? _canvas.scaleFactor : 1f); RectTransform targetRect = TargetRect; targetRect.anchoredPosition += eventData.delta / num; } } public void OnEndDrag(PointerEventData eventData) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)TargetRect != (Object)null) { OnDragFinished?.Invoke(TargetRect.anchoredPosition); } } } public class PanelResizeHandler : MonoBehaviour, IBeginDragHandler, IEventSystemHandler, IDragHandler, IEndDragHandler { public RectTransform TargetRect; public Action OnResizeStarted; public Action<float, float> OnResizing; public Action<float, float> OnResizeFinished; private Vector2 _grabOffset; private float _lastWidth = 310f; private float _lastTotalHeight = 300f; public void OnBeginDrag(PointerEventData eventData) { //IL_0016: 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_0076: 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_0035: 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_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_009b: 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) if (!((Object)(object)TargetRect == (Object)null)) { Vector2 val = default(Vector2); Rect rect; if (RectTransformUtility.ScreenPointToLocalPointInRectangle(TargetRect, eventData.position, eventData.pressEventCamera, ref val)) { rect = TargetRect.rect; float width = ((Rect)(ref rect)).width; rect = TargetRect.rect; float height = ((Rect)(ref rect)).height; _grabOffset = new Vector2(width - val.x, height - (0f - val.y)); } else { _grabOffset = Vector2.zero; } rect = TargetRect.rect; _lastWidth = ((Rect)(ref rect)).width; rect = TargetRect.rect; _lastTotalHeight = ((Rect)(ref rect)).height; OnResizeStarted?.Invoke(); } } public void OnDrag(PointerEventData eventData) { //IL_0016: 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_003d: Unknown result type (might be due to invalid IL or missing references) Vector2 val = default(Vector2); if (!((Object)(object)TargetRect == (Object)null) && RectTransformUtility.ScreenPointToLocalPointInRectangle(TargetRect, eventData.position, eventData.pressEventCamera, ref val)) { float num = val.x + _grabOffset.x; float num2 = 0f - val.y + _grabOffset.y; _lastWidth = Mathf.Clamp(num, 240f, 700f); _lastTotalHeight = Mathf.Clamp(num2, 10f, 1020f); OnResizing?.Invoke(_lastWidth, _lastTotalHeight); } } public void OnEndDrag(PointerEventData eventData) { OnResizeFinished?.Invoke(_lastWidth, _lastTotalHeight); } } public class UIStarmapLogisticsPanel : MonoBehaviour { private class ItemRowView { public GameObject RootGo; public RectTransform RootRect; public Image BgImage; public Button RowButton; public Action OnRowClick; public GameObject MuteBtnGo; public Action OnMuteClick; public RectTransform FillBarRect; public Image FillBarImage; public float FillRatioCached; public RectTransform TransitBarRect; public Image TransitBarImage; public float TransitRatioCached; public Image StatusStripeImage; public Image IconImage; public Text NameText; public Text MetaText; public Text AmountText; public Text SubStatusText; } private class PlanetFilterRowView { public GameObject RootGo; public RectTransform RootRect; public Image BgImage; public Button Btn; public Image CheckBoxBg; public Text CheckMarkText; public Text NameText; public Text MetaText; public Action OnClick; } private class GeneralToggleRow { public Func<bool> Getter; public Action Toggler; public Button Btn; public Image CheckBoxBg; public Text CheckMarkText; public Text LabelText; } private class FilterToggleRow { public EItemCategoryFilter Category; public Button Btn; public Image CheckBoxBg; public Text CheckMarkText; public Text LabelText; } private class CustomPickerCell { public int ItemId; public string ItemName; public EItemCategoryFilter Category; public int TabIndex; public GameObject CellGo; public Image BgImage; public Image IconImage; } private StellogisticsConfig _config; private UIGame _uiGame; private Font _gameFont; private RectTransform _panelRect; private RectTransform _headerRect; private Image _panelBg; private PointerHoverTracker _panelHoverTracker; private PointerHoverTracker _optionsHoverTracker; private PointerHoverTracker _generalOptionsHoverTracker; private PointerHoverTracker _customPickerHoverTracker; private Sprite _hatchedTransitSprite; private Button _panelCollapseBtn; private Text _panelCollapseBtnText; private Text _titleText; private Text _subtitleText; private Text _fleetInfoText; private Button _filterModeBtn; private Text _filterModeBtnText; private Button _finderModeBtn; private Text _finderModeBtnText; private Button _sortModeBtn; private Text _sortModeBtnText; private Button _optionsBtn; private Text _optionsBtnText; private Button _generalOptionsBtn; private Text _generalOptionsBtnText; private RectTransform _scrollViewportRect; private RectTransform _scrollContentRect; private ScrollRect _scrollRect; private GameObject _scrollbarGo; private Scrollbar _verticalScrollbar; private GameObject _resizeGripGo; private GameObject _emptyStateGo; private Text _emptyStateText; private GameObject _exportsHeaderGo; private RectTransform _exportsHeaderRect; private Text _exportsHeaderText; private Text _exportsAlertText; private GameObject _importsHeaderGo; private RectTransform _importsHeaderRect; private Text _importsHeaderText; private Text _importsAlertText; private GameObject _optionsMenuGo; private RectTransform _optionsMenuRect; private Text _optionsTargetLabel; private Text _excludeRowLabelText; private Text _excludeThresholdBtnText; private GeneralToggleRow _ignoreTargetToggleRow; private readonly List<FilterToggleRow> _filterToggles = new List<FilterToggleRow>(); private GameObject _generalOptionsMenuGo; private RectTransform _generalOptionsMenuRect; private readonly List<GeneralToggleRow> _generalOptionToggles = new List<GeneralToggleRow>(); private GameObject _customPickerGo; private RectTransform _customPickerRect; private GameObject _customPickerGridGo; private GameObject _customPickerPlanetsScrollGo; private RectTransform _customPickerPlanetsContentRect; private GameObject _customPickerPlanetsEmptyGo; private Text _customPickerTitleText; private Text _customPickerHoveredLabel; private Image _customTabItemsBg; private Image _customTabBuildingsBg; private Image _customTabPlanetsBg; private Text _customTabPlanetsText; private Button _pickerCheckAllBtn; private Button _pickerUncheckAllBtn; private Button _pickerBottlenecksBtn; private Text _pickerBottlenecksTxt; private Button _pickerShowAllPlanetsBtn; private int _customPickerActiveTab = 1; private bool _customPickerOpen; private readonly List<CustomPickerCell> _customPickerCells = new List<CustomPickerCell>(); private readonly List<PlanetFilterRowView> _planetFilterRowPool = new List<PlanetFilterRowView>(); private readonly List<PlanetLogisticsFilterEntry> _planetFilterEntries = new List<PlanetLogisticsFilterEntry>(); private readonly HashSet<int> _storedItemsSet = new HashSet<int>(); private readonly HashSet<int> _savedFinderHiddenSnapshot = new HashSet<int>(); private bool _hasSavedFinderSnapshot; private bool _savedFinderOnlyBottlenecks = true; private int _lastFinderCheckedCount; private bool _finderOnlyBottlenecks = true; private readonly List<ItemRowView> _rowPool = new List<ItemRowView>(); private UIStarmap _currentStarmap; private bool _finderModeActive; private int _lastTargetAstroId = -1; private int _lastGalaxySeed; private string _lastTargetDisplayName = ""; private PlanetData _lastResolvedPlanet; private StarData _lastResolvedStar; private float _nextRefreshTime; private bool _forceRefresh = true; private float _activeContentHeight = 160f; private bool _panelCollapsed; private bool _exportsCollapsed; private bool _importsCollapsed; private bool _optionsMenuOpen; private bool _generalOptionsMenuOpen; private bool _isResizing; private static readonly Color PanelBgColor = new Color(0.055f, 0.085f, 0.13f, 0.94f); private static readonly Color HeaderBgColor = new Color(0.09f, 0.145f, 0.22f, 0.98f); private static readonly Color SectionHeaderBgColor = new Color(0.12f, 0.19f, 0.28f, 0.95f); private static readonly Color SectionHeaderHoverColor = new Color(0.17f, 0.27f, 0.39f, 0.98f); private static readonly Color RowEvenBgColor = new Color(0.08f, 0.12f, 0.18f, 0.78f); private static readonly Color RowOddBgColor = new Color(0.065f, 0.1f, 0.15f, 0.78f); private static readonly Color CriticalColor = new Color(1f, 0.34f, 0.34f, 1f); private static readonly Color CriticalFillColor = new Color(0.85f, 0.18f, 0.18f, 0.24f); private static readonly Color CriticalTransitColor = new Color(1f, 0.42f, 0.42f, 0.38f); private static readonly Color WarningColor = new Color(1f, 0.7f, 0.24f, 1f); private static readonly Color WarningFillColor = new Color(0.85f, 0.52f, 0.12f, 0.22f); private static readonly Color WarningTransitColor = new Color(1f, 0.72f, 0.28f, 0.36f); private static readonly Color HealthyColor = new Color(0.3f, 0.9f, 0.58f, 1f); private static readonly Color HealthyFillColor = new Color(0.18f, 0.68f, 0.42f, 0.18f); private static readonly Color HealthyTransitColor = new Color(0.32f, 0.92f, 0.62f, 0.34f); private const float HeaderHeight = 74f; private const float StackedHeaderHeight = 96f; private const float StackedWidthPlanet = 305f; private const float StackedWidthFiveBtns = 355f; private const float CollapsedTabWidth = 148f; private const float CollapsedTabHeight = 32f; private const float SectionHeaderHeight = 26f; private const float RowHeight = 38f; private const float RowSpacing = 2f; private const float MinScrollHeight = 56f; private const float ScrollbarWidth = 7f; public void Initialize(UIGame uiGame, StellogisticsConfig config) { _uiGame = uiGame; _config = config; if ((Object)(object)_uiGame.planetDetail != (Object)null && (Object)(object)_uiGame.planetDetail.typeText != (Object)null) { _gameFont = _uiGame.planetDetail.typeText.font; } else if ((Object)(object)_uiGame.starmap != (Object)null && (Object)(object)_uiGame.starmap.cursorViewText != (Object)null) { _gameFont = _uiGame.starmap.cursorViewText.font; } if ((Object)(object)_gameFont == (Object)null) { _gameFont = Resources.GetBuiltinResource<Font>("Arial.ttf"); } BuildUI(); BuildOptionsMenu(); BuildGeneralOptionsMenu(); BuildCustomItemPicker(); } private Sprite GetOrCreateHatchedTransitSprite() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_0070: 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) if ((Object)(object)_hatchedTransitSprite != (Object)null) { return _hatchedTransitSprite; } Texture2D val = new Texture2D(16, 16, (TextureFormat)4, false) { wrapMode = (TextureWrapMode)0, filterMode = (FilterMode)1 }; Color[] array = (Color[])(object)new Color[256]; for (int i = 0; i < 16; i++) { for (int j = 0; j < 16; j++) { float num = ((((j + i) & 7) < 4) ? 1f : 0.22f); array[i * 16 + j] = new Color(1f, 1f, 1f, num); } } val.SetPixels(array); val.Apply(); _hatchedTransitSprite = Sprite.Create(val, new Rect(0f, 0f, 16f, 16f), new Vector2(0.5f, 0.5f), 100f); return _hatchedTransitSprite; } public bool IsPointerOverUI() { if (!((Component)this).gameObject.activeInHierarchy) { return false; } if ((Object)(object)_panelHoverTracker != (Object)null && _panelHoverTracker.IsHovered) { return true; } if (_optionsMenuOpen && (Object)(object)_optionsHoverTracker != (Object)null && _optionsHoverTracker.IsHovered) { return true; } if (_generalOptionsMenuOpen && (Object)(object)_generalOptionsHoverTracker != (Object)null && _generalOptionsHoverTracker.IsHovered) { return true; } if (_customPickerOpen && (Object)(object)_customPickerHoverTracker != (Object)null && _customPickerHoverTracker.IsHovered) { return true; } return false; } private void BuildUI() { //IL_0040: 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) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: 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_0118: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Expected O, but got Unknown //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Unknown result type (might be due to invalid IL or missing references) //IL_02bd: Unknown result type (might be due to invalid IL or missing references) //IL_02f5: Unknown result type (might be due to invalid IL or missing references) //IL_02ff: Expected O, but got Unknown //IL_0324: Unknown result type (might be due to invalid IL or missing references) //IL_0348: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_0386: Unknown result type (might be due to invalid IL or missing references) //IL_03a5: Unknown result type (might be due to invalid IL or missing references) //IL_03c4: Unknown result type (might be due to invalid IL or missing references) //IL_0423: Unknown result type (might be due to invalid IL or missing references) //IL_0432: Unknown result type (might be due to invalid IL or missing references) //IL_045a: Unknown result type (might be due to invalid IL or missing references) //IL_0464: Expected O, but got Unknown //IL_047b: Unknown result type (might be due to invalid IL or missing references) //IL_048a: Unknown result type (might be due to invalid IL or missing references) //IL_04c2: Unknown result type (might be due to invalid IL or missing references) //IL_04cc: Expected O, but got Unknown //IL_04e3: Unknown result type (might be due to invalid IL or missing references) //IL_04f2: Unknown result type (might be due to invalid IL or missing references) //IL_051a: Unknown result type (might be due to invalid IL or missing references) //IL_0524: Expected O, but got Unknown //IL_053b: Unknown result type (might be due to invalid IL or missing references) //IL_054a: Unknown result type (might be due to invalid IL or missing references) //IL_0582: Unknown result type (might be due to invalid IL or missing references) //IL_058c: Expected O, but got Unknown //IL_05a3: Unknown result type (might be due to invalid IL or missing references) //IL_05b2: Unknown result type (might be due to invalid IL or missing references) //IL_05ea: Unknown result type (might be due to invalid IL or missing references) //IL_05f4: Expected O, but got Unknown //IL_0619: Unknown result type (might be due to invalid IL or missing references) //IL_063d: Unknown result type (might be due to invalid IL or missing references) //IL_065c: Unknown result type (might be due to invalid IL or missing references) //IL_067b: Unknown result type (might be due to invalid IL or missing references) //IL_069a: Unknown result type (might be due to invalid IL or missing references) //IL_06b9: Unknown result type (might be due to invalid IL or missing references) //IL_06e8: Unknown result type (might be due to invalid IL or missing references) //IL_070c: Unknown result type (might be due to invalid IL or missing references) //IL_072b: Unknown result type (might be due to invalid IL or missing references) //IL_074a: Unknown result type (might be due to invalid IL or missing references) //IL_0769: Unknown result type (might be due to invalid IL or missing references) //IL_0788: Unknown result type (might be due to invalid IL or missing references) //IL_07d1: Unknown result type (might be due to invalid IL or missing references) //IL_07d7: Expected O, but got Unknown //IL_0805: Unknown result type (might be due to invalid IL or missing references) //IL_081f: Unknown result type (might be due to invalid IL or missing references) //IL_0839: Unknown result type (might be due to invalid IL or missing references) //IL_0853: Unknown result type (might be due to invalid IL or missing references) //IL_086d: Unknown result type (might be due to invalid IL or miss