Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Location Placement Accelerator v1.0.22
LocationPlacementAccelerator.dll
Decompiled 3 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.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<Vector2i> GetOrBuildCandidateList(ZoneLocation locationP); protected static void Shuffle<T>(List<T> 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<string> 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<string> list = new List<string>(); 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<Biome, Biome> 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<Biome, Biome> dictionary2 = new Dictionary<Biome, Biome>(); 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<string, int> RelaxationAttempts = new Dictionary<string, int>(); private static Dictionary<string, OriginalStats> _originalStats = new Dictionary<string, OriginalStats>(); 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<string, OriginalStats> 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<ZoneLocation> 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<ZoneLocation>) && fields[j].Name.Contains("ordered")) { fieldInfo = fields[j]; } if (fields[j].FieldType == typeof(int) && fields[j].Name.Contains("<i>")) { fieldInfo2 = fields[j]; } } if (fieldInfo != null && fieldInfo2 != null) { List<ZoneLocation> list2 = fieldInfo.GetValue(CapturedOuterLoop) as List<ZoneLocation>; 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<string> list = new List<string>(); 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<string, int> dictionary = new Dictionary<string, int>(); List<LocationInstance> list = new List<LocationInstance>(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<string, int> _preExistingCounts = new Dictionary<string, int>(StringComparer.Ordinal); public static ZoneLocation CurrentLocation = null; public static string StaticTopText = ""; public static string StaticBottomText = ""; private static volatile string[] _threadSlots = null; private static List<ZoneLocation> _validLocations = new List<ZoneLocation>(); 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<ZoneLocation> 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<Vector2i, LocationInstance> 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<Vector2i, LocationInstance> 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("<color=" + text + ">"); stringBuilder.AppendLine("<size=28><b>Placing locations using " + _modeName + "</b></size>"); StaticTopText = stringBuilder.ToString(); StringBuilder stringBuilder2 = new StringBuilder(); stringBuilder2.Append("</color>"); if (snapshot.Active.Count > 0) { stringBuilder2.AppendLine("\n<color=#FF4444><size=22><b>FAILED - ATTEMPTING RELAXATION:</b></size>"); foreach (string item in snapshot.Active) { if (snapshot.AttemptLog.TryGetValue(item, out var value)) { for (int i = 0; i < value.Count; i++) { stringBuilder2.AppendLine("<size=20> " + item + " " + value[i] + "</size>"); } } else { stringBuilder2.AppendLine("<size=20> " + item + "</size>"); } } stringBuilder2.Append("</color>"); } if (snapshot.Succeeded.Count > 0) { stringBuilder2.AppendLine("\n<color=#55AAFF><size=22><b>RELAXED CONSTRAINTS:</b></size>"); 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("<size=20> " + item2 + " " + ConstraintRelaxer.GetRelaxationSummary(item2, val) + "</size>"); } } stringBuilder2.Append("</color>"); } if (snapshot.Exhausted.Count > 0) { stringBuilder2.AppendLine("\n<color=#FF4444><size=22><b>FAILED - COULD NOT PLACE:</b></size>"); 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($"<size=20> {item3} (exhausted {num} relaxation attempts)</size>"); } stringBuilder2.Append("</color>"); } 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<ZoneLocation> hashSet = new HashSet<ZoneLocation>(); List<ZoneLocation> list = new List<ZoneLocation>(); 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<string, int> dictionary = new Dictionary<string, int>(); 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<string> list2 = new List<string>(); List<string> list3 = new List<string>(); List<string> list4 = new List<string>(); HashSet<string> hashSet2 = new HashSet<string>(); 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<KeyValuePair<string, int>> list5 = new List<KeyValuePair<string, int>>(); foreach (KeyValuePair<string, int> 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<string, int> 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<char>()), 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<ZoneLocation, int> _budgets = new Dictionary<ZoneLocation, int>(); public static bool IsGenerating = false; public static Dictionary<string, int> PendingPackets = new Dictionary<string, int>(); public static HashSet<string> LoggedStarts = new HashSet<string>(); private static FieldInfo[] _zoneLocationFieldCache; public static List<ZoneLocation> 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<ZoneLocation>(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<ZoneLocation> list = new List<ZoneLocation>(); List<ZoneLocation> list2 = new List<ZoneLocation>(); 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<ZoneLocation> list3 = new List<ZoneLocation>(); 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<ZoneLocation> ProcessTier(List<ZoneLocation> 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<ZoneLocation> list = new List<ZoneLocation>(); Dictionary<string, Queue<ZoneLocation>> dictionary = new Dictionary<string, Queue<ZoneLocation>>(); 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<string, List<ZoneLocation>> dictionary2 = new Dictionary<string, List<ZoneLocation>>(); foreach (KeyValuePair<string, Queue<ZoneLocation>> 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<ZoneLocation>()); } value2.Add(item3); } } List<Queue<ZoneLocation>> list3 = new List<Queue<ZoneLocation>>(); foreach (KeyValuePair<string, List<ZoneLocation>> item4 in dictionary2) { list3.Add(new Queue<ZoneLocation>(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<ZoneLocation> 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<ZoneLocation> list = new List<ZoneLocation>(); list.Add(val); return list; } List<ZoneLocation> list2 = new List<ZoneLocation>(); list2.Add(relaxedLocP); int quantity = relaxedLocP.m_quantity; relaxedLocP.m_quantity = quantityToPlaceP; List<ZoneLocation> result = ProcessTier(list2, fallbackBaseP); relaxedLocP.m_quantity = quantity; return result; } private static void Enqueue(Dictionary<string, Queue<ZoneLocation>> queuesP, ZoneLocation locP) { if (!queuesP.TryGetValue(locP.m_prefabName, out var value)) { value = new Queue<ZoneLocation>(); 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<string, List<Vector2i>> _candidateCache = new ConcurrentDictionary<string, List<Vector2i>>(StringComparer.Ordinal); private ConcurrentDictionary<string, int> _explorationIndex = new ConcurrentDictionary<string, int>(StringComparer.Ordinal); private ConcurrentDictionary<string, int> _visitPass = new ConcurrentDictionary<string, int>(StringComparer.Ordinal); private ConcurrentDictionary<string, byte> _exhaustedLocations = new ConcurrentDictionary<string, byte>(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<Vector2i> 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<Vector2i>(value); } private void HandleExhaustion(string prefabNameP, int candidateCountP, int limitP) { _exhaustedLocations.TryAdd(prefabNameP, 0); SurveyMode.SurveyExhausted = true; SurveyMode.CurrentActiveZoneIndex = -1; } private List<Vector2i> 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<Vector2i> list = new List<Vector2i>(); 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<Minimap, bool> _hasGenerated; private static readonly FieldRef<Minimap, Texture2D> _mapTexture; private static readonly FieldRef<Minimap, Texture2D> _forestMaskTexture; private static readonly FieldRef<Minimap, Texture2D> _heightTexture; private static readonly FieldRef<Minimap, Color> _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<Minimap, bool>("m_hasGenerated"); _mapTexture = AccessTools.FieldRefAccess<Minimap, Texture2D>("m_mapTexture"); _forestMaskTexture = AccessTools.FieldRefAccess<Minimap, Texture2D>("m_forestMaskTexture"); _heightTexture = AccessTools.FieldRefAccess<Minimap, Texture2D>("m_heightTexture"); _mistlandsColor = AccessTools.FieldRefAccess<Minimap, Color>("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<Biome, Color32> biomeColorMap = BuildBiomeColorMap(instanceP); Dictionary<Biome, Biome> 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<Biome, Color32> 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<Biome, Color32> dictionary = new Dictionary<Biome, Color32>(); 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<Biome, Biome> ewdBiomeToTerrainMap = Compatibility.GetEwdBiomeToTerrainMap(); if (ewdBiomeToTerrainMap != null) { foreach (KeyValuePair<Biome, Biome> 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<PlacementMode> Mode; public static ConfigEntry<bool> ShowGui; public static ConfigEntry<bool> UseLegacyEngine; public static ConfigEntry<bool> EnableParallelPlacement; public static ConfigEntry<bool> EnableInterleavedScheduling; public static ConfigEntry<int> SurveyScanResolution; public static ConfigEntry<int> SurveyVisitLimit; public static ConfigEntry<float> OuterMultiplier; public static ConfigEntry<float> InnerMultiplier; public static ConfigEntry<int> MaxRelaxationAttempts; public static ConfigEntry<float> RelaxationMagnitude; public static ConfigEntry<bool> WriteToFile; public static ConfigEntry<bool> VerboseLogFileName; public static ConfigEntry<bool> LogSuccesses; public static ConfigEntry<bool> MinimalLogging; public static ConfigEntry<bool> DiagnosticMode; public static ConfigEntry<int> ProgressInterval; public static ConfigEntry<int> InnerProgressInterval; public static ConfigEntry<float> PresenceGridCellSize; public static ConfigEntry<bool> Enable3DSimilarityCheck; public static ConfigEntry<bool> OptimizePlacementChecks; public static float WorldRadius = 10000f; public static ManualLogSource Log; public static void Initialize(ConfigFile configP, ManualLogSource loggerP) { Log = loggerP; Mode = configP.Bind<PlacementMode>("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<bool>("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<bool>("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<bool>("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<bool>("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<int>("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.