using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Threading; using System.Threading.Tasks; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using YamlDotNet.Serialization; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("LocationPlacementAccelerator")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+08dec1f5d0deb0d768753023c8e0d899c992d171")] [assembly: AssemblyProduct("LocationPlacementAccelerator")] [assembly: AssemblyTitle("LocationPlacementAccelerator")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace LPA { public class AltitudeStat { public float Min = float.MaxValue; public float Max = float.MinValue; public double Sum = 0.0; public long Count = 0L; public void Add(float valueP) { if (valueP < Min) { Min = valueP; } if (valueP > Max) { Max = valueP; } Sum += valueP; Count++; } public string GetString() { if (Count == 0) { return ""; } return $"[Observed: Min {Min:F1}m, Avg {Sum / (double)Count:F1}m, Max {Max:F1}m]"; } } public abstract class BucketingStrategy { protected static int _cachedVisitLimit = 1; protected static float _cachedWorldRadius = 10000f; public virtual void Initialize() { WorldSurveyData.Initialize(); _cachedVisitLimit = ModConfig.SurveyVisitLimit.Value; _cachedWorldRadius = ModConfig.WorldRadius; } public abstract bool GetZone(ZoneLocation locationP, out Vector2i result); public virtual void MarkZoneOccupied(int zoneIndexP) { if (zoneIndexP >= 0 && zoneIndexP < WorldSurveyData.Grid.Length) { WorldSurveyData.OccupiedZoneIndices.Add(zoneIndexP); } } public abstract void PruneZone(string prefabNameP, Vector2i zoneIdP); public abstract void ClearCache(string prefabNameP); public abstract void DumpDiagnostics(); public abstract List GetOrBuildCandidateList(ZoneLocation locationP); protected static void Shuffle(List listP) { int num = listP.Count; while (num > 1) { num--; int index = Random.Range(0, num + 1); T value = listP[index]; listP[index] = listP[num]; listP[num] = value; } } } internal static class CenterFirstPlacer { private const int DartsPerZone = 20; private const int MaxOuterIter = 200000; public static List PlaceAll(ZoneSystem zsP) { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) List list = new List(); foreach (ZoneLocation location in zsP.m_locations) { if (!location.m_enable || !location.m_centerFirst || !Compatibility.IsValidLocation(location)) { continue; } bool flag = false; foreach (LocationInstance value in zsP.m_locationInstances.Values) { if (value.m_location.m_prefabName == location.m_prefabName) { flag = true; break; } } if (flag) { list.Add(location.m_prefabName); DiagnosticLog.WriteTimestampedLog("[CenterFirstPlacer] " + location.m_prefabName + ": already present in world, skipping center-first placement.", (LogLevel)16); } else if (TryPlace(zsP, location)) { list.Add(location.m_prefabName); DiagnosticLog.WriteTimestampedLog($"[CenterFirstPlacer] {location.m_prefabName}: placed 1/{location.m_quantity}.", (LogLevel)16); } else { DiagnosticLog.WriteTimestampedLog($"[CenterFirstPlacer] {location.m_prefabName}: failed to place center-first instance. The replaced engine will handle all {location.m_quantity}.", (LogLevel)4); } } return list; } private static bool TryPlace(ZoneSystem zsP, ZoneLocation locP) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: 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_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Invalid comparison between Unknown and I4 //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Invalid comparison between Unknown and I4 //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Unknown result type (might be due to invalid IL or missing references) float num = locP.m_minDistance; int num2 = Mathf.Max(1, Mathf.RoundToInt(200000f * ModConfig.OuterMultiplier.Value)); Vector2i val = default(Vector2i); for (int i = 0; i < num2; i++) { int num3 = Mathf.FloorToInt(num / 64f) + 1; ((Vector2i)(ref val))..ctor(ThreadSafePRNG.NextInt(-num3, num3), ThreadSafePRNG.NextInt(-num3, num3)); num += 1f; if (zsP.m_locationInstances.ContainsKey(val)) { continue; } Vector3 zonePos = ZoneSystem.GetZonePos(val); BiomeArea biomeArea = WorldGenerator.instance.GetBiomeArea(zonePos); if ((locP.m_biomeArea & biomeArea) == 0) { continue; } for (int j = 0; j < 20; j++) { float num4 = ThreadSafePRNG.NextFloat(-32f + locP.m_exteriorRadius, 32f - locP.m_exteriorRadius); float num5 = ThreadSafePRNG.NextFloat(-32f + locP.m_exteriorRadius, 32f - locP.m_exteriorRadius); Vector3 val2 = zonePos + new Vector3(num4, 0f, num5); float magnitude = ((Vector3)(ref val2)).magnitude; if ((locP.m_minDistance > 0f && magnitude < locP.m_minDistance) || (locP.m_maxDistance > 0f && magnitude > locP.m_maxDistance) || (WorldGenerator.instance.GetBiome(val2) & locP.m_biome) == 0) { continue; } float num6 = (val2.y = WorldGenerator.instance.GetHeight(val2.x, val2.z)) - ZoneSystem.instance.m_waterLevel; if (num6 < locP.m_minAltitude || num6 > locP.m_maxAltitude) { continue; } if (locP.m_maxTerrainDelta > 0f || locP.m_minTerrainDelta > 0f) { ThreadSafeTerrainDelta.GetTerrainDelta(val2, locP.m_exteriorRadius, out var delta, out var _); if (delta > locP.m_maxTerrainDelta || delta < locP.m_minTerrainDelta) { continue; } } if ((locP.m_minDistanceFromSimilar > 0f && zsP.HaveLocationInRange(locP.m_prefabName, locP.m_group, val2, locP.m_minDistanceFromSimilar, false)) || (locP.m_maxDistanceFromSimilar > 0f && !zsP.HaveLocationInRange(locP.m_prefabName, locP.m_group, val2, locP.m_maxDistanceFromSimilar, true))) { continue; } zsP.RegisterLocation(locP, val2, false); if (WorldSurveyData.ZoneToIndex.TryGetValue(val, out var value)) { WorldSurveyData.OccupiedZoneIndices.Add(value); SurveyMode.MarkZoneOccupied(value); } DiagnosticLog.WriteTimestampedLog("[CenterFirstPlacer] Placed " + locP.m_prefabName + ".", (LogLevel)16); return true; } } return false; } } public static class Compatibility { public static volatile bool BCMinimapDone = false; private static PropertyInfo _ewsWorldRadiusProp; private static FieldInfo _ewsWorldRadiusField; private static FieldInfo _ewdRadiusField; private static FieldInfo _ewdTotalRadiusField; private static FieldInfo _ewdStretchField; private static FieldInfo _ewdBiomeStretchField; private static Type _ewdBiomeManagerType; private static FieldInfo _ewdBiomeToTerrainField; private static Biome _cachedHighReliefMask = (Biome)516; private static bool _highReliefMaskComputed = false; public static bool IsBetterContinentsActive { get; private set; } = false; public static bool IsExpandWorldSizeActive { get; private set; } = false; public static bool IsExpandWorldDataActive { get; private set; } = false; public static float DetectedWorldRadius { get; private set; } = 10000f; public static string WorldRadiusSource { get; private set; } = "Vanilla default"; public static bool IsValidLocation(ZoneLocation locP) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (locP == null) { return false; } _ = locP.m_prefab; if (false) { return false; } if (locP.m_prefab.IsValid) { return true; } if (locP.m_prefab.m_name != null) { return true; } return false; } public static void Initialize(ManualLogSource loggerP) { DetectBetterContinents(loggerP); DetectExpandWorldSize(loggerP); DetectExpandWorldData(loggerP); RefreshWorldRadius(loggerP); loggerP.LogInfo((object)("[LPACompatibility] Init complete. " + $"BC={IsBetterContinentsActive}, " + $"EWS={IsExpandWorldSizeActive}," + $" EWD={IsExpandWorldDataActive}")); if (IsExpandWorldDataActive) { LogEWDWorldInfoSnapshot(loggerP); } } public static float RefreshWorldRadius(ManualLogSource loggerP) { float num = 10000f; string worldRadiusSource = "Vanilla default"; if (IsExpandWorldSizeActive) { float? num2 = ReadEWSRadius(); if (num2.HasValue && num2.Value > 100f) { num = num2.Value; worldRadiusSource = "Expand World Size"; } else { loggerP.LogWarning((object)"[LPACompatibility] EWS detected but radius read failed - using 10000m."); } } DetectedWorldRadius = num; WorldRadiusSource = worldRadiusSource; return num; } public static Dictionary GetEwdBiomeToTerrainMap() { //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) if (!IsExpandWorldDataActive || _ewdBiomeToTerrainField == null) { return null; } try { object value = _ewdBiomeToTerrainField.GetValue(null); if (value is IDictionary dictionary) { Dictionary dictionary2 = new Dictionary(); foreach (DictionaryEntry item in dictionary) { if (item.Key != null && item.Value != null) { dictionary2[(Biome)item.Key] = (Biome)item.Value; } } return dictionary2; } } catch (Exception ex) { DiagnosticLog.WriteTimestampedLog("[LPACompatibility] Failed to extract EWD BiomeToTerrain map: " + ex.Message, (LogLevel)4); } return null; } public static Biome GetHighReliefBiomeMask() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Invalid comparison between Unknown and I4 //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Invalid comparison between Unknown and I4 //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Invalid comparison between Unknown and I4 //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) if (_highReliefMaskComputed) { return _cachedHighReliefMask; } Biome val = (Biome)516; if (IsExpandWorldDataActive && _ewdBiomeToTerrainField != null) { try { object value = _ewdBiomeToTerrainField.GetValue(null); if (value is IDictionary dictionary) { int num = 0; foreach (DictionaryEntry item in dictionary) { if (item.Key != null && item.Value != null) { Biome val2 = (Biome)item.Key; Biome val3 = (Biome)item.Value; if (val2 != val3 && ((int)val3 == 4 || (int)val3 == 512) && (val & val2) == 0) { val |= val2; num++; } } } if (num > 0) { DiagnosticLog.WriteTimestampedLog($"[LPACompatibility] EWD high-relief: {num} custom biome(s) mapped to Mountain/Mistlands terrain. Added to 3D similarity mask.", (LogLevel)16); } } } catch (Exception ex) { DiagnosticLog.WriteTimestampedLog("[LPACompatibility] High-relief discovery failed: " + ex.Message + ". Falling back to vanilla Mountain|Mistlands.", (LogLevel)4); } } _cachedHighReliefMask = val; _highReliefMaskComputed = true; return val; } private static void LogEWDWorldInfoSnapshot(ManualLogSource loggerP) { try { float num = ReadEWDFloatField(_ewdRadiusField); float num2 = ReadEWDFloatField(_ewdTotalRadiusField); float num3 = ReadEWDFloatField(_ewdStretchField); float num4 = ReadEWDFloatField(_ewdBiomeStretchField); loggerP.LogInfo((object)("[LPACompatibility] EWD WorldInfo snapshot: " + $"Radius={num:F0} TotalRadius={num2:F0} " + $"Stretch={num3:F3} BiomeStretch={num4:F3}")); } catch (Exception ex) { loggerP.LogWarning((object)("[LPACompatibility] EWD WorldInfo snapshot failed: " + ex.Message)); } } private static float ReadEWDFloatField(FieldInfo fieldP) { if (fieldP == null) { return 0f; } return Convert.ToSingle(fieldP.GetValue(null)); } private static void DetectBetterContinents(ManualLogSource loggerP) { if (!Chainloader.PluginInfos.TryGetValue("BetterContinents", out var value)) { return; } IsBetterContinentsActive = true; loggerP.LogInfo((object)"[LPACompatibility] Better Continents detected."); try { Assembly assembly = ((object)value.Instance).GetType().Assembly; Type type = assembly.GetType("BetterContinents.BetterContinents"); if (type == null) { loggerP.LogWarning((object)"[LPACompatibility] BC: BetterContinents type not found - minimap wait disabled."); BCMinimapDone = true; return; } EventInfo @event = type.GetEvent("MinimapGenerationComplete", BindingFlags.Static | BindingFlags.Public); if (@event == null) { loggerP.LogWarning((object)"[LPACompatibility] BC: MinimapGenerationComplete event not found - minimap wait disabled."); BCMinimapDone = true; return; } @event.AddEventHandler(null, (Action)delegate { BCMinimapDone = true; }); loggerP.LogInfo((object)"[LPACompatibility] BC: Subscribed to MinimapGenerationComplete. Placement will wait for minimap."); } catch (Exception ex) { loggerP.LogWarning((object)("[LPACompatibility] BC: Event subscription failed - minimap wait disabled. " + ex.Message)); BCMinimapDone = true; } } private static void DetectExpandWorldSize(ManualLogSource loggerP) { if (!Chainloader.PluginInfos.TryGetValue("expand_world_size", out var value)) { return; } try { Assembly assembly = ((object)value.Instance).GetType().Assembly; Type type = assembly.GetType("ExpandWorldSize.Configuration"); if (type == null) { loggerP.LogWarning((object)"[LPACompatibility] EWS: Configuration type not found."); return; } _ewsWorldRadiusProp = AccessTools.Property(type, "WorldRadius"); if (_ewsWorldRadiusProp == null) { _ewsWorldRadiusField = AccessTools.Field(type, "WorldRadius"); } if (_ewsWorldRadiusProp == null && _ewsWorldRadiusField == null) { loggerP.LogWarning((object)"[LPACompatibility] EWS: WorldRadius member not found."); return; } IsExpandWorldSizeActive = true; loggerP.LogInfo((object)"[LPACompatibility] Expand World Size detected."); } catch (Exception ex) { loggerP.LogWarning((object)("[LPACompatibility] EWS error: " + ex.Message)); } } private static void DetectExpandWorldData(ManualLogSource loggerP) { if (!Chainloader.PluginInfos.TryGetValue("expand_world_data", out var value)) { return; } try { Assembly assembly = ((object)value.Instance).GetType().Assembly; Type type = assembly.GetType("ExpandWorldData.WorldInfo"); if (type == null) { loggerP.LogWarning((object)"[LPACompatibility] EWD: ExpandWorldData.WorldInfo type not found."); return; } _ewdRadiusField = AccessTools.Field(type, "Radius"); _ewdTotalRadiusField = AccessTools.Field(type, "TotalRadius"); _ewdStretchField = AccessTools.Field(type, "Stretch"); _ewdBiomeStretchField = AccessTools.Field(type, "BiomeStretch"); if (_ewdRadiusField == null) { loggerP.LogWarning((object)"[LPACompatibility] EWD: Radius field not found on WorldInfo. EWD integration will remain inactive."); return; } _ewdBiomeManagerType = assembly.GetType("ExpandWorldData.BiomeManager"); if (_ewdBiomeManagerType != null) { _ewdBiomeToTerrainField = AccessTools.Field(_ewdBiomeManagerType, "BiomeToTerrain"); if (_ewdBiomeToTerrainField == null) { loggerP.LogWarning((object)"[LPACompatibility] EWD: BiomeToTerrain field not found. Custom biomes will not participate in 3D similarity mask (vanilla fallback used)."); } } else { loggerP.LogWarning((object)"[LPACompatibility] EWD: BiomeManager type not found. Custom biome terrain classification unavailable."); } IsExpandWorldDataActive = true; loggerP.LogInfo((object)"[LPACompatibility] Expand World Data detected."); } catch (Exception ex) { loggerP.LogWarning((object)("[LPACompatibility] EWD reflection error: " + ex.Message)); } } private static float? ReadEWSRadius() { try { if (_ewsWorldRadiusProp != null) { return Convert.ToSingle(_ewsWorldRadiusProp.GetValue(null)); } if (_ewsWorldRadiusField != null) { return Convert.ToSingle(_ewsWorldRadiusField.GetValue(null)); } } catch { } return null; } } public static class ConstraintRelaxer { public class OriginalStats { public float MinAlt; public float MaxAlt; public float MinDist; public float MaxDist; public float MinTerr; public float MaxTerr; public float ExtRad; public int Quantity; } public static Dictionary RelaxationAttempts = new Dictionary(); private static Dictionary _originalStats = new Dictionary(); public static object CapturedOuterLoop = null; public static void CaptureStateMachine(object smP) { CapturedOuterLoop = smP; } public static void Reset() { RelaxationAttempts.Clear(); _originalStats.Clear(); CapturedOuterLoop = null; } public static void RestoreQuantities() { ZoneSystem instance = ZoneSystem.instance; if ((Object)(object)instance == (Object)null) { return; } foreach (KeyValuePair originalStat in _originalStats) { ZoneLocation val = null; for (int i = 0; i < instance.m_locations.Count; i++) { if (instance.m_locations[i].m_prefabName == originalStat.Key) { val = instance.m_locations[i]; break; } } if (val != null && val.m_quantity != originalStat.Value.Quantity) { val.m_quantity = originalStat.Value.Quantity; if (ModConfig.DiagnosticMode.Value) { DiagnosticLog.WriteLog($"[Adjuster] Restored {originalStat.Key} m_quantity to {originalStat.Value.Quantity}.", (LogLevel)16); } } } } public static bool TryRelax(ReportData dataP) { if (dataP == null || dataP.Loc == null) { return false; } int value = ModConfig.MaxRelaxationAttempts.Value; if (value <= 0) { return false; } string prefabName = dataP.Loc.m_prefabName; int quantity = dataP.Loc.m_quantity; if (Interleaver.OriginalLocations != null) { for (int i = 0; i < Interleaver.OriginalLocations.Count; i++) { if (Interleaver.OriginalLocations[i].m_prefabName == prefabName) { quantity = Interleaver.OriginalLocations[i].m_quantity; break; } } } int placed = dataP.Placed; if (!PlayabilityPolicy.NeedsRelaxation(prefabName, placed, quantity)) { return false; } if (!RelaxationAttempts.TryGetValue(prefabName, out var value2)) { value2 = 0; RelaxationAttempts[prefabName] = 0; _originalStats[prefabName] = new OriginalStats { MinAlt = dataP.Loc.m_minAltitude, MaxAlt = dataP.Loc.m_maxAltitude, MinDist = dataP.Loc.m_minDistance, MaxDist = dataP.Loc.m_maxDistance, MinTerr = dataP.Loc.m_minTerrainDelta, MaxTerr = dataP.Loc.m_maxTerrainDelta, ExtRad = dataP.Loc.m_exteriorRadius, Quantity = quantity }; } if (value2 >= value) { DiagnosticLog.WriteTimestampedLog($"[Adjuster] {prefabName} failed after {value} relaxation attempts. Abandoning.", (LogLevel)4); RelaxationTracker.MarkRelaxationExhausted(prefabName); return false; } RelaxationAttempts[prefabName] = value2 + 1; PlacementBottleneck bottleneck = PlacementBottleneck.Unknown; float maxFailureRate = -1f; AnalyzeConstraint(dataP.ErrDist, dataP.InDist, PlacementBottleneck.Distance); AnalyzeConstraint(dataP.ErrBiome, dataP.InBiome, PlacementBottleneck.Biome); AnalyzeConstraint(dataP.ErrAlt, dataP.InAlt, PlacementBottleneck.Altitude); AnalyzeConstraint(dataP.ErrTerrain, dataP.InTerr, PlacementBottleneck.Terrain); AnalyzeConstraint(dataP.ErrSim + dataP.ErrNotSim, dataP.InSim, PlacementBottleneck.Similarity); float minAltitude = dataP.Loc.m_minAltitude; float maxAltitude = dataP.Loc.m_maxAltitude; float minDistance = dataP.Loc.m_minDistance; float maxDistance = dataP.Loc.m_maxDistance; float maxTerrainDelta = dataP.Loc.m_maxTerrainDelta; float exteriorRadius = dataP.Loc.m_exteriorRadius; ApplyRelaxation(dataP.Loc, prefabName, bottleneck, value2 + 1, value); string attemptDescriptionP = BuildAttemptDescription(bottleneck, value2 + 1, minAltitude, maxAltitude, minDistance, maxDistance, maxTerrainDelta, exteriorRadius, dataP.Loc.m_minAltitude, dataP.Loc.m_maxAltitude, dataP.Loc.m_minDistance, dataP.Loc.m_maxDistance, dataP.Loc.m_maxTerrainDelta, dataP.Loc.m_exteriorRadius); RelaxationTracker.MarkRelaxationAttempt(prefabName, attemptDescriptionP, dataP.Loc.m_prioritized); Interleaver.SyncRelaxation(dataP.Loc); int minimumNeededCount = PlayabilityPolicy.GetMinimumNeededCount(prefabName, quantity); int quantityToPlaceP = Mathf.Max(1, minimumNeededCount - placed); SurveyMode.ClearCache(dataP.PrefabName); int fallbackBaseP = 200000; if (dataP.Loc.m_prioritized) { fallbackBaseP = 100000; } List list = Interleaver.CreateRelaxedPackets(dataP.Loc, quantityToPlaceP, fallbackBaseP); bool flag = false; if (CapturedOuterLoop != null) { Type type = CapturedOuterLoop.GetType(); FieldInfo fieldInfo = null; FieldInfo fieldInfo2 = null; FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic); for (int j = 0; j < fields.Length; j++) { if (fields[j].FieldType == typeof(List) && fields[j].Name.Contains("ordered")) { fieldInfo = fields[j]; } if (fields[j].FieldType == typeof(int) && fields[j].Name.Contains("")) { fieldInfo2 = fields[j]; } } if (fieldInfo != null && fieldInfo2 != null) { List list2 = fieldInfo.GetValue(CapturedOuterLoop) as List; int num = (int)fieldInfo2.GetValue(CapturedOuterLoop); if (list2 != null) { int num2 = Math.Min(num + 1, list2.Count); list2.InsertRange(num2, list); flag = true; DiagnosticLog.WriteLog($"[Adjuster] {prefabName} ({list.Count} Chunks) inserted at index {num2} for immediate retry.", (LogLevel)16); } } } if (!flag) { ZoneSystem instance = ZoneSystem.instance; if ((Object)(object)instance != (Object)null) { instance.m_locations.AddRange(list); } } TranspiledEnginePatches.ResetLocationLog(); DiagnosticLog.WriteLog("[Adjuster] " + prefabName + " re-queued for retry.", (LogLevel)16); return true; void AnalyzeConstraint(long errP, long inputP, PlacementBottleneck nameP) { if (inputP > 0) { float num3 = (float)errP / (float)inputP; if (num3 >= maxFailureRate) { maxFailureRate = num3; bottleneck = nameP; } } } } private static void ApplyRelaxation(ZoneLocation locP, string prefabNameP, PlacementBottleneck bottleneckP, int attemptNumberP, int maxAttemptsP) { float value = ModConfig.RelaxationMagnitude.Value; DiagnosticLog.WriteTimestampedLog($"[Adjuster] RELAXING {locP.m_prefabName} (Attempt {attemptNumberP}/{maxAttemptsP}). Bottleneck: {bottleneckP}. Attempting immediate retry.", (LogLevel)8); if (!_originalStats.TryGetValue(prefabNameP, out var value2)) { value2 = new OriginalStats { MinAlt = locP.m_minAltitude, MaxAlt = locP.m_maxAltitude, MinDist = locP.m_minDistance, MaxDist = locP.m_maxDistance, MinTerr = locP.m_minTerrainDelta, MaxTerr = locP.m_maxTerrainDelta, ExtRad = locP.m_exteriorRadius }; } bool flag = bottleneckP == PlacementBottleneck.Altitude || bottleneckP == PlacementBottleneck.Unknown; bool flag2 = bottleneckP == PlacementBottleneck.Distance || bottleneckP == PlacementBottleneck.Unknown; bool flag3 = bottleneckP == PlacementBottleneck.Terrain || bottleneckP == PlacementBottleneck.Unknown; bool flag4 = bottleneckP == PlacementBottleneck.Similarity || bottleneckP == PlacementBottleneck.Unknown; if (flag) { float num = Mathf.Max(1f, Mathf.Abs(locP.m_minAltitude) * value); locP.m_minAltitude -= num; if (value2.MinAlt >= 0f && locP.m_minAltitude < 0f) { locP.m_minAltitude = 0f; } float num2 = Mathf.Max(1f, Mathf.Abs(locP.m_maxAltitude) * value); locP.m_maxAltitude += num2; if (value2.MaxAlt <= 0f && locP.m_maxAltitude > 0f) { locP.m_maxAltitude = 0f; } DiagnosticLog.WriteLog($" -> Altitude relaxed to {locP.m_minAltitude:F0}m..{locP.m_maxAltitude:F0}m", (LogLevel)16); } if (flag2) { if (locP.m_maxDistance > 0.1f) { float num3 = Mathf.Max(1f, locP.m_maxDistance * value); locP.m_maxDistance += num3; if (locP.m_maxDistance > ModConfig.WorldRadius) { locP.m_maxDistance = ModConfig.WorldRadius; } } if (locP.m_minDistance > 0f) { float num4 = Mathf.Max(1f, locP.m_minDistance * value); locP.m_minDistance -= num4; if (locP.m_minDistance < 0f) { locP.m_minDistance = 0f; } } DiagnosticLog.WriteLog($" -> Distance relaxed to {locP.m_minDistance:F0}m..{locP.m_maxDistance:F0}m", (LogLevel)16); } if (flag3) { float num5 = Mathf.Max(1f, locP.m_maxTerrainDelta * value); locP.m_maxTerrainDelta += num5; if (locP.m_minTerrainDelta > 0f) { float num6 = Mathf.Max(1f, locP.m_minTerrainDelta * value); locP.m_minTerrainDelta -= num6; if (locP.m_minTerrainDelta < 0f) { locP.m_minTerrainDelta = 0f; } } DiagnosticLog.WriteLog($" -> TerrainDelta relaxed to {locP.m_minTerrainDelta:F1}..{locP.m_maxTerrainDelta:F1}", (LogLevel)16); } if (!flag4) { return; } if (locP.m_exteriorRadius > 0f) { float num7 = Mathf.Max(1f, locP.m_exteriorRadius * value); locP.m_exteriorRadius -= num7; if (locP.m_exteriorRadius < 0f) { locP.m_exteriorRadius = 0f; } } DiagnosticLog.WriteLog($" -> ExteriorRadius relaxed to {locP.m_exteriorRadius:F0}", (LogLevel)16); } private static string BuildAttemptDescription(PlacementBottleneck bottleneckP, int attemptNumP, float preMinAltP, float preMaxAltP, float preMinDistP, float preMaxDistP, float preMaxTerrP, float preExtRadP, float postMinAltP, float postMaxAltP, float postMinDistP, float postMaxDistP, float postMaxTerrP, float postExtRadP) { return string.Format(arg1: bottleneckP switch { PlacementBottleneck.Altitude => $"Altitude {preMinAltP:F0}..{preMaxAltP:F0}-->{postMinAltP:F0}..{postMaxAltP:F0}", PlacementBottleneck.Distance => $"Distance {preMinDistP:F0}..{preMaxDistP:F0}-->{postMinDistP:F0}..{postMaxDistP:F0}", PlacementBottleneck.Terrain => $"TerrainDelta {preMaxTerrP:F1}-->{postMaxTerrP:F1}", PlacementBottleneck.Similarity => $"ExteriorRadius {preExtRadP:F0}-->{postExtRadP:F0}", _ => "Constraints loosened", }, format: "[attempt {0}]: {1}", arg0: attemptNumP); } public static string GetRelaxationSummary(string prefabNameP, ZoneLocation currentLocP) { if (!RelaxationAttempts.TryGetValue(prefabNameP, out var value) || value == 0) { return ""; } if (!_originalStats.TryGetValue(prefabNameP, out var value2)) { return $"(Relaxed {value} times)"; } List list = new List(); if (Mathf.Abs(currentLocP.m_minAltitude - value2.MinAlt) > 1f) { list.Add($"MinAlt: {value2.MinAlt:F0}->{currentLocP.m_minAltitude:F0}"); } if (Mathf.Abs(currentLocP.m_maxDistance - value2.MaxDist) > 1f) { list.Add($"MaxDist: {value2.MaxDist:F0}->{currentLocP.m_maxDistance:F0}"); } if (Mathf.Abs(currentLocP.m_minDistance - value2.MinDist) > 1f) { list.Add($"MinDist: {value2.MinDist:F0}->{currentLocP.m_minDistance:F0}"); } if (Mathf.Abs(currentLocP.m_maxTerrainDelta - value2.MaxTerr) > 0.1f) { list.Add($"MaxTerr: {value2.MaxTerr:F1}->{currentLocP.m_maxTerrainDelta:F1}"); } if (Mathf.Abs(currentLocP.m_exteriorRadius - value2.ExtRad) > 1f) { list.Add($"ExtRadius: {value2.ExtRad:F0}->{currentLocP.m_exteriorRadius:F0}"); } if (list.Count == 0) { return $"(Relaxed {value} times)"; } return string.Format("(Relaxed {0}x: {1})", value, string.Join(", ", list)); } } public static class DiagnosticLog { private static StreamWriter _logWriter; private static readonly object _logLock = new object(); public static bool MinimalLogging = false; private static string _runVersion = "000"; private static string _runFingerprint = ""; public static string RunFingerprint => _runFingerprint; public static void Initialize(string versionP) { Compatibility.Initialize(ModConfig.Log); _runVersion = versionP; } public static string BuildFingerprint(string versionP = null) { if (versionP != null) { _runVersion = versionP; } PlacementMode effectiveMode = ModConfig.EffectiveMode; bool effectiveLegacy = ModConfig.EffectiveLegacy; string text = (effectiveLegacy ? "Transpiled" : "Replaced"); string text2 = effectiveMode switch { PlacementMode.Survey => "Survey", PlacementMode.Filter => "Filter", PlacementMode.Force => "Force", _ => "Vanilla", }; StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("LPA_" + text + "_" + text2); if (!effectiveLegacy && ModConfig.EnableParallelPlacement.Value) { stringBuilder.Append("_MT"); } if (!effectiveLegacy && ModConfig.EnableInterleavedScheduling.Value) { stringBuilder.Append("_Interleaved"); } if (effectiveMode == PlacementMode.Survey) { int value = ModConfig.SurveyScanResolution.Value; stringBuilder.Append($"_{value}x"); } float value2 = ModConfig.OuterMultiplier.Value; float value3 = ModConfig.InnerMultiplier.Value; if (Mathf.Abs(value2 - 1f) > 0.001f) { stringBuilder.Append($"_Outer{value2:G}x"); } if (Mathf.Abs(value3 - 1f) > 0.001f) { stringBuilder.Append($"_Inner{value3:G}x"); } int value4 = ModConfig.MaxRelaxationAttempts.Value; if (value4 > 0) { stringBuilder.Append($"_Relax{value4}"); } string text3 = DateTime.Now.ToString("HHmm"); stringBuilder.Append("_" + text3); _runFingerprint = stringBuilder.ToString(); return _runFingerprint; } public static void OpenLogFile() { MinimalLogging = ModConfig.MinimalLogging.Value; if (!ModConfig.WriteToFile.Value) { return; } try { _logWriter?.Close(); _logWriter = null; string path; if (ModConfig.VerboseLogFileName.Value) { string text = BuildFingerprint(_runVersion); path = Path.Combine(Paths.BepInExRootPath, text + ".log"); } else { BuildFingerprint(_runVersion); path = Path.Combine(Paths.BepInExRootPath, "LocationPlacementAccelerator.log"); } _logWriter = new StreamWriter(path, append: false) { AutoFlush = true }; WriteConfigHeader(_runVersion); } catch { } } private static void WriteConfigHeader(string versionP) { if (_logWriter != null) { string text = (ModConfig.EffectiveLegacy ? "Transpiled" : "Replaced"); bool flag = ModConfig.EffectiveMode == PlacementMode.Survey; _logWriter.WriteLine("=== Location Placement Accelerator v" + versionP + " ==="); _logWriter.WriteLine("=== Run Configuration ==="); _logWriter.WriteLine(" Engine: " + text); _logWriter.WriteLine($" Mode: {ModConfig.EffectiveMode}"); _logWriter.WriteLine($" World Radius: {Compatibility.DetectedWorldRadius:F0}m [{Compatibility.WorldRadiusSource}]"); if (flag) { _logWriter.WriteLine($" Scan Resolution: {ModConfig.SurveyScanResolution.Value}x{ModConfig.SurveyScanResolution.Value}"); _logWriter.WriteLine($" Visit Limit: {ModConfig.SurveyVisitLimit.Value}"); } if (!ModConfig.EffectiveLegacy) { _logWriter.WriteLine(" Multithreaded: " + (ModConfig.EnableParallelPlacement.Value ? "ON" : "OFF")); _logWriter.WriteLine(" Interleaved: " + (ModConfig.EnableInterleavedScheduling.Value ? "ON" : "OFF")); _logWriter.WriteLine($" PresenceGrid Cell: {ModConfig.PresenceGridCellSize.Value}m"); } _logWriter.WriteLine($" Outer Multiplier: {ModConfig.OuterMultiplier.Value}x"); _logWriter.WriteLine($" Inner Multiplier: {ModConfig.InnerMultiplier.Value}x"); _logWriter.WriteLine($" Relaxation: {ModConfig.MaxRelaxationAttempts.Value} attempts @ {ModConfig.RelaxationMagnitude.Value * 100f:F0}%/step"); _logWriter.WriteLine(" Diagnostic Mode: " + (ModConfig.DiagnosticMode.Value ? "ON" : "OFF")); _logWriter.WriteLine(" Better Continents: " + (Compatibility.IsBetterContinentsActive ? "Detected" : "Not present")); _logWriter.WriteLine(" Expand World Size: " + (Compatibility.IsExpandWorldSizeActive ? "Detected" : "Not present")); _logWriter.WriteLine(" Expand World Data: " + (Compatibility.IsExpandWorldDataActive ? "Detected" : "Not present")); _logWriter.WriteLine("=========================================="); } } public static void OnWorldRadiusResolved() { WriteLog($"[LPA] World radius resolved: {ModConfig.WorldRadius = Compatibility.RefreshWorldRadius(ModConfig.Log):F0}m [{Compatibility.WorldRadiusSource}]", (LogLevel)16); if (Compatibility.IsExpandWorldSizeActive || Compatibility.IsExpandWorldDataActive) { WriteLog("[LPA] Modded world size detected. Location quantities reflect any external multipliers.", (LogLevel)16); } } public static void Dispose() { _logWriter?.Close(); } public static void WriteBlankLine() { lock (_logLock) { _logWriter?.WriteLine(""); } } public static void DumpPlacementsToFile() { //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: 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_010d: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZoneSystem.instance == (Object)null || !ModConfig.WriteToFile.Value || !ModConfig.DiagnosticMode.Value) { return; } try { string path = Path.Combine(Paths.BepInExRootPath, _runFingerprint + ".placements"); using (StreamWriter streamWriter = new StreamWriter(path, append: false)) { streamWriter.WriteLine("=== Final Location Placements - " + _runFingerprint + " ==="); Dictionary dictionary = new Dictionary(); List list = new List(ZoneSystem.instance.m_locationInstances.Values); list.Sort(CompareLocationInstancesByName); for (int i = 0; i < list.Count; i++) { LocationInstance val = list[i]; string prefabName = val.m_location.m_prefabName; if (!dictionary.TryGetValue(prefabName, out var value)) { value = 0; } value = (dictionary[prefabName] = value + 1); Vector3 position = val.m_position; streamWriter.WriteLine($"{prefabName}_{value} ({position.x:F1}, {position.y:F1}, {position.z:F1})"); } } WriteLog($"[LPA] Dumped {ZoneSystem.instance.m_locationInstances.Count} placements to {_runFingerprint}.placements", (LogLevel)16); } catch (Exception ex) { WriteLog("[LPA] Failed to dump placements: " + ex.Message, (LogLevel)2); } } private static int CompareLocationInstancesByName(LocationInstance aP, LocationInstance bP) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) return string.Compare(aP.m_location.m_prefabName, bP.m_location.m_prefabName, StringComparison.Ordinal); } public static void WriteLog(string messageP, LogLevel levelP = 16) { //IL_0018: 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) lock (_logLock) { ModConfig.Log.Log(levelP, (object)messageP); _logWriter?.WriteLine($"[{levelP}] {messageP}"); } } public static void WriteTimestampedLog(string messageP, LogLevel levelP = 16) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) string text = DateTime.Now.ToString("HH:mm:ss.fff"); string text2 = "[" + text + "] " + messageP; lock (_logLock) { ModConfig.Log.Log(levelP, (object)text2); _logWriter?.WriteLine($"[{levelP}]{text2}"); } } } public enum FailureSeverity { Green, Yellow, Orange, Red } public static class FilterMode { public static Vector2i GenerateSieve(float minDistanceP, float maxDistanceP, float worldRadiusP) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) int num = (int)(worldRadiusP / 64f); int num2 = 0; Vector2i val = default(Vector2i); float magnitude; do { ((Vector2i)(ref val))..ctor(Random.Range(-num, num), Random.Range(-num, num)); Vector3 zonePos = ZoneSystem.GetZonePos(val); magnitude = ((Vector3)(ref zonePos)).magnitude; num2++; } while (num2 <= 1000 && (magnitude < minDistanceP || magnitude > maxDistanceP)); return val; } } public static class ForceMode { public static Vector2i GenerateDonut(float minDistanceP, float maxDistanceP) { //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) float num = minDistanceP + 64f; float num2 = maxDistanceP - 64f; if (num2 <= num) { num2 = num + 1f; } float num3 = num / 64f; float num4 = num2 / 64f; float num5 = Random.Range(0f, (float)Math.PI * 2f); float num6 = Mathf.Sqrt(Random.Range(num3 * num3, num4 * num4)); int num7 = Mathf.RoundToInt(num6 * Mathf.Cos(num5)); int num8 = Mathf.RoundToInt(num6 * Mathf.Sin(num5)); return new Vector2i(num7, num8); } } public static class GenerationProgress { private static bool _initialized = false; private static int _totalRequested = 0; private static volatile int _currentProcessed = 0; private static volatile int _currentPlaced = 0; private static string _modeName = "Vanilla"; private static DateTime _startTime; private static bool _isSurveying = false; private static Dictionary _preExistingCounts = new Dictionary(StringComparer.Ordinal); public static ZoneLocation CurrentLocation = null; public static string StaticTopText = ""; public static string StaticBottomText = ""; private static volatile string[] _threadSlots = null; private static List _validLocations = new List(); public static bool IsSurveying => _isSurveying; public static string[] ThreadSlots => _threadSlots; public static int ThreadSlotCount { get { string[] threadSlots = _threadSlots; if (threadSlots == null) { return 0; } return threadSlots.Length; } } public static int TotalRequested => _totalRequested; public static int CurrentProcessed => _currentProcessed; public static int CurrentPlaced => _currentPlaced; public static void InitThreadSlots(int countP) { _threadSlots = new string[countP]; } public static void SetThreadSlot(int slotIndexP, string prefabNameP) { string[] threadSlots = _threadSlots; if (threadSlots != null && slotIndexP >= 0 && slotIndexP < threadSlots.Length) { Volatile.Write(ref threadSlots[slotIndexP], prefabNameP); } } public static void ClearThreadSlots() { _threadSlots = null; } private static string BuildModeName() { bool effectiveLegacy = ModConfig.EffectiveLegacy; string text = ModConfig.EffectiveMode switch { PlacementMode.Survey => "Survey", PlacementMode.Filter => "Filter", PlacementMode.Force => "Force", _ => "Vanilla", }; string text2 = (effectiveLegacy ? "Transpiled" : "Replaced"); if (!effectiveLegacy && ModConfig.EnableParallelPlacement.Value) { return text2 + " - " + text + " - Parallel"; } return text2 + " - " + text; } public static void StartGeneration(ZoneSystem zsP) { //IL_00f5: Unknown result type (might be due to invalid IL or missing references) if (_initialized) { return; } _initialized = true; PlayabilityPolicy.Initialize(); if (ModConfig.ShowGui.Value) { ProgressOverlay.EnsureInstance(); } ConstraintRelaxer.Reset(); DiagnosticLog.OpenLogFile(); DiagnosticLog.OnWorldRadiusResolved(); _modeName = BuildModeName(); _validLocations.Clear(); List list = zsP.m_locations; if (Interleaver.OriginalLocations != null) { list = Interleaver.OriginalLocations; } foreach (ZoneLocation item in list) { if (item.m_enable && Compatibility.IsValidLocation(item)) { _validLocations.Add(item); } } _preExistingCounts.Clear(); foreach (KeyValuePair locationInstance in zsP.m_locationInstances) { string prefabName = locationInstance.Value.m_location.m_prefabName; _preExistingCounts.TryGetValue(prefabName, out var value); _preExistingCounts[prefabName] = value + 1; } int num = 0; for (int i = 0; i < _validLocations.Count; i++) { ZoneLocation val = _validLocations[i]; _preExistingCounts.TryGetValue(val.m_prefabName, out var value2); int num2 = val.m_quantity - value2; if (num2 > 0) { num += num2; } } _totalRequested = num; _currentProcessed = 0; _currentPlaced = 0; RelaxationTracker.Reset(); UpdateText(); } public static void MarkActualStart() { _startTime = DateTime.Now; DiagnosticLog.WriteTimestampedLog("=== GLOBAL START: Generating Locations (" + _modeName + ") ===", (LogLevel)16); if (ModConfig.EffectiveMode == PlacementMode.Survey) { WorldSurveyData.Initialize(); SurveyMode.Initialize(); } } public static void MarkActualStartNoSurvey() { _startTime = DateTime.Now; bool flag = ModConfig.EnableParallelPlacement.Value && !ModConfig.EffectiveLegacy; DiagnosticLog.WriteTimestampedLog("=== GLOBAL START: Generating Locations (" + _modeName + ") ===", (LogLevel)16); DiagnosticLog.WriteTimestampedLog(" Multithreaded: " + (flag ? "ON" : "OFF"), (LogLevel)16); } public static void BeginSurvey() { _isSurveying = true; } public static void EndSurvey() { _isSurveying = false; } public static void IncrementProcessed(bool successfullyPlacedP, int countP = 1) { _currentProcessed += countP; if (successfullyPlacedP) { _currentPlaced += countP; } UpdateText(); } public static void IncrementAttempted(int countP) { Interlocked.Add(ref _currentProcessed, countP); } public static void IncrementPlaced(int countP) { Interlocked.Add(ref _currentPlaced, countP); } private static int GetActualPlacedCount(string prefabNameP) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZoneSystem.instance == (Object)null) { return 0; } int num = 0; foreach (KeyValuePair locationInstance in ZoneSystem.instance.m_locationInstances) { if (locationInstance.Value.m_location.m_prefabName == prefabNameP) { num++; } } _preExistingCounts.TryGetValue(prefabNameP, out var value); int num2 = num - value; if (num2 < 0) { num2 = 0; } return num2; } public static void UpdateText() { if ((Object)(object)ProgressOverlay.instance == (Object)null) { return; } RelaxationSnapshot snapshot = RelaxationTracker.GetSnapshot(); string text = ((snapshot.AnyRelaxationOccurred && !snapshot.AnyUnrescued) ? "#55AAFF" : ((!snapshot.AnyUnrescued) ? "#55FF55" : ((snapshot.HighestSeverity == FailureSeverity.Red) ? "#FF4444" : ((snapshot.HighestSeverity != FailureSeverity.Orange) ? "#FFFF55" : "#FFAA00")))); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine(""); stringBuilder.AppendLine("Placing locations using " + _modeName + ""); StaticTopText = stringBuilder.ToString(); StringBuilder stringBuilder2 = new StringBuilder(); stringBuilder2.Append(""); if (snapshot.Active.Count > 0) { stringBuilder2.AppendLine("\nFAILED - ATTEMPTING RELAXATION:"); foreach (string item in snapshot.Active) { if (snapshot.AttemptLog.TryGetValue(item, out var value)) { for (int i = 0; i < value.Count; i++) { stringBuilder2.AppendLine(" " + item + " " + value[i] + ""); } } else { stringBuilder2.AppendLine(" " + item + ""); } } stringBuilder2.Append(""); } if (snapshot.Succeeded.Count > 0) { stringBuilder2.AppendLine("\nRELAXED CONSTRAINTS:"); foreach (string item2 in snapshot.Succeeded) { ZoneLocation val = null; if ((Object)(object)ZoneSystem.instance != (Object)null) { for (int j = 0; j < ZoneSystem.instance.m_locations.Count; j++) { if (ZoneSystem.instance.m_locations[j].m_prefabName == item2) { val = ZoneSystem.instance.m_locations[j]; break; } } } if (val != null) { stringBuilder2.AppendLine(" " + item2 + " " + ConstraintRelaxer.GetRelaxationSummary(item2, val) + ""); } } stringBuilder2.Append(""); } if (snapshot.Exhausted.Count > 0) { stringBuilder2.AppendLine("\nFAILED - COULD NOT PLACE:"); foreach (string item3 in snapshot.Exhausted) { int value2; bool flag = ConstraintRelaxer.RelaxationAttempts.TryGetValue(item3, out value2); int num = 0; if (flag) { num = value2; } stringBuilder2.AppendLine($" {item3} (exhausted {num} relaxation attempts)"); } stringBuilder2.Append(""); } StaticBottomText = stringBuilder2.ToString(); } public static void EndGeneration() { //IL_038b: Unknown result type (might be due to invalid IL or missing references) //IL_037c: Unknown result type (might be due to invalid IL or missing references) //IL_039f: Unknown result type (might be due to invalid IL or missing references) //IL_0698: Unknown result type (might be due to invalid IL or missing references) if (!_initialized) { return; } DateTime now = DateTime.Now; TimeSpan timeSpan = now - _startTime; string text = $"{(int)timeSpan.TotalMinutes}m {timeSpan.Seconds}.{timeSpan.Milliseconds / 100}s"; DiagnosticLog.WriteBlankLine(); DiagnosticLog.WriteTimestampedLog("=== GLOBAL END: Generating Locations (" + _modeName + ") ===", (LogLevel)16); DiagnosticLog.WriteBlankLine(); if ((Object)(object)ZoneSystem.instance != (Object)null) { Interleaver.RestoreLocations(ZoneSystem.instance); HashSet hashSet = new HashSet(); List list = new List(); for (int i = 0; i < ZoneSystem.instance.m_locations.Count; i++) { if (hashSet.Add(ZoneSystem.instance.m_locations[i])) { list.Add(ZoneSystem.instance.m_locations[i]); } } ZoneSystem.instance.m_locations.Clear(); ZoneSystem.instance.m_locations.AddRange(list); } ConstraintRelaxer.RestoreQuantities(); int num = 0; Dictionary dictionary = new Dictionary(); foreach (ZoneLocation validLocation in _validLocations) { if (!dictionary.TryGetValue(validLocation.m_prefabName, out var _)) { int actualPlacedCount = GetActualPlacedCount(validLocation.m_prefabName); dictionary[validLocation.m_prefabName] = actualPlacedCount; num += actualPlacedCount; } } List list2 = new List(); List list3 = new List(); List list4 = new List(); HashSet hashSet2 = new HashSet(); foreach (ZoneLocation validLocation2 in _validLocations) { if (!hashSet2.Add(validLocation2.m_prefabName)) { continue; } _preExistingCounts.TryGetValue(validLocation2.m_prefabName, out var value2); int num2 = validLocation2.m_quantity - value2; if (num2 <= 0 || !dictionary.TryGetValue(validLocation2.m_prefabName, out var value3)) { continue; } if (value3 == 0) { list2.Add($"-{validLocation2.m_prefabName} : {value3}/{num2}"); if (PlayabilityPolicy.IsNecessity(validLocation2.m_prefabName)) { list4.Add(validLocation2.m_prefabName); } } else if (value3 < num2) { list3.Add($"-{validLocation2.m_prefabName} : {value3}/{num2}"); } } List> list5 = new List>(); foreach (KeyValuePair relaxationAttempt in ConstraintRelaxer.RelaxationAttempts) { if (relaxationAttempt.Value > 0) { list5.Add(relaxationAttempt); } } string text2; LogLevel levelP; if (list4.Count > 0) { text2 = "UNPLAYABLE"; levelP = (LogLevel)2; } else { text2 = "Playable"; levelP = (LogLevel)16; if (list5.Count > 0) { levelP = (LogLevel)4; } } int num3 = _totalRequested - num; if (num3 < 0) { num3 = 0; } float num4 = 100f; if (_totalRequested > 0) { num4 = (float)num * 100f / (float)_totalRequested; } StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("================================================="); stringBuilder.AppendLine("=== WORLD GENERATION SUMMARY ==="); stringBuilder.AppendLine("================================================="); stringBuilder.AppendLine(" Total Time: " + text); stringBuilder.AppendLine($" Total Requested: {_totalRequested:N0}"); stringBuilder.AppendLine($" Total Placed: {num:N0} ({num4:F2}%)"); stringBuilder.AppendLine($" Total Failed: {num3:N0}"); if (list2.Count > 0) { stringBuilder.AppendLine(" ----------------"); stringBuilder.AppendLine(" Complete failures:"); for (int j = 0; j < list2.Count; j++) { stringBuilder.AppendLine(" " + list2[j]); } } if (list3.Count > 0) { stringBuilder.AppendLine(" ----------------"); stringBuilder.AppendLine(" Partial failures:"); for (int k = 0; k < list3.Count; k++) { stringBuilder.AppendLine(" " + list3[k]); } } stringBuilder.AppendLine(" Playability: " + text2); if (list5.Count > 0) { stringBuilder.AppendLine("-------------------------------------------------"); stringBuilder.AppendLine(" Relaxations Applied:"); foreach (KeyValuePair item in list5) { ZoneLocation val = null; if ((Object)(object)ZoneSystem.instance != (Object)null) { for (int l = 0; l < ZoneSystem.instance.m_locations.Count; l++) { if (ZoneSystem.instance.m_locations[l].m_prefabName == item.Key) { val = ZoneSystem.instance.m_locations[l]; break; } } } if (val != null) { stringBuilder.AppendLine(" - " + item.Key + " " + ConstraintRelaxer.GetRelaxationSummary(item.Key, val)); } } } stringBuilder.AppendLine("================================================="); DiagnosticLog.WriteLog("\n" + stringBuilder.ToString().TrimEnd(Array.Empty()), levelP); ProgressOverlay.DestroyInstance(); ThreadSafePRNG.Reset(); WorldSurveyData.Reset(); SurveyMode.Reset(); ReplacedEnginePatches.Reset(); _initialized = false; } public static void ForceCleanup() { ProgressOverlay.DestroyInstance(); StaticTopText = ""; StaticBottomText = ""; _totalRequested = 0; _currentProcessed = 0; _currentPlaced = 0; CurrentLocation = null; _threadSlots = null; _validLocations.Clear(); _preExistingCounts.Clear(); _isSurveying = false; _initialized = false; } } public enum HeartbeatType { Outer, Inner } public static class Interleaver { private static Dictionary _budgets = new Dictionary(); public static bool IsGenerating = false; public static Dictionary PendingPackets = new Dictionary(); public static HashSet LoggedStarts = new HashSet(); private static FieldInfo[] _zoneLocationFieldCache; public static List OriginalLocations { get; private set; } = null; public static void ClearLoggedStart(string prefabNameP) { LoggedStarts.Remove(prefabNameP); } public static bool TryLogStart(string prefabNameP) { return LoggedStarts.Add(prefabNameP); } public static int GetOriginalQuantity(string prefabNameP) { if (OriginalLocations != null) { for (int i = 0; i < OriginalLocations.Count; i++) { if (OriginalLocations[i].m_prefabName == prefabNameP) { return OriginalLocations[i].m_quantity; } } } else if ((Object)(object)ZoneSystem.instance != (Object)null) { for (int j = 0; j < ZoneSystem.instance.m_locations.Count; j++) { if (ZoneSystem.instance.m_locations[j].m_prefabName == prefabNameP) { return ZoneSystem.instance.m_locations[j].m_quantity; } } } return 1; } public static void InterleaveLocations(ZoneSystem zsP) { if (OriginalLocations != null) { return; } IsGenerating = true; _budgets.Clear(); PendingPackets.Clear(); LoggedStarts.Clear(); OriginalLocations = new List(zsP.m_locations); if (!ModConfig.EnableInterleavedScheduling.Value) { foreach (ZoneLocation originalLocation in OriginalLocations) { if (originalLocation.m_enable && originalLocation.m_quantity > 0) { PendingPackets[originalLocation.m_prefabName] = originalLocation.m_quantity; } } DiagnosticLog.WriteTimestampedLog($"[Dispatcher] Interleaved Scheduling is OFF. Retaining {OriginalLocations.Count} locations sequential.", (LogLevel)16); return; } List list = new List(); List list2 = new List(); for (int i = 0; i < OriginalLocations.Count; i++) { ZoneLocation val = OriginalLocations[i]; if (val.m_enable && val.m_quantity > 0) { if (val.m_prioritized) { list.Add(val); } else { list2.Add(val); } } } List list3 = new List(); list3.AddRange(ProcessTier(list, 200000)); list3.AddRange(ProcessTier(list2, 100000)); zsP.m_locations = list3; DiagnosticLog.WriteTimestampedLog($"[Dispatcher] Interleaved {OriginalLocations.Count} prefabs into {list3.Count} round-robin packets.", (LogLevel)16); } private static List ProcessTier(List tierP, int baseBudgetP) { //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) List list = new List(); Dictionary> dictionary = new Dictionary>(); ZoneSystem instance = ZoneSystem.instance; float value = ModConfig.OuterMultiplier.Value; int num = Mathf.Max(1, Mathf.RoundToInt((float)baseBudgetP * value)); foreach (ZoneLocation item in tierP) { if (item.m_centerFirst || item.m_quantity <= 1) { ZoneLocation val = CloneLocation(item); _budgets[val] = num; Enqueue(dictionary, val); PendingPackets[item.m_prefabName] = 1; continue; } int num2 = 0; if ((Object)(object)instance != (Object)null) { foreach (LocationInstance value3 in instance.m_locationInstances.Values) { if (value3.m_location.m_prefabName == item.m_prefabName) { num2++; } } } int num3 = item.m_quantity - num2; if (num3 <= 0) { continue; } int num4 = num / num3; int num5 = num % num3; PendingPackets[item.m_prefabName] = num3; for (int i = 0; i < num3; i++) { ZoneLocation val2 = CloneLocation(item); val2.m_quantity = 1; int num6 = 0; if (i < num5) { num6 = 1; } int num7 = num4 + num6; _budgets[val2] = Mathf.Max(1, num7); Enqueue(dictionary, val2); } } Dictionary> dictionary2 = new Dictionary>(); foreach (KeyValuePair> item2 in dictionary) { foreach (ZoneLocation item3 in item2.Value) { string key = item3.m_prefabName; if (!string.IsNullOrEmpty(item3.m_group)) { key = item3.m_group; } if (!dictionary2.TryGetValue(key, out var value2)) { value2 = (dictionary2[key] = new List()); } value2.Add(item3); } } List> list3 = new List>(); foreach (KeyValuePair> item4 in dictionary2) { list3.Add(new Queue(item4.Value)); } bool flag = true; while (flag) { flag = false; for (int j = 0; j < list3.Count; j++) { if (list3[j].Count > 0) { list.Add(list3[j].Dequeue()); flag = true; } } } return list; } public static List CreateRelaxedPackets(ZoneLocation relaxedLocP, int quantityToPlaceP, int fallbackBaseP) { if (!ModConfig.EnableInterleavedScheduling.Value) { ZoneLocation val = CloneLocation(relaxedLocP); val.m_quantity = quantityToPlaceP; PendingPackets[val.m_prefabName] = quantityToPlaceP; List list = new List(); list.Add(val); return list; } List list2 = new List(); list2.Add(relaxedLocP); int quantity = relaxedLocP.m_quantity; relaxedLocP.m_quantity = quantityToPlaceP; List result = ProcessTier(list2, fallbackBaseP); relaxedLocP.m_quantity = quantity; return result; } private static void Enqueue(Dictionary> queuesP, ZoneLocation locP) { if (!queuesP.TryGetValue(locP.m_prefabName, out var value)) { value = new Queue(); queuesP[locP.m_prefabName] = value; } value.Enqueue(locP); } private static ZoneLocation CloneLocation(ZoneLocation origP) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ZoneLocation val = new ZoneLocation(); if (_zoneLocationFieldCache == null) { _zoneLocationFieldCache = typeof(ZoneLocation).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } for (int i = 0; i < _zoneLocationFieldCache.Length; i++) { _zoneLocationFieldCache[i].SetValue(val, _zoneLocationFieldCache[i].GetValue(origP)); } return val; } public static int GetBudget(ZoneLocation locP, int fallbackBaseP) { if (ModConfig.EnableInterleavedScheduling.Value && locP != null && _budgets.TryGetValue(locP, out var value)) { return value; } return Mathf.Max(1, Mathf.RoundToInt((float)fallbackBaseP * ModConfig.OuterMultiplier.Value)); } public static void SyncRelaxation(ZoneLocation relaxedLocP) { if ((Object)(object)ZoneSystem.instance == (Object)null) { return; } foreach (ZoneLocation location in ZoneSystem.instance.m_locations) { if (location != relaxedLocP && location.m_prefabName == relaxedLocP.m_prefabName) { location.m_minAltitude = relaxedLocP.m_minAltitude; location.m_maxAltitude = relaxedLocP.m_maxAltitude; location.m_maxDistance = relaxedLocP.m_maxDistance; location.m_minDistance = relaxedLocP.m_minDistance; location.m_minTerrainDelta = relaxedLocP.m_minTerrainDelta; location.m_maxTerrainDelta = relaxedLocP.m_maxTerrainDelta; location.m_exteriorRadius = relaxedLocP.m_exteriorRadius; } } } public static void RestoreLocations(ZoneSystem zsP) { if (OriginalLocations != null && OriginalLocations.Count > 0) { zsP.m_locations = OriginalLocations; } _budgets.Clear(); PendingPackets.Clear(); OriginalLocations = null; IsGenerating = false; } } public class LocationTypeBucketingStrategy : BucketingStrategy { private ConcurrentDictionary> _candidateCache = new ConcurrentDictionary>(StringComparer.Ordinal); private ConcurrentDictionary _explorationIndex = new ConcurrentDictionary(StringComparer.Ordinal); private ConcurrentDictionary _visitPass = new ConcurrentDictionary(StringComparer.Ordinal); private ConcurrentDictionary _exhaustedLocations = new ConcurrentDictionary(StringComparer.Ordinal); private readonly object _cacheLock = new object(); public override void Initialize() { base.Initialize(); } public override void ClearCache(string prefabNameP) { _candidateCache.TryRemove(prefabNameP, out var _); _explorationIndex.TryRemove(prefabNameP, out var value2); _visitPass.TryRemove(prefabNameP, out value2); } public override void DumpDiagnostics() { } public override bool GetZone(ZoneLocation locationP, out Vector2i result) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) result = Vector2i.zero; string prefabName = locationP.m_prefabName; if (!_candidateCache.TryGetValue(prefabName, out var value)) { lock (_cacheLock) { if (!_candidateCache.TryGetValue(prefabName, out value)) { value = ScanWorldForCandidates(locationP, prefabName); _candidateCache.TryAdd(prefabName, value); } } } if (value.Count == 0) { SurveyMode.SurveyExhausted = true; result = Vector2i.zero; SurveyMode.CurrentActiveZoneIndex = -1; return false; } int cachedVisitLimit = BucketingStrategy._cachedVisitLimit; int num2; bool flag; int value4; while (true) { if (value.Count == 0) { HandleExhaustion(prefabName, 0, cachedVisitLimit); return false; } int num = 0; if (_visitPass.TryGetValue(prefabName, out var value2)) { num = value2; } if (num >= cachedVisitLimit) { HandleExhaustion(prefabName, value.Count, cachedVisitLimit); return false; } num2 = 0; if (_explorationIndex.TryGetValue(prefabName, out var value3)) { num2 = value3; } if (num2 >= value.Count) { _visitPass[prefabName] = num + 1; if (num + 1 >= cachedVisitLimit) { HandleExhaustion(prefabName, value.Count, cachedVisitLimit); return false; } BucketingStrategy.Shuffle(value); num2 = 0; _explorationIndex[prefabName] = 0; } result = value[num2]; flag = WorldSurveyData.ZoneToIndex.TryGetValue(result, out value4); if (!flag || !WorldSurveyData.OccupiedZoneIndices.Contains(value4)) { break; } int index = value.Count - 1; value[num2] = value[index]; value.RemoveAt(index); } SurveyMode.CurrentActiveZoneIndex = -1; if (flag) { SurveyMode.CurrentActiveZoneIndex = value4; } _explorationIndex[prefabName] = num2 + 1; return true; } public override void MarkZoneOccupied(int zoneIndexP) { if (zoneIndexP >= 0) { WorldSurveyData.OccupiedZoneIndices.Add(zoneIndexP); } } public override void PruneZone(string prefabNameP, Vector2i zoneIdP) { } public override List GetOrBuildCandidateList(ZoneLocation locationP) { string prefabName = locationP.m_prefabName; if (!_candidateCache.TryGetValue(prefabName, out var value)) { lock (_cacheLock) { if (!_candidateCache.TryGetValue(prefabName, out value)) { value = ScanWorldForCandidates(locationP, prefabName); _candidateCache.TryAdd(prefabName, value); } } } return new List(value); } private void HandleExhaustion(string prefabNameP, int candidateCountP, int limitP) { _exhaustedLocations.TryAdd(prefabNameP, 0); SurveyMode.SurveyExhausted = true; SurveyMode.CurrentActiveZoneIndex = -1; } private List ScanWorldForCandidates(ZoneLocation locationP, string prefabNameP) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Expected I4, but got Unknown //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) List list = new List(); int num = (int)locationP.m_biomeArea; long num2 = (long)(ulong)locationP.m_biome; if ((num2 & 0x20) != 0 && locationP.m_minAltitude < -4f) { num2 = ((!(locationP.m_maxAltitude < -4f)) ? (num2 | 0x10000000000L) : 1099511627776L); } bool flag = (num2 & 0x10000000100L) != 0L && (num2 & 0xFFFFFEFFu) != 0; float minDistance = locationP.m_minDistance; float num3 = BucketingStrategy._cachedWorldRadius; if (locationP.m_maxDistance > 0.1f) { num3 = locationP.m_maxDistance; } for (int i = 0; i < WorldSurveyData.Grid.Length; i++) { ZoneProfile zoneProfile = WorldSurveyData.Grid[i]; bool flag2 = (zoneProfile.BiomeMask & num2) != 0; bool flag3 = (zoneProfile.AreaMask & num) != 0; if (flag2 && flag3 && (!flag || (zoneProfile.BiomeMask & 0x20000000000L) != 0)) { Vector3 zonePos = ZoneSystem.GetZonePos(zoneProfile.ID); float magnitude = ((Vector3)(ref zonePos)).magnitude; if (!(magnitude < minDistance) && !(magnitude > num3)) { list.Add(zoneProfile.ID); } } } BucketingStrategy.Shuffle(list); return list; } } internal class LocationTypeWorkItem { public ZoneLocation Loc { get; set; } public string Group { get; set; } public PresenceGrid Grid { get; set; } public int TokenCount { get; set; } public int OuterBudget { get; set; } public PlacementCounters Counters { get; set; } public TelemetryContext TelCtx { get; set; } } [BepInPlugin("nickpappas.locationplacementaccelerator", "Location Placement Accelerator", "1.0.22")] public class LPAPlugin : BaseUnityPlugin { private static Harmony _harmony; private static FileSystemWatcher _configWatcher; private void Awake() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Expected O, but got Unknown //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Expected O, but got Unknown //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Expected O, but got Unknown //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Expected O, but got Unknown //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Expected O, but got Unknown //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Expected O, but got Unknown //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Expected O, but got Unknown ModConfig.Initialize(((BaseUnityPlugin)this).Config, ((BaseUnityPlugin)this).Logger); DiagnosticLog.Initialize(((BaseUnityPlugin)this).Info.Metadata.Version.ToString()); _harmony = new Harmony("nickpappas.locationplacementaccelerator"); if (ModConfig.EffectiveLegacy) { TranspiledEnginePatches.SkipTelemetry = ModConfig.MinimalLogging.Value; TranspiledEnginePatches.SkipAltTrack = ModConfig.MinimalLogging.Value; MethodInfo methodInfo = AccessTools.Method(typeof(ZoneSystem), "GetRandomZone", (Type[])null, (Type[])null); if (methodInfo != null) { _harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(TranspiledEnginePatches), "GetRandomZonePrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } _harmony.Patch((MethodBase)AccessTools.Method(typeof(ZoneSystem), "HaveLocationInRange", new Type[5] { typeof(string), typeof(string), typeof(Vector3), typeof(float), typeof(bool) }, (Type[])null), new HarmonyMethod(typeof(TranspiledEnginePatches), "HaveLocationInRangePrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); if (!TranspiledEnginePatches.SkipTelemetry) { _harmony.Patch((MethodBase)AccessTools.Method(typeof(WorldGenerator), "GetBiome", new Type[1] { typeof(Vector3) }, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(TelemetryHelpers), "CaptureWrongBiome", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); _harmony.Patch((MethodBase)AccessTools.Method(typeof(WorldGenerator), "GetBiomeArea", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(TelemetryHelpers), "CaptureWrongBiomeArea", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } MethodInfo methodInfo2 = AccessTools.Method(typeof(Game), "Logout", (Type[])null, (Type[])null); if (methodInfo2 != null) { _harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(TranspiledEnginePatches), "OnGameLogout", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); if (!ModConfig.EffectiveLegacy) { _harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(ReplacedEnginePatches), "Reset", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } PatchCoroutines(ModConfig.EffectiveLegacy); MethodInfo methodInfo3 = AccessTools.Method(typeof(Minimap), "Update", (Type[])null, (Type[])null); if (methodInfo3 != null) { _harmony.Patch((MethodBase)methodInfo3, new HarmonyMethod(typeof(MinimapParallelizer), "Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } SetupConfigWatcher(); DiagnosticLog.WriteLog(string.Format("[LPA] Initialized. Engine: {0}. Mode: {1}. WorldRadius will be resolved before survey.", ModConfig.EffectiveLegacy ? "Transpiled" : "Replaced", ModConfig.EffectiveMode), (LogLevel)16); } private void PatchCoroutines(bool legacyP) { //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Expected O, but got Unknown //IL_0142: Expected O, but got Unknown //IL_0142: Expected O, but got Unknown //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Expected O, but got Unknown //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Expected O, but got Unknown //IL_019a: Expected O, but got Unknown Type typeFromHandle = typeof(ZoneSystem); Type[] nestedTypes = typeFromHandle.GetNestedTypes(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); Type[] array = nestedTypes; foreach (Type type in array) { if (!type.Name.Contains("GenerateLocationsTimeSliced") || TranspiledEnginePatches.PatchedTypes.Contains(type.FullName)) { continue; } MethodInfo methodInfo = AccessTools.Method(type, "MoveNext", (Type[])null, (Type[])null); if (methodInfo == null) { continue; } bool flag = TranspiledEnginePatches.ScanForInnerLoop(methodInfo); bool flag2 = TranspiledEnginePatches.ScanForOuterLoop(methodInfo); if (!legacyP) { if (flag2) { _harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(ReplacedEnginePatches), "OuterLoopV2Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); TranspiledEnginePatches.PatchedTypes.Add(type.FullName); } } else if (flag2) { _harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(TranspiledEnginePatches), "OuterLoopPrefix", (Type[])null), new HarmonyMethod(typeof(TranspiledEnginePatches), "OuterLoopPostfix", (Type[])null), new HarmonyMethod(typeof(TranspiledEnginePatches), "OuterLoopTranspiler", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null); TranspiledEnginePatches.PatchedTypes.Add(type.FullName); } else if (flag) { _harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(TranspiledEnginePatches), "InnerLoopPrefix", (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(TranspiledEnginePatches), "InnerLoopTranspiler", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null); TranspiledEnginePatches.PatchedTypes.Add(type.FullName); } } } private void SetupConfigWatcher() { _configWatcher = new FileSystemWatcher(Paths.ConfigPath, Path.GetFileName(((BaseUnityPlugin)this).Config.ConfigFilePath)) { NotifyFilter = NotifyFilters.LastWrite, EnableRaisingEvents = true }; _configWatcher.Changed += OnConfigChanged; } private void OnConfigChanged(object senderP, FileSystemEventArgs eP) { if (!(eP.FullPath != ((BaseUnityPlugin)this).Config.ConfigFilePath)) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Configuration file modified. Reloading."); ((BaseUnityPlugin)this).Config.Reload(); } } private void OnDestroy() { _configWatcher?.Dispose(); DiagnosticLog.Dispose(); } } internal static class MinimapParallelizer { private static bool _started; private static bool _cacheChecked; private static Task _task; private static Stopwatch _stopwatch; private static Color32[] _mapColors; private static Color32[] _maskColors; private static Color[] _heights; private static Color32[] _heightPacked; private static volatile int _rowsDone; private static int _totalRows; public static volatile bool GenerationComplete; private static readonly FieldRef _hasGenerated; private static readonly FieldRef _mapTexture; private static readonly FieldRef _forestMaskTexture; private static readonly FieldRef _heightTexture; private static readonly FieldRef _mistlandsColor; private static MethodInfo _tryLoadMethod; private static MethodInfo _loadMapDataMethod; private static MethodInfo _saveMethod; private static readonly Color32 White32; public static bool IsGenerating => _started && _task != null && !_task.IsCompleted; public static string DeferredTimingMessage { get; private set; } public static float Progress { get { if (_totalRows <= 0) { return 0f; } return Math.Min(1f, (float)_rowsDone / (float)_totalRows); } } static MinimapParallelizer() { //IL_005f: 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) _hasGenerated = AccessTools.FieldRefAccess("m_hasGenerated"); _mapTexture = AccessTools.FieldRefAccess("m_mapTexture"); _forestMaskTexture = AccessTools.FieldRefAccess("m_forestMaskTexture"); _heightTexture = AccessTools.FieldRefAccess("m_heightTexture"); _mistlandsColor = AccessTools.FieldRefAccess("m_mistlandsColor"); White32 = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue); _tryLoadMethod = AccessTools.Method(typeof(Minimap), "TryLoadMinimapTextureData", (Type[])null, (Type[])null); _loadMapDataMethod = AccessTools.Method(typeof(Minimap), "LoadMapData", (Type[])null, (Type[])null); _saveMethod = AccessTools.Method(typeof(Minimap), "SaveMapTextureDataToDisk", (Type[])null, (Type[])null); } public static void Reset() { _started = false; _cacheChecked = false; _task = null; _stopwatch = null; _mapColors = null; _maskColors = null; _heights = null; _heightPacked = null; _rowsDone = 0; _totalRows = 0; GenerationComplete = false; DeferredTimingMessage = null; } public static bool Prefix(Minimap __instance) { if (_hasGenerated.Invoke(__instance)) { GenerationComplete = true; return true; } if (WorldGenerator.instance == null) { return true; } if (Compatibility.IsBetterContinentsActive) { GenerationComplete = true; return true; } if (!_cacheChecked) { _cacheChecked = true; if ((bool)_tryLoadMethod.Invoke(__instance, null)) { _loadMapDataMethod.Invoke(__instance, null); _hasGenerated.Invoke(__instance) = true; GenerationComplete = true; return false; } } if (!_started) { LaunchGeneration(__instance); _started = true; return false; } if (!_task.IsCompleted) { return false; } if (_task.IsFaulted) { ModConfig.Log.LogError((object)("[LPA] Minimap generation failed: " + _task.Exception?.InnerException?.Message)); _started = false; _cacheChecked = false; return true; } UploadTextures(__instance); _loadMapDataMethod.Invoke(__instance, null); _hasGenerated.Invoke(__instance) = true; GenerationComplete = true; _stopwatch.Stop(); int num = Math.Max(1, Environment.ProcessorCount - 2); DeferredTimingMessage = $"[LPA] Minimap generated: {_stopwatch.ElapsedMilliseconds}ms " + $"(parallel, {num} workers, {__instance.m_textureSize}x{__instance.m_textureSize} @ {__instance.m_pixelSize:F1}m/px)"; _started = false; _cacheChecked = false; _task = null; _mapColors = null; _maskColors = null; _heights = null; _heightPacked = null; return false; } private static void LaunchGeneration(Minimap instanceP) { if (ModConfig.ShowGui.Value) { ProgressOverlay.EnsureInstance(); } Minimap.DeleteMapTextureData(ZNet.World.m_name); int texSize = instanceP.m_textureSize; float pixSize = instanceP.m_pixelSize; int half = texSize / 2; float halfPix = pixSize / 2f; int num = texSize * texSize; _mapColors = (Color32[])(object)new Color32[num]; _maskColors = (Color32[])(object)new Color32[num]; _heights = (Color[])(object)new Color[num]; _heightPacked = (Color32[])(object)new Color32[num]; Dictionary biomeColorMap = BuildBiomeColorMap(instanceP); Dictionary terrainMap = null; if (Compatibility.IsExpandWorldDataActive) { terrainMap = Compatibility.GetEwdBiomeToTerrainMap(); } _rowsDone = 0; _totalRows = texSize; _stopwatch = Stopwatch.StartNew(); int maxDegreeOfParallelism = Math.Max(1, Environment.ProcessorCount - 2); ParallelOptions pOpts = new ParallelOptions { MaxDegreeOfParallelism = maxDegreeOfParallelism }; _task = Task.Run(delegate { Parallel.For(0, texSize, pOpts, delegate(int iP) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: 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_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) Color val = default(Color); for (int i = 0; i < texSize; i++) { float num2 = (float)(i - half) * pixSize + halfPix; float num3 = (float)(iP - half) * pixSize + halfPix; Biome biome = WorldGenerator.instance.GetBiome(num2, num3, 0.02f, false); float biomeHeight = WorldGenerator.instance.GetBiomeHeight(biome, num2, num3, ref val, false); int num4 = iP * texSize + i; Color32 value; bool flag = biomeColorMap.TryGetValue(biome, out value); Color32 val2 = White32; if (flag) { val2 = value; } _mapColors[num4] = val2; Biome biomeP = biome; if (terrainMap != null && terrainMap.TryGetValue(biome, out var value2)) { biomeP = value2; } _maskColors[num4] = ComputeMaskColor(num2, num3, biomeHeight, biomeP); _heights[num4].r = biomeHeight; int num5 = Mathf.Clamp((int)(biomeHeight * 127.5f), 0, 65025); _heightPacked[num4] = new Color32((byte)(num5 >> 8), (byte)((uint)num5 & 0xFFu), (byte)0, byte.MaxValue); } Interlocked.Increment(ref _rowsDone); }); }); } private static void UploadTextures(Minimap instanceP) { //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected O, but got Unknown //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Invalid comparison between Unknown and I4 _forestMaskTexture.Invoke(instanceP).SetPixels32(_maskColors); _forestMaskTexture.Invoke(instanceP).Apply(); _mapTexture.Invoke(instanceP).SetPixels32(_mapColors); _mapTexture.Invoke(instanceP).Apply(); _heightTexture.Invoke(instanceP).SetPixels(_heights); _heightTexture.Invoke(instanceP).Apply(); Texture2D val = new Texture2D(instanceP.m_textureSize, instanceP.m_textureSize); val.SetPixels32(_heightPacked); val.Apply(); if ((int)FileHelpers.LocalStorageSupport == 2 && _saveMethod != null) { _saveMethod.Invoke(instanceP, new object[3] { _forestMaskTexture.Invoke(instanceP), _mapTexture.Invoke(instanceP), val }); } } private static Dictionary BuildBiomeColorMap(Minimap instanceP) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: 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_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0057: 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_006b: 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_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: 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_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) Dictionary dictionary = new Dictionary(); dictionary[(Biome)1] = Color32.op_Implicit(instanceP.m_meadowsColor); dictionary[(Biome)2] = Color32.op_Implicit(instanceP.m_swampColor); dictionary[(Biome)4] = Color32.op_Implicit(instanceP.m_mountainColor); dictionary[(Biome)8] = Color32.op_Implicit(instanceP.m_blackforestColor); dictionary[(Biome)16] = Color32.op_Implicit(instanceP.m_heathColor); dictionary[(Biome)32] = Color32.op_Implicit(instanceP.m_ashlandsColor); dictionary[(Biome)64] = Color32.op_Implicit(instanceP.m_deepnorthColor); dictionary[(Biome)256] = Color32.op_Implicit(Color.white); dictionary[(Biome)512] = Color32.op_Implicit(_mistlandsColor.Invoke(instanceP)); if (Compatibility.IsExpandWorldDataActive) { Dictionary ewdBiomeToTerrainMap = Compatibility.GetEwdBiomeToTerrainMap(); if (ewdBiomeToTerrainMap != null) { foreach (KeyValuePair item in ewdBiomeToTerrainMap) { Color pixelColor = instanceP.GetPixelColor(item.Key); dictionary[item.Key] = Color32.op_Implicit(pixelColor); } } } return dictionary; } private static Color32 ComputeMaskColor(float wxP, float wyP, float heightP, Biome biomeP) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Invalid comparison between Unknown and I4 //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Invalid comparison between Unknown and I4 //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Invalid comparison between Unknown and I4 //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Invalid comparison between Unknown and I4 //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Invalid comparison between Unknown and I4 //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) if (heightP < 30f) { float num = Mathf.Clamp01(WorldGenerator.GetAshlandsOceanGradient(wxP, wyP)); return new Color32((byte)0, (byte)0, (byte)(num * 255f), (byte)0); } float num2 = 0f; float num3 = 0f; float num4 = 0f; if ((int)biomeP == 1) { num2 = (WorldGenerator.InForest(new Vector3(wxP, 0f, wyP)) ? 1f : 0f); } else if ((int)biomeP == 16) { num2 = ((WorldGenerator.GetForestFactor(new Vector3(wxP, 0f, wyP)) < 0.8f) ? 1f : 0f); } else if ((int)biomeP == 8) { num2 = 1f; } else if ((int)biomeP == 512) { float forestFactor = WorldGenerator.GetForestFactor(new Vector3(wxP, 0f, wyP)); num3 = 1f - SmoothStep(1.1f, 1.3f, forestFactor); } else if ((int)biomeP == 32) { Color val = default(Color); WorldGenerator.instance.GetAshlandsHeight(wxP, wyP, ref val, true); num4 = val.a; } return new Color32((byte)(num2 * 255f), (byte)(num3 * 255f), (byte)(num4 * 255f), (byte)0); } private static float SmoothStep(float edge0P, float edge1P, float xP) { float num = Mathf.Clamp01((xP - edge0P) / (edge1P - edge0P)); return num * num * (3f - 2f * num); } } public static class ModConfig { public static PlacementMode EffectiveMode; public static bool EffectiveLegacy; public static ConfigEntry Mode; public static ConfigEntry ShowGui; public static ConfigEntry UseLegacyEngine; public static ConfigEntry EnableParallelPlacement; public static ConfigEntry EnableInterleavedScheduling; public static ConfigEntry SurveyScanResolution; public static ConfigEntry SurveyVisitLimit; public static ConfigEntry OuterMultiplier; public static ConfigEntry InnerMultiplier; public static ConfigEntry MaxRelaxationAttempts; public static ConfigEntry RelaxationMagnitude; public static ConfigEntry WriteToFile; public static ConfigEntry VerboseLogFileName; public static ConfigEntry LogSuccesses; public static ConfigEntry MinimalLogging; public static ConfigEntry DiagnosticMode; public static ConfigEntry ProgressInterval; public static ConfigEntry InnerProgressInterval; public static ConfigEntry PresenceGridCellSize; public static ConfigEntry Enable3DSimilarityCheck; public static ConfigEntry OptimizePlacementChecks; public static float WorldRadius = 10000f; public static ManualLogSource Log; public static void Initialize(ConfigFile configP, ManualLogSource loggerP) { Log = loggerP; Mode = configP.Bind("1 - General", "PlacementMode", PlacementMode.Survey, "Controls the overall placement strategy.\n\n Vanilla - Unmodified Logic. The mod adds placement logging and smart\n recovery only. World generation is identical to vanilla.\n Filter - Vanilla Logic + Spatial Constraints. Rejects candidate zones\n that fall outside each location's Min/Max distance ring.\n Requires the transpiled engine (see section 2).\n Force - Vanilla Logic + Spatial Constraints. Mathematically generates\n candidate zones inside the distance ring rather than filtering.\n Requires the transpiled engine (see section 2).\n Survey - Full engine. Pre-scans the world, builds sorted candidate lists\n per biome and altitude. Required for parallel placement.\n Recommended for all modded worlds.\n\nOVERRIDE: Parallel Placement (section 2) forces Survey regardless of this setting.\nOVERRIDE: Filter and Force force the transpiled engine regardless of section 2 settings.\nOVERRIDE: Vanilla forces the transpiled engine."); ShowGui = configP.Bind("1 - General", "ShowGui", true, "Show the on-screen placement progress overlay during world generation.\nSet to false to disable the overlay entirely."); UseLegacyEngine = configP.Bind("2 - Engine", "UseLegacyEngine", false, "false - Replaced engine. Uses pre-built candidate lists and spatial exclusion\n grids for faster, higher-quality placement. Recommended.\ntrue - Transpiled engine. Full original patch surface. Required for Filter\n and Force modes.\n\nOVERRIDE: Parallel Placement ON forces the replaced engine regardless of this setting.\nOVERRIDE: Filter, Force, or Vanilla mode forces the transpiled engine regardless of this setting.\nChanging this requires a full game restart."); EnableParallelPlacement = configP.Bind("2 - Engine", "EnableParallelPlacement", true, "Enables multi-threaded placement. Multiple location types are placed\nsimultaneously, dramatically reducing world generation time on multi-core\nsystems.\n\nON by default. When ON:\n - Forces Survey mode regardless of the PlacementMode setting.\n - Forces the replaced engine regardless of the UseLegacyEngine setting.\n - Eliminates determinism: each generation run of the same seed produces a different placement\n layout (placement order is no longer fixed).\n\nChanging this requires a full game restart."); EnableInterleavedScheduling = configP.Bind("2 - Engine", "EnableInterleavedScheduling", false, "Splits each location type's total quantity into individual work packets\nand interleaves them across all types, rather than placing all of one type\nbefore moving to the next.\n\nCan reduce spatial clustering when many of the same type compete for the\nsame regions. OFF by default.\n\nWARNING: Changes the deterministic layout of the world."); SurveyScanResolution = configP.Bind("3 - Placement", "ScanResolution", 1, "Number of sample points per side of each zone during the pre-scan.\nOnly applies in Survey mode.\n\n 1 - One dart at the zone center. Fastest. Default.\n 3 - 3x3 = 9 darts spread across the zone.\n 5 - 5x5 = 25 darts.\n\nMust be an odd number (sampling is balanced around the center).\nEven values are rounded up to the nearest odd number automatically.\nHigher values improve altitude and biome accuracy at the cost of scan time."); SurveyVisitLimit = configP.Bind("3 - Placement", "VisitLimit", 1, "Number of passes through the candidate zone list per placement attempt.\nOnly applies in Survey mode.\n\nAt 1, each candidate zone is examined at most once per location type.\nHigher values allow re-examination of zones already visited, which can\nimprove placement success in constrained worlds at the cost of additional\ntime. Works together with the Iteration Budget settings (section 4)."); OuterMultiplier = configP.Bind("4 - Iteration Budgets", "OuterLoopMultiplier", 1f, "Multiplies the maximum number of candidate zones examined before giving up\non a single placement attempt. Applies in all modes.\n\n1.0 = vanilla budget. 2.0 = twice as many zones examined.\n0.5 = half the budget. 0.0 = disables placement entirely.\nAccepts decimals."); InnerMultiplier = configP.Bind("4 - Iteration Budgets", "InnerLoopMultiplier", 1f, "Multiplies the maximum number of placement attempts within a single zone.\nApplies in all modes.\n\n1.0 = vanilla budget. 0.0 = disables placement entirely.\nAccepts decimals.\n\nNote: VisitLimit and these budgets interact. A high VisitLimit with a high\nOuterLoopMultiplier can significantly extend placement time."); MaxRelaxationAttempts = configP.Bind("5 - Smart Recovery", "MaxRelaxationAttempts", 4, "When a critical location type cannot be placed, the engine automatically\nrelaxes its placement constraints and retries. This setting controls how\nmany retry attempts are made before giving up.\n\n0 = disables smart recovery entirely.\n\nCritical types covered (must place at least 1):\n Eikthyrnir, GDKing, Bonemass, Dragonqueen, GoblinKing,\n Mistlands_DvergrBossEntrance1, FaderLocation, Vendor_BlackForest,\n Hildir_camp, BogWitch_Camp, Hildir_crypt, Hildir_cave,\n Hildir_plainsfortress\n\nImportant types covered (must place at least 50%):\n Crypt, SunkenCrypt, MountainCave, InfestedMine, TarPit, CharredFortress"); RelaxationMagnitude = configP.Bind("5 - Smart Recovery", "RelaxationMagnitude", 0.05f, "Fraction of each original placement constraint to relax per retry attempt.\n0.05 = 5% per attempt. At 4 attempts, up to 20% total relaxation.\nIncrease if smart recovery is failing to find placements."); WriteToFile = configP.Bind("6 - Logging", "WriteToFile", true, "Write the generation log to a file in the BepInEx folder.\nThe file contains the full run configuration and per-location placement\nresults. Useful for diagnosing placement failures."); VerboseLogFileName = configP.Bind("6 - Logging", "VerboseLogFileName", false, "Controls the name of the log file written each run.\n\nfalse - Log file is always named LocationPlacementAccelerator.log.\n Overwrites the previous run's file each time. Default.\ntrue - Log file name includes a fingerprint of the run configuration\n and a timestamp. Multiple runs produce separate files."); LogSuccesses = configP.Bind("6 - Logging", "LogSuccess", false, "Log each successfully placed location type to the console.\nOFF by default. Failures and smart recovery events are always logged."); MinimalLogging = configP.Bind("6 - Logging", "MinimalLogging", false, "When ON, suppresses per-location placement detail in the log file.\nThe run configuration header and final world summary are always written.\n\nNOTE: Changing this requires a full game restart."); DiagnosticMode = configP.Bind("6 - Logging", "DiagnosticMode", false, "Enables verbose diagnostic output. Intended for mod development.\nLeave OFF unless investigating a specific problem."); ProgressInterval = configP.Bind("6 - Logging", "ProgressInterval", 0, "Log a heartbeat every N zone candidates examined (outer loop).\n0 = disabled. Only meaningful when DiagnosticMode is ON."); InnerProgressInterval = configP.Bind("6 - Logging", "InnerProgressInterval", 0, "Log a heartbeat every N placement attempts within a zone (inner loop).\n0 = disabled. Only meaningful when DiagnosticMode is ON."); PresenceGridCellSize = configP.Bind("7 - Advanced", "PresenceGridCellSize", 16f, "Only applies when using the replaced engine.\n\nCell size in metres for the spatial exclusion grid used to enforce minimum\ndistances between similar location types.\n\nSmaller values = finer resolution = higher memory use.\nMinimum: 4m. Default 16m uses approximately 4.9 MB per location group\nat maximum world radius."); Enable3DSimilarityCheck = configP.Bind("7 - Advanced", "Enable3DSimilarityCheck", false, "Only applies when using the replaced engine.\n\nWhen ON, Mountain and Mistlands similarity checks use 3D distance\nverification when the 2D exclusion grid reports a conflict. This reduces\nfalse positives in high-relief terrain at the cost of additional lookups.\n\nOFF by default. The 2D grid is conservative (never misses real conflicts)\nso this only affects placement success rates in mountainous terrain."); OptimizePlacementChecks = configP.Bind("7 - Advanced", "OptimizePlacementChecks", true, "Only applies in Vanilla mode.\n\nWhen ON (default), two performance optimizations remain active even in Vanilla mode:\n - HaveLocationInRange uses a zone-neighborhood lookup (O(K)) instead of a\n full world scan (O(N)).\n - The inner placement loop checks similarity before terrain delta, saving\n terrain height samples on darts that would fail similarity anyway.\n\nBoth optimizations are correctness-neutral: placement results are identical to\nunmodified Valheim. Leave ON unless benchmarking against true vanilla."); List list = new List(configP.Keys); foreach (ConfigDefinition item in list) { if (item.Section == "DistanceFilter" || item.Section == "Performance" || item.Section == "2 - Survey Strategy" || item.Section == "4 - Performance" || item.Section == "5 - Logging" || (item.Section == "Strategy" && item.Key == "TargetLocation") || item.Key == "WorldRadius" || item.Key == "PruningKnowledgeThreshold" || item.Key == "ActivePreset" || item.Key == "EnableAltitudeMapping" || item.Key == "AltitudeMappingAllBiomes" || item.Key == "EnableRuntimeAltitudeEnrichment" || item.Key == "EnableRuntimeBiomeEnrichment" || item.Key == "MaxAttempts" || item.Key == "BucketingMode" || item.Key == "AltitudeMappingScope" || item.Key == "ExplorationRate" || item.Key == "AltitudeInferenceGap" || item.Key == "RuntimeEnrichment" || item.Section == "8 - Learning" || item.Key == "EnableAdvancedPruning" || item.Key == "BiomeConfidenceThreshold" || item.Section == "8 - Survey Tuning" || item.Key == "SubBiomeFiltering") { configP.Remove(item); } } int value = SurveyScanResolution.Value; int num = value; if (value < 1) { num = 1; } else if (value % 2 == 0) { num = value + 1; } if (num != value) { SurveyScanResolution.Value = num; Log.LogWarning((object)$"[LPA] ScanResolution {value} is not a valid odd integer. Corrected to {num}."); } EffectiveMode = Mode.Value; EffectiveLegacy = UseLegacyEngine.Value; if (EnableParallelPlacement.Value) { EffectiveMode = PlacementMode.Survey; EffectiveLegacy = false; } if (!EffectiveLegacy && EffectiveMode != PlacementMode.Survey) { EffectiveMode = PlacementMode.Survey; } if (EffectiveMode == PlacementMode.Filter || EffectiveMode == PlacementMode.Force) { EffectiveLegacy = true; } if (EffectiveMode == PlacementMode.Vanilla) { EffectiveLegacy = true; } } } public enum PlacementBottleneck { Unknown, Distance, Biome, Altitude, Terrain, Similarity } internal class PlacementCounters { public int ZonesExamined; public int ZoneExhausted; public int DartsThrown; public int Placed; public int ErrOccupied; public int ErrDist; public int ErrBiome; public int ErrAlt; public int ErrSim; public int ErrTerrain; public int ErrForest; } internal static class PlacementEngine { private struct OrderedEntry { public ZoneLocation Loc; public int BaseQty; } private class WorkUnit { public List TypeWork; public bool IsPrioritized; } private class TypeRegionWork { public ZoneLocation Loc; public string Group; public PresenceGrid Grid; public List Zones; public PlacementCounters Counters; public TelemetryContext TelCtx; } private class GtsStream { public string GroupKey; public List SubGroups; public int CurrentSubGroup; public bool IsPrioritized; } private class SubGroupStream { public float MinDistFromSimilar; public Queue WorkUnits; } [CompilerGenerated] private sealed class <>c__DisplayClass50_0 { public ZoneSystem zsP; } [CompilerGenerated] private sealed class <>c__DisplayClass50_1 { public int idx; public <>c__DisplayClass50_0 CS$<>8__locals1; internal void b__0() { WorkerBody(CS$<>8__locals1.zsP, idx); } } [CompilerGenerated] private sealed class d__19 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ZoneSystem zsP; private float 5__1; private float 5__2; private int 5__3; private Dictionary 5__4; private int 5__5; private List 5__6; private int 5__7; private IEnumerator 5__8; private int 5__9; private Dictionary.Enumerator <>s__10; private KeyValuePair 5__11; private Task 5__12; private Exception 5__13; private List.Enumerator <>s__14; private ZoneLocation 5__15; private string 5__16; private bool 5__17; private HashSet 5__18; private List.Enumerator <>s__19; private string 5__20; private int 5__21; private Dictionary.ValueCollection.Enumerator <>s__22; private LocationInstance 5__23; private string 5__24; private IEnumerator 5__25; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__19(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { //IL_0081: Unknown result type (might be due to invalid IL or missing references) 5__4 = null; 5__6 = null; 5__8 = null; <>s__10 = default(Dictionary.Enumerator); 5__11 = default(KeyValuePair); 5__12 = null; 5__13 = null; <>s__14 = default(List.Enumerator); 5__15 = null; 5__16 = null; 5__18 = null; <>s__19 = default(List.Enumerator); 5__20 = null; <>s__22 = default(Dictionary.ValueCollection.Enumerator); 5__23 = default(LocationInstance); 5__24 = null; 5__25 = null; <>1__state = -2; } private bool MoveNext() { //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_06e2: Unknown result type (might be due to invalid IL or missing references) //IL_06e7: Unknown result type (might be due to invalid IL or missing references) //IL_0745: Unknown result type (might be due to invalid IL or missing references) //IL_075e: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (!MinimapParallelizer.GenerationComplete) { goto IL_008e; } goto IL_009d; case 1: <>1__state = -1; goto IL_008e; case 2: <>1__state = -1; goto IL_00d1; case 3: <>1__state = -1; goto IL_03f2; case 4: <>1__state = -1; 5__12 = null; goto IL_047c; case 5: <>1__state = -1; PresenceGrid.Initialize(ModConfig.PresenceGridCellSize.Value); _groupPartitions = new Dictionary>(StringComparer.Ordinal); <>s__14 = zsP.m_locations.GetEnumerator(); try { while (<>s__14.MoveNext()) { 5__15 = <>s__14.Current; if (5__15.m_enable && Compatibility.IsValidLocation(5__15)) { 5__16 = 5__15.m_prefabName; if (!string.IsNullOrEmpty(5__15.m_group)) { 5__16 = 5__15.m_group; } 5__17 = _groupPartitions.TryGetValue(5__16, out 5__18); if (!5__17) { 5__18 = new HashSet(); _groupPartitions[5__16] = 5__18; } if (5__15.m_minDistanceFromSimilar > 0f) { 5__18.Add(5__15.m_minDistanceFromSimilar); } 5__16 = null; 5__18 = null; 5__15 = null; } } } finally { ((IDisposable)<>s__14).Dispose(); } <>s__14 = default(List.Enumerator); 5__6 = CenterFirstPlacer.PlaceAll(zsP); _centerFirstCounts = new Dictionary(StringComparer.Ordinal); <>s__19 = 5__6.GetEnumerator(); try { while (<>s__19.MoveNext()) { 5__20 = <>s__19.Current; _centerFirstCounts.TryGetValue(5__20, out 5__21); _centerFirstCounts[5__20] = 5__21 + 1; 5__20 = null; } } finally { ((IDisposable)<>s__19).Dispose(); } <>s__19 = default(List.Enumerator); <>s__22 = zsP.m_locationInstances.Values.GetEnumerator(); try { while (<>s__22.MoveNext()) { 5__23 = <>s__22.Current; 5__24 = 5__23.m_location.m_prefabName; if (!string.IsNullOrEmpty(5__23.m_location.m_group)) { 5__24 = 5__23.m_location.m_group; } CommitToGroup(5__24, 5__23.m_position); 5__24 = null; 5__23 = default(LocationInstance); } } finally { ((IDisposable)<>s__22).Dispose(); } <>s__22 = default(Dictionary.ValueCollection.Enumerator); <>2__current = null; <>1__state = 6; return true; case 6: <>1__state = -1; 5__7 = zsP.m_locations.Count; if (_parallelPlacement) { 5__25 = RunParallelPath(zsP, 5__7); goto IL_080a; } 5__8 = RunSequentialPath(zsP, 5__7); break; case 7: <>1__state = -1; goto IL_080a; case 8: { <>1__state = -1; break; } IL_008e: if (!MinimapParallelizer.GenerationComplete) { <>2__current = null; <>1__state = 1; return true; } goto IL_009d; IL_080a: if (5__25.MoveNext()) { <>2__current = 5__25.Current; <>1__state = 7; return true; } return false; IL_009d: if (Compatibility.IsBetterContinentsActive && !Compatibility.BCMinimapDone) { goto IL_00d1; } goto IL_00e2; IL_047c: <>2__current = null; <>1__state = 5; return true; IL_03f2: if (!5__12.IsCompleted) { <>2__current = null; <>1__state = 3; return true; } if (5__12.IsFaulted) { 5__13 = 5__12.Exception.InnerException; if (5__13 != null) { throw 5__13; } throw 5__12.Exception; } SurveyMode.Initialize(); GenerationProgress.EndSurvey(); <>2__current = null; <>1__state = 4; return true; IL_00d1: if (!Compatibility.BCMinimapDone) { <>2__current = null; <>1__state = 2; return true; } goto IL_00e2; IL_00e2: 5__1 = ModConfig.OuterMultiplier.Value; 5__2 = ModConfig.InnerMultiplier.Value; _outerBudgetBase = Mathf.Max(1, Mathf.RoundToInt(100000f * 5__1)); _outerBudgetPrioritized = Mathf.Max(1, Mathf.RoundToInt(200000f * 5__1)); _dartsPerZone = Mathf.Max(1, Mathf.RoundToInt(20f * 5__2)); _maxRelaxationAttempts = ModConfig.MaxRelaxationAttempts.Value; _interleavedScheduling = ModConfig.EnableInterleavedScheduling.Value; _minimalLogging = ModConfig.MinimalLogging.Value; _logSuccesses = ModConfig.LogSuccesses.Value; _mode = ModConfig.EffectiveMode; _enable3DSimilarity = ModConfig.Enable3DSimilarityCheck.Value; _highReliefBiomeMask = Compatibility.GetHighReliefBiomeMask(); _parallelPlacement = ModConfig.EnableParallelPlacement.Value && _mode == PlacementMode.Survey; if (_parallelPlacement) { 5__9 = Environment.ProcessorCount - 2; _parallelThreadCount = Math.Max(1, 5__9); } _locationsGeneratedProp = typeof(ZoneSystem).GetProperty("LocationsGenerated", BindingFlags.Instance | BindingFlags.Public); _generateLocationsProgressField = typeof(ZoneSystem).GetField("m_generateLocationsProgress", BindingFlags.Instance | BindingFlags.NonPublic); 5__3 = zsP.m_locationInstances.Count; 5__4 = new Dictionary(); <>s__10 = zsP.m_locationInstances.GetEnumerator(); try { while (<>s__10.MoveNext()) { 5__11 = <>s__10.Current; if (5__11.Value.m_placed) { 5__4.Add(5__11.Key, 5__11.Value); } 5__11 = default(KeyValuePair); } } finally { ((IDisposable)<>s__10).Dispose(); } <>s__10 = default(Dictionary.Enumerator); zsP.m_locationInstances = 5__4; 5__5 = 5__3 - 5__4.Count; if (5__5 > 0) { DiagnosticLog.WriteTimestampedLog($"[LPA] Cleared {5__5} non-placed location reservations. Kept {5__4.Count} placed instances.", (LogLevel)16); } Interleaver.InterleaveLocations(zsP); GenerationProgress.StartGeneration(zsP); if (MinimapParallelizer.DeferredTimingMessage != null) { DiagnosticLog.WriteTimestampedLog(MinimapParallelizer.DeferredTimingMessage, (LogLevel)16); } GenerationProgress.MarkActualStartNoSurvey(); if (ModConfig.EffectiveMode == PlacementMode.Survey) { GenerationProgress.BeginSurvey(); 5__12 = Task.Run(delegate { WorldSurveyData.Initialize(); }); goto IL_03f2; } goto IL_047c; } if (5__8.MoveNext()) { <>2__current = 5__8.Current; <>1__state = 8; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__63 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ZoneSystem zsP; public ZoneLocation locP; public PlacementCounters ctrP; public int overrideQtyP; public bool suppressFlushP; private bool 5__1; private string 5__2; private PresenceGrid 5__3; private int 5__4; private int 5__5; private int 5__6; private TelemetryContext 5__7; private int 5__8; private int 5__9; private int 5__10; private bool 5__11; private int 5__12; private Vector2i 5__13; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__63(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__2 = null; 5__3 = null; 5__7 = null; <>1__state = -2; } private bool MoveNext() { //IL_0306: Unknown result type (might be due to invalid IL or missing references) //IL_030b: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Unknown result type (might be due to invalid IL or missing references) //IL_03c8: Unknown result type (might be due to invalid IL or missing references) //IL_03cd: Unknown result type (might be due to invalid IL or missing references) //IL_03d2: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_0458: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_0330: Unknown result type (might be due to invalid IL or missing references) //IL_038f: Unknown result type (might be due to invalid IL or missing references) //IL_0394: Unknown result type (might be due to invalid IL or missing references) //IL_0399: Unknown result type (might be due to invalid IL or missing references) //IL_02cd: 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_02d7: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; GenerationProgress.CurrentLocation = locP; 5__1 = !TranspiledCompletionHandler.AggregateSessions.ContainsKey(locP.m_prefabName); if (5__1) { if (_logSuccesses || ModConfig.DiagnosticMode.Value) { TelemetryHelpers.LogLocationStart(locP, _mode); } TranspiledCompletionHandler.AggregateSessions[locP.m_prefabName] = new TelemetryContext(); } 5__2 = locP.m_prefabName; if (!string.IsNullOrEmpty(locP.m_group)) { 5__2 = locP.m_group; } 5__3 = PresenceGrid.GetOrCreate($"{5__2}:{locP.m_minDistanceFromSimilar:F0}"); 5__4 = 100000; if (locP.m_prioritized) { 5__4 = 200000; } 5__5 = Interleaver.GetBudget(locP, 5__4); 5__6 = locP.m_quantity; if (overrideQtyP > 0) { 5__6 = overrideQtyP; } if (_interleavedScheduling) { 5__6 = 1; } 5__7 = null; TranspiledCompletionHandler.AggregateSessions.TryGetValue(locP.m_prefabName, out 5__7); 5__8 = 0; _outsideRngState = Random.state; 5__9 = WorldGenerator.instance.GetSeed() + StringExtensionMethods.GetStableHashCode(locP.m_prefabName); Random.InitState(5__9); _rngIsolationActive = true; 5__10 = 0; goto IL_0435; case 1: <>1__state = -1; if (_rngIsolationActive) { _outsideRngState = Random.state; Random.state = _insideRngState; } goto IL_03e0; case 2: { <>1__state = -1; if (_rngIsolationActive) { _outsideRngState = Random.state; Random.state = _insideRngState; } goto IL_03e0; } IL_03f2: if (5__12 < 5__5 && !5__11) { if (SurveyMode.GetZone(locP, out 5__13)) { ctrP.ZonesExamined++; if (zsP.m_locationInstances.ContainsKey(5__13)) { ctrP.ErrOccupied++; if (++5__8 >= 512) { 5__8 = 0; if (_rngIsolationActive) { _insideRngState = Random.state; Random.state = _outsideRngState; } <>2__current = null; <>1__state = 1; return true; } } else { 5__11 = EvaluateZone(zsP, locP, 5__13, 5__3, 5__2, ctrP, 5__7); if (++5__8 >= 512) { 5__8 = 0; if (_rngIsolationActive) { _insideRngState = Random.state; Random.state = _outsideRngState; } <>2__current = null; <>1__state = 2; return true; } } goto IL_03e0; } ctrP.ZoneExhausted++; } GenerationProgress.IncrementProcessed(5__11); 5__10++; goto IL_0435; IL_0435: if (5__10 < 5__6) { 5__11 = false; 5__12 = 0; goto IL_03f2; } if (_rngIsolationActive) { Random.state = _outsideRngState; _rngIsolationActive = false; } if (!suppressFlushP) { FlushLTS(zsP, locP, ctrP); TranspiledCompletionHandler.AggregateSessions.Remove(locP.m_prefabName); } return false; IL_03e0: 5__12++; goto IL_03f2; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__50 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ZoneSystem zsP; public int locListSnapshotP; private <>c__DisplayClass50_0 <>8__1; private HashSet 5__2; private List 5__3; private List 5__4; private List 5__5; private Task[] 5__6; private bool 5__7; private Stopwatch 5__8; private Task 5__9; private int 5__10; private int 5__11; private ZoneLocation 5__12; private int 5__13; private List.Enumerator <>s__14; private OrderedEntry 5__15; private string 5__16; private int 5__17; private <>c__DisplayClass50_1 <>8__18; private bool 5__19; private bool 5__20; private List.Enumerator <>s__21; private GtsStream 5__22; private SubGroupStream 5__23; private int 5__24; private int 5__25; private List.Enumerator <>s__26; private GtsStream 5__27; private SubGroupStream 5__28; private int 5__29; private int 5__30; private List.Enumerator <>s__31; private GtsStream 5__32; private List.Enumerator <>s__33; private SubGroupStream 5__34; private Task[] <>s__35; private int <>s__36; private Task 5__37; private Exception 5__38; private PlacementResult 5__39; private int 5__40; private int 5__41; private List 5__42; private Dictionary 5__43; private Dictionary 5__44; private List.Enumerator <>s__45; private ZoneLocation 5__46; private string 5__47; private bool 5__48; private IEnumerator 5__49; private Dictionary.Enumerator <>s__50; private KeyValuePair 5__51; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__50(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { switch (<>1__state) { case -3: case 2: try { } finally { <>m__Finally1(); } break; case -4: case 5: try { } finally { <>m__Finally2(); } break; } <>8__1 = null; 5__2 = null; 5__3 = null; 5__4 = null; 5__5 = null; 5__6 = null; 5__8 = null; 5__9 = null; 5__12 = null; <>s__14 = default(List.Enumerator); 5__15 = default(OrderedEntry); 5__16 = null; <>8__18 = null; <>s__21 = default(List.Enumerator); 5__22 = null; 5__23 = null; <>s__26 = default(List.Enumerator); 5__27 = null; 5__28 = null; <>s__31 = default(List.Enumerator); 5__32 = null; <>s__33 = default(List.Enumerator); 5__34 = null; <>s__35 = null; 5__37 = null; 5__38 = null; 5__39 = default(PlacementResult); 5__42 = null; 5__43 = null; 5__44 = null; <>s__45 = default(List.Enumerator); 5__46 = null; 5__47 = null; 5__49 = null; <>s__50 = default(Dictionary.Enumerator); 5__51 = default(KeyValuePair); <>1__state = -2; } private bool MoveNext() { //IL_0cf3: Unknown result type (might be due to invalid IL or missing references) try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>8__1 = new <>c__DisplayClass50_0(); <>8__1.zsP = zsP; DiagnosticLog.WriteTimestampedLog($"[LPA] Parallel placement ENABLED. Workers: {_parallelThreadCount}." + $" BC: {Compatibility.IsBetterContinentsActive}", (LogLevel)16); 5__2 = new HashSet(); 5__10 = 0; while (5__10 < <>8__1.zsP.m_locations.Count) { if (<>8__1.zsP.m_locations[5__10].m_centerFirst) { 5__2.Add(<>8__1.zsP.m_locations[5__10].m_prefabName); } 5__10++; } 5__3 = <>8__1.zsP.m_locations; if (Interleaver.OriginalLocations != null) { 5__3 = Interleaver.OriginalLocations; } 5__4 = new List(); 5__11 = 0; while (5__11 < 5__3.Count) { 5__12 = 5__3[5__11]; if (5__12.m_enable && Compatibility.IsValidLocation(5__12) && 5__12.m_quantity > 0) { 5__13 = 5__12.m_quantity; if (5__2.Contains(5__12.m_prefabName)) { 5__13 = 5__12.m_quantity - 1; } if (5__13 > 0) { 5__4.Add(new OrderedEntry { Loc = 5__12, BaseQty = 5__13 }); 5__12 = null; } } 5__11++; } 5__4.Sort(CompareOrderedEntries); _workQueue = new BlockingCollection(); _resultQueue = new ConcurrentQueue(); _pendingOccupancy = new ConcurrentDictionary(); _occupancySnapshot = new Dictionary(<>8__1.zsP.m_locationInstances); _ltsCompletionLock = new object(); _startedPrefabs = new ConcurrentDictionary(StringComparer.Ordinal); _priorityBarrierDone = new ManualResetEventSlim(initialState: false); _parallelTokensProcessed = 0; _inFlightRegions = new ConcurrentDictionary>(StringComparer.Ordinal); _remainingToPlace = new ConcurrentDictionary>(StringComparer.Ordinal); _counterLists = new ConcurrentDictionary>(StringComparer.Ordinal); _telemetryLists = new ConcurrentDictionary>(StringComparer.Ordinal); _totalZonesPerPrefab = new ConcurrentDictionary(StringComparer.Ordinal); _parallelTotalZones = 0; _prioritizedInFlight = 0; <>s__14 = 5__4.GetEnumerator(); try { while (<>s__14.MoveNext()) { 5__15 = <>s__14.Current; 5__16 = 5__15.Loc.m_prefabName; _remainingToPlace[5__16] = new StrongBox(5__15.BaseQty); _inFlightRegions[5__16] = new StrongBox(0); _counterLists[5__16] = new List(); _telemetryLists[5__16] = new List(); if (5__15.Loc.m_prioritized) { _prioritizedInFlight++; } 5__16 = null; 5__15 = default(OrderedEntry); } } finally { ((IDisposable)<>s__14).Dispose(); } <>s__14 = default(List.Enumerator); if (_prioritizedInFlight == 0) { _priorityBarrierDone.Set(); } 5__5 = BuildSpatialStreams(5__4); GenerationProgress.InitThreadSlots(_parallelThreadCount); 5__6 = new Task[_parallelThreadCount]; 5__17 = 0; while (5__17 < _parallelThreadCount) { <>8__18 = new <>c__DisplayClass50_1(); <>8__18.CS$<>8__locals1 = <>8__1; <>8__18.idx = 5__17; 5__6[5__17] = Task.Run(delegate { WorkerBody(<>8__18.CS$<>8__locals1.zsP, <>8__18.idx); }); <>8__18 = null; 5__17++; } 5__7 = false; 5__8 = Stopwatch.StartNew(); if (_interleavedScheduling) { 5__19 = true; while (5__19) { 5__19 = false; <>s__21 = 5__5.GetEnumerator(); try { while (<>s__21.MoveNext()) { 5__22 = <>s__21.Current; if (!5__22.IsPrioritized || 5__22.CurrentSubGroup >= 5__22.SubGroups.Count) { continue; } 5__23 = 5__22.SubGroups[5__22.CurrentSubGroup]; if (5__23.WorkUnits.Count == 0) { 5__22.CurrentSubGroup++; if (5__22.CurrentSubGroup < 5__22.SubGroups.Count) { 5__19 = true; } continue; } 5__24 = 1; if (5__22.SubGroups.Count > 1) { 5__24 = Math.Min(_parallelThreadCount, 5__23.WorkUnits.Count); } 5__25 = 0; while (5__25 < 5__24 && 5__23.WorkUnits.Count > 0) { _workQueue.Add(5__23.WorkUnits.Dequeue()); 5__25++; } 5__19 = true; 5__23 = null; 5__22 = null; } } finally { ((IDisposable)<>s__21).Dispose(); } <>s__21 = default(List.Enumerator); } goto IL_07d2; } <>s__31 = 5__5.GetEnumerator(); <>1__state = -3; goto IL_0b5e; case 1: <>1__state = -1; goto IL_07d2; case 2: <>1__state = -3; goto IL_0aa9; case 3: <>1__state = -1; goto IL_0c07; case 4: <>1__state = -1; 5__40 = 0; goto IL_104f; case 5: { <>1__state = -4; goto IL_0f36; } IL_104f: if (5__40 >= _maxRelaxationAttempts || <>8__1.zsP.m_locations.Count <= locListSnapshotP) { break; } 5__41 = <>8__1.zsP.m_locations.Count - locListSnapshotP; 5__42 = <>8__1.zsP.m_locations.GetRange(locListSnapshotP, 5__41); locListSnapshotP = <>8__1.zsP.m_locations.Count; 5__43 = new Dictionary(StringComparer.Ordinal); 5__44 = new Dictionary(StringComparer.Ordinal); <>s__45 = 5__42.GetEnumerator(); <>1__state = -4; goto IL_0f5d; IL_0aa9: while (!_priorityBarrierDone.IsSet) { DrainAndCommit(<>8__1.zsP); UpdateAnnulus(<>8__1.zsP); if (5__8.ElapsedMilliseconds >= 100) { 5__8.Restart(); <>2__current = null; <>1__state = 2; return true; } } goto IL_0abd; IL_0f5d: while (<>s__45.MoveNext()) { 5__46 = <>s__45.Current; if (!5__46.m_enable || 5__46.m_centerFirst) { continue; } 5__47 = 5__46.m_prefabName; if (RelaxationTracker.IsRelaxationSucceeded(5__47)) { continue; } goto IL_0e85; } <>m__Finally2(); <>s__45 = default(List.Enumerator); <>s__50 = 5__44.GetEnumerator(); try { while (<>s__50.MoveNext()) { 5__51 = <>s__50.Current; FlushLTS(<>8__1.zsP, 5__51.Value, 5__43[5__51.Key]); TranspiledCompletionHandler.AggregateSessions.Remove(5__51.Key); 5__51 = default(KeyValuePair); } } finally { ((IDisposable)<>s__50).Dispose(); } <>s__50 = default(Dictionary.Enumerator); 5__42 = null; 5__43 = null; 5__44 = null; 5__40++; goto IL_104f; IL_07d2: while (!_priorityBarrierDone.IsSet) { DrainAndCommit(<>8__1.zsP); UpdateAnnulus(<>8__1.zsP); if (5__8.ElapsedMilliseconds >= 100) { 5__8.Restart(); <>2__current = null; <>1__state = 1; return true; } } 5__20 = true; while (5__20) { 5__20 = false; <>s__26 = 5__5.GetEnumerator(); try { while (<>s__26.MoveNext()) { 5__27 = <>s__26.Current; if (5__27.IsPrioritized || 5__27.CurrentSubGroup >= 5__27.SubGroups.Count) { continue; } 5__28 = 5__27.SubGroups[5__27.CurrentSubGroup]; if (5__28.WorkUnits.Count == 0) { 5__27.CurrentSubGroup++; if (5__27.CurrentSubGroup < 5__27.SubGroups.Count) { 5__20 = true; } continue; } 5__29 = 1; if (5__27.SubGroups.Count > 1) { 5__29 = Math.Min(_parallelThreadCount, 5__28.WorkUnits.Count); } 5__30 = 0; while (5__30 < 5__29 && 5__28.WorkUnits.Count > 0) { _workQueue.Add(5__28.WorkUnits.Dequeue()); 5__30++; } 5__20 = true; 5__28 = null; 5__27 = null; } } finally { ((IDisposable)<>s__26).Dispose(); } <>s__26 = default(List.Enumerator); } goto IL_0b82; IL_0e85: 5__48 = 5__43.ContainsKey(5__47); if (!5__48) { 5__43[5__47] = new PlacementCounters(); 5__44[5__47] = 5__46; } 5__49 = RunLocSerial(<>8__1.zsP, 5__46, 5__43[5__47], -1, suppressFlushP: true); goto IL_0f36; IL_0b82: _workQueue.CompleteAdding(); 5__9 = Task.WhenAll(5__6); goto IL_0c07; IL_0abd: <>s__33 = 5__32.SubGroups.GetEnumerator(); try { while (<>s__33.MoveNext()) { 5__34 = <>s__33.Current; while (5__34.WorkUnits.Count > 0) { _workQueue.Add(5__34.WorkUnits.Dequeue()); } 5__34 = null; } } finally { ((IDisposable)<>s__33).Dispose(); } <>s__33 = default(List.Enumerator); 5__32 = null; goto IL_0b5e; IL_0f36: if (5__49.MoveNext()) { <>2__current = 5__49.Current; <>1__state = 5; return true; } 5__47 = null; 5__49 = null; 5__46 = null; goto IL_0f5d; IL_0b5e: if (<>s__31.MoveNext()) { 5__32 = <>s__31.Current; if (!5__7 && !5__32.IsPrioritized) { 5__7 = true; goto IL_0aa9; } goto IL_0abd; } <>m__Finally1(); <>s__31 = default(List.Enumerator); goto IL_0b82; IL_0c07: while (!5__9.IsCompleted) { DrainAndCommit(<>8__1.zsP); UpdateAnnulus(<>8__1.zsP); if (5__8.ElapsedMilliseconds >= 100) { 5__8.Restart(); <>2__current = null; <>1__state = 3; return true; } } <>s__35 = 5__6; for (<>s__36 = 0; <>s__36 < <>s__35.Length; <>s__36++) { 5__37 = <>s__35[<>s__36]; if (5__37.IsFaulted) { 5__38 = 5__37.Exception.InnerException; if (5__38 != null) { throw 5__38; } throw 5__37.Exception; } 5__37 = null; } <>s__35 = null; while (_resultQueue.TryDequeue(out 5__39)) { <>8__1.zsP.RegisterLocation(5__39.Loc, 5__39.Position, false); if (5__39.ZoneIdx >= 0) { SurveyMode.MarkZoneOccupied(5__39.ZoneIdx); } } <>2__current = null; <>1__state = 4; return true; } GenerationProgress.ClearThreadSlots(); if (_locationsGeneratedProp != null) { _locationsGeneratedProp.SetValue(<>8__1.zsP, true); } else { DiagnosticLog.WriteLog("[LPA] WARNING: Could not set LocationsGenerated via reflection.", (LogLevel)2); } SurveyMode.DumpDiagnostics(); DiagnosticLog.DumpPlacementsToFile(); GenerationProgress.CurrentLocation = null; RelaxationTracker.MarkPlacementComplete(); GenerationProgress.EndGeneration(); _workQueue?.Dispose(); _workQueue = null; _priorityBarrierDone?.Dispose(); _priorityBarrierDone = null; return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; ((IDisposable)<>s__31).Dispose(); } private void <>m__Finally2() { <>1__state = -1; ((IDisposable)<>s__45).Dispose(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__62 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ZoneSystem zsP; public int locListSnapshotP; private List 5__1; private int 5__2; private Dictionary 5__3; private Dictionary 5__4; private Dictionary 5__5; private int 5__6; private PlacementToken 5__7; private ZoneLocation 5__8; private bool 5__9; private PlacementCounters 5__10; private bool 5__11; private string 5__12; private PresenceGrid 5__13; private int 5__14; private int 5__15; private bool 5__16; private TelemetryContext 5__17; private bool 5__18; private int 5__19; private int 5__20; private State 5__21; private int 5__22; private bool 5__23; private int 5__24; private Vector2i 5__25; private Dictionary.Enumerator <>s__26; private KeyValuePair 5__27; private ZoneLocation 5__28; private int 5__29; private int 5__30; private int 5__31; private List 5__32; private Dictionary 5__33; private Dictionary 5__34; private List.Enumerator <>s__35; private ZoneLocation 5__36; private string 5__37; private bool 5__38; private PlacementCounters 5__39; private string 5__40; private PresenceGrid 5__41; private int 5__42; private int 5__43; private int 5__44; private bool 5__45; private int 5__46; private bool 5__47; private TelemetryContext 5__48; private int 5__49; private Vector2i 5__50; private Dictionary.Enumerator <>s__51; private KeyValuePair 5__52; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__62(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || (uint)(num - 3) <= 1u) { try { } finally { <>m__Finally1(); } } 5__1 = null; 5__3 = null; 5__4 = null; 5__5 = null; 5__7 = null; 5__8 = null; 5__10 = null; 5__12 = null; 5__13 = null; 5__17 = null; <>s__26 = default(Dictionary.Enumerator); 5__27 = default(KeyValuePair); 5__28 = null; 5__32 = null; 5__33 = null; 5__34 = null; <>s__35 = default(List.Enumerator); 5__36 = null; 5__37 = null; 5__39 = null; 5__40 = null; 5__41 = null; 5__48 = null; <>s__51 = default(Dictionary.Enumerator); 5__52 = default(KeyValuePair); <>1__state = -2; } private bool MoveNext() { //IL_04b5: Unknown result type (might be due to invalid IL or missing references) //IL_04ba: Unknown result type (might be due to invalid IL or missing references) //IL_04bf: Unknown result type (might be due to invalid IL or missing references) //IL_05d1: Unknown result type (might be due to invalid IL or missing references) //IL_05d6: Unknown result type (might be due to invalid IL or missing references) //IL_05db: Unknown result type (might be due to invalid IL or missing references) //IL_0ced: Unknown result type (might be due to invalid IL or missing references) //IL_0cf2: Unknown result type (might be due to invalid IL or missing references) //IL_0cf7: Unknown result type (might be due to invalid IL or missing references) //IL_0db5: Unknown result type (might be due to invalid IL or missing references) //IL_0dba: Unknown result type (might be due to invalid IL or missing references) //IL_0dbf: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_0418: Unknown result type (might be due to invalid IL or missing references) //IL_0c4f: Unknown result type (might be due to invalid IL or missing references) //IL_04df: Unknown result type (might be due to invalid IL or missing references) //IL_0d17: Unknown result type (might be due to invalid IL or missing references) //IL_0e4c: Unknown result type (might be due to invalid IL or missing references) //IL_0477: Unknown result type (might be due to invalid IL or missing references) //IL_047c: Unknown result type (might be due to invalid IL or missing references) //IL_0481: Unknown result type (might be due to invalid IL or missing references) //IL_0d76: Unknown result type (might be due to invalid IL or missing references) //IL_0d7b: Unknown result type (might be due to invalid IL or missing references) //IL_0d80: Unknown result type (might be due to invalid IL or missing references) //IL_0cae: Unknown result type (might be due to invalid IL or missing references) //IL_0cb3: Unknown result type (might be due to invalid IL or missing references) //IL_0cb8: Unknown result type (might be due to invalid IL or missing references) //IL_0667: Unknown result type (might be due to invalid IL or missing references) //IL_0593: Unknown result type (might be due to invalid IL or missing references) //IL_0598: Unknown result type (might be due to invalid IL or missing references) //IL_059d: Unknown result type (might be due to invalid IL or missing references) //IL_070a: Unknown result type (might be due to invalid IL or missing references) //IL_0b86: Unknown result type (might be due to invalid IL or missing references) //IL_0b8b: Unknown result type (might be due to invalid IL or missing references) try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; 5__1 = BuildTokenList(zsP); DiagnosticLog.WriteTimestampedLog($"[LPA] Token list built: {5__1.Count} tokens across {zsP.m_locations.Count} location entries.", (LogLevel)16); 5__2 = 0; 5__3 = new Dictionary(); 5__4 = new Dictionary(Interleaver.PendingPackets); 5__5 = new Dictionary(StringComparer.Ordinal); 5__6 = 0; goto IL_07a1; case 1: <>1__state = -1; if (_rngIsolationActive) { _outsideRngState = Random.state; Random.state = _insideRngState; } goto IL_05e9; case 2: <>1__state = -1; if (_rngIsolationActive) { _outsideRngState = Random.state; Random.state = _insideRngState; } goto IL_05e9; case 3: <>1__state = -3; if (_rngIsolationActive) { _outsideRngState = Random.state; Random.state = _insideRngState; } goto IL_0dcd; case 4: { <>1__state = -3; if (_rngIsolationActive) { _outsideRngState = Random.state; Random.state = _insideRngState; } goto IL_0dcd; } IL_0e82: while (<>s__35.MoveNext()) { 5__36 = <>s__35.Current; if (!5__36.m_enable || 5__36.m_centerFirst) { continue; } goto IL_0a19; } <>m__Finally1(); <>s__35 = default(List.Enumerator); <>s__51 = 5__33.GetEnumerator(); try { while (<>s__51.MoveNext()) { 5__52 = <>s__51.Current; FlushLTS(zsP, 5__34[5__52.Key], 5__52.Value); 5__52 = default(KeyValuePair); } } finally { ((IDisposable)<>s__51).Dispose(); } <>s__51 = default(Dictionary.Enumerator); 5__32 = null; 5__33 = null; 5__34 = null; 5__30++; goto IL_0f5b; IL_05e9: 5__24++; goto IL_05fb; IL_0dcd: 5__49++; goto IL_0ddf; IL_0a19: 5__37 = 5__36.m_prefabName; 5__38 = 5__33.ContainsKey(5__37); if (!5__38) { 5__33[5__37] = new PlacementCounters(); 5__34[5__37] = 5__36; 5__45 = TranspiledCompletionHandler.AggregateSessions.ContainsKey(5__37); if (!5__45) { TranspiledCompletionHandler.AggregateSessions[5__37] = new TelemetryContext(); } } 5__39 = 5__33[5__37]; 5__40 = 5__37; if (!string.IsNullOrEmpty(5__36.m_group)) { 5__40 = 5__36.m_group; } 5__41 = PresenceGrid.GetOrCreate($"{5__40}:{5__36.m_minDistanceFromSimilar:F0}"); 5__42 = _outerBudgetBase; if (5__36.m_prioritized) { 5__42 = _outerBudgetPrioritized; } 5__43 = 5__36.m_quantity; if (_interleavedScheduling) { 5__43 = 1; } _outsideRngState = Random.state; 5__44 = WorldGenerator.instance.GetSeed() + StringExtensionMethods.GetStableHashCode(5__37); Random.InitState(5__44); _rngIsolationActive = true; 5__46 = 0; goto IL_0e29; IL_07a1: if (5__6 < 5__1.Count) { 5__7 = 5__1[5__6]; 5__8 = 5__7.Location; 5__9 = 5__3.TryGetValue(5__8.m_prefabName, out 5__10); if (!5__9) { 5__10 = new PlacementCounters(); 5__3[5__8.m_prefabName] = 5__10; } 5__11 = !_rngIsolationActive; if (_interleavedScheduling) { 5__11 = !5__5.ContainsKey(5__8.m_prefabName); } if (_interleavedScheduling) { if (5__11) { _outsideRngState = Random.state; 5__20 = WorldGenerator.instance.GetSeed() + StringExtensionMethods.GetStableHashCode(5__8.m_prefabName); Random.InitState(5__20); } else { 5__5.TryGetValue(5__8.m_prefabName, out 5__21); Random.state = 5__21; } _rngIsolationActive = true; } else if (5__11) { _outsideRngState = Random.state; 5__22 = WorldGenerator.instance.GetSeed() + StringExtensionMethods.GetStableHashCode(5__8.m_prefabName); Random.InitState(5__22); _rngIsolationActive = true; } if (5__11) { if (_logSuccesses || ModConfig.DiagnosticMode.Value) { TelemetryHelpers.LogLocationStart(5__8, _mode); } 5__23 = TranspiledCompletionHandler.AggregateSessions.ContainsKey(5__8.m_prefabName); if (!5__23) { TranspiledCompletionHandler.AggregateSessions[5__8.m_prefabName] = new TelemetryContext(); } } GenerationProgress.CurrentLocation = 5__8; 5__12 = 5__8.m_prefabName; if (!string.IsNullOrEmpty(5__8.m_group)) { 5__12 = 5__8.m_group; } 5__13 = PresenceGrid.GetOrCreate($"{5__12}:{5__8.m_minDistanceFromSimilar:F0}"); 5__14 = 100000; if (5__8.m_prioritized) { 5__14 = 200000; } 5__15 = Interleaver.GetBudget(5__8, 5__14); 5__16 = false; 5__17 = null; TranspiledCompletionHandler.AggregateSessions.TryGetValue(5__8.m_prefabName, out 5__17); 5__24 = 0; goto IL_05fb; } <>s__26 = 5__3.GetEnumerator(); try { while (<>s__26.MoveNext()) { 5__27 = <>s__26.Current; 5__28 = null; 5__29 = 0; while (5__29 < zsP.m_locations.Count) { if (zsP.m_locations[5__29].m_prefabName == 5__27.Key) { 5__28 = zsP.m_locations[5__29]; break; } 5__29++; } if (5__28 != null) { FlushLTS(zsP, 5__28, 5__27.Value); } 5__28 = null; 5__27 = default(KeyValuePair); } } finally { ((IDisposable)<>s__26).Dispose(); } <>s__26 = default(Dictionary.Enumerator); 5__30 = 0; goto IL_0f5b; IL_0e29: if (5__46 < 5__43) { 5__47 = false; 5__48 = null; TranspiledCompletionHandler.AggregateSessions.TryGetValue(5__37, out 5__48); 5__49 = 0; goto IL_0ddf; } if (_rngIsolationActive) { Random.state = _outsideRngState; _rngIsolationActive = false; } 5__37 = null; 5__39 = null; 5__40 = null; 5__41 = null; 5__36 = null; goto IL_0e82; IL_0ddf: if (5__49 < 5__42 && !5__47) { if (SurveyMode.GetZone(5__36, out 5__50)) { 5__39.ZonesExamined++; if (zsP.m_locationInstances.ContainsKey(5__50)) { 5__39.ErrOccupied++; if (++5__2 >= 512) { 5__2 = 0; if (_rngIsolationActive) { _insideRngState = Random.state; Random.state = _outsideRngState; } <>2__current = null; <>1__state = 3; return true; } } else { 5__47 = EvaluateZone(zsP, 5__36, 5__50, 5__41, 5__40, 5__39, 5__48); if (++5__2 >= 512) { 5__2 = 0; if (_rngIsolationActive) { _insideRngState = Random.state; Random.state = _outsideRngState; } <>2__current = null; <>1__state = 4; return true; } } goto IL_0dcd; } 5__39.ZoneExhausted++; } GenerationProgress.IncrementProcessed(5__47); 5__48 = null; 5__46++; goto IL_0e29; IL_0f5b: if (5__30 >= _maxRelaxationAttempts || zsP.m_locations.Count <= locListSnapshotP) { break; } 5__31 = zsP.m_locations.Count - locListSnapshotP; 5__32 = zsP.m_locations.GetRange(locListSnapshotP, 5__31); locListSnapshotP = zsP.m_locations.Count; DiagnosticLog.WriteTimestampedLog($"[LPA] Relaxation pass {5__30 + 1}: processing {5__31} relaxed packet(s).", (LogLevel)16); 5__33 = new Dictionary(StringComparer.Ordinal); 5__34 = new Dictionary(StringComparer.Ordinal); <>s__35 = 5__32.GetEnumerator(); <>1__state = -3; goto IL_0e82; IL_05fb: if (5__24 < 5__15 && !5__16) { if (SurveyMode.GetZone(5__8, out 5__25)) { 5__10.ZonesExamined++; if (zsP.m_locationInstances.ContainsKey(5__25)) { 5__10.ErrOccupied++; if (++5__2 >= 512) { 5__2 = 0; if (_rngIsolationActive) { _insideRngState = Random.state; Random.state = _outsideRngState; } <>2__current = null; <>1__state = 1; return true; } } else { 5__16 = EvaluateZone(zsP, 5__8, 5__25, 5__13, 5__12, 5__10, 5__17); if (++5__2 >= 512) { 5__2 = 0; if (_generateLocationsProgressField != null && 5__1.Count > 0) { _generateLocationsProgressField.SetValue(zsP, (float)(5__6 + 1) / (float)5__1.Count); } if (_rngIsolationActive) { _insideRngState = Random.state; Random.state = _outsideRngState; } <>2__current = null; <>1__state = 2; return true; } } goto IL_05e9; } 5__10.ZoneExhausted++; } if (5__16) { GenerationProgress.IncrementProcessed(successfullyPlacedP: true); } else { GenerationProgress.IncrementProcessed(successfullyPlacedP: false); } if (_interleavedScheduling && _rngIsolationActive) { 5__5[5__8.m_prefabName] = Random.state; } 5__18 = 5__4.TryGetValue(5__8.m_prefabName, out 5__19); if (5__18) { 5__19--; 5__4[5__8.m_prefabName] = 5__19; if (5__19 <= 0) { 5__4.Remove(5__8.m_prefabName); if (_rngIsolationActive) { Random.state = _outsideRngState; _rngIsolationActive = false; } 5__5.Remove(5__8.m_prefabName); FlushLTS(zsP, 5__8, 5__10); 5__3.Remove(5__8.m_prefabName); } } 5__7 = null; 5__8 = null; 5__10 = null; 5__12 = null; 5__13 = null; 5__17 = null; 5__6++; goto IL_07a1; } if (_locationsGeneratedProp != null) { _locationsGeneratedProp.SetValue(zsP, true); } else { DiagnosticLog.WriteLog("[LPA] WARNING: Could not set LocationsGenerated via reflection. Black screen likely.", (LogLevel)2); } SurveyMode.DumpDiagnostics(); DiagnosticLog.DumpPlacementsToFile(); GenerationProgress.CurrentLocation = null; RelaxationTracker.MarkPlacementComplete(); GenerationProgress.EndGeneration(); return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; ((IDisposable)<>s__35).Dispose(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static int _outerBudgetBase; private static int _outerBudgetPrioritized; private static int _dartsPerZone; private static int _maxRelaxationAttempts; private static bool _interleavedScheduling; private static bool _minimalLogging; private static bool _logSuccesses; private static PlacementMode _mode; private static bool _enable3DSimilarity; private static Biome _highReliefBiomeMask = (Biome)516; private static Dictionary> _groupPartitions; private static Dictionary _centerFirstCounts; private static PropertyInfo _locationsGeneratedProp; private static FieldInfo _generateLocationsProgressField; private static State _outsideRngState; private static State _insideRngState; private static bool _rngIsolationActive; private static bool _parallelPlacement; private static int _parallelThreadCount; private static BlockingCollection _workQueue; private static ConcurrentQueue _resultQueue; private static int _prioritizedInFlight; private static ManualResetEventSlim _priorityBarrierDone; private static ConcurrentDictionary _pendingOccupancy; private static Dictionary _occupancySnapshot; private static ConcurrentDictionary> _inFlightRegions; private static ConcurrentDictionary> _remainingToPlace; private static ConcurrentDictionary> _counterLists; private static ConcurrentDictionary> _telemetryLists; private static ConcurrentDictionary _startedPrefabs; private static object _ltsCompletionLock; private static int _parallelTokensProcessed; private static int _parallelTotalZones; private static ConcurrentDictionary _totalZonesPerPrefab; [IteratorStateMachine(typeof(d__19))] public static IEnumerator Run(ZoneSystem zsP) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__19(0) { zsP = zsP }; } private static bool EvaluateZone(ZoneSystem zsP, ZoneLocation locP, Vector2i zoneIDP, PresenceGrid groupGridP, string groupP, PlacementCounters ctrP, TelemetryContext telCtxP) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0092: 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_009e: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Invalid comparison between Unknown and I4 //IL_0183: 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_0171: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_0333: Unknown result type (might be due to invalid IL or missing references) Vector3 zonePos = ZoneSystem.GetZonePos(zoneIDP); int num = -1; if (WorldSurveyData.ZoneToIndex.TryGetValue(zoneIDP, out var value)) { num = value; } for (int i = 0; i < _dartsPerZone; i++) { ctrP.DartsThrown++; float num2 = Random.Range(-32f + locP.m_exteriorRadius, 32f - locP.m_exteriorRadius); float num3 = Random.Range(-32f + locP.m_exteriorRadius, 32f - locP.m_exteriorRadius); Vector3 val = zonePos + new Vector3(num2, 0f, num3); Vector2 val2 = new Vector2(val.x, val.z); float magnitude = ((Vector2)(ref val2)).magnitude; if (locP.m_minDistance > 0f && magnitude < locP.m_minDistance) { ctrP.ErrDist++; TelemetryHelpers.TrackDistanceFailureCtx(telCtxP, magnitude, locP.m_minDistance, locP.m_maxDistance); continue; } if (locP.m_maxDistance > 0f && magnitude > locP.m_maxDistance) { ctrP.ErrDist++; TelemetryHelpers.TrackDistanceFailureCtx(telCtxP, magnitude, locP.m_minDistance, locP.m_maxDistance); continue; } Biome biome = WorldGenerator.instance.GetBiome(val); if ((biome & locP.m_biome) == 0) { ctrP.ErrBiome++; TelemetryHelpers.CaptureWrongBiomeCtx(telCtxP, biome); continue; } float num4 = (val.y = WorldGenerator.instance.GetHeight(val.x, val.z)) - 30f; TelemetryHelpers.TrackGlobalAltitude(num4); if (num4 < locP.m_minAltitude || num4 > locP.m_maxAltitude) { ctrP.ErrAlt++; TelemetryHelpers.TrackAltitudeFailureCtx(telCtxP, num4, locP.m_minAltitude, locP.m_maxAltitude, val); continue; } if (locP.m_minDistanceFromSimilar > 0f && groupGridP.HasConflict(val) && (!_enable3DSimilarity || !IsHighRelief(biome) || Confirm3DSimilarityConflict(val, locP.m_minDistanceFromSimilar, groupP, zsP.m_locationInstances))) { ctrP.ErrSim++; continue; } if (locP.m_maxTerrainDelta > 0f || locP.m_minTerrainDelta > 0f) { ThreadSafeTerrainDelta.GetTerrainDelta(val, locP.m_exteriorRadius, out var delta, out var _, num); if (delta > locP.m_maxTerrainDelta || delta < locP.m_minTerrainDelta) { ctrP.ErrTerrain++; continue; } } if (locP.m_inForest) { float forestFactor = WorldGenerator.GetForestFactor(val); if (forestFactor < locP.m_forestTresholdMin || forestFactor > locP.m_forestTresholdMax) { ctrP.ErrForest++; continue; } } zsP.RegisterLocation(locP, val, false); if (num >= 0) { SurveyMode.MarkZoneOccupied(num); } CommitToGroup(groupP, val); ctrP.Placed++; return true; } return false; } private static bool IsHighRelief(Biome biomeP) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 return (biomeP & _highReliefBiomeMask) > 0; } private static bool Confirm3DSimilarityConflict(Vector3 pP, float radiusP, string groupP, Dictionary instancesP) { //IL_0012: 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_005d: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) float num = radiusP * radiusP; int num2 = Mathf.CeilToInt(radiusP / 64f); int num3 = Mathf.FloorToInt((pP.x + 32f) / 64f); int num4 = Mathf.FloorToInt((pP.z + 32f) / 64f); for (int i = num4 - num2; i <= num4 + num2; i++) { for (int j = num3 - num2; j <= num3 + num2; j++) { if (!instancesP.TryGetValue(new Vector2i(j, i), out var value)) { continue; } string text = value.m_location.m_prefabName; if (!string.IsNullOrEmpty(value.m_location.m_group)) { text = value.m_location.m_group; } if (!(text != groupP)) { float num5 = value.m_position.x - pP.x; float num6 = value.m_position.y - pP.y; float num7 = value.m_position.z - pP.z; if (num5 * num5 + num6 * num6 + num7 * num7 < num) { return true; } } } } return false; } private static void CommitToGroup(string groupP, Vector3 pP) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) if (!_groupPartitions.TryGetValue(groupP, out var value)) { return; } foreach (float item in value) { PresenceGrid.GetOrCreate($"{groupP}:{item:F0}").Commit(pP, item); } } private static void FlushLTS(ZoneSystem zsP, ZoneLocation locP, PlacementCounters ctrP) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) string prefabName = locP.m_prefabName; int num = 0; foreach (LocationInstance value in zsP.m_locationInstances.Values) { if (value.m_location.m_prefabName == prefabName) { num++; } } FlushLTSCore(zsP, locP, ctrP, num); } private static void FlushLTS(ZoneSystem zsP, ZoneLocation locP, PlacementCounters ctrP, int globalPlacedOverrideP) { FlushLTSCore(zsP, locP, ctrP, globalPlacedOverrideP); } private static void FlushLTSCore(ZoneSystem zsP, ZoneLocation locP, PlacementCounters ctrP, int globalPlacedP) { string prefabName = locP.m_prefabName; int originalQuantity = Interleaver.GetOriginalQuantity(prefabName); bool flag = globalPlacedP >= originalQuantity; int minimumNeededCount = PlayabilityPolicy.GetMinimumNeededCount(prefabName, originalQuantity); bool flag2 = globalPlacedP >= minimumNeededCount; int value; bool flag3 = ConstraintRelaxer.RelaxationAttempts.TryGetValue(prefabName, out value) && value > 0; bool flag4 = flag || (flag3 && flag2); int num = originalQuantity; if (flag3 && flag4 && !flag) { num = minimumNeededCount; } ReportData dataP = BuildReportData(locP, ctrP, globalPlacedP, num, flag); if (flag4 && flag3) { RelaxationTracker.MarkRelaxationSucceeded(prefabName); } if (!_minimalLogging) { if (flag4) { if (_logSuccesses || flag3) { if (flag3) { DiagnosticLog.WriteTimestampedLog($"[RELAXATION SUCCESS] {prefabName} placed {globalPlacedP}/{num} after {value} relaxation(s). {ConstraintRelaxer.GetRelaxationSummary(prefabName, locP)}", (LogLevel)8); } ReportFormatter.WriteReport(dataP, isHeartbeatP: false, prefabName); } } else { ReportFormatter.WriteReport(dataP, isHeartbeatP: false, prefabName); } } if (!flag4 && !ConstraintRelaxer.TryRelax(dataP)) { RelaxationTracker.CheckAndMarkFailed(prefabName, globalPlacedP, originalQuantity, locP.m_prioritized); } TranspiledCompletionHandler.AggregateSessions.Remove(prefabName); } private static ReportData BuildReportData(ZoneLocation locP, PlacementCounters ctrP, int globalPlacedP, int origQtyP, bool isCompleteP) { long num = ctrP.DartsThrown; long num2 = num - ctrP.ErrDist; long num3 = num2 - ctrP.ErrBiome; long num4 = num3 - ctrP.ErrAlt; long num5 = num4 - ctrP.ErrSim; long num6 = num5 - ctrP.ErrTerrain; long inVeg = num6 - ctrP.ErrForest; int fallbackBaseP = 100000; if (locP.m_prioritized) { fallbackBaseP = 200000; } return new ReportData { Loc = locP, PrefabName = locP.m_prefabName, CurrentOuter = ctrP.ZonesExamined, LimitOuter = Interleaver.GetBudget(locP, fallbackBaseP), Placed = globalPlacedP, OriginalQuantity = origQtyP, IsComplete = isCompleteP, ErrZone = ctrP.ErrOccupied, ValidZones = ctrP.ZonesExamined - ctrP.ErrOccupied, InDist = num, ErrDist = ctrP.ErrDist, InBiome = num2, ErrBiome = ctrP.ErrBiome, InSim = num4, ErrSim = ctrP.ErrSim, InAlt = num3, ErrAlt = ctrP.ErrAlt, InTerr = num5, ErrTerrain = ctrP.ErrTerrain, InForest = num6, ErrForest = ctrP.ErrForest, InVeg = inVeg, ErrVeg = 0L }; } private static List BuildTokenList(ZoneSystem zsP) { List list = new List(); HashSet hashSet = new HashSet(); for (int i = 0; i < zsP.m_locations.Count; i++) { if (zsP.m_locations[i].m_centerFirst) { hashSet.Add(zsP.m_locations[i].m_prefabName); } } List list2 = new List(); for (int j = 0; j < zsP.m_locations.Count; j++) { ZoneLocation val = zsP.m_locations[j]; if (val.m_enable && Compatibility.IsValidLocation(val) && val.m_quantity > 0) { list2.Add(val); } } list2.Sort(CompareLocationsByPriorityThenOrigin); foreach (ZoneLocation item in list2) { int num = item.m_quantity; if (hashSet.Contains(item.m_prefabName)) { num = item.m_quantity - 1; } if (num > 0) { int num2 = num; if (_interleavedScheduling) { num2 = 1; } for (int k = 0; k < num2; k++) { list.Add(new PlacementToken { Location = item }); } } } return list; } private static int CompareLocationsByPriorityThenOrigin(ZoneLocation aP, ZoneLocation bP) { if (aP.m_prioritized != bP.m_prioritized) { if (aP.m_prioritized) { return -1; } return 1; } bool flag = aP.m_prefabName.StartsWith("MWL_", StringComparison.OrdinalIgnoreCase); bool flag2 = bP.m_prefabName.StartsWith("MWL_", StringComparison.OrdinalIgnoreCase); if (flag != flag2) { if (flag) { return 1; } return -1; } return 0; } [IteratorStateMachine(typeof(d__50))] private static IEnumerator RunParallelPath(ZoneSystem zsP, int locListSnapshotP) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__50(0) { zsP = zsP, locListSnapshotP = locListSnapshotP }; } private static List BuildSpatialStreams(List orderedP) { //IL_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_02c8: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Unknown result type (might be due to invalid IL or missing references) //IL_030b: Unknown result type (might be due to invalid IL or missing references) Dictionary> dictionary = new Dictionary>(StringComparer.Ordinal); List list = new List(); Dictionary dictionary2 = new Dictionary(StringComparer.Ordinal); foreach (OrderedEntry item2 in orderedP) { string text = item2.Loc.m_prefabName; if (!string.IsNullOrEmpty(item2.Loc.m_group)) { text = item2.Loc.m_group; } if (!dictionary.TryGetValue(text, out var value)) { value = (dictionary[text] = new List()); list.Add(text); dictionary2[text] = item2.Loc.m_prioritized; } value.Add(item2); } List list3 = new List(list.Count); foreach (string item3 in list) { List list4 = dictionary[item3]; Dictionary> dictionary3 = new Dictionary>(); List list5 = new List(); foreach (OrderedEntry item4 in list4) { float minDistanceFromSimilar = item4.Loc.m_minDistanceFromSimilar; float num = Mathf.Round(minDistanceFromSimilar * 100f) / 100f; if (!dictionary3.TryGetValue(num, out var value2)) { value2 = (dictionary3[num] = new List()); list5.Add(num); } value2.Add(item4); } list5.Sort((float aP, float bP) => bP.CompareTo(aP)); GtsStream gtsStream = new GtsStream { GroupKey = item3, SubGroups = new List(), CurrentSubGroup = 0, IsPrioritized = dictionary2[item3] }; foreach (float item5 in list5) { List list7 = dictionary3[item5]; PartitionRule ruleP = SpatialPartitionAlgorithms.BuildRule(item5, _parallelThreadCount); int partitionCount = ruleP.PartitionCount; Dictionary>[] array = new Dictionary>[partitionCount]; for (int i = 0; i < partitionCount; i++) { array[i] = new Dictionary>(StringComparer.Ordinal); } int num2 = 0; foreach (OrderedEntry item6 in list7) { string prefabName = item6.Loc.m_prefabName; List orBuildCandidateList = SurveyMode.GetOrBuildCandidateList(item6.Loc); num2 += orBuildCandidateList.Count; foreach (Vector2i item7 in orBuildCandidateList) { int partition = SpatialPartitionAlgorithms.GetPartition(item7, ref ruleP); if (!array[partition].TryGetValue(prefabName, out var value3)) { value3 = new List(); array[partition][prefabName] = value3; } value3.Add(item7); } } if (ModConfig.DiagnosticMode.Value) { DiagnosticLog.WriteTimestampedLog($"[LPA] GTS={item3} minDist={item5:F0} " + $"types={list7.Count} zones={num2} " + $"partitions={partitionCount} mode={ruleP.Mode}", (LogLevel)16); } foreach (OrderedEntry item8 in list7) { string prefabName2 = item8.Loc.m_prefabName; int num3 = 0; for (int j = 0; j < partitionCount; j++) { if (array[j].TryGetValue(prefabName2, out var value4) && value4.Count > 0) { num3++; } } Interlocked.Add(ref _inFlightRegions[prefabName2].Value, num3); } PresenceGrid orCreate = PresenceGrid.GetOrCreate($"{item3}:{item5:F0}"); SubGroupStream subGroupStream = new SubGroupStream { MinDistFromSimilar = item5, WorkUnits = new Queue() }; for (int k = 0; k < partitionCount; k++) { List list8 = new List(); foreach (OrderedEntry item9 in list7) { string prefabName3 = item9.Loc.m_prefabName; if (array[k].TryGetValue(prefabName3, out var value5) && value5.Count != 0) { PlacementCounters placementCounters = new PlacementCounters(); TelemetryContext telemetryContext = new TelemetryContext(); _counterLists[prefabName3].Add(placementCounters); _telemetryLists[prefabName3].Add(telemetryContext); list8.Add(new TypeRegionWork { Loc = item9.Loc, Group = item3, Grid = orCreate, Zones = value5, Counters = placementCounters, TelCtx = telemetryContext }); } } if (list8.Count > 0) { subGroupStream.WorkUnits.Enqueue(new WorkUnit { TypeWork = list8, IsPrioritized = gtsStream.IsPrioritized }); } } gtsStream.SubGroups.Add(subGroupStream); } list3.Add(gtsStream); } int num4 = 0; Dictionary dictionary4 = new Dictionary(StringComparer.Ordinal); foreach (GtsStream item10 in list3) { foreach (SubGroupStream subGroup in item10.SubGroups) { foreach (WorkUnit workUnit in subGroup.WorkUnits) { foreach (TypeRegionWork item11 in workUnit.TypeWork) { num4 += item11.Zones.Count; string prefabName4 = item11.Loc.m_prefabName; dictionary4.TryGetValue(prefabName4, out var value6); dictionary4[prefabName4] = value6 + item11.Zones.Count; } } } } _parallelTotalZones = Math.Max(1, num4); foreach (KeyValuePair item12 in dictionary4) { _totalZonesPerPrefab[item12.Key] = item12.Value; } foreach (string item13 in list) { List list9 = dictionary[item13]; foreach (OrderedEntry item14 in list9) { string prefabName5 = item14.Loc.m_prefabName; if (_inFlightRegions[prefabName5].Value > 0) { continue; } _inFlightRegions[prefabName5] = new StrongBox(1); PlacementCounters placementCounters2 = new PlacementCounters(); TelemetryContext telemetryContext2 = new TelemetryContext(); _counterLists[prefabName5].Add(placementCounters2); _telemetryLists[prefabName5].Add(telemetryContext2); string text2 = item14.Loc.m_prefabName; if (!string.IsNullOrEmpty(item14.Loc.m_group)) { text2 = item14.Loc.m_group; } PresenceGrid orCreate2 = PresenceGrid.GetOrCreate($"{text2}:{item14.Loc.m_minDistanceFromSimilar:F0}"); WorkUnit item = new WorkUnit { TypeWork = new List { new TypeRegionWork { Loc = item14.Loc, Group = text2, Grid = orCreate2, Zones = new List(), Counters = placementCounters2, TelCtx = telemetryContext2 } }, IsPrioritized = item14.Loc.m_prioritized }; GtsStream gtsStream2 = null; for (int l = 0; l < list3.Count; l++) { if (list3[l].GroupKey == item13) { gtsStream2 = list3[l]; break; } } if (gtsStream2 != null && gtsStream2.SubGroups.Count > 0) { gtsStream2.SubGroups[0].WorkUnits.Enqueue(item); } } } return list3; } private static void WorkerBody(ZoneSystem zsP, int workerIdxP) { //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) foreach (WorkUnit item in _workQueue.GetConsumingEnumerable()) { foreach (TypeRegionWork item2 in item.TypeWork) { string prefabName = item2.Loc.m_prefabName; GenerationProgress.SetThreadSlot(workerIdxP, prefabName); if (_startedPrefabs.TryAdd(prefabName, 0) && (_logSuccesses || ModConfig.DiagnosticMode.Value)) { TelemetryHelpers.LogLocationStart(item2.Loc, _mode); } int num = 0; if (item2.Zones.Count > 0) { Vector2i val = item2.Zones[0]; num = ((object)(Vector2i)(ref val)).GetHashCode(); } ThreadSafePRNG.SeedForLts(WorldGenerator.instance.GetSeed() + StringExtensionMethods.GetStableHashCode(prefabName) + num); if (Volatile.Read(ref _remainingToPlace[prefabName].Value) > 0) { EvaluateZoneList(item2, prefabName); } if (Interlocked.Decrement(ref _inFlightRegions[prefabName].Value) == 0) { DoFlushAndRelax(zsP, item2.Loc, item.IsPrioritized, workerIdxP); if (item.IsPrioritized && Interlocked.Decrement(ref _prioritizedInFlight) == 0) { _priorityBarrierDone.Set(); } } } GenerationProgress.SetThreadSlot(workerIdxP, null); } } private static void EvaluateZoneList(TypeRegionWork twP, string prefabP) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_012a: 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_016c: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) ZoneLocation loc = twP.Loc; PlacementCounters counters = twP.Counters; string group = twP.Group; int fallbackBaseP = 100000; if (loc.m_prioritized) { fallbackBaseP = 200000; } int budget = Interleaver.GetBudget(loc, fallbackBaseP); long num = (long)(ulong)loc.m_biome; if ((num & 0x20) != 0 && loc.m_minAltitude < -4f) { if (loc.m_maxAltitude < -4f) { num = 1099511627776L; } else { num |= 0x10000000000L; } } int num2 = 0; foreach (Vector2i zone in twP.Zones) { if (num2 >= budget || Volatile.Read(ref _remainingToPlace[prefabP].Value) <= 0) { break; } num2++; counters.ZonesExamined++; Interlocked.Increment(ref _parallelTokensProcessed); if (_occupancySnapshot.ContainsKey(zone) || _pendingOccupancy.ContainsKey(zone)) { counters.ErrOccupied++; continue; } int num3 = -1; if (WorldSurveyData.ZoneToIndex.TryGetValue(zone, out var value)) { num3 = value; } if (EvaluateZoneParallel(loc, zone, num3, twP.Grid, group, counters, twP.TelCtx, out var position)) { if (Interlocked.Decrement(ref _remainingToPlace[prefabP].Value) < 0) { Interlocked.Increment(ref _remainingToPlace[prefabP].Value); break; } if (!_pendingOccupancy.TryAdd(zone, 1)) { Interlocked.Increment(ref _remainingToPlace[prefabP].Value); counters.ErrOccupied++; continue; } CommitToGroup(group, position); _resultQueue.Enqueue(new PlacementResult { Loc = loc, Position = position, Group = group, ZoneIdx = num3, ZoneID = zone, Counters = counters }); counters.Placed++; GenerationProgress.IncrementAttempted(1); GenerationProgress.IncrementPlaced(1); } } } private static PlacementCounters AggregateCounters(string prefabP) { PlacementCounters placementCounters = new PlacementCounters(); if (!_counterLists.TryGetValue(prefabP, out var value)) { return placementCounters; } foreach (PlacementCounters item in value) { placementCounters.ZonesExamined += item.ZonesExamined; placementCounters.ZoneExhausted += item.ZoneExhausted; placementCounters.DartsThrown += item.DartsThrown; placementCounters.Placed += item.Placed; placementCounters.ErrOccupied += item.ErrOccupied; placementCounters.ErrDist += item.ErrDist; placementCounters.ErrBiome += item.ErrBiome; placementCounters.ErrAlt += item.ErrAlt; placementCounters.ErrSim += item.ErrSim; placementCounters.ErrTerrain += item.ErrTerrain; placementCounters.ErrForest += item.ErrForest; } return placementCounters; } private static TelemetryContext AggregateTelemetry(string prefabP) { TelemetryContext telemetryContext = new TelemetryContext(); if (_telemetryLists.TryGetValue(prefabP, out var value)) { foreach (TelemetryContext item in value) { telemetryContext.Merge(item); } } return telemetryContext; } private static void DoFlushAndRelax(ZoneSystem zsP, ZoneLocation locP, bool isPrioritizedP, int workerIdxP) { string prefabName = locP.m_prefabName; PlacementCounters placementCounters = AggregateCounters(prefabName); TelemetryContext value = AggregateTelemetry(prefabName); int num = 0; if (_centerFirstCounts.TryGetValue(prefabName, out var value2)) { num = value2; } int num2 = placementCounters.Placed + num; int originalQuantity = Interleaver.GetOriginalQuantity(prefabName); bool flag = num2 >= originalQuantity; int minimumNeededCount = PlayabilityPolicy.GetMinimumNeededCount(prefabName, originalQuantity); int value3; bool flag2 = ConstraintRelaxer.RelaxationAttempts.TryGetValue(prefabName, out value3) && value3 > 0; bool flag3 = flag || (flag2 && num2 >= minimumNeededCount); int num3 = 0; if (_totalZonesPerPrefab.TryGetValue(prefabName, out var value4)) { num3 = value4; } int num4 = Math.Max(0, num3 - placementCounters.ZonesExamined); if (num4 > 0) { Interlocked.Add(ref _parallelTokensProcessed, num4); } lock (TranspiledCompletionHandler.AggregateSessions) { TranspiledCompletionHandler.AggregateSessions[prefabName] = value; } int num5 = originalQuantity; if (flag2 && flag3 && !flag) { num5 = minimumNeededCount; } ReportData dataP = BuildReportData(locP, placementCounters, num2, num5, flag); int num6 = Math.Max(0, originalQuantity - num2); if (num6 > 0) { GenerationProgress.IncrementAttempted(num6); } if (flag3 && flag2) { RelaxationTracker.MarkRelaxationSucceeded(prefabName); } if (!_minimalLogging) { if (flag3) { if (_logSuccesses || flag2) { if (flag2) { DiagnosticLog.WriteTimestampedLog($"[RELAXATION SUCCESS] {prefabName} placed {num2}/{num5} " + $"after {value3} relaxation(s). " + ConstraintRelaxer.GetRelaxationSummary(prefabName, locP), (LogLevel)8); } ReportFormatter.WriteReport(dataP, isHeartbeatP: false, prefabName); } } else { ReportFormatter.WriteReport(dataP, isHeartbeatP: false, prefabName); } } if (!flag3) { ZoneLocation val = null; lock (_ltsCompletionLock) { int count = zsP.m_locations.Count; if (!ConstraintRelaxer.TryRelax(dataP)) { RelaxationTracker.CheckAndMarkFailed(prefabName, num2, originalQuantity, locP.m_prioritized); } else if (zsP.m_locations.Count > count) { val = zsP.m_locations[count]; if (isPrioritizedP) { Interlocked.Increment(ref _prioritizedInFlight); } } } if (val != null) { RunInlineRelaxation(zsP, val, isPrioritizedP, workerIdxP, num2, originalQuantity, minimumNeededCount, num); if (isPrioritizedP && Interlocked.Decrement(ref _prioritizedInFlight) == 0) { _priorityBarrierDone.Set(); } } } lock (TranspiledCompletionHandler.AggregateSessions) { TranspiledCompletionHandler.AggregateSessions.Remove(prefabName); } } private static void RunInlineRelaxation(ZoneSystem zsP, ZoneLocation relaxLocP, bool isPrioritizedP, int workerIdxP, int priorPlacedP, int origQtyP, int minNeededP, int cfCountP) { //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) string prefabName = relaxLocP.m_prefabName; int num = 1; if (ConstraintRelaxer.RelaxationAttempts.TryGetValue(prefabName, out var value)) { num = value; } GenerationProgress.SetThreadSlot(workerIdxP, $"{prefabName} (Relaxation attempt {num})"); string text = relaxLocP.m_prefabName; if (!string.IsNullOrEmpty(relaxLocP.m_group)) { text = relaxLocP.m_group; } PresenceGrid orCreate = PresenceGrid.GetOrCreate($"{text}:{relaxLocP.m_minDistanceFromSimilar:F0}"); int num2 = _outerBudgetBase; if (relaxLocP.m_prioritized) { num2 = _outerBudgetPrioritized; } int quantity = relaxLocP.m_quantity; ThreadSafePRNG.SeedForLts(WorldGenerator.instance.GetSeed() + StringExtensionMethods.GetStableHashCode(prefabName)); PlacementCounters placementCounters = new PlacementCounters(); TelemetryContext telemetryContext = new TelemetryContext(); for (int i = 0; i < quantity; i++) { bool flag = false; for (int j = 0; j < num2; j++) { if (flag) { break; } if (!SurveyMode.GetZone(relaxLocP, out var result)) { placementCounters.ZoneExhausted++; break; } placementCounters.ZonesExamined++; if (_occupancySnapshot.ContainsKey(result) || _pendingOccupancy.ContainsKey(result)) { placementCounters.ErrOccupied++; continue; } int num3 = -1; if (WorldSurveyData.ZoneToIndex.TryGetValue(result, out var value2)) { num3 = value2; } if (EvaluateZoneParallel(relaxLocP, result, num3, orCreate, text, placementCounters, telemetryContext, out var position)) { if (!_pendingOccupancy.TryAdd(result, 1)) { placementCounters.ErrOccupied++; continue; } CommitToGroup(text, position); _resultQueue.Enqueue(new PlacementResult { Loc = relaxLocP, Position = position, Group = text, ZoneIdx = num3, ZoneID = result, Counters = placementCounters }); placementCounters.Placed++; flag = true; GenerationProgress.IncrementAttempted(1); GenerationProgress.IncrementPlaced(1); Interlocked.Increment(ref _parallelTokensProcessed); } } if (!flag) { GenerationProgress.IncrementAttempted(1); Interlocked.Increment(ref _parallelTokensProcessed); } } int num4 = priorPlacedP + placementCounters.Placed; if (_counterLists.TryGetValue(prefabName, out var value3)) { value3.Add(placementCounters); } lock (TranspiledCompletionHandler.AggregateSessions) { TranspiledCompletionHandler.AggregateSessions[prefabName] = telemetryContext; } int value4; bool flag2 = num4 >= origQtyP || (ConstraintRelaxer.RelaxationAttempts.TryGetValue(prefabName, out value4) && value4 > 0 && num4 >= minNeededP); int num5 = origQtyP; if (flag2 && num4 < origQtyP) { num5 = minNeededP; } ReportData dataP = BuildReportData(relaxLocP, placementCounters, num4, num5, num4 >= origQtyP); if (flag2) { RelaxationTracker.MarkRelaxationSucceeded(prefabName); if (!_minimalLogging) { int num6 = 0; if (ConstraintRelaxer.RelaxationAttempts.TryGetValue(prefabName, out var value5)) { num6 = value5; } DiagnosticLog.WriteTimestampedLog($"[RELAXATION SUCCESS] {prefabName} placed {num4}/{num5} " + $"after {num6} relaxation(s). " + ConstraintRelaxer.GetRelaxationSummary(prefabName, relaxLocP), (LogLevel)8); ReportFormatter.WriteReport(dataP, isHeartbeatP: false, prefabName); } } else { if (!_minimalLogging) { ReportFormatter.WriteReport(dataP, isHeartbeatP: false, prefabName); } lock (_ltsCompletionLock) { int count = zsP.m_locations.Count; if (!ConstraintRelaxer.TryRelax(dataP)) { RelaxationTracker.CheckAndMarkFailed(prefabName, num4, origQtyP, relaxLocP.m_prioritized); } else if (zsP.m_locations.Count > count) { ZoneLocation relaxLocP2 = zsP.m_locations[count]; if (isPrioritizedP) { Interlocked.Increment(ref _prioritizedInFlight); } RunInlineRelaxation(zsP, relaxLocP2, isPrioritizedP, workerIdxP, num4, origQtyP, minNeededP, cfCountP); if (isPrioritizedP && Interlocked.Decrement(ref _prioritizedInFlight) == 0) { _priorityBarrierDone.Set(); } } } } lock (TranspiledCompletionHandler.AggregateSessions) { TranspiledCompletionHandler.AggregateSessions.Remove(prefabName); } } private static bool EvaluateZoneParallel(ZoneLocation locP, Vector2i zoneIDP, int zoneGridIdxP, PresenceGrid groupGridP, string groupP, PlacementCounters ctrP, TelemetryContext telCtxP, out Vector3 position) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Invalid comparison between Unknown and I4 //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: 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_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_02f6: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Unknown result type (might be due to invalid IL or missing references) //IL_02bb: Unknown result type (might be due to invalid IL or missing references) position = Vector3.zero; Vector3 zonePos = ZoneSystem.GetZonePos(zoneIDP); for (int i = 0; i < _dartsPerZone; i++) { ctrP.DartsThrown++; float num = ThreadSafePRNG.NextFloat(-32f + locP.m_exteriorRadius, 32f - locP.m_exteriorRadius); float num2 = ThreadSafePRNG.NextFloat(-32f + locP.m_exteriorRadius, 32f - locP.m_exteriorRadius); Vector3 val = zonePos + new Vector3(num, 0f, num2); Vector2 val2 = new Vector2(val.x, val.z); float magnitude = ((Vector2)(ref val2)).magnitude; if (locP.m_minDistance > 0f && magnitude < locP.m_minDistance) { ctrP.ErrDist++; TelemetryHelpers.TrackDistanceFailureCtx(telCtxP, magnitude, locP.m_minDistance, locP.m_maxDistance); continue; } if (locP.m_maxDistance > 0f && magnitude > locP.m_maxDistance) { ctrP.ErrDist++; TelemetryHelpers.TrackDistanceFailureCtx(telCtxP, magnitude, locP.m_minDistance, locP.m_maxDistance); continue; } Biome biome = WorldGenerator.instance.GetBiome(val); if ((biome & locP.m_biome) == 0) { ctrP.ErrBiome++; TelemetryHelpers.CaptureWrongBiomeCtx(telCtxP, biome); continue; } float num3 = (val.y = WorldGenerator.instance.GetHeight(val.x, val.z)) - 30f; if (num3 < locP.m_minAltitude || num3 > locP.m_maxAltitude) { ctrP.ErrAlt++; TelemetryHelpers.TrackAltitudeFailureCtx(telCtxP, num3, locP.m_minAltitude, locP.m_maxAltitude, val); continue; } if (locP.m_minDistanceFromSimilar > 0f && groupGridP.HasConflict(val) && (!_enable3DSimilarity || !IsHighRelief(biome) || Confirm3DSimilarityConflict(val, locP.m_minDistanceFromSimilar, groupP, _occupancySnapshot))) { ctrP.ErrSim++; continue; } if (locP.m_maxTerrainDelta > 0f || locP.m_minTerrainDelta > 0f) { ThreadSafeTerrainDelta.GetTerrainDelta(val, locP.m_exteriorRadius, out var delta, out var _, zoneGridIdxP); if (delta > locP.m_maxTerrainDelta || delta < locP.m_minTerrainDelta) { ctrP.ErrTerrain++; continue; } } if (locP.m_inForest) { float forestFactor = WorldGenerator.GetForestFactor(val); if (forestFactor < locP.m_forestTresholdMin || forestFactor > locP.m_forestTresholdMax) { ctrP.ErrForest++; continue; } } position = val; return true; } return false; } private static void DrainAndCommit(ZoneSystem zsP) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) PlacementResult result; while (_resultQueue.TryDequeue(out result)) { zsP.RegisterLocation(result.Loc, result.Position, false); if (result.ZoneIdx >= 0) { SurveyMode.MarkZoneOccupied(result.ZoneIdx); } } } private static int CompareOrderedEntries(OrderedEntry aP, OrderedEntry bP) { if (aP.Loc.m_prioritized != bP.Loc.m_prioritized) { if (aP.Loc.m_prioritized) { return -1; } return 1; } bool flag = aP.Loc.m_prefabName.StartsWith("MWL_", StringComparison.OrdinalIgnoreCase); bool flag2 = bP.Loc.m_prefabName.StartsWith("MWL_", StringComparison.OrdinalIgnoreCase); if (flag != flag2) { if (flag) { return 1; } return -1; } return 0; } private static void UpdateAnnulus(ZoneSystem zsP) { if (_generateLocationsProgressField != null && _parallelTotalZones > 0) { _generateLocationsProgressField.SetValue(zsP, Mathf.Clamp01((float)Volatile.Read(ref _parallelTokensProcessed) / (float)_parallelTotalZones)); } } [IteratorStateMachine(typeof(d__62))] private static IEnumerator RunSequentialPath(ZoneSystem zsP, int locListSnapshotP) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__62(0) { zsP = zsP, locListSnapshotP = locListSnapshotP }; } [IteratorStateMachine(typeof(d__63))] private static IEnumerator RunLocSerial(ZoneSystem zsP, ZoneLocation locP, PlacementCounters ctrP, int overrideQtyP = -1, bool suppressFlushP = false) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__63(0) { zsP = zsP, locP = locP, ctrP = ctrP, overrideQtyP = overrideQtyP, suppressFlushP = suppressFlushP }; } } public enum PlacementMode { Vanilla, Filter, Force, Survey } internal struct PlacementResult { public ZoneLocation Loc; public Vector3 Position; public string Group; public int ZoneIdx; public Vector2i ZoneID; public PlacementCounters Counters; } internal class PlacementToken { public ZoneLocation Location; } public static class PlayabilityPolicy { public class LocationYamlOverride { public string prefab { get; set; } public bool? relaxable { get; set; } public bool? relaxableunique { get; set; } public float? relaxableamount { get; set; } } private struct EffectivePolicy { public bool IsDisabled; public bool IsUnique; public bool IsRelaxable; public float Amount; } private static readonly HashSet _necessities = new HashSet { "Eikthyrnir", "GDKing", "Bonemass", "Dragonqueen", "GoblinKing", "Mistlands_DvergrBossEntrance1", "FaderLocation", "Vendor_BlackForest", "Hildir_camp", "BogWitch_Camp", "Hildir_crypt", "Hildir_cave", "Hildir_plainsfortress" }; private static readonly Dictionary _secondaryGoals = new Dictionary { { "Crypt", 0.5f }, { "SunkenCrypt", 0.5f }, { "MountainCave", 0.5f }, { "InfestedMine", 0.5f }, { "TarPit", 0.5f }, { "CharredFortress", 0.5f } }; private static Dictionary _yamlOverrides = new Dictionary(StringComparer.Ordinal); private static Dictionary _resolvedCache = new Dictionary(StringComparer.Ordinal); public static void Initialize() { _yamlOverrides.Clear(); _resolvedCache.Clear(); if (Compatibility.IsExpandWorldDataActive) { LoadYamlOverrides(); } } private static void LoadYamlOverrides() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) try { string path = Path.Combine(Paths.ConfigPath, "expand_world"); if (!Directory.Exists(path)) { return; } string[] files = Directory.GetFiles(path, "expand_locations*.yaml"); Array.Sort(files); IDeserializer val = new DeserializerBuilder().IgnoreUnmatchedProperties().Build(); foreach (string path2 in files) { string text = File.ReadAllText(path2); List list = val.Deserialize>(text); if (list == null) { continue; } for (int j = 0; j < list.Count; j++) { LocationYamlOverride locationYamlOverride = list[j]; if (!string.IsNullOrEmpty(locationYamlOverride.prefab)) { _yamlOverrides[locationYamlOverride.prefab] = locationYamlOverride; } } } DiagnosticLog.WriteLog($"[PlayabilityPolicy] Loaded {_yamlOverrides.Count} location overrides from EWD YAMLs.", (LogLevel)16); } catch (Exception ex) { DiagnosticLog.WriteLog("[PlayabilityPolicy] Failed to load EWD YAMLs: " + ex.Message, (LogLevel)4); } } private static EffectivePolicy GetEffectivePolicy(string prefabNameP) { if (_resolvedCache.TryGetValue(prefabNameP, out var value)) { return value; } EffectivePolicy effectivePolicy = ResolvePolicy(prefabNameP); _resolvedCache[prefabNameP] = effectivePolicy; return effectivePolicy; } private static EffectivePolicy ResolvePolicy(string prefabNameP) { EffectivePolicy result; if (_yamlOverrides.TryGetValue(prefabNameP, out var value)) { if (value.relaxable.HasValue && !value.relaxable.Value) { result = default(EffectivePolicy); result.IsDisabled = true; result.IsUnique = false; result.IsRelaxable = false; result.Amount = 0f; return result; } bool flag = _necessities.Contains(prefabNameP); if (value.relaxableunique.HasValue) { flag = value.relaxableunique.Value; } bool isRelaxable = flag || _secondaryGoals.ContainsKey(prefabNameP); if (value.relaxable.HasValue) { isRelaxable = value.relaxable.Value; } float amount = 0.5f; if (_secondaryGoals.TryGetValue(prefabNameP, out var value2)) { amount = value2; } if (value.relaxableamount.HasValue) { amount = value.relaxableamount.Value; } result = default(EffectivePolicy); result.IsDisabled = false; result.IsUnique = flag; result.IsRelaxable = isRelaxable; result.Amount = amount; return result; } bool flag2 = _necessities.Contains(prefabNameP); bool isRelaxable2 = flag2 || _secondaryGoals.ContainsKey(prefabNameP); float amount2 = 0.5f; if (_secondaryGoals.TryGetValue(prefabNameP, out var value3)) { amount2 = value3; } result = default(EffectivePolicy); result.IsDisabled = false; result.IsUnique = flag2; result.IsRelaxable = isRelaxable2; result.Amount = amount2; return result; } public static bool IsNecessity(string prefabNameP) { EffectivePolicy effectivePolicy = GetEffectivePolicy(prefabNameP); if (effectivePolicy.IsDisabled) { return false; } return effectivePolicy.IsUnique; } public static bool NeedsRelaxation(string prefabNameP, int placedCountP, int requestedCountP) { EffectivePolicy effectivePolicy = GetEffectivePolicy(prefabNameP); if (effectivePolicy.IsDisabled) { return false; } if (effectivePolicy.IsUnique) { return placedCountP == 0; } if (effectivePolicy.IsRelaxable) { return (float)placedCountP / (float)requestedCountP < effectivePolicy.Amount; } return false; } public static int GetMinimumNeededCount(string prefabNameP, int requestedCountP) { EffectivePolicy effectivePolicy = GetEffectivePolicy(prefabNameP); if (effectivePolicy.IsDisabled) { return 0; } if (effectivePolicy.IsUnique) { return 1; } if (effectivePolicy.IsRelaxable) { return Mathf.Max(1, Mathf.CeilToInt((float)requestedCountP * effectivePolicy.Amount)); } return requestedCountP; } public static FailureSeverity GetSeverity(string prefabNameP, bool isPrioritizedP) { EffectivePolicy effectivePolicy = GetEffectivePolicy(prefabNameP); if (effectivePolicy.IsDisabled) { return FailureSeverity.Green; } if (effectivePolicy.IsUnique) { if (isPrioritizedP) { return FailureSeverity.Red; } return FailureSeverity.Yellow; } if (effectivePolicy.IsRelaxable) { if (isPrioritizedP) { return FailureSeverity.Orange; } return FailureSeverity.Yellow; } return FailureSeverity.Green; } } internal sealed class PresenceGrid { private static float _gridExtent; private static int _cellsPerAxis; private static int _arrayLength; private static readonly ConcurrentDictionary _registry = new ConcurrentDictionary(StringComparer.Ordinal); public static readonly PresenceGrid Occupancy = new PresenceGrid(); private volatile long[] _grid; public static float CellSize { get; private set; } = 16f; public static void Initialize(float cellSizeP = 0f) { float val = ModConfig.PresenceGridCellSize.Value; if (cellSizeP > 0f) { val = cellSizeP; } CellSize = Math.Max(4f, val); _gridExtent = ModConfig.WorldRadius; _cellsPerAxis = (int)(_gridExtent * 2f / CellSize); int num = _cellsPerAxis * _cellsPerAxis; _arrayLength = (num + 63) / 64; ClearAll(); } public static PresenceGrid GetOrCreate(string groupP) { return _registry.GetOrAdd(groupP, (string keyP) => new PresenceGrid()); } public bool TrySet(Vector3 worldPosP) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) EnsureAllocated(); WorldToCell(worldPosP, out var cx, out var cz); int num = cz * _cellsPerAxis + cx; int num2 = num >> 6; ulong num3 = (ulong)(1L << (num & 0x3F)); if (num2 >= _arrayLength) { return false; } ulong num4; ulong value; do { num4 = (ulong)Volatile.Read(ref _grid[num2]); if ((num4 & num3) != 0) { return false; } value = num4 | num3; } while (Interlocked.CompareExchange(ref _grid[num2], (long)value, (long)num4) != (long)num4); return true; } public bool HasConflict(Vector3 worldPosP, float radiusP) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) if (_grid == null) { return false; } WorldToCell(worldPosP, out var cx, out var cz); int num = (int)Math.Ceiling(radiusP / CellSize); for (int i = -num; i <= num; i++) { int num2 = cz + i; if (num2 < 0 || num2 >= _cellsPerAxis) { continue; } int num3 = (int)Math.Sqrt(num * num - i * i); int num4 = Math.Max(0, cx - num3); int num5 = Math.Min(_cellsPerAxis - 1, cx + num3); int num6 = num2 * _cellsPerAxis + num4; int num7 = num2 * _cellsPerAxis + num5; int num8 = num6 >> 6; int num9 = num7 >> 6; for (int j = num8; j <= num9; j++) { ulong num10 = (ulong)Volatile.Read(ref _grid[j]); if (num10 != 0) { int loP = 0; if (j == num8) { loP = num6 & 0x3F; } int hiP = 63; if (j == num9) { hiP = num7 & 0x3F; } if ((num10 & RangeMask(loP, hiP)) != 0) { return true; } } } } return false; } public void Commit(Vector3 worldPosP, float radiusP) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) EnsureAllocated(); WorldToCell(worldPosP, out var cx, out var cz); int num = (int)Math.Ceiling(radiusP / CellSize); for (int i = -num; i <= num; i++) { int num2 = cz + i; if (num2 < 0 || num2 >= _cellsPerAxis) { continue; } int num3 = (int)Math.Sqrt(num * num - i * i); int num4 = Math.Max(0, cx - num3); int num5 = Math.Min(_cellsPerAxis - 1, cx + num3); for (int j = num4; j <= num5; j++) { int num6 = num2 * _cellsPerAxis + j; int num7 = num6 >> 6; if (num7 >= _arrayLength) { continue; } ulong num8 = (ulong)(1L << (num6 & 0x3F)); ulong num9; ulong value; do { num9 = (ulong)Volatile.Read(ref _grid[num7]); if ((num9 & num8) != 0) { break; } value = num9 | num8; } while (Interlocked.CompareExchange(ref _grid[num7], (long)value, (long)num9) != (long)num9); } } } public bool HasConflict(Vector3 worldPosP) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) if (_grid == null) { return false; } WorldToCell(worldPosP, out var cx, out var cz); int num = cz * _cellsPerAxis + cx; int num2 = num >> 6; if (num2 >= _arrayLength) { return false; } ulong num3 = (ulong)Volatile.Read(ref _grid[num2]); ulong num4 = (ulong)(1L << num); return (num3 & num4) != 0; } public void Clear() { long[] grid = _grid; if (grid != null) { Array.Clear(grid, 0, grid.Length); } } public static void ClearAll() { foreach (PresenceGrid value in _registry.Values) { value.Clear(); } _registry.Clear(); Occupancy._grid = new long[_arrayLength]; } private void EnsureAllocated() { if (_grid == null) { Interlocked.CompareExchange(ref _grid, new long[_arrayLength], null); } } private static void WorldToCell(Vector3 pP, out int cx, out int cz) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) cx = (int)((pP.x + _gridExtent) / CellSize); cz = (int)((pP.z + _gridExtent) / CellSize); if (cx < 0) { cx = 0; } else if (cx >= _cellsPerAxis) { cx = _cellsPerAxis - 1; } if (cz < 0) { cz = 0; } else if (cz >= _cellsPerAxis) { cz = _cellsPerAxis - 1; } } private static ulong RangeMask(int loP, int hiP) { if (hiP == 63) { return (ulong)(-1L << loP); } return (ulong)((1L << hiP - loP + 1) - 1 << loP); } } public class ProgressOverlay : MonoBehaviour { public static ProgressOverlay instance; private GUIStyle _style; private Font _valheimFont; private readonly string[] _spinner = new string[4] { "|", "/", "-", "\\" }; private bool _pendingDestroy = false; public static void EnsureInstance() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown if ((Object)(object)instance == (Object)null) { GameObject val = new GameObject("LPAProgressOverlay"); Object.DontDestroyOnLoad((Object)(object)val); instance = val.AddComponent(); } } public static void DestroyInstance() { if ((Object)(object)instance != (Object)null) { instance._pendingDestroy = true; instance = null; } } private void Awake() { if ((Object)(object)instance != (Object)null && (Object)(object)instance != (Object)(object)this) { Object.Destroy((Object)(object)((Component)this).gameObject); } else { instance = this; } } private void Start() { Font[] array = Resources.FindObjectsOfTypeAll(); for (int i = 0; i < array.Length; i++) { if (((Object)array[i]).name == "AveriaSerifLibre-Bold") { _valheimFont = array[i]; break; } } } private void OnGUI() { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Invalid comparison between Unknown and I4 //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Expected O, but got Unknown //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0334: Unknown result type (might be due to invalid IL or missing references) if (_pendingDestroy) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } bool isSurveying = GenerationProgress.IsSurveying; bool isGenerating = MinimapParallelizer.IsGenerating; bool flag = !string.IsNullOrEmpty(GenerationProgress.StaticTopText); if (!isGenerating && !isSurveying && !flag) { return; } Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; if ((int)Event.current.type != 7) { return; } if (_style == null) { _style = new GUIStyle(GUI.skin.label) { richText = true, alignment = (TextAnchor)0, font = _valheimFont }; } float realtimeSinceStartup = Time.realtimeSinceStartup; Rect val = default(Rect); ((Rect)(ref val))..ctor((float)(Screen.width - 780), 20f, 760f, (float)(Screen.height - 40)); int num = (int)(realtimeSinceStartup * 8f) % _spinner.Length; if (isGenerating) { float num2 = MinimapParallelizer.Progress * 100f; string text = $"Generating minimap: {num2:0.0}% {_spinner[num]}"; GUI.Label(val, text, _style); } else if (isSurveying) { float num3 = WorldSurveyData.SurveyProgress * 100f; string text2 = $"Surveying the map: {num3:0.0}% {_spinner[num]}"; GUI.Label(val, text2, _style); } else { if (!flag) { return; } int currentProcessed = GenerationProgress.CurrentProcessed; int currentPlaced = GenerationProgress.CurrentPlaced; int totalRequested = GenerationProgress.TotalRequested; float num4 = 0f; if (totalRequested > 0) { num4 = 100f * (float)currentProcessed / (float)totalRequested; } float num5 = 0f; if (currentProcessed > 0) { num5 = 100f * (float)currentPlaced / (float)currentProcessed; } string text3 = $"Attempted placements: {currentProcessed}/{totalRequested} ({num4:0.00}%)\n" + $"Successfully placed: {currentPlaced}/{currentProcessed} ({num5:0.00}%)\n"; string[] threadSlots = GenerationProgress.ThreadSlots; string text5; if (threadSlots != null && threadSlots.Length != 0) { StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < threadSlots.Length; i++) { string text4 = Volatile.Read(ref threadSlots[i]); if (!string.IsNullOrEmpty(text4)) { stringBuilder.AppendLine($"T{i + 1}: {text4} {_spinner[num]}"); } } text5 = stringBuilder.ToString(); } else { string text6 = "Finished"; if (GenerationProgress.CurrentLocation != null) { text6 = GenerationProgress.CurrentLocation.m_prefabName; } text5 = "Current: " + text6 + " " + _spinner[num] + "\n"; } string text7 = GenerationProgress.StaticTopText + text3 + text5 + GenerationProgress.StaticBottomText; GUI.Label(val, text7, _style); } } } public struct RelaxationSnapshot { public bool AnyUnrescued; public List Active; public List Succeeded; public List Exhausted; public Dictionary> AttemptLog; public bool AnyRelaxationOccurred; public FailureSeverity HighestSeverity; } public static class RelaxationTracker { private static HashSet _relaxationFailed = new HashSet(); private static HashSet _relaxationSucceeded = new HashSet(); private static HashSet _relaxationExhausted = new HashSet(); private static Dictionary> _relaxationAttemptLog = new Dictionary>(StringComparer.Ordinal); private static Dictionary _failureSeverities = new Dictionary(StringComparer.Ordinal); private static bool _placementComplete = false; private static readonly object _relaxationLock = new object(); public static int FailedCount => _relaxationFailed.Count; public static void MarkRelaxationAttempt(string prefabNameP, string attemptDescriptionP, bool isPrioritizedP) { lock (_relaxationLock) { _relaxationFailed.Add(prefabNameP); _failureSeverities[prefabNameP] = PlayabilityPolicy.GetSeverity(prefabNameP, isPrioritizedP); if (!_relaxationAttemptLog.TryGetValue(prefabNameP, out var value)) { value = new List(); _relaxationAttemptLog[prefabNameP] = value; } value.Add(attemptDescriptionP); } GenerationProgress.UpdateText(); } public static void MarkRelaxationExhausted(string prefabNameP) { lock (_relaxationLock) { _relaxationFailed.Add(prefabNameP); _relaxationExhausted.Add(prefabNameP); } GenerationProgress.UpdateText(); } public static void MarkRelaxationSucceeded(string prefabNameP) { lock (_relaxationLock) { _relaxationSucceeded.Add(prefabNameP); } GenerationProgress.UpdateText(); } public static bool IsRelaxationSucceeded(string prefabNameP) { lock (_relaxationLock) { return _relaxationSucceeded.Contains(prefabNameP); } } public static void CheckAndMarkFailed(string prefabNameP, int placedP, int requestedP, bool isPrioritizedP) { if (PlayabilityPolicy.NeedsRelaxation(prefabNameP, placedP, requestedP)) { lock (_relaxationLock) { _relaxationFailed.Add(prefabNameP); _failureSeverities[prefabNameP] = PlayabilityPolicy.GetSeverity(prefabNameP, isPrioritizedP); } GenerationProgress.UpdateText(); } } public static void MarkPlacementComplete() { _placementComplete = true; GenerationProgress.UpdateText(); } public static RelaxationSnapshot GetSnapshot() { lock (_relaxationLock) { bool anyUnrescued = false; FailureSeverity failureSeverity = FailureSeverity.Green; foreach (string item in _relaxationFailed) { if (!_relaxationSucceeded.Contains(item)) { anyUnrescued = true; if (_failureSeverities.TryGetValue(item, out var value) && value > failureSeverity) { failureSeverity = value; } } } List list = new List(); if (!_placementComplete) { foreach (string item2 in _relaxationFailed) { if (!_relaxationSucceeded.Contains(item2) && !_relaxationExhausted.Contains(item2)) { list.Add(item2); } } } List succeeded = new List(_relaxationSucceeded); List exhausted = new List(_relaxationExhausted); RelaxationSnapshot result = default(RelaxationSnapshot); result.AnyUnrescued = anyUnrescued; result.Active = list; result.Succeeded = succeeded; result.Exhausted = exhausted; result.AttemptLog = new Dictionary>(_relaxationAttemptLog, StringComparer.Ordinal); result.AnyRelaxationOccurred = _relaxationFailed.Count > 0; result.HighestSeverity = failureSeverity; return result; } } public static void Reset() { lock (_relaxationLock) { _relaxationFailed.Clear(); _relaxationSucceeded.Clear(); _relaxationExhausted.Clear(); _relaxationAttemptLog.Clear(); _failureSeverities.Clear(); _placementComplete = false; } } } public static class ReplacedEnginePatches { private static volatile bool _firstCallDone; private static volatile bool _v2Started; public static bool OuterLoopV2Prefix() { if (!_firstCallDone) { _firstCallDone = true; return true; } if (!_v2Started) { _v2Started = true; if ((Object)(object)ZoneSystem.instance != (Object)null) { ((MonoBehaviour)ZoneSystem.instance).StartCoroutine(PlacementEngine.Run(ZoneSystem.instance)); } } return false; } public static void Reset() { _firstCallDone = false; _v2Started = false; } } public class ReportData { public ZoneLocation Loc; public object Instance; public int InstanceHash; public string PrefabName; public long CurrentOuter; public long LimitOuter; public int Placed; public int OriginalQuantity; public bool IsComplete; public long ErrZone; public long ErrArea; public long ValidZones; public long InDist; public long InBiome; public long InAlt; public long InForest; public long InTerr; public long InSim; public long InVeg; public long ErrDist; public long ErrBiome; public long ErrAlt; public long ErrForest; public long ErrTerrain; public long ErrSim; public long ErrNotSim; public long ErrVeg; public void Merge(ReportData otherP) { if (otherP != null) { CurrentOuter += otherP.CurrentOuter; LimitOuter += otherP.LimitOuter; ErrZone += otherP.ErrZone; ErrArea += otherP.ErrArea; ValidZones += otherP.ValidZones; InDist += otherP.InDist; InBiome += otherP.InBiome; InAlt += otherP.InAlt; InForest += otherP.InForest; InTerr += otherP.InTerr; InSim += otherP.InSim; InVeg += otherP.InVeg; ErrDist += otherP.ErrDist; ErrBiome += otherP.ErrBiome; ErrAlt += otherP.ErrAlt; ErrForest += otherP.ErrForest; ErrTerrain += otherP.ErrTerrain; ErrSim += otherP.ErrSim; ErrNotSim += otherP.ErrNotSim; ErrVeg += otherP.ErrVeg; } } } public static class ReportFormatter { private class FunnelStep { public string Name; public string ConfigInfo; public string PassedContext; public long Input; public long Failures; public Action FailurePrinter; public long Passed => Input - Failures; } private struct FailureEntry { public string Name; public long Count; public Action DetailsPrinter; public FailureEntry(string nameP, long countP, Action detailsPrinterP) { Name = nameP; Count = countP; DetailsPrinter = detailsPrinterP; } } public static void WriteReport(ReportData dataP, bool isHeartbeatP, string prefabNameP = null, HeartbeatType heartbeatTypeP = HeartbeatType.Inner) { if (dataP != null) { string prefabNameP2 = prefabNameP ?? dataP.Loc.m_prefabName; if (isHeartbeatP) { LogHeartbeat(dataP, prefabNameP2, heartbeatTypeP); } else { LogFullReport(dataP, prefabNameP2); } } } private static void LogHeartbeat(ReportData dataP, string prefabNameP, HeartbeatType typeP) { if (!TranspiledCompletionHandler.AggregateSessions.TryGetValue(prefabNameP, out var value)) { return; } StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine(); string text = ((typeP == HeartbeatType.Outer) ? "[PROGRESS-OUTER]" : "[PROGRESS-INNER]"); stringBuilder.AppendLine($"{text} {prefabNameP}: {dataP.Placed}/{dataP.OriginalQuantity}. Cost: {dataP.CurrentOuter:N0}/{dataP.LimitOuter:N0}"); if (TelemetryHelpers.GlobalMaxAltitudeSeen > float.MinValue) { stringBuilder.AppendLine($" (World Altitude Profile: Min {TelemetryHelpers.GlobalMinAltitudeSeen:F1}m, Max {TelemetryHelpers.GlobalMaxAltitudeSeen:F1}m)"); } if (dataP.ErrZone > 0 || dataP.ErrArea > 0) { stringBuilder.AppendLine(" PHASE 1 FAILURES (Zone Search):"); if (dataP.ErrZone > 0) { stringBuilder.AppendLine($" - Zone Occupied : {dataP.ErrZone,12:N0}"); } if (dataP.ErrArea > 0) { stringBuilder.AppendLine($" - Wrong Biome Area : {dataP.ErrArea,12:N0}"); PrintDict(stringBuilder, " └─ ", value.BiomeAreaFailures); } } stringBuilder.AppendLine(" PHASE 2 FAILURES (Placement Filters):"); List list = new List(); if (dataP.ErrDist > 0) { list.Add(new FailureEntry("Distance Filter", dataP.ErrDist, delegate(StringBuilder sP, string padP, TelemetryContext ctxP) { PrintDist(sP, padP, ctxP); })); } if (dataP.ErrBiome > 0) { list.Add(new FailureEntry("Wrong Biome Type", dataP.ErrBiome, delegate(StringBuilder sP, string padP, TelemetryContext ctxP) { PrintDict(sP, padP, ctxP.BiomeFailures); })); } if (dataP.ErrAlt > 0) { list.Add(new FailureEntry("Wrong Altitude", dataP.ErrAlt, delegate(StringBuilder sP, string padP, TelemetryContext ctxP) { PrintAlt(sP, " ", ctxP); })); } if (dataP.ErrForest > 0) { list.Add(new FailureEntry("Forest Check", dataP.ErrForest, null)); } if (dataP.ErrTerrain > 0) { list.Add(new FailureEntry("Terrain Check", dataP.ErrTerrain, null)); } if (dataP.ErrSim + dataP.ErrNotSim > 0) { list.Add(new FailureEntry("Similarity Check", dataP.ErrSim + dataP.ErrNotSim, null)); } if (dataP.ErrVeg > 0) { list.Add(new FailureEntry("Vegetation Density", dataP.ErrVeg, null)); } list.Sort((FailureEntry aP, FailureEntry bP) => bP.Count.CompareTo(aP.Count)); int num = Math.Min(5, list.Count); for (int i = 0; i < num; i++) { FailureEntry failureEntry = list[i]; stringBuilder.AppendLine($" - {failureEntry.Name.PadRight(25)}: {failureEntry.Count,12:N0}"); failureEntry.DetailsPrinter?.Invoke(stringBuilder, " └─ ", value); } if (typeP == HeartbeatType.Outer) { stringBuilder.AppendLine("─────────────────────────────────────────────────────────"); } DiagnosticLog.WriteTimestampedLog(stringBuilder.ToString().TrimEnd(Array.Empty()), (LogLevel)16); } private static void LogFullReport(ReportData dataP, string prefabNameP) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_02e8: Unknown result type (might be due to invalid IL or missing references) //IL_0448: Unknown result type (might be due to invalid IL or missing references) //IL_046d: Unknown result type (might be due to invalid IL or missing references) //IL_0ba0: Unknown result type (might be due to invalid IL or missing references) if (!TranspiledCompletionHandler.AggregateSessions.TryGetValue(prefabNameP, out var value)) { value = new TelemetryContext(); } StringBuilder stringBuilder = new StringBuilder(); string text; LogLevel levelP; if (dataP.IsComplete) { text = "COMPLETE"; levelP = (LogLevel)16; } else { int value2; bool flag = ConstraintRelaxer.RelaxationAttempts.TryGetValue(prefabNameP, out value2) && value2 > 0; int minimumNeededCount = PlayabilityPolicy.GetMinimumNeededCount(prefabNameP, dataP.OriginalQuantity); if (flag && dataP.Placed >= minimumNeededCount) { text = "RELAXED"; levelP = (LogLevel)8; } else { text = "FAILURE"; levelP = (LogLevel)4; } } stringBuilder.AppendLine($"[{text}] {prefabNameP}: {dataP.Placed}/{dataP.OriginalQuantity}. Cost: {dataP.CurrentOuter:N0}/{dataP.LimitOuter:N0} outer loop budget and {dataP.InDist:N0} inner loop iterations."); string relaxationSummary = ConstraintRelaxer.GetRelaxationSummary(prefabNameP, dataP.Loc); if (!string.IsNullOrEmpty(relaxationSummary)) { stringBuilder.AppendLine(" " + relaxationSummary); } if (TelemetryHelpers.GlobalMaxAltitudeSeen > float.MinValue) { stringBuilder.AppendLine($"(World Altitude Profile: Min {TelemetryHelpers.GlobalMinAltitudeSeen:F1}m, Max {TelemetryHelpers.GlobalMaxAltitudeSeen:F1}m)"); } stringBuilder.AppendLine("────────────────────────────────────────────────────────"); stringBuilder.AppendLine($"PHASE 1 (Zone Search): {dataP.CurrentOuter:N0} Checks"); if (dataP.ErrZone > 0) { stringBuilder.AppendLine($"[x] Occupied Zones: {dataP.ErrZone:N0}"); } if (dataP.ErrArea > 0) { stringBuilder.AppendLine($"[x] Wrong Biome Area: {dataP.ErrArea:N0}"); PrintDict(stringBuilder, " └─ ", value.BiomeAreaFailures); } string text2 = ((object)(BiomeArea)(ref dataP.Loc.m_biomeArea)).ToString(); stringBuilder.AppendLine($"[!] Valid Zones: {dataP.ValidZones:N0}"); stringBuilder.AppendLine(" └─ " + text2); if (dataP.ValidZones <= 0 || dataP.InDist <= 0) { stringBuilder.AppendLine("────────────────────────────────────────────────────────"); DiagnosticLog.WriteTimestampedLog(stringBuilder.ToString(), levelP); return; } stringBuilder.AppendLine(); stringBuilder.AppendLine($"PHASE 2 (Placement): {dataP.InDist:N0} Points Sampled in the {dataP.ValidZones:N0} {text2} zones"); List list = new List(); float num = ModConfig.WorldRadius; if (dataP.Loc.m_maxDistance > 0.1f) { num = dataP.Loc.m_maxDistance; } list.Add(new FunnelStep { Name = "DISTANCE FILTER", ConfigInfo = $"(Min: {dataP.Loc.m_minDistance:F0}, Max: {num:F0})", PassedContext = $"Range {dataP.Loc.m_minDistance:F0}-{num:F0}", Input = dataP.InDist, Failures = dataP.ErrDist, FailurePrinter = delegate(StringBuilder sP, string indentP, TelemetryContext ctxP) { PrintDist(sP, indentP, ctxP); } }); list.Add(new FunnelStep { Name = "BIOME MATCH", ConfigInfo = $"(Required: {dataP.Loc.m_biome})", PassedContext = $"{dataP.Loc.m_biome}", Input = dataP.InBiome, Failures = dataP.ErrBiome, FailurePrinter = delegate(StringBuilder sP, string indentP, TelemetryContext ctxP) { PrintDict(sP, indentP + " └─ ", ctxP.BiomeFailures); } }); FunnelStep item = new FunnelStep { Name = "ALTITUDE CHECK", ConfigInfo = $"(Min: {dataP.Loc.m_minAltitude:F0}, Max: {dataP.Loc.m_maxAltitude:F0})", PassedContext = $"Alt {dataP.Loc.m_minAltitude:F0} to {dataP.Loc.m_maxAltitude:F0}", Input = dataP.InAlt, Failures = dataP.ErrAlt, FailurePrinter = delegate(StringBuilder sP, string indentP, TelemetryContext ctxP) { PrintAlt(sP, indentP + " ", ctxP); } }; FunnelStep item2 = new FunnelStep { Name = "TERRAIN DELTA", ConfigInfo = $"(Min: {dataP.Loc.m_minTerrainDelta:F1}, Max: {dataP.Loc.m_maxTerrainDelta:F1})", PassedContext = $"Delta {dataP.Loc.m_minTerrainDelta:F1} to {dataP.Loc.m_maxTerrainDelta:F1}", Input = dataP.InTerr, Failures = dataP.ErrTerrain, FailurePrinter = delegate(StringBuilder sP, string indentP, TelemetryContext ctxP) { sP.AppendLine($"{indentP} └─ Slope/Flatness mismatch: {dataP.ErrTerrain:N0}"); } }; string text3 = (string.IsNullOrEmpty(dataP.Loc.m_group) ? "Default" : dataP.Loc.m_group); FunnelStep item3 = new FunnelStep { Name = "SIMILARITY CHECK", ConfigInfo = "(Group: " + text3 + ")", PassedContext = "Proximity Clear", Input = dataP.InSim, Failures = dataP.ErrSim + dataP.ErrNotSim, FailurePrinter = delegate(StringBuilder sP, string indentP, TelemetryContext ctxP) { if (dataP.ErrSim > 0) { sP.AppendLine($"{indentP} └─ Too Close: {dataP.ErrSim:N0}"); } if (dataP.ErrNotSim > 0) { sP.AppendLine($"{indentP} └─ Too Far: {dataP.ErrNotSim:N0}"); } } }; FunnelStep funnelStep = null; if (dataP.Loc.m_inForest) { funnelStep = new FunnelStep { Name = "FOREST FACTOR", ConfigInfo = $"(Min: {dataP.Loc.m_forestTresholdMin:F2}, Max: {dataP.Loc.m_forestTresholdMax:F2})", PassedContext = $"Forest {dataP.Loc.m_forestTresholdMin:F2}-{dataP.Loc.m_forestTresholdMax:F2}", Input = dataP.InForest, Failures = dataP.ErrForest }; } list.Add(item); if (funnelStep != null) { list.Add(funnelStep); } list.Add(item3); list.Add(item2); list.Add(new FunnelStep { Name = "VEGETATION DENSITY", ConfigInfo = $"(Min: {dataP.Loc.m_minimumVegetation:F2}, Max: {dataP.Loc.m_maximumVegetation:F2})", PassedContext = "Density Match", Input = dataP.InVeg, Failures = dataP.ErrVeg }); string text4 = ""; for (int i = 0; i < list.Count; i++) { FunnelStep funnelStep2 = list[i]; if (i > 0 && list[i - 1].Passed == 0) { break; } bool flag2 = true; for (int j = i; j < list.Count; j++) { if (list[j].Failures != 0) { flag2 = false; break; } } if (flag2) { StringBuilder stringBuilder2 = new StringBuilder(); for (int k = i; k < list.Count; k++) { if (k > i) { stringBuilder2.Append(" -> "); } stringBuilder2.Append(list[k].Name.Replace(" CHECK", "").Replace(" FILTER", "").Replace(" MATCH", "")); } stringBuilder.AppendLine($"{text4}└─ PASSED REMAINING CHECKS ({stringBuilder2}): {funnelStep2.Passed:N0}"); break; } if (i == 0) { stringBuilder.AppendLine("1. " + funnelStep2.Name + " " + funnelStep2.ConfigInfo); } else { stringBuilder.AppendLine($"{text4}└─ {i + 1}. {funnelStep2.Name} {funnelStep2.ConfigInfo}: {funnelStep2.Input:N0} points checked"); } string text5 = ((i == 0) ? "" : (text4 + " ")); if (funnelStep2.Failures > 0) { stringBuilder.AppendLine($"{text5}[x] Failed: {funnelStep2.Failures:N0}"); funnelStep2.FailurePrinter?.Invoke(stringBuilder, text5, value); } if (funnelStep2.Passed <= 0) { continue; } stringBuilder.AppendLine($"{text5}[!] Passed: {funnelStep2.Passed:N0}"); stringBuilder.AppendLine(text5 + " └─ " + funnelStep2.PassedContext); text4 += " "; bool flag3 = i == list.Count - 1; bool flag4 = false; if (!flag3) { flag4 = true; for (int l = i + 1; l < list.Count; l++) { if (list[l].Failures != 0) { flag4 = false; break; } } } if (!flag3 && !flag4) { stringBuilder.AppendLine(text4 + "|"); } } stringBuilder.AppendLine("────────────────────────────────────────────────────────"); DiagnosticLog.WriteTimestampedLog(stringBuilder.ToString(), levelP); } private static void PrintDict(StringBuilder sbP, string prefixP, Dictionary dictP) { if (dictP != null) { List> list = new List>(dictP); list.Sort((KeyValuePair aP, KeyValuePair bP) => bP.Value.CompareTo(aP.Value)); int num = Math.Min(5, list.Count); for (int i = 0; i < num; i++) { sbP.AppendLine($"{prefixP}{list[i].Key}: {list[i].Value:N0}"); } } } private static void PrintDist(StringBuilder sbP, string prefixP, TelemetryContext contextP) { if (contextP.DistanceTooClose > 0) { sbP.AppendLine($"{prefixP}Below Min: {contextP.DistanceTooClose:N0}"); } if (contextP.DistanceTooFar > 0) { sbP.AppendLine($"{prefixP}Above Max: {contextP.DistanceTooFar:N0}"); } } private static void PrintAlt(StringBuilder sbP, string prefixP, TelemetryContext contextP) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_0497: Unknown result type (might be due to invalid IL or missing references) //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_0328: Unknown result type (might be due to invalid IL or missing references) //IL_04cc: Unknown result type (might be due to invalid IL or missing references) //IL_038c: Unknown result type (might be due to invalid IL or missing references) HashSet hashSet = new HashSet(); foreach (Biome key in contextP.AltLowStats_Standard.Keys) { hashSet.Add(key); } foreach (Biome key2 in contextP.AltLowStats_Anomalous.Keys) { hashSet.Add(key2); } foreach (Biome key3 in contextP.AltLowStats_Underwater.Keys) { hashSet.Add(key3); } foreach (Biome key4 in contextP.AltHighStats.Keys) { hashSet.Add(key4); } long num = 0L; foreach (long value5 in contextP.AltitudeTooLow_Standard.Values) { num += value5; } foreach (long value6 in contextP.AltitudeTooLow_Anomalous.Values) { num += value6; } foreach (long value7 in contextP.AltitudeTooLow_Underwater.Values) { num += value7; } if (num > 0) { sbP.AppendLine($"{prefixP}└─ Too Low: {num:N0}"); List list = new List(hashSet); list.Sort((Biome aP, Biome bP) => string.Compare(((object)(Biome)(ref aP)).ToString(), ((object)(Biome)(ref bP)).ToString(), StringComparison.Ordinal)); foreach (Biome item in list) { long value; bool flag = contextP.AltitudeTooLow_Underwater.TryGetValue(item, out value); long value2; bool flag2 = contextP.AltitudeTooLow_Anomalous.TryGetValue(item, out value2); long value3; bool flag3 = contextP.AltitudeTooLow_Standard.TryGetValue(item, out value3); if (flag || flag2 || flag3) { sbP.AppendLine($"{prefixP} └─ {item}:"); if (flag) { string @string = contextP.AltLowStats_Underwater[item].GetString(); string text = ((flag2 || flag3) ? "├─" : "└─"); sbP.AppendLine($"{prefixP} {text} Underwater (<0m): {value:N0} {@string}"); } if (flag2) { string string2 = contextP.AltLowStats_Anomalous[item].GetString(); float anomalyFloor = TelemetryHelpers.GetAnomalyFloor(item); string text2 = (flag3 ? "├─" : "└─"); sbP.AppendLine($"{prefixP} {text2} Anomalous (0m to {anomalyFloor:F0}m): {value2:N0} {string2}"); } if (flag3) { string string3 = contextP.AltLowStats_Standard[item].GetString(); sbP.AppendLine($"{prefixP} └─ Standard Failures: {value3:N0} {string3}"); } } } } long num2 = 0L; foreach (long value8 in contextP.AltitudeTooHigh.Values) { num2 += value8; } if (num2 <= 0) { return; } sbP.AppendLine($"{prefixP}└─ Too High: {num2:N0}"); List> list2 = new List>(contextP.AltitudeTooHigh); list2.Sort((KeyValuePair aP, KeyValuePair bP) => bP.Value.CompareTo(aP.Value)); foreach (KeyValuePair item2 in list2) { string text3 = ""; if (contextP.AltHighStats.TryGetValue(item2.Key, out var value4)) { text3 = value4.GetString(); } sbP.AppendLine($"{prefixP} └─ {item2.Key}: {item2.Value:N0} {text3}"); } } } internal enum PartitionMode : byte { Single, BitShift, Modulo } internal struct PartitionRule { public PartitionMode Mode; public int PartitionCount; public int BlockSize; public int BlockSizeLog2; public int ColorsPerAxis; public int ColorBits; public int ColorMask; } internal static class SpatialPartitionAlgorithms { private struct ZoneAngle { public Vector2i Zone; public float Angle; } private struct AngularGap { public int AfterIndex; public float GapSize; } public static PartitionRule BuildRule(float minDistP, int maxPartitionsP) { PartitionRule result; if (minDistP <= 0f || maxPartitionsP <= 1) { result = default(PartitionRule); result.Mode = PartitionMode.Single; result.PartitionCount = 1; return result; } int num = (int)Math.Sqrt(maxPartitionsP); if (num < 2) { num = 2; } int num2 = (int)Math.Ceiling((double)minDistP / (64.0 * (double)(num - 1))); if (num2 < 1) { num2 = 1; } bool flag = (num & (num - 1)) == 0; bool flag2 = (num2 & (num2 - 1)) == 0; if (flag && flag2) { int colorBits = FindExponent(num); result = default(PartitionRule); result.Mode = PartitionMode.BitShift; result.PartitionCount = num * num; result.BlockSize = num2; result.BlockSizeLog2 = FindExponent(num2); result.ColorsPerAxis = num; result.ColorBits = colorBits; result.ColorMask = num - 1; return result; } result = default(PartitionRule); result.Mode = PartitionMode.Modulo; result.PartitionCount = num * num; result.BlockSize = num2; result.ColorsPerAxis = num; return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int FindExponent(int valueP) { int num = 0; while (valueP > 1) { valueP >>= 1; num++; } return num; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int GetPartition(Vector2i zoneP, ref PartitionRule ruleP) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) switch (ruleP.Mode) { case PartitionMode.BitShift: { int num3 = (zoneP.x >> ruleP.BlockSizeLog2) & ruleP.ColorMask; int num4 = (zoneP.y >> ruleP.BlockSizeLog2) & ruleP.ColorMask; return num3 | (num4 << ruleP.ColorBits); } case PartitionMode.Modulo: { int num = FloorMod(FloorDiv(zoneP.x, ruleP.BlockSize), ruleP.ColorsPerAxis); int num2 = FloorMod(FloorDiv(zoneP.y, ruleP.BlockSize), ruleP.ColorsPerAxis); return num * ruleP.ColorsPerAxis + num2; } default: return 0; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int FloorDiv(int dividendP, int divisorP) { int num = dividendP / divisorP; int num2 = dividendP % divisorP; bool flag = num2 != 0; bool flag2 = (dividendP ^ divisorP) < 0; if (flag && flag2) { return num - 1; } return num; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int FloorMod(int dividendP, int divisorP) { int num = dividendP % divisorP; if (num < 0) { return num + divisorP; } return num; } private static int CompareByAngle(ZoneAngle aP, ZoneAngle bP) { if (aP.Angle < bP.Angle) { return -1; } if (aP.Angle > bP.Angle) { return 1; } return 0; } private static int CompareByGapSizeDescending(AngularGap aP, AngularGap bP) { if (bP.GapSize < aP.GapSize) { return -1; } if (bP.GapSize > aP.GapSize) { return 1; } return 0; } } public static class SurveyMode { private static BucketingStrategy _activeStrategy; private static bool _initialized = false; public static bool SurveyExhausted = false; public static int CurrentActiveZoneIndex = -1; public static bool GetZone(ZoneLocation locationP, out Vector2i result) { return _activeStrategy.GetZone(locationP, out result); } public static List GetOrBuildCandidateList(ZoneLocation locationP) { return _activeStrategy.GetOrBuildCandidateList(locationP); } public static void Initialize() { if (!_initialized) { _activeStrategy = new LocationTypeBucketingStrategy(); _activeStrategy.Initialize(); _initialized = true; } } public static void DumpDiagnostics() { _activeStrategy?.DumpDiagnostics(); } public static void ClearCache(string prefabNameP) { _activeStrategy?.ClearCache(prefabNameP); SurveyExhausted = false; } public static void Reset() { _activeStrategy = null; _initialized = false; SurveyExhausted = false; CurrentActiveZoneIndex = -1; } public static void NotifyZonePlaced() { if (_initialized && CurrentActiveZoneIndex >= 0) { _activeStrategy.MarkZoneOccupied(CurrentActiveZoneIndex); } } public static void MarkZoneOccupied(int zoneIndexP) { if (_initialized && _activeStrategy != null) { _activeStrategy.MarkZoneOccupied(zoneIndexP); } } } public class TelemetryContext { public Dictionary BiomeFailures { get; } = new Dictionary(); public Dictionary BiomeAreaFailures { get; } = new Dictionary(); public Dictionary AltitudeTooHigh { get; } = new Dictionary(); public Dictionary AltitudeTooLow_Standard { get; } = new Dictionary(); public Dictionary AltitudeTooLow_Anomalous { get; } = new Dictionary(); public Dictionary AltitudeTooLow_Underwater { get; } = new Dictionary(); public Dictionary AltHighStats { get; } = new Dictionary(); public Dictionary AltLowStats_Standard { get; } = new Dictionary(); public Dictionary AltLowStats_Anomalous { get; } = new Dictionary(); public Dictionary AltLowStats_Underwater { get; } = new Dictionary(); public long DistanceTooClose { get; set; } = 0L; public long DistanceTooFar { get; set; } = 0L; public Dictionary ShadowCounters { get; } = new Dictionary(); public void Merge(TelemetryContext otherP) { if (otherP != null) { MergeDict(BiomeFailures, otherP.BiomeFailures); MergeDict(BiomeAreaFailures, otherP.BiomeAreaFailures); MergeDict(AltitudeTooHigh, otherP.AltitudeTooHigh); MergeDict(AltitudeTooLow_Standard, otherP.AltitudeTooLow_Standard); MergeDict(AltitudeTooLow_Anomalous, otherP.AltitudeTooLow_Anomalous); MergeDict(AltitudeTooLow_Underwater, otherP.AltitudeTooLow_Underwater); MergeStats(AltHighStats, otherP.AltHighStats); MergeStats(AltLowStats_Standard, otherP.AltLowStats_Standard); MergeStats(AltLowStats_Anomalous, otherP.AltLowStats_Anomalous); MergeStats(AltLowStats_Underwater, otherP.AltLowStats_Underwater); DistanceTooClose += otherP.DistanceTooClose; DistanceTooFar += otherP.DistanceTooFar; MergeDict(ShadowCounters, otherP.ShadowCounters); } } private void MergeDict(Dictionary targetP, Dictionary sourceP) { foreach (KeyValuePair item in sourceP) { if (targetP.TryGetValue(item.Key, out var value)) { targetP[item.Key] = value + item.Value; } else { targetP[item.Key] = item.Value; } } } private void MergeStats(Dictionary targetP, Dictionary sourceP) { foreach (KeyValuePair item in sourceP) { if (!targetP.TryGetValue(item.Key, out var value)) { value = new AltitudeStat(); targetP[item.Key] = value; } AltitudeStat value2 = item.Value; if (value2.Min < value.Min) { value.Min = value2.Min; } if (value2.Max > value.Max) { value.Max = value2.Max; } value.Sum += value2.Sum; value.Count += value2.Count; } } } public static class TelemetryHelpers { public static int FilterTotalCalls = 0; public static int FilterAcceptedZones = 0; public static float GlobalMinAltitudeSeen = float.MaxValue; public static float GlobalMaxAltitudeSeen = float.MinValue; private static long _totalInnerIterations = 0L; private static long _lastInnerLogValue = 0L; public static void TrackGlobalAltitude(float altitudeP) { if (altitudeP < GlobalMinAltitudeSeen) { GlobalMinAltitudeSeen = altitudeP; } if (altitudeP > GlobalMaxAltitudeSeen) { GlobalMaxAltitudeSeen = altitudeP; } } public static void TrackGlobalAltitude(float altitudeP, Vector3 pointP) { if (altitudeP < GlobalMinAltitudeSeen) { GlobalMinAltitudeSeen = altitudeP; } if (altitudeP > GlobalMaxAltitudeSeen) { GlobalMaxAltitudeSeen = altitudeP; } } public static void TrackAltitudeFailure(object instanceP, float heightP, float minAltP, float maxAltP, Vector3 pointP) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) if (!DiagnosticLog.MinimalLogging) { TelemetryContext context = TranspiledCompletionHandler.GetContext(instanceP.GetHashCode()); if (context != null) { Biome biome = WorldGenerator.instance.GetBiome(pointP); RecordAltitudeFailure(context, biome, heightP, minAltP, maxAltP); } } } public static void TrackDistanceFailure(object instanceP, float distanceP, float minDistP, float maxDistP) { if (DiagnosticLog.MinimalLogging) { return; } TelemetryContext context = TranspiledCompletionHandler.GetContext(instanceP.GetHashCode()); if (context != null) { if (maxDistP != 0f && distanceP > maxDistP) { context.DistanceTooFar++; } else if (distanceP < minDistP) { context.DistanceTooClose++; } } } public static void TrackAltitudeFailureCtx(TelemetryContext ctxP, float heightP, float minAltP, float maxAltP, Vector3 pointP) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (!DiagnosticLog.MinimalLogging && ctxP != null) { Biome biome = WorldGenerator.instance.GetBiome(pointP); RecordAltitudeFailure(ctxP, biome, heightP, minAltP, maxAltP); } } public static void TrackDistanceFailureCtx(TelemetryContext ctxP, float distanceP, float minDistP, float maxDistP) { if (!DiagnosticLog.MinimalLogging && ctxP != null) { if (maxDistP != 0f && distanceP > maxDistP) { ctxP.DistanceTooFar++; } else if (distanceP < minDistP) { ctxP.DistanceTooClose++; } } } public static void CaptureWrongBiomeCtx(TelemetryContext ctxP, Biome biomeP) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) if (!DiagnosticLog.MinimalLogging && ctxP != null) { ctxP.BiomeFailures.TryGetValue(biomeP, out var value); ctxP.BiomeFailures[biomeP] = value + 1; } } public static void CaptureWrongBiome(Vector3 point, Biome __result) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Invalid comparison between Unknown and I4 //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) if (DiagnosticLog.MinimalLogging) { return; } int currentInstanceHash = TranspiledCompletionHandler.CurrentInstanceHash; if (currentInstanceHash != 0 && GenerationProgress.CurrentLocation != null && (GenerationProgress.CurrentLocation.m_biome & __result) <= 0) { TelemetryContext context = TranspiledCompletionHandler.GetContext(currentInstanceHash); if (context != null) { context.BiomeFailures.TryGetValue(__result, out var value); context.BiomeFailures[__result] = value + 1; } } } public static void CaptureWrongBiomeArea(Vector3 point, BiomeArea __result) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Invalid comparison between Unknown and I4 //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) if (DiagnosticLog.MinimalLogging) { return; } int currentInstanceHash = TranspiledCompletionHandler.CurrentInstanceHash; if (currentInstanceHash != 0 && GenerationProgress.CurrentLocation != null && (GenerationProgress.CurrentLocation.m_biomeArea & __result) <= 0) { TelemetryContext context = TranspiledCompletionHandler.GetContext(currentInstanceHash); if (context != null) { context.BiomeAreaFailures.TryGetValue(__result, out var value); context.BiomeAreaFailures[__result] = value + 1; } } } public static void IncrementShadow(object instanceP, string fieldNameP) { if (!DiagnosticLog.MinimalLogging) { TelemetryContext context = TranspiledCompletionHandler.GetContext(instanceP.GetHashCode()); if (context != null) { context.ShadowCounters.TryGetValue(fieldNameP, out var value); context.ShadowCounters[fieldNameP] = value + 1; } } } public static void ResetInnerLoopCounter() { _totalInnerIterations = 0L; _lastInnerLogValue = 0L; } public static void LogInnerLoopProgress(object instanceP) { if (ModConfig.DiagnosticMode.Value) { _totalInnerIterations++; int value = ModConfig.InnerProgressInterval.Value; if (value > 0 && _totalInnerIterations >= _lastInnerLogValue + value) { _lastInnerLogValue = _totalInnerIterations; ReportData reportData = TranspiledStateExtractor.Analyze(instanceP); } } } public static void LogProgress(object instanceP) { if (!ModConfig.DiagnosticMode.Value) { return; } int value = ModConfig.ProgressInterval.Value; if (value <= 0) { return; } Type type = instanceP.GetType(); if (TranspiledEngineFieldCache.CounterFields.TryGetValue(type, out var value2)) { long num = Convert.ToInt64(value2.GetValue(instanceP)); if (num >= value && num % value == 0) { ReportData reportData = TranspiledStateExtractor.Analyze(instanceP); } } } public static void LogLocationStart(ZoneLocation locationP, PlacementMode modeP) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Invalid comparison between Unknown and I4 //IL_003e: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("[START] Placing [" + locationP.m_prefabName + "]"); List list = new List(); if ((int)locationP.m_biome > 0) { list.Add($"{locationP.m_biome}"); } float num = ModConfig.WorldRadius; if (locationP.m_maxDistance > 0.1f) { num = locationP.m_maxDistance; } if (locationP.m_minDistance > 0f || num < ModConfig.WorldRadius) { list.Add($"Distance: {locationP.m_minDistance:F0}-{num:F0}m"); } if (locationP.m_minAltitude > -1000f || locationP.m_maxAltitude < 10000f) { list.Add($"Altitude: {locationP.m_minAltitude:F0}-{locationP.m_maxAltitude:F0}m"); } if (locationP.m_minTerrainDelta > 0f || locationP.m_maxTerrainDelta < 100f) { list.Add($"Terrain: {locationP.m_minTerrainDelta:F1}-{locationP.m_maxTerrainDelta:F1}"); } if (locationP.m_inForest) { list.Add($"Forest: {locationP.m_forestTresholdMin:F2}-{locationP.m_forestTresholdMax:F2}"); } if (list.Count > 0) { stringBuilder.AppendLine(" Requires: " + string.Join(" | ", list)); } if (GlobalMaxAltitudeSeen > float.MinValue) { stringBuilder.AppendLine($" World Altitude: Min {GlobalMinAltitudeSeen:F1}m, Max {GlobalMaxAltitudeSeen:F1}m"); } stringBuilder.AppendLine("*****************************************"); DiagnosticLog.WriteTimestampedLog(stringBuilder.ToString().TrimEnd(Array.Empty()), (LogLevel)16); } public static float GetAnomalyFloor(Biome biomeP) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Invalid comparison between Unknown and I4 //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Invalid comparison between Unknown and I4 if ((int)biomeP <= 4) { if (biomeP - 1 <= 1) { goto IL_002c; } if ((int)biomeP == 4) { return 50f; } } else if ((int)biomeP == 8 || (int)biomeP == 16) { goto IL_002c; } return -10000f; IL_002c: return 1f; } private static void RecordAltitudeFailure(TelemetryContext ctxP, Biome biomeP, float heightP, float minAltP, float maxAltP) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_0164: 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_0185: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: 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) if (heightP > maxAltP) { ctxP.AltitudeTooHigh.TryGetValue(biomeP, out var value); ctxP.AltitudeTooHigh[biomeP] = value + 1; if (!ctxP.AltHighStats.TryGetValue(biomeP, out var value2)) { value2 = new AltitudeStat(); ctxP.AltHighStats[biomeP] = value2; } value2.Add(heightP); } else { if (!(heightP < minAltP)) { return; } if (heightP < 0f) { ctxP.AltitudeTooLow_Underwater.TryGetValue(biomeP, out var value3); ctxP.AltitudeTooLow_Underwater[biomeP] = value3 + 1; if (!ctxP.AltLowStats_Underwater.TryGetValue(biomeP, out var value4)) { value4 = new AltitudeStat(); ctxP.AltLowStats_Underwater[biomeP] = value4; } value4.Add(heightP); return; } float anomalyFloor = GetAnomalyFloor(biomeP); if (heightP < anomalyFloor) { ctxP.AltitudeTooLow_Anomalous.TryGetValue(biomeP, out var value5); ctxP.AltitudeTooLow_Anomalous[biomeP] = value5 + 1; if (!ctxP.AltLowStats_Anomalous.TryGetValue(biomeP, out var value6)) { value6 = new AltitudeStat(); ctxP.AltLowStats_Anomalous[biomeP] = value6; } value6.Add(heightP); } else { ctxP.AltitudeTooLow_Standard.TryGetValue(biomeP, out var value7); ctxP.AltitudeTooLow_Standard[biomeP] = value7 + 1; if (!ctxP.AltLowStats_Standard.TryGetValue(biomeP, out var value8)) { value8 = new AltitudeStat(); ctxP.AltLowStats_Standard[biomeP] = value8; } value8.Add(heightP); } } } } internal static class ThreadSafePRNG { [ThreadStatic] private static Random _rng; private static Random Rng { get { if (_rng == null) { int num = Environment.TickCount; if (WorldGenerator.instance != null) { num = WorldGenerator.instance.GetSeed(); } _rng = new Random(num ^ Thread.CurrentThread.ManagedThreadId); } return _rng; } } public static void SeedForLts(int ltsSeedP) { _rng = new Random(ltsSeedP); } public static Random SwapRng(Random nextP) { Random rng = _rng; _rng = nextP; return rng; } public static void Reset() { _rng = null; } public static float NextFloat(float minP, float maxP) { return minP + (float)(Rng.NextDouble() * (double)(maxP - minP)); } public static int NextInt(int minP, int maxP) { return (int)(Rng.NextDouble() * (double)(maxP - minP)) + minP; } public static Vector2 InsideUnitCircle() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) Random rng = Rng; double num = Math.Sqrt(rng.NextDouble()); double num2 = rng.NextDouble() * (Math.PI * 2.0); return new Vector2((float)(num * Math.Cos(num2)), (float)(num * Math.Sin(num2))); } public static Vector3 NextDartInZone(Vector2i zoneP) { //IL_0001: 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_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_004c: Unknown result type (might be due to invalid IL or missing references) float num = (float)zoneP.x * 64f + NextFloat(-32f, 32f); float num2 = (float)zoneP.y * 64f + NextFloat(-32f, 32f); return new Vector3(num, 0f, num2); } } internal static class ThreadSafeTerrainDelta { private const int Samples = 10; public static void GetTerrainDelta(Vector3 centerP, float radiusP, out float delta, out Vector3 slopeDirection, int zoneGridIdxP = -1) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0049: 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_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) float num = -999999f; float num2 = 999999f; Vector3 val = centerP; Vector3 val2 = centerP; for (int i = 0; i < 10; i++) { Vector2 val3 = ThreadSafePRNG.InsideUnitCircle() * radiusP; Vector3 val4 = centerP + new Vector3(val3.x, 0f, val3.y); float height = WorldGenerator.instance.GetHeight(val4.x, val4.z); if (height < num2) { num2 = height; val2 = val4; } if (height > num) { num = height; val = val4; } } delta = num - num2; slopeDirection = Vector3.Normalize(val2 - val); } } public static class TranspiledCompletionHandler { public static Dictionary ActiveSessions = new Dictionary(); public static Dictionary AggregateSessions = new Dictionary(); public static Dictionary AggregateReports = new Dictionary(); public static int CurrentInstanceHash = 0; public static Vector2i? CachedOccupiedZone = null; public static TelemetryContext GetContext(int instanceHashP, bool createIfMissingP = true) { if (ActiveSessions.TryGetValue(instanceHashP, out var value)) { return value; } if (createIfMissingP) { TelemetryContext telemetryContext = new TelemetryContext(); ActiveSessions[instanceHashP] = telemetryContext; return telemetryContext; } return null; } public static void ReportPacketCompletion(object instanceP, bool isSuccessP) { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_02c9: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: Unknown result type (might be due to invalid IL or missing references) if (isSuccessP) { SurveyMode.NotifyZonePlaced(); } ZoneLocation location = TranspiledEngineFieldCache.GetLocation(instanceP); if (location == null) { return; } string prefabName = location.m_prefabName; Type type = instanceP.GetType(); if (isSuccessP) { FieldInfo value; bool flag = TranspiledEngineFieldCache.ZoneIDFields.TryGetValue(type, out value); if (!CachedOccupiedZone.HasValue && flag) { CachedOccupiedZone = (Vector2i)value.GetValue(instanceP); } } int overridePlacedP = -1; if (ModConfig.EnableInterleavedScheduling.Value) { overridePlacedP = 1; } ReportData reportData = TranspiledStateExtractor.Analyze(instanceP, overridePlacedP); int num = 1; if (!ModConfig.EnableInterleavedScheduling.Value && !isSuccessP && reportData != null) { num = Math.Max(1, reportData.Loc.m_quantity - reportData.Placed); } GenerationProgress.IncrementProcessed(isSuccessP, num); if (reportData != null) { ReportData value2; if (!ModConfig.EnableInterleavedScheduling.Value) { AggregateReports[prefabName] = reportData; } else if (!AggregateReports.TryGetValue(prefabName, out value2)) { AggregateReports[prefabName] = reportData; } else { value2.Merge(reportData); } } int instanceHashP = instanceP.GetHashCode(); if (reportData != null) { instanceHashP = reportData.InstanceHash; } TelemetryContext context = GetContext(instanceHashP, createIfMissingP: false); if (context != null) { if (!ModConfig.EnableInterleavedScheduling.Value) { AggregateSessions[prefabName] = context; } else { if (!AggregateSessions.TryGetValue(prefabName, out var value3)) { value3 = new TelemetryContext(); AggregateSessions[prefabName] = value3; } value3.Merge(context); } } bool flag2 = false; if (Interleaver.PendingPackets.TryGetValue(prefabName, out var value4)) { Interleaver.PendingPackets[prefabName] = value4 - num; if (value4 - num <= 0) { flag2 = true; } } else { flag2 = true; } if (flag2 || ModConfig.EnableInterleavedScheduling.Value) { ActiveSessions.Remove(instanceP.GetHashCode()); CurrentInstanceHash = 0; } if (!flag2) { return; } if (!AggregateReports.TryGetValue(prefabName, out var value5)) { value5 = reportData; } int num2 = 0; if ((Object)(object)ZoneSystem.instance != (Object)null) { foreach (LocationInstance value7 in ZoneSystem.instance.m_locationInstances.Values) { if (value7.m_location.m_prefabName == prefabName) { num2++; } } } int originalQuantity = Interleaver.GetOriginalQuantity(prefabName); if (value5 != null) { value5.Placed = num2; value5.IsComplete = num2 >= originalQuantity; value5.Loc.m_quantity = originalQuantity; int value6; bool flag3 = ConstraintRelaxer.RelaxationAttempts.TryGetValue(prefabName, out value6) && value6 > 0; if (value5.IsComplete) { if (flag3) { RelaxationTracker.MarkRelaxationSucceeded(prefabName); } if (!DiagnosticLog.MinimalLogging && (ModConfig.LogSuccesses.Value || flag3)) { if (flag3) { DiagnosticLog.WriteTimestampedLog($"[RELAXATION SUCCESS] {prefabName} placed {num2}/{originalQuantity} after {value6} relaxation(s). {ConstraintRelaxer.GetRelaxationSummary(prefabName, location)}", (LogLevel)8); } ReportFormatter.WriteReport(value5, isHeartbeatP: false, prefabName); } } else { if (!DiagnosticLog.MinimalLogging) { ReportFormatter.WriteReport(value5, isHeartbeatP: false, prefabName); } if (ConstraintRelaxer.TryRelax(value5)) { GenerationProgress.UpdateText(); } else { RelaxationTracker.CheckAndMarkFailed(prefabName, num2, originalQuantity, value5.Loc.m_prioritized); } } } AggregateReports.Remove(prefabName); AggregateSessions.Remove(prefabName); } public static void ReportSuccess(object instanceP) { ReportPacketCompletion(instanceP, isSuccessP: true); } public static void ReportFailure(object instanceP) { ReportPacketCompletion(instanceP, isSuccessP: false); } } public static class TranspiledEngineFieldCache { public static Dictionary LocationFields = new Dictionary(); public static Dictionary LimitFields = new Dictionary(); public static Dictionary CounterFields = new Dictionary(); public static Dictionary InnerCounterFields = new Dictionary(); public static Dictionary PlacedFields = new Dictionary(); public static Dictionary ZoneIDFields = new Dictionary(); public static Dictionary ErrorFields = new Dictionary(); public static FieldInfo IterationsPkgField = null; public static void SetCurrentLocation(ZoneLocation locationP) { if (GenerationProgress.CurrentLocation != locationP) { GenerationProgress.CurrentLocation = locationP; } } public static ZoneLocation GetLocation(object instanceP) { Type type = instanceP.GetType(); if (LocationFields.TryGetValue(type, out var value)) { object? value2 = value.GetValue(instanceP); return (ZoneLocation)((value2 is ZoneLocation) ? value2 : null); } return null; } public static long GetVal(object instanceP, string fieldNameP) { int hashCode = instanceP.GetHashCode(); if (TranspiledCompletionHandler.ActiveSessions.TryGetValue(hashCode, out var value) && value.ShadowCounters.TryGetValue(fieldNameP, out var value2)) { return value2; } if (ErrorFields.TryGetValue(fieldNameP, out var value3)) { try { return Convert.ToInt64(value3.GetValue(instanceP)); } catch { } } return 0L; } } public static class TranspiledEnginePatches { [CompilerGenerated] private sealed class <>c__DisplayClass22_0 { public MethodInfo getTerrainDeltaMethod; public MethodInfo haveLocationInRangeMethod; internal bool b__1(CodeInstruction cP) { return CodeInstructionExtensions.Calls(cP, getTerrainDeltaMethod); } internal bool b__2(CodeInstruction cP) { return CodeInstructionExtensions.Calls(cP, haveLocationInRangeMethod); } } [CompilerGenerated] private sealed class <>c__DisplayClass22_1 { public MethodInfo getInstanceMethod; public FieldInfo minSimilarField; internal bool b__3(CodeInstruction cP) { return CodeInstructionExtensions.Calls(cP, getInstanceMethod); } internal bool b__4(CodeInstruction cP) { return CodeInstructionExtensions.LoadsField(cP, minSimilarField, false); } } [CompilerGenerated] private sealed class d__22 : IEnumerable, IEnumerable, IEnumerator, IDisposable, IEnumerator { private int <>1__state; private CodeInstruction <>2__current; private int <>l__initialThreadId; private IEnumerable instructions; public IEnumerable <>3__instructions; private MethodBase original; public MethodBase <>3__original; private ILGenerator generator; public ILGenerator <>3__generator; private List 5__1; private Type 5__2; private float 5__3; private string 5__4; private FieldInfo 5__5; private int 5__6; private int 5__7; private CodeInstruction 5__8; private FieldInfo 5__9; private FieldInfo 5__10; private int 5__11; private string 5__12; private int 5__13; private FieldInfo 5__14; private <>c__DisplayClass22_0 <>8__15; private int 5__16; private int 5__17; private <>c__DisplayClass22_1 <>8__18; private int 5__19; private int 5__20; private int 5__21; private int 5__22; private int 5__23; private int 5__24; private int 5__25; private int 5__26; private List 5__27; private List 5__28; private Label 5__29; private List