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 FehuUnchartedHorizons v420.100.1
FehuUnchartedHorizons.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.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security.Cryptography; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using FehuVanillaBiomes.Biomes; using FehuVanillaBiomes.BuildingAndPlanting; using FehuVanillaBiomes.Content; using FehuVanillaBiomes.Core; using FehuVanillaBiomes.Integrations; using FehuVanillaBiomes.Islands; using FehuVanillaBiomes.TerrainPrototype; using HarmonyLib; using Jotunn.Entities; using Jotunn.Managers; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Fehu Uncharted Horizons")] [assembly: AssemblyProduct("Fehu Uncharted Horizons")] [assembly: AssemblyCompany("BlackViking")] [assembly: AssemblyDescription("Living vanilla biomes suspended above Valheim.")] [assembly: AssemblyFileVersion("420.100.1.0")] [assembly: AssemblyInformationalVersion("420.100.1")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("420.100.1.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace FehuVanillaBiomes.TerrainPrototype { internal static class BigLandBiomePopulation { private readonly struct Placement { internal readonly Vector3 Position; internal readonly Quaternion Rotation; internal readonly float Scale; internal Placement(Vector3 position, Quaternion rotation, float scale) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) Position = position; Rotation = rotation; Scale = scale; } } private sealed class Counts { internal int Trees; internal int Bushes; internal int Rocks; internal int Resources; internal int Misc; internal int Total => Trees + Bushes + Rocks + Resources + Misc; public override string ToString() { return $"trees={Trees}; bushes={Bushes}; rocks={Rocks}; resources={Resources}; misc={Misc}"; } } internal const string LogPrefix = "[FVB/BIG-POP]"; internal const int PopulationVersion = 2; internal const string PopulationVersionKey = "FVB_BigLandPopulationVersion"; internal const string PopulationCompleteKey = "FVB_BigLandPopulationComplete"; internal const string PopulationIslandKey = "FVB_BigLandPopulationIsland"; internal const string PopulationSlotKey = "FVB_BigLandPopulationSlot"; internal const string PopulationBiomeKey = "FVB_BigLandPopulationBiome"; internal const string PopulationCategoryKey = "FVB_BigLandPopulationCategory"; private const int TreeCapPerBiome = 72; private const int BushCapPerBiome = 52; private const int RockCapPerBiome = 48; private const int MiscCapPerBiome = 40; private const int ClutterCapPerBiome = 140; private const int EquivalentVanillaZones = 12; private static readonly MethodInfo CreateObjectMethod = typeof(ZNetScene).GetMethod("CreateObject", BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[1] { typeof(ZDO) }, null) ?? throw new MissingMethodException("ZNetScene.CreateObject(ZDO)"); private static readonly FieldInfo ObjectsByIdField = typeof(ZDOMan).GetField("m_objectsByID", BindingFlags.Instance | BindingFlags.NonPublic) ?? throw new MissingFieldException("ZDOMan.m_objectsByID"); private static FehuVanillaBiomesPlugin _plugin; private static Coroutine _coroutine; private static string _world = string.Empty; private static string _completedWorld = string.Empty; private static GameObject _clutterRoot; private static bool _clutterComplete; private static bool _blockedLogged; private static bool _ownershipLogged; private static readonly Vector2[] Directions = (Vector2[])(object)new Vector2[4] { Vector2.left, Vector2.right, Vector2.up, Vector2.down }; internal static void Start(FehuVanillaBiomesPlugin plugin) { _plugin = plugin; } internal static void Stop() { if ((Object)(object)_plugin != (Object)null && _coroutine != null) { ((MonoBehaviour)_plugin).StopCoroutine(_coroutine); } _coroutine = null; DestroyClutter(); _world = string.Empty; _completedWorld = string.Empty; _blockedLogged = false; _ownershipLogged = false; _plugin = null; } internal static void ResetWorld(string world) { if ((Object)(object)_plugin != (Object)null && _coroutine != null) { ((MonoBehaviour)_plugin).StopCoroutine(_coroutine); } _coroutine = null; DestroyClutter(); _completedWorld = string.Empty; _blockedLogged = false; _ownershipLogged = false; _world = world; } internal static void OnHeightmapRegenerated(Heightmap map) { if ((Object)(object)map == (Object)(object)NextGenerationBigLand.Heightmap && _clutterComplete) { DestroyClutter(); } } internal static bool ValidateTopConsistency(OrganicLandmassPlan plan, out int populationSamples, out int missingTop, out int outsideFootprint, out int heightMismatch) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0074: 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_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) populationSamples = 0; missingTop = 0; outsideFootprint = 0; heightMismatch = 0; if (plan == null || ZDOMan.instance == null || !OrganicVisibleTop.Valid) { return false; } int duplicates; Dictionary<string, ZDO> dictionary = FindObjects(out duplicates); if (duplicates != 0) { return false; } foreach (ZDO value in dictionary.Values) { if (value != null) { populationSamples++; Vector3 position = value.GetPosition(); float height; if (!OrganicVisibleTop.ContainsLocal(new Vector2(position.x - NextGenerationBigLand.CenterX, position.z - NextGenerationBigLand.CenterZ))) { outsideFootprint++; } else if (!NextGenerationBigLand.TryWorldHeight(new Vector3(position.x, NextGenerationBigLand.LayerY, position.z), out height)) { missingTop++; } else if (Mathf.Abs(position.y - height) > 6f) { heightMismatch++; } } } if (missingTop == 0) { return outsideFootprint == 0; } return false; } internal static void Ensure(Heightmap map, TerrainComp compiler, OrganicLandmassPlan plan, string world, float centerX, float centerZ, float layerY) { if ((Object)(object)_plugin == (Object)null || (Object)(object)map == (Object)null || (Object)(object)compiler == (Object)null || plan == null || string.IsNullOrEmpty(world)) { return; } LogPopulationOwnershipWhenNear(); if (!NextGenerationBigLand.FinalReady) { if (!_blockedLogged) { _blockedLogged = true; Log("BLOCKED reason=final-landmass-not-ready"); } return; } if (!_clutterComplete) { BuildClutter(map, plan, world, centerX, centerZ, layerY); } if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer() && _coroutine == null && !(_completedWorld == world)) { _coroutine = ((MonoBehaviour)_plugin).StartCoroutine(PopulateServer(map, compiler, plan, world, centerX, centerZ, layerY)); } } private static IEnumerator PopulateServer(Heightmap map, TerrainComp compiler, OrganicLandmassPlan plan, string world, float centerX, float centerZ, float layerY) { List<ZDO> list = new List<ZDO>(); try { ZNetView component = ((Component)compiler).GetComponent<ZNetView>(); ZDO val = (((Object)(object)component != (Object)null) ? component.GetZDO() : null); if (val == null) { throw new InvalidOperationException("Big Land TerrainComp has no persistent ZDO."); } int duplicates; Dictionary<string, ZDO> dictionary = FindObjects(out duplicates); if (duplicates > 0) { throw new InvalidOperationException($"duplicate stable population slots={duplicates}"); } if (val.GetBool("FVB_BigLandPopulationComplete", false) && val.GetInt("FVB_BigLandPopulationVersion", 0) == 2) { _completedWorld = world; Log($"COMPLETE restore=true; Meadows={Summary(dictionary.Values, (Biome)1)}; BlackForest={Summary(dictionary.Values, (Biome)8)}; persistentObjects={dictionary.Count}; duplicates=0; clutterLocal={_clutterComplete}"); yield break; } List<ZoneVegetation> list2 = ZoneSystem.instance.m_vegetation.Where((ZoneVegetation definition) => definition != null && definition.m_enable && (Object)(object)definition.m_prefab != (Object)null).ToList(); Log(string.Format("BEGIN identity={0}; version={1}; seed={2}; vanillaDefinitions={3}; globalTablesModified=false", "earth-above-bigland-30-v3", 2, PopulationSeed(world), list2.Count)); List<string> list3 = (from name in (from definition in list2 select ((Object)definition.m_prefab).name into name where name.StartsWith("BMM_", StringComparison.OrdinalIgnoreCase) || name.IndexOf("Mithril", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Warpstone", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Meteorite", StringComparison.OrdinalIgnoreCase) >= 0 select name).Distinct() orderby name select name).ToList(); Log(string.Format("ACTIVE DEFINITIONS compatibleExternal={0}; names={1}; hardDependencies=none", list3.Count, (list3.Count > 0) ? string.Join(",", list3) : "none")); Random random = new Random(PopulationSeed(world)); List<Vector3> occupied = new List<Vector3>(); int duplicatesSkipped = 0; Counts counts = PopulateBiome((Biome)1, list2, map, plan, world, centerX, centerZ, layerY, random, occupied, dictionary, list, ref duplicatesSkipped); Counts counts2 = PopulateBiome((Biome)8, list2, map, plan, world, centerX, centerZ, layerY, random, occupied, dictionary, list, ref duplicatesSkipped); if (counts.Total == 0 || counts2.Total == 0) { throw new InvalidOperationException($"population validation failed: Meadows={counts.Total}; BlackForest={counts2.Total}"); } Log($"MEADOWS {counts}; definitions={DefinitionNames(list2, (Biome)1)}"); Log($"BLACKFOREST {counts2}; definitions={DefinitionNames(list2, (Biome)8)}"); Log("CREATURES mode=vanilla-biome-routing; deer+boar+neck+greydwarf+troll+skeleton rules unchanged; globalSpawnTablesModified=false"); Log("[FVB/BIG-LOCATIONS] attempted=0; placed=0; rejected=0; Meadows=0; BlackForest=0; status=DEFERRED; reason=ZoneSystem.SpawnLocation/CreateLocationProxy bind persistence to vanilla X/Z zone identity; unsafe without isolated location registry"); Log("[FVB/BIG-DUNGEON] candidate=BurialChambers; status=DEFERRED; reason=LocationProxy.SpawnLocation delegates to ZoneSystem.SpawnProxyLocation and vanilla location registry; entryPosition=none; instanceIdentity=none"); Log("[FVB/BIG-DUNGEON] candidate=TrollCave; status=DEFERRED; reason=same vanilla X/Z LocationProxy ownership blocker; entryPosition=none; instanceIdentity=none"); Log($"[FVB/BIG-LAKE-BASIN] center=({plan.LakeBasinLocal.x + centerX:F1},{layerY:F1},{plan.LakeBasinLocal.y + centerZ:F1}); radius=25.0; depth=5.0; drainEdgeDistance={DistanceToContour(plan, plan.LakeBasinLocal):F1}; waterEnabled=false"); val.Set("FVB_BigLandPopulationVersion", 2); val.Set("FVB_BigLandPopulationComplete", true); _completedWorld = world; Log($"COMPLETE Meadows={counts}; BlackForest={counts2}; persistentObjects={dictionary.Count + list.Count}; duplicatesSkipped={duplicatesSkipped}; clutterLocal={_clutterComplete}; locations=0; caveFeatures=0"); int populationSamples; int missingTop; int outsideFootprint; int heightMismatch; bool flag = ValidateTopConsistency(plan, out populationSamples, out missingTop, out outsideFootprint, out heightMismatch); Log(string.Format("[FVB/BIG-TOP-CONSISTENCY] populationSamples={0}; missingTop={1}; outsideFootprint={2}; heightMismatch={3}; phase=after-population; result={4}", populationSamples, missingTop, outsideFootprint, heightMismatch, flag ? "PASS" : "FAIL")); } catch (Exception ex) { Rollback(list); LogError("transaction rolled back; completion marker NOT written: " + ex); } finally { _coroutine = null; } } private static Counts PopulateBiome(Biome biome, List<ZoneVegetation> vanilla, Heightmap map, OrganicLandmassPlan plan, string world, float centerX, float centerZ, float layerY, Random random, List<Vector3> occupied, Dictionary<string, ZDO> existing, List<ZDO> created, ref int duplicatesSkipped) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) List<ZoneVegetation> source = vanilla.Where((ZoneVegetation definition) => (definition.m_biome & biome) != 0 && (definition.m_biomeArea & 2) > 0).ToList(); return new Counts { Trees = PlaceCategory(biome, "tree", source.Where((ZoneVegetation definition) => Category(((Object)definition.m_prefab).name) == "tree").ToList(), 72, 4f, map, plan, world, centerX, centerZ, layerY, random, occupied, existing, created, ref duplicatesSkipped), Bushes = PlaceCategory(biome, "bush", source.Where((ZoneVegetation definition) => Category(((Object)definition.m_prefab).name) == "bush").ToList(), 52, 2f, map, plan, world, centerX, centerZ, layerY, random, occupied, existing, created, ref duplicatesSkipped), Rocks = PlaceCategory(biome, "rock", source.Where((ZoneVegetation definition) => Category(((Object)definition.m_prefab).name) == "rock").ToList(), 48, 3f, map, plan, world, centerX, centerZ, layerY, random, occupied, existing, created, ref duplicatesSkipped), Resources = PlaceCategory(biome, "resource", source.Where((ZoneVegetation definition) => Category(((Object)definition.m_prefab).name) == "resource").ToList(), 18, 5f, map, plan, world, centerX, centerZ, layerY, random, occupied, existing, created, ref duplicatesSkipped), Misc = PlaceCategory(biome, "misc", source.Where((ZoneVegetation definition) => Category(((Object)definition.m_prefab).name) == "misc").ToList(), 40, 1.3f, map, plan, world, centerX, centerZ, layerY, random, occupied, existing, created, ref duplicatesSkipped) }; } private static int PlaceCategory(Biome biome, string category, List<ZoneVegetation> definitions, int cap, float spacing, Heightmap map, OrganicLandmassPlan plan, string world, float centerX, float centerZ, float layerY, Random random, List<Vector3> occupied, Dictionary<string, ZDO> existing, List<ZDO> created, ref int duplicatesSkipped) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: 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_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) if (definitions.Count == 0) { return 0; } Shuffle(definitions, random); int num = 0; int num2 = 0; foreach (ZoneVegetation definition in definitions) { int num3 = DefinitionGroupBudget(definition, random); for (int i = 0; i < num3; i++) { if (num >= cap) { break; } Vector2 groupCenter = RandomBiomePoint(random, plan, biome); int num4 = Math.Max(1, random.Next(Math.Max(1, definition.m_groupSizeMin), Math.Max(1, definition.m_groupSizeMax) + 1)); for (int j = 0; j < num4; j++) { if (num >= cap) { break; } string text = string.Format("{0}|{1}|vegetation|{2}|{3}|{4:D4}|v{5}", world, "earth-above-bigland-30-v3", biome, category, num2++, 2); Placement placement; if (existing.ContainsKey(text)) { duplicatesSkipped++; num++; } else if (TryPlacement(definition, biome, map, plan, groupCenter, centerX, centerZ, layerY, random, occupied, spacing, out placement)) { ZDO val = SpawnPersistent(definition, placement, text, biome, category); if (val != null) { created.Add(val); occupied.Add(placement.Position); num++; } } } } } return num; } private static int DefinitionGroupBudget(ZoneVegetation definition, Random random) { if (definition.m_max < 1f) { return (random.NextDouble() <= (double)definition.m_max) ? 1 : 0; } int num = Math.Max(0, Mathf.FloorToInt(definition.m_min * 12f)); int num2 = Math.Max(num, Mathf.CeilToInt(definition.m_max * 12f)); return Math.Min(36, random.Next(num, num2 + 1)); } private static bool TryPlacement(ZoneVegetation definition, Biome biome, Heightmap map, OrganicLandmassPlan plan, Vector2 groupCenter, float centerX, float centerZ, float layerY, Random random, List<Vector3> occupied, float spacing, out Placement placement) { //IL_005d: 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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_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_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016f: 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_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_02ef: Unknown result type (might be due to invalid IL or missing references) //IL_02f4: Unknown result type (might be due to invalid IL or missing references) //IL_02f6: Unknown result type (might be due to invalid IL or missing references) //IL_0307: Unknown result type (might be due to invalid IL or missing references) //IL_030c: Unknown result type (might be due to invalid IL or missing references) //IL_02e8: Unknown result type (might be due to invalid IL or missing references) //IL_0311: Unknown result type (might be due to invalid IL or missing references) //IL_0316: Unknown result type (might be due to invalid IL or missing references) //IL_031b: Unknown result type (might be due to invalid IL or missing references) placement = default(Placement); float num5 = default(float); for (int i = 0; i < 32; i++) { float num = (float)(random.NextDouble() * Math.PI * 2.0); float num2 = definition.m_groupRadius * Mathf.Sqrt((float)random.NextDouble()); float num3 = groupCenter.x + Mathf.Cos(num) * num2; float num4 = groupCenter.y + Mathf.Sin(num) * num2; if (plan.LandFactor(num3, num4) < 0.72f || plan.BiomeAt(num3, num4) != biome) { continue; } Vector3 point = new Vector3(centerX + num3, layerY, centerZ + num4); if (!Heightmap.GetHeight(point, ref num5)) { continue; } point.y = num5 + definition.m_groundOffset; if (map.IsCleared(point) || occupied.Any((Vector3 other) => HorizontalDistance(other, point) < spacing)) { continue; } float num6 = num5 - layerY; if (num6 < definition.m_minAltitude || num6 > definition.m_maxAltitude) { continue; } float vegetationMask = map.GetVegetationMask(point); if (definition.m_minVegetation != definition.m_maxVegetation && (vegetationMask < definition.m_minVegetation || vegetationMask > definition.m_maxVegetation)) { continue; } Vector3 val = SurfaceNormal(point); float y = val.y; if (y < Mathf.Cos(definition.m_maxTilt * ((float)Math.PI / 180f)) || y > Mathf.Cos(definition.m_minTilt * ((float)Math.PI / 180f)) || !PassTerrainDelta(definition, point) || !PassSurroundVegetation(definition, map, point)) { continue; } Vector2 val2 = new Vector2(point.x, point.z); float magnitude = ((Vector2)(ref val2)).magnitude; if ((definition.m_minDistanceFromCenter > 0f && magnitude < definition.m_minDistanceFromCenter) || (definition.m_maxDistanceFromCenter > 0f && magnitude > definition.m_maxDistanceFromCenter) || definition.m_snapToWater || definition.m_minOceanDepth > 0f) { continue; } if (definition.m_inForest) { float forestFactor = WorldGenerator.GetForestFactor(point); if (forestFactor < definition.m_forestTresholdMin || forestFactor > definition.m_forestTresholdMax) { continue; } } if (!definition.m_blockCheck || !IsBlocked(map, point)) { float num7 = (float)random.NextDouble() * 360f; float num8 = Mathf.Lerp(0f - definition.m_randTilt, definition.m_randTilt, (float)random.NextDouble()); float num9 = Mathf.Lerp(0f - definition.m_randTilt, definition.m_randTilt, (float)random.NextDouble()); Quaternion rotation = ((random.NextDouble() <= (double)definition.m_chanceToUseGroundTilt) ? (Quaternion.FromToRotation(Vector3.up, val) * Quaternion.Euler(0f, num7, 0f)) : Quaternion.Euler(num8, num7, num9)); placement = new Placement(point, rotation, Mathf.Lerp(definition.m_scaleMin, definition.m_scaleMax, (float)random.NextDouble())); return true; } } return false; } private static bool PassTerrainDelta(ZoneVegetation definition, Vector3 point) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) if (definition.m_terrainDeltaRadius <= 0f) { return true; } float num = float.MaxValue; float num2 = float.MinValue; Vector2[] directions = Directions; float num3 = default(float); foreach (Vector2 val in directions) { if (!Heightmap.GetHeight(point + new Vector3(val.x * definition.m_terrainDeltaRadius, 0f, val.y * definition.m_terrainDeltaRadius), ref num3)) { return false; } num = Mathf.Min(num, num3); num2 = Mathf.Max(num2, num3); } float num4 = num2 - num; if (num4 >= definition.m_minTerrainDelta) { return num4 <= definition.m_maxTerrainDelta; } return false; } private static bool PassSurroundVegetation(ZoneVegetation definition, Heightmap map, Vector3 point) { //IL_005d: 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_007c: Unknown result type (might be due to invalid IL or missing references) if (!definition.m_surroundCheckVegetation || definition.m_surroundCheckLayers <= 0 || definition.m_surroundCheckDistance <= 0f) { return true; } float num = 0f; int num2 = 0; for (int i = 1; i <= definition.m_surroundCheckLayers; i++) { for (int j = 0; j < 6; j++) { float num3 = (float)j / 6f * (float)Math.PI * 2f; float num4 = (float)i / (float)definition.m_surroundCheckLayers * definition.m_surroundCheckDistance; num += map.GetVegetationMask(point + new Vector3(Mathf.Sin(num3) * num4, 0f, Mathf.Cos(num3) * num4)); num2++; } } float num5 = ((num2 > 0) ? (num / (float)num2) : 0f); if (num5 >= definition.m_minVegetation) { return num5 <= definition.m_maxVegetation; } return false; } private static bool IsBlocked(Heightmap map, Vector3 point) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: 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) Collider[] array = Physics.OverlapSphere(point + Vector3.up * 0.5f, 0.45f, -5, (QueryTriggerInteraction)1); foreach (Collider val in array) { if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).GetComponentInParent<Heightmap>() != (Object)(object)map) { return true; } } return false; } private unsafe static ZDO SpawnPersistent(ZoneVegetation definition, Placement placement, string slot, Biome biome, string category) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0098: 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_0199: Unknown result type (might be due to invalid IL or missing references) GameObject prefab = definition.m_prefab; ZNetView val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<ZNetView>() : null); if ((Object)(object)val == (Object)null) { return null; } int num = StableHash(((Object)prefab).name); if ((Object)(object)ZNetScene.instance.GetPrefab(((Object)prefab).name) == (Object)null) { return null; } ZDO val2 = ZDOMan.instance.CreateNewZDO(placement.Position, num); if (val2 == null) { throw new InvalidOperationException("CreateNewZDO failed slot=" + slot + "; prefab=" + ((Object)prefab).name); } val2.SetPrefab(num); val2.SetRotation(placement.Rotation); val2.Persistent = true; val2.Type = val.m_type; val2.Distant = val.m_distant; val2.Set("FVB_BigLandPopulationIsland", "earth-above-bigland-30-v3"); val2.Set("FVB_BigLandPopulationSlot", slot); val2.Set("FVB_BigLandPopulationBiome", ((object)(*(Biome*)(&biome))/*cast due to .constrained prefix*/).ToString()); val2.Set("FVB_BigLandPopulationCategory", category); val2.Set("FVB_BigLandPopulationVersion", 2); object? obj = CreateObjectMethod.Invoke(ZNetScene.instance, new object[1] { val2 }); GameObject val3 = (GameObject)((obj is GameObject) ? obj : null); ZNetView val4 = (((Object)(object)val3 != (Object)null) ? val3.GetComponent<ZNetView>() : null); if ((Object)(object)val4 == (Object)null || !val4.IsValid() || val4.GetZDO() == null) { ZDOMan.instance.DestroyZDO(val2); throw new InvalidOperationException("CreateObject validation failed slot=" + slot + "; prefab=" + ((Object)prefab).name); } if (Mathf.Abs(placement.Scale - 1f) > 0.001f) { val4.SetLocalScale(Vector3.one * placement.Scale); } return val2; } private static Dictionary<string, ZDO> FindObjects(out int duplicates) { duplicates = 0; Dictionary<string, ZDO> dictionary = new Dictionary<string, ZDO>(StringComparer.Ordinal); if (!(ObjectsByIdField.GetValue(ZDOMan.instance) is Dictionary<ZDOID, ZDO> dictionary2)) { return dictionary; } foreach (ZDO value in dictionary2.Values) { if (value == null || value.GetString("FVB_BigLandPopulationIsland", string.Empty) != "earth-above-bigland-30-v3") { continue; } string text = value.GetString("FVB_BigLandPopulationSlot", string.Empty); if (!string.IsNullOrEmpty(text)) { if (dictionary.ContainsKey(text)) { duplicates++; } else { dictionary.Add(text, value); } } } return dictionary; } private static void LogPopulationOwnershipWhenNear() { //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) if (_ownershipLogged || (Object)(object)Player.m_localPlayer == (Object)null || ZDOMan.instance == null) { return; } Vector3 position = ((Component)Player.m_localPlayer).transform.position; float num = position.x - NextGenerationBigLand.CenterX; float num2 = position.z - NextGenerationBigLand.CenterZ; float num3 = 192f; if (num * num + num2 * num2 > num3 * num3 || !(ObjectsByIdField.GetValue(ZDOMan.instance) is Dictionary<ZDOID, ZDO> dictionary)) { return; } int num4 = 0; int num5 = 0; int num6 = 0; foreach (ZDO value in dictionary.Values) { if (value != null && value.Persistent) { switch (value.GetString("FVB_BigLandPopulationIsland", value.GetString("FVB_PopulationIslandId", string.Empty))) { case "earth-above-bigland-18-v1": num4++; break; case "earth-above-bigland-30-v2": num5++; break; case "earth-above-bigland-30-v3": num6++; break; } } } _ownershipLogged = true; if ((Object)(object)_plugin != (Object)null) { _plugin.Log.LogInfo((object)string.Format("[FVB/POP-OWNERSHIP] {0}={1}; {2}={3}; {4}={5}; mutation=false", "earth-above-bigland-18-v1", num4, "earth-above-bigland-30-v2", num5, "earth-above-bigland-30-v3", num6)); } } private static void BuildClutter(Heightmap map, OrganicLandmassPlan plan, string world, float centerX, float centerZ, float layerY) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_040f: Unknown result type (might be due to invalid IL or missing references) //IL_0417: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0176: 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_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_023f: 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_0246: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_02d0: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_02f2: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_0319: Unknown result type (might be due to invalid IL or missing references) //IL_031f: Unknown result type (might be due to invalid IL or missing references) //IL_0326: Unknown result type (might be due to invalid IL or missing references) //IL_033c: Unknown result type (might be due to invalid IL or missing references) //IL_0341: Unknown result type (might be due to invalid IL or missing references) //IL_0343: Unknown result type (might be due to invalid IL or missing references) //IL_0335: Unknown result type (might be due to invalid IL or missing references) //IL_035f: Unknown result type (might be due to invalid IL or missing references) //IL_0364: Unknown result type (might be due to invalid IL or missing references) //IL_036e: Unknown result type (might be due to invalid IL or missing references) //IL_0374: Unknown result type (might be due to invalid IL or missing references) //IL_0393: Unknown result type (might be due to invalid IL or missing references) //IL_039d: Unknown result type (might be due to invalid IL or missing references) //IL_03d0: Unknown result type (might be due to invalid IL or missing references) //IL_03d8: Unknown result type (might be due to invalid IL or missing references) if (_clutterComplete || (Object)(object)ClutterSystem.instance == (Object)null) { return; } List<Clutter> list = ClutterSystem.instance.m_clutter.Where((Clutter definition) => definition != null && definition.m_enabled && (Object)(object)definition.m_prefab != (Object)null && (definition.m_biome & 9) > 0).ToList(); if (list.Count == 0) { _clutterComplete = true; Log("CLUTTER slots=0; definitions unavailable"); return; } _clutterRoot = new GameObject("FVB_EarthAbove_BigLand30V3_LocalClutter"); Random random = new Random(PopulationSeed(world) ^ 0x434C5554); Dictionary<Biome, int> dictionary = new Dictionary<Biome, int>(); Dictionary<Biome, int> dictionary2 = new Dictionary<Biome, int>(); int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; int num5 = 0; int num6 = 0; int num7 = 0; int num8 = 0; Biome[] array = (Biome[])(object)new Biome[2] { (Biome)1, (Biome)8 }; Vector3 val3 = default(Vector3); float num12 = default(float); foreach (Biome biome in array) { for (int num10 = 0; num10 < 140; num10++) { List<Clutter> list2 = list.Where((Clutter definition) => (definition.m_biome & biome) > 0).ToList(); if (list2.Count == 0) { break; } bool flag = false; for (int num11 = 0; num11 < 12; num11++) { if (flag) { break; } Clutter val = list2[random.Next(list2.Count)]; Vector2 val2 = RandomBiomePoint(random, plan, biome); if (plan.LandFactor(val2.x, val2.y) < 0.74f) { num++; continue; } if (plan.BiomeAt(val2.x, val2.y) != biome) { num4++; continue; } ((Vector3)(ref val3))..ctor(centerX + val2.x, layerY, centerZ + val2.y); if (!Heightmap.GetHeight(val3, ref num12)) { num5++; continue; } val3.y = num12 + val.m_randomOffset * ((float)random.NextDouble() * 2f - 1f); if (map.IsCleared(val3) || (!val.m_onUncleared && val.m_onCleared)) { num3++; continue; } float vegetationMask = map.GetVegetationMask(val3); if (vegetationMask < val.m_minVegetation || vegetationMask > val.m_maxVegetation) { num6++; continue; } Vector3 val4 = SurfaceNormal(val3); float num13 = Vector3.Angle(val4, Vector3.up); if (num13 < val.m_minTilt || num13 > val.m_maxTilt) { num2++; continue; } MeshFilter val5 = LargestMeshFilter(val.m_prefab); MeshRenderer val6 = (((Object)(object)val5 != (Object)null) ? ((Component)val5).GetComponent<MeshRenderer>() : null); if ((Object)(object)val5 == (Object)null || (Object)(object)val5.sharedMesh == (Object)null || (Object)(object)val6 == (Object)null) { num8++; continue; } GameObject val7 = new GameObject($"FVB_BigClutter_{biome}_{num10:D3}_{val.m_name}") { layer = ((Component)map).gameObject.layer }; val7.transform.SetParent(_clutterRoot.transform, false); val7.transform.position = val3; val7.transform.rotation = (val.m_terrainTilt ? Quaternion.FromToRotation(Vector3.up, val4) : Quaternion.identity) * Quaternion.Euler(0f, (float)random.NextDouble() * 360f, 0f); val7.transform.localScale = Vector3.one * Mathf.Lerp(val.m_scaleMin, val.m_scaleMax, (float)random.NextDouble()); val7.AddComponent<MeshFilter>().sharedMesh = val5.sharedMesh; MeshRenderer obj = val7.AddComponent<MeshRenderer>(); ((Renderer)obj).sharedMaterials = ((Renderer)val6).sharedMaterials; ((Renderer)obj).receiveShadows = ((Renderer)val6).receiveShadows; dictionary[biome] = ((!dictionary.TryGetValue(biome, out var value)) ? 1 : (value + 1)); flag = true; } if (!flag) { dictionary2[biome] = ((!dictionary2.TryGetValue(biome, out var value2)) ? 1 : (value2 + 1)); } } } _clutterComplete = true; Log($"CLUTTER Meadows={GetCount(dictionary, (Biome)1)}; BlackForest={GetCount(dictionary, (Biome)8)}; rejectedMeadows={GetCount(dictionary2, (Biome)1)}; rejectedBlackForest={GetCount(dictionary2, (Biome)8)}; rejectedOutsideMask={num}; rejectedSlope={num2}; rejectedPaint={num3}; rejectedBiome={num4}; rejectedHeight={num5}; rejectedVegetationMask={num6}; rejectedRaycast={num7}; rejectedOther={num8}; persistent=false; zdoCount=0"); } private static void DestroyClutter() { if ((Object)(object)_clutterRoot != (Object)null) { Object.Destroy((Object)(object)_clutterRoot); } _clutterRoot = null; _clutterComplete = false; } private static Vector2 RandomBiomePoint(Random random, OrganicLandmassPlan plan, Biome biome) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < 512; i++) { float num = Mathf.Lerp(-128f, 128f, (float)random.NextDouble()); float num2 = Mathf.Lerp(-128f, 128f, (float)random.NextDouble()); if (plan.LandFactor(num, num2) >= 0.74f && plan.BiomeAt(num, num2) == biome) { return new Vector2(num, num2); } } throw new InvalidOperationException($"No deterministic placement point for {biome}."); } private static Vector3 SurfaceNormal(Vector3 point) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: 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_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_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_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: 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_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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_0088: Unknown result type (might be due to invalid IL or missing references) float num = default(float); Heightmap.GetHeight(point + Vector3.left * 0.75f, ref num); float num2 = default(float); Heightmap.GetHeight(point + Vector3.right * 0.75f, ref num2); float num3 = default(float); Heightmap.GetHeight(point + Vector3.back * 0.75f, ref num3); float num4 = default(float); Heightmap.GetHeight(point + Vector3.forward * 0.75f, ref num4); Vector3 val = new Vector3(num - num2, 1.5f, num3 - num4); return ((Vector3)(ref val)).normalized; } private static MeshFilter LargestMeshFilter(GameObject prefab) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) MeshFilter result = null; float num = -1f; MeshFilter[] componentsInChildren = prefab.GetComponentsInChildren<MeshFilter>(true); foreach (MeshFilter val in componentsInChildren) { Mesh sharedMesh = val.sharedMesh; if (!((Object)(object)sharedMesh == (Object)null) && !((Object)(object)((Component)val).GetComponent<MeshRenderer>() == (Object)null)) { Bounds bounds = sharedMesh.bounds; Vector3 size = ((Bounds)(ref bounds)).size; float num2 = Mathf.Abs(size.x * size.y * size.z); if (num2 > num) { result = val; num = num2; } } } return result; } private static string Category(string name) { string text = name.ToLowerInvariant(); if (text.Contains("beech") || text.Contains("birch") || text.Contains("oak") || text.Contains("fir") || text.Contains("pine")) { return "tree"; } if (text.Contains("bush") || text.Contains("shrub") || text.Contains("sapling") || text.Contains("blueberr") || text.Contains("raspberr")) { return "bush"; } if (text.Contains("tin")) { return "water-resource-disabled"; } if (text.Contains("copper") || text.Contains("meteorite") || text.Contains("mithril") || text.Contains("warpstone") || text.Contains("mine") || text.Contains("deposit")) { return "resource"; } if (text.Contains("rock") || text.Contains("stone") || text.Contains("cliff")) { return "rock"; } return "misc"; } private static string DefinitionNames(IEnumerable<ZoneVegetation> values, Biome biome) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) return string.Join(",", from value in (from value in values where (value.m_biome & biome) > 0 select ((Object)value.m_prefab).name).Distinct() orderby value select value); } private unsafe static string Summary(IEnumerable<ZDO> values, Biome biome) { string name = ((object)(*(Biome*)(&biome))/*cast due to .constrained prefix*/).ToString(); return string.Join(",", new string[5] { "tree", "bush", "rock", "resource", "misc" }.Select((string category) => category + "=" + values.Count((ZDO zdo) => zdo.GetString("FVB_BigLandPopulationBiome", string.Empty) == name && zdo.GetString("FVB_BigLandPopulationCategory", string.Empty) == category))); } private static int GetCount(Dictionary<Biome, int> values, Biome biome) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if (!values.TryGetValue(biome, out var value)) { return 0; } return value; } private static float HorizontalDistance(Vector3 a, Vector3 b) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) float num = a.x - b.x; float num2 = a.z - b.z; return Mathf.Sqrt(num * num + num2 * num2); } private static float DistanceToContour(OrganicLandmassPlan plan, Vector2 point) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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) float num = float.MaxValue; foreach (Vector2 point2 in plan.Contour.Points) { num = Mathf.Min(num, Vector2.Distance(point, point2)); } return num; } private static int PopulationSeed(string world) { return WorldGenerator.instance.GetSeed() ^ StableHash(world) ^ StableHash("earth-above-bigland-30-v3") ^ 2; } private static int StableHash(string text) { int num = 5381; int num2 = num; for (int i = 0; i < text.Length && text[i] != 0; i += 2) { num = ((num << 5) + num) ^ text[i]; if (i == text.Length - 1 || text[i + 1] == '\0') { break; } num2 = ((num2 << 5) + num2) ^ text[i + 1]; } return num + num2 * 1566083941; } private static void Shuffle<T>(IList<T> values, Random random) { for (int num = values.Count - 1; num > 0; num--) { int index = random.Next(num + 1); T value = values[num]; values[num] = values[index]; values[index] = value; } } private static void Rollback(IEnumerable<ZDO> created) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) foreach (ZDO item in created.Reverse()) { if (item != null) { GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.FindInstance(item.m_uid) : null); if ((Object)(object)val != (Object)null) { ZNetScene.instance.Destroy(val); } else if (ZDOMan.instance != null) { ZDOMan.instance.DestroyZDO(item); } } } } private static void Log(string message) { if ((Object)(object)_plugin != (Object)null) { _plugin.Log.LogInfo((object)("[FVB/BIG-POP] " + message)); } } private static void LogError(string message) { if ((Object)(object)_plugin != (Object)null) { _plugin.Log.LogError((object)("[FVB/BIG-POP] " + message)); } } } internal static class BigLandSpawnAudit { private const string Prefix = "[FVB/SPAWN-AUDIT]"; private static int _candidates; private static int _accepted; private static int _rejected; private static int _spawnedObserved; private static float _lastSummary; internal static void ObserveCandidate(SpawnData spawn, Vector3 point, bool accepted) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: 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_00dc: Unknown result type (might be due to invalid IL or missing references) if (!NextGenerationBigLand.ContainsElevatedVolume(point)) { return; } _candidates++; if (accepted) { _accepted++; } else { _rejected++; } if (_candidates <= 8) { Heightmap val = Heightmap.FindHeightmap(point); FehuVanillaBiomesPlugin instance = FehuVanillaBiomesPlugin.Instance; if (instance != null) { ManualLogSource log = instance.Log; object[] obj = new object[10] { "[FVB/SPAWN-AUDIT]", spawn?.m_biome, null, null, null, null, null, null, null, null }; object obj2; if (spawn == null) { obj2 = null; } else { GameObject prefab = spawn.m_prefab; obj2 = ((prefab != null) ? ((Object)prefab).name : null); } if (obj2 == null) { obj2 = "null"; } obj[2] = obj2; obj[3] = point.x; obj[4] = point.y; obj[5] = point.z; obj[6] = point.y; obj[7] = ((val != null) ? ((Object)((Component)val).gameObject).name : null) ?? "none"; obj[8] = accepted; obj[9] = (accepted ? "vanilla-rules-pass" : "vanilla-rules-rejected"); log.LogInfo((object)string.Format("{0} biome={1}; prefab={2}; candidatePosition=({3:F1},{4:F1},{5:F1}); resolvedGround={6:F2}; resolvedHeightmap={7}; accepted={8}; reason={9}", obj)); } } SummaryIfDue(); } internal static void ObserveSpawn(SpawnData spawn, Vector3 point) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if (NextGenerationBigLand.ContainsElevatedVolume(point)) { _spawnedObserved++; SummaryIfDue(force: true); } } private static void SummaryIfDue(bool force = false) { if (force || !(Time.realtimeSinceStartup - _lastSummary < 30f) || _candidates % 25 == 0) { _lastSummary = Time.realtimeSinceStartup; FehuVanillaBiomesPlugin instance = FehuVanillaBiomesPlugin.Instance; if (instance != null) { instance.Log.LogInfo((object)string.Format("{0} SUMMARY candidateCount={1}; acceptedCount={2}; rejectedCount={3}; spawnedObserved={4}; scopedTo={5}; globalSpawnTablesModified=false", "[FVB/SPAWN-AUDIT]", _candidates, _accepted, _rejected, _spawnedObserved, "earth-above-bigland-30-v3")); } } } } [HarmonyPatch] internal static class BigLandSpawnPointPatch { private static MethodBase TargetMethod() { return AccessTools.Method(typeof(SpawnSystem), "IsSpawnPointGood", new Type[2] { typeof(SpawnData), typeof(Vector3).MakeByRefType() }, (Type[])null); } [HarmonyPostfix] private static void Postfix(SpawnData __0, Vector3 __1, bool __result) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) BigLandSpawnAudit.ObserveCandidate(__0, __1, __result); } } [HarmonyPatch] internal static class BigLandSpawnObservedPatch { private static MethodBase TargetMethod() { return AccessTools.Method(typeof(SpawnSystem), "Spawn", new Type[3] { typeof(SpawnData), typeof(Vector3), typeof(bool) }, (Type[])null); } [HarmonyPostfix] private static void Postfix(SpawnData __0, Vector3 __1) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) BigLandSpawnAudit.ObserveSpawn(__0, __1); } } internal static class ClusterLandManager { private sealed class Island { internal readonly string Id; internal readonly Vector2 Center; internal Heightmap Map; internal TerrainComp Comp; internal string Bounds => "(" + (Center.x - 64f) + "," + (Center.y - 64f) + ")..(" + (Center.x + 64f) + "," + (Center.y + 64f) + ")"; internal Island(int index) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) Id = "earth-above-cluster-land-v1-" + index.ToString("D2"); Center = Centers[index]; } } internal const string PrototypeId = "earth-above-cluster-land-v1"; internal const int Width = 128; internal const float LayerY = 180f; private const float Half = 64f; private const float LayerBand = 40f; private static readonly Vector2[] Centers = (Vector2[])(object)new Vector2[5] { new Vector2(4096f, -2048f), new Vector2(4096f, -1888f), new Vector2(4256f, -2048f), new Vector2(3936f, -2208f), new Vector2(4256f, -2208f) }; private static readonly MethodInfo CreateObject = typeof(ZNetScene).GetMethod("CreateObject", BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[1] { typeof(ZDO) }, null); private static readonly List<Island> Islands = new List<Island>(); private static FehuVanillaBiomesPlugin _plugin; private static Coroutine _life; private static bool _creatingCompiler; private static string _world = string.Empty; internal static bool Enabled { get { if ((Object)(object)_plugin != (Object)null) { return _plugin.Settings.ClusterLandEnabled.Value; } return false; } } internal static void Start(FehuVanillaBiomesPlugin plugin) { _plugin = plugin; if (_life == null) { _life = ((MonoBehaviour)plugin).StartCoroutine(Lifecycle()); } } internal static void Stop() { if ((Object)(object)_plugin != (Object)null && _life != null) { ((MonoBehaviour)_plugin).StopCoroutine(_life); } _life = null; foreach (Island island in Islands) { if ((Object)(object)island.Map != (Object)null) { Object.Destroy((Object)(object)((Component)island.Map).gameObject); } } Islands.Clear(); _plugin = null; _world = string.Empty; } private static IEnumerator Lifecycle() { while (true) { yield return (object)new WaitForSeconds(1f); if (!Enabled || (Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer() || (Object)(object)ZNetScene.instance == (Object)null || (Object)(object)ZoneSystem.instance == (Object)null || WorldGenerator.instance == null) { continue; } string text = ZNet.instance.GetWorldName() + ":" + ZNet.instance.GetWorldUID(); if (_world != text) { StopMaps(); _world = text; Log("LAYOUT prototype=earth-above-cluster-land-v1; islandCount=5; overallBounds=(3872,-2272)..(4320,-1824); positions=" + LayoutText()); CheckBounds(); } Heightmap reference = FindReference(); if ((Object)(object)reference == (Object)null) { continue; } for (int n = 0; n < Centers.Length; n++) { Island island = Get(n); if ((Object)(object)island.Map == (Object)null) { CreateMap(island, reference); } if ((Object)(object)island.Map != (Object)null && (Object)(object)island.Comp == (Object)null) { yield return CreateCompiler(island); } } if (Islands.Count == 5 && Islands.TrueForAll((Island i) => (Object)(object)i.Map != (Object)null && (Object)(object)i.Comp != (Object)null && (Object)(object)((Component)i.Map).GetComponent<MeshRenderer>() != (Object)null && ((Renderer)((Component)i.Map).GetComponent<MeshRenderer>()).enabled && (Object)(object)((Component)i.Map).GetComponent<MeshCollider>() != (Object)null && ((Collider)((Component)i.Map).GetComponent<MeshCollider>()).enabled && (Object)(object)((Component)i.Map).GetComponent<MeshCollider>().sharedMesh != (Object)null)) { Log("FINAL roots=5; boundsOverlap=0; shell=False; customCollider=False; result=PASS"); } } } private static void StopMaps() { foreach (Island island in Islands) { if ((Object)(object)island.Map != (Object)null) { Object.Destroy((Object)(object)((Component)island.Map).gameObject); } } Islands.Clear(); } private static Island Get(int index) { while (Islands.Count <= index) { Islands.Add(new Island(Islands.Count)); } return Islands[index]; } private static Heightmap FindReference() { foreach (Heightmap allHeightmap in Heightmap.GetAllHeightmaps()) { if ((Object)(object)allHeightmap != (Object)null && (Object)(object)allHeightmap.m_material != (Object)null && (Object)(object)allHeightmap.m_terrainCompilerPrefab != (Object)null && !IsClusterMap(allHeightmap)) { return allHeightmap; } } return null; } private static void CreateMap(Island island, Heightmap reference) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001c: 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005f: 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_00d5: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("FVB_ClusterLand_" + island.Id); val.SetActive(false); val.layer = ((Component)reference).gameObject.layer; val.transform.position = new Vector3(island.Center.x, 180f, island.Center.y); val.AddComponent<MeshCollider>(); Heightmap val2 = val.AddComponent<Heightmap>(); val2.m_width = 128; val2.m_scale = 1f; val2.m_material = reference.m_material; val2.m_terrainCompilerPrefab = reference.m_terrainCompilerPrefab; island.Map = val2; val.SetActive(true); val2.Poke(0, false); Log("ISLAND id=" + island.Id + "; center=" + ((object)((Component)val2).transform.position/*cast due to .constrained prefix*/).ToString() + "; bounds=" + island.Bounds + "; usableOrganicExtent=~104m; footprintSeed=" + Seed(island.Id)); } private static IEnumerator CreateCompiler(Island island) { _creatingCompiler = true; try { island.Comp = island.Map.GetAndCreateTerrainCompiler(); } finally { _creatingCompiler = false; } yield return null; ZNetView val = (((Object)(object)island.Comp != (Object)null) ? ((Component)island.Comp).GetComponent<ZNetView>() : null); ZDO val2 = (((Object)(object)val != (Object)null) ? val.GetZDO() : null); if (val2 != null) { val2.Set("FVB_IslandId", island.Id); val2.Set("FVB_TerrainLayerId", island.Id); val2.Set("FVB_TerrainLayerY", 180f); } MeshRenderer component = ((Component)island.Map).GetComponent<MeshRenderer>(); MeshCollider component2 = ((Component)island.Map).GetComponent<MeshCollider>(); Log("NATIVE id=" + island.Id + "; rendererEnabled=" + ((Object)(object)component != (Object)null && ((Renderer)component).enabled) + "; colliderEnabled=" + ((Object)(object)component2 != (Object)null && ((Collider)component2).enabled) + "; sharedMesh=" + ((Object)(object)component2 != (Object)null && (Object)(object)component2.sharedMesh != (Object)null) + "; TerrainComp=" + ((Object)(object)island.Comp != (Object)null) + "; shell=False; customCollider=False"); } internal static void ShapeBuildData(Vector3 center, HMBuildData data) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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_00f6: Unknown result type (might be due to invalid IL or missing references) Island island = Find(center); if (!Enabled || island == null || data == null || data.m_width != 128) { return; } int num = 129; float num2 = 64f; WorldGenerator instance = WorldGenerator.instance; Color val = default(Color); for (int i = 0; i < num; i++) { for (int j = 0; j < num; j++) { int num3 = i * num + j; float num4 = center.x - num2 + (float)j; float num5 = center.z - num2 + (float)i; float biomeHeight = instance.GetBiomeHeight((Biome)1, num4, num5, ref val, false, true); float num6 = (num4 - center.x) / 64f; float num7 = (num5 - center.z) / 64f; float num8 = Mathf.Clamp01(1f - Mathf.Sqrt(num6 * num6 + num7 * num7)); data.m_baseHeights[num3] = Mathf.Clamp(biomeHeight * 0.25f, -8f, 8f) - (1f - num8) * 7f; data.m_baseMask[num3] = val; } } if (data.m_cornerBiomes != null) { for (int k = 0; k < data.m_cornerBiomes.Length; k++) { data.m_cornerBiomes[k] = BiomeSector.EmptyMeadows; } } } internal static Heightmap RouteHeightmap(Vector3 point, Heightmap vanilla) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) Island island = Find(point); if (island == null || !(Mathf.Abs(point.y - 180f) <= 40f)) { return vanilla; } return island.Map ?? vanilla; } internal static void RouteHeightmaps(Vector3 point, float radius, List<Heightmap> maps) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) Island island = Find(point); if (island != null && Mathf.Abs(point.y - 180f) <= 40f && (Object)(object)island.Map != (Object)null && !maps.Contains(island.Map)) { maps.Add(island.Map); } } internal static TerrainComp RouteCompiler(Vector3 point, TerrainComp vanilla) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) Island island = Find(point); if (island == null || Mathf.Abs(point.y - 180f) > 40f) { return vanilla; } if (_creatingCompiler) { return null; } return island.Comp ?? vanilla; } internal static bool IsClusterMap(Heightmap map) { if ((Object)(object)map != (Object)null) { return ((Object)((Component)map).gameObject).name.StartsWith("FVB_ClusterLand_", StringComparison.Ordinal); } return false; } private static Island Find(Vector3 point) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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) foreach (Island island in Islands) { if (Mathf.Abs(point.x - island.Center.x) <= 64f && Mathf.Abs(point.z - island.Center.y) <= 64f) { return island; } } for (int i = 0; i < Centers.Length; i++) { if (Mathf.Abs(point.x - Centers[i].x) <= 64f && Mathf.Abs(point.z - Centers[i].y) <= 64f) { return Get(i); } } return null; } private static void CheckBounds() { int num = 0; float num2 = float.MaxValue; float num3 = 0f; for (int i = 0; i < Centers.Length; i++) { for (int j = i + 1; j < Centers.Length; j++) { float num4 = Mathf.Max(0f, Mathf.Abs(Centers[i].x - Centers[j].x) - 128f); float num5 = Mathf.Max(0f, Mathf.Abs(Centers[i].y - Centers[j].y) - 128f); if (num4 == 0f && num5 == 0f) { num++; } float num6 = Mathf.Sqrt(num4 * num4 + num5 * num5); num2 = Mathf.Min(num2, num6); num3 = Mathf.Max(num3, num6); } } Log("BOUNDS-OVERLAP overlapCount=" + num + "; result=" + ((num == 0) ? "PASS" : "FAIL")); Log("CONNECTIVITY-VISUAL nearestUsableEdge=8..30m; minTechnicalGap=" + num2.ToString("F1") + "; maxTechnicalGap=" + num3.ToString("F1")); } private static int Seed(string id) { return ((WorldGenerator.instance != null) ? WorldGenerator.instance.GetSeed() : 0) ^ StringExtensionMethods.GetStableHashCode(id); } private static string LayoutText() { string text = string.Empty; for (int i = 0; i < Centers.Length; i++) { text = text + ((i == 0) ? "" : ";") + i + "=(" + Centers[i].x + "," + Centers[i].y + ")"; } return text; } private static void Log(string message) { FvbLog.Info(_plugin.Log, "CLUSTER", "[FVB/CLUSTER] " + message); } } [HarmonyPatch(typeof(ClutterSystem), "GetGroundInfo")] internal static class ClutterGroundRouting { private sealed class Probe { internal Vector3 Query; internal Heightmap Selected; internal Heightmap Direct; internal Heightmap Parent; internal RaycastHit Hit; internal bool HitFound; internal Collider SideCollider; internal bool SideHitRejected; } private static readonly FieldInfo PlaceRayMask = AccessTools.Field(typeof(ClutterSystem), "m_placeRayMask") ?? throw new MissingFieldException(typeof(ClutterSystem).FullName, "m_placeRayMask"); private static bool _loggedFailure; private static bool _loggedSuccess; private static bool _loggedSideRejection; [HarmonyPrefix] private static void Before(ClutterSystem __instance, Vector3 __0, out Probe __state) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_0063: 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_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0093: 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) __state = null; Heightmap val = Heightmap.FindHeightmap(new Vector3(__0.x, 350f, __0.z)); if (OrganicEdgeProofManager.IsCanonicalSurface(val)) { Probe probe = new Probe { Query = __0, Selected = val }; int num = (int)PlaceRayMask.GetValue(__instance); probe.HitFound = Physics.Raycast(__0 + Vector3.up * 500f, Vector3.down, ref probe.Hit, 1000f, num); RaycastHit val2 = default(RaycastHit); if (!_loggedSideRejection && Physics.Raycast(__0 + Vector3.up * 500f, Vector3.down, ref val2, 1000f, num | LayerMask.GetMask(new string[1] { "static_solid" })) && (Object)(object)((RaycastHit)(ref val2)).collider != (Object)null && ((Object)((Component)((RaycastHit)(ref val2)).collider).gameObject).name == "FVB_OrganicV4Sides" && OrganicEdgeProofManager.IsCanonicalSurface(((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent<Heightmap>())) { probe.SideCollider = ((RaycastHit)(ref val2)).collider; probe.SideHitRejected = (num & (1 << ((Component)((RaycastHit)(ref val2)).collider).gameObject.layer)) == 0; } if (probe.HitFound && (Object)(object)((RaycastHit)(ref probe.Hit)).collider != (Object)null) { probe.Direct = ((Component)((RaycastHit)(ref probe.Hit)).collider).GetComponent<Heightmap>(); probe.Parent = ((Component)((RaycastHit)(ref probe.Hit)).collider).GetComponentInParent<Heightmap>(); } __state = probe; } } [HarmonyPostfix] private static void After(Probe __state, Vector3 __1, Vector3 __2, Heightmap __3, Biome __4, bool __result) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) if (__state == null) { return; } if ((Object)(object)__state.SideCollider != (Object)null) { if (_loggedSideRejection) { return; } _loggedSideRejection = true; } else { if (_loggedSuccess) { return; } _loggedSuccess = true; } Log(__state, __3, __4, __1, __2, __result, "none", "PASS"); } [HarmonyFinalizer] private static Exception OnException(Exception __exception, Probe __state) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) if (__exception != null && __state != null && !_loggedFailure) { _loggedFailure = true; string failure = ((__state.HitFound && (Object)(object)((RaycastHit)(ref __state.Hit)).collider != (Object)null && (Object)(object)__state.Direct == (Object)null) ? "hitCollider.GetComponent<Heightmap>" : "GetGroundInfo/unknown"); Log(__state, __state.Direct, (Biome)0, ((RaycastHit)(ref __state.Hit)).point, ((RaycastHit)(ref __state.Hit)).normal, found: false, failure, "FAIL"); } return __exception; } private unsafe static void Log(Probe probe, Heightmap map, Biome biome, Vector3 ground, Vector3 normal, bool found, string failure, string result) { //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) FehuVanillaBiomesPlugin instance = FehuVanillaBiomesPlugin.Instance; if (!((Object)(object)instance == (Object)null)) { string text = ((probe.HitFound && (Object)(object)((RaycastHit)(ref probe.Hit)).collider != (Object)null) ? (((Object)((Component)((RaycastHit)(ref probe.Hit)).collider).gameObject).name + "#" + ((Object)((RaycastHit)(ref probe.Hit)).collider).GetInstanceID()) : "none"); Collider val = (((Object)(object)probe.SideCollider != (Object)null) ? probe.SideCollider : ((RaycastHit)(ref probe.Hit)).collider); Heightmap val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<Heightmap>() : null); Heightmap val3 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponentInParent<Heightmap>() : null); ManualLogSource log = instance.Log; string[] array = new string[46]; array[0] = "[FVB/CLUTTER] point="; Vector3 query = probe.Query; array[1] = ((object)(*(Vector3*)(&query))/*cast due to .constrained prefix*/).ToString(); array[2] = "; queryY="; array[3] = probe.Query.y.ToString("F1"); array[4] = "; selectedHeightmap="; array[5] = (((Object)(object)map != (Object)null) ? ((Object)map).GetInstanceID().ToString() : "none"); array[6] = "; selectedHeightmapCenter="; array[7] = (((Object)(object)map != (Object)null) ? ((object)((Component)map).transform.position/*cast due to .constrained prefix*/).ToString() : "none"); array[8] = "; selectedHeightmapY="; array[9] = (((Object)(object)map != (Object)null) ? ((Component)map).transform.position.y.ToString("F1") : "none"); array[10] = "; selectedIsCanonical="; array[11] = OrganicEdgeProofManager.IsCanonicalSurface(map).ToString(); array[12] = "; canonicalCandidate="; array[13] = ((Object)probe.Selected).GetInstanceID().ToString(); array[14] = "; colliderDirectHeightmap="; array[15] = (((Object)(object)probe.Direct != (Object)null) ? ((Object)probe.Direct).GetInstanceID().ToString() : "none"); array[16] = "; colliderParentHeightmap="; array[17] = (((Object)(object)probe.Parent != (Object)null) ? ((Object)probe.Parent).GetInstanceID().ToString() : "none"); array[18] = "; biome="; array[19] = ((object)(*(Biome*)(&biome))/*cast due to .constrained prefix*/).ToString(); array[20] = "; groundPoint="; query = ground; array[21] = ((object)(*(Vector3*)(&query))/*cast due to .constrained prefix*/).ToString(); array[22] = "; groundNormal="; query = normal; array[23] = ((object)(*(Vector3*)(&query))/*cast due to .constrained prefix*/).ToString(); array[24] = "; groundCollider="; array[25] = text; array[26] = "; groundFound="; array[27] = found.ToString(); array[28] = "; failureStage="; array[29] = failure; array[30] = "; hitCollider="; array[31] = (((Object)(object)val != (Object)null) ? ((Object)((Component)val).gameObject).name : "none"); array[32] = "; isSideCollider="; array[33] = ((Object)(object)probe.SideCollider != (Object)null).ToString(); array[34] = "; directHeightmap="; array[35] = (((Object)(object)val2 != (Object)null) ? ((Object)val2).GetInstanceID().ToString() : "none"); array[36] = "; parentHeightmap="; array[37] = (((Object)(object)val3 != (Object)null) ? ((Object)val3).GetInstanceID().ToString() : "none"); array[38] = "; canonicalHeightmap="; array[39] = ((Object)probe.Selected).GetInstanceID().ToString(); array[40] = "; sideHitRejected="; array[41] = probe.SideHitRejected.ToString(); array[42] = "; fallbackTopHit="; array[43] = ((Object)(object)probe.SideCollider != (Object)null && found && OrganicEdgeProofManager.IsCanonicalSurface(map)).ToString(); array[44] = "; result="; array[45] = result; FvbLog.Info(log, "CLUTTER", string.Concat(array)); } } } internal static class ElevatedBiomePopulation { private readonly struct Placement { internal readonly Vector3 Position; internal readonly Quaternion Rotation; internal readonly float Scale; internal Placement(Vector3 position, Quaternion rotation, float scale) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) Position = position; Rotation = rotation; Scale = scale; } } internal const string LogPrefix = "[FVB/BIOME-POP]"; internal const int PopulationVersion = 1; internal const string PopulationVersionKey = "FVB_PopulationVersion"; internal const string PopulationCompleteKey = "FVB_PopulationComplete"; internal const string PopulationIslandKey = "FVB_PopulationIslandId"; internal const string PopulationSlotKey = "FVB_PopulationSlotId"; internal const string PopulationCategoryKey = "FVB_PopulationCategory"; private const int TreeCap = 60; private const int BushCap = 48; private const int RockCap = 36; private const int ClutterCap = 160; private const int EquivalentVanillaZones = 4; private static readonly MethodInfo CreateObjectMethod = typeof(ZNetScene).GetMethod("CreateObject", BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[1] { typeof(ZDO) }, null) ?? throw new MissingMethodException("ZNetScene.CreateObject(ZDO)"); private static readonly FieldInfo ObjectsByIdField = typeof(ZDOMan).GetField("m_objectsByID", BindingFlags.Instance | BindingFlags.NonPublic) ?? throw new MissingFieldException("ZDOMan.m_objectsByID"); private static FehuVanillaBiomesPlugin _plugin; private static Coroutine _populationCoroutine; private static string _world = string.Empty; private static string _completedWorld = string.Empty; private static GameObject _clutterRoot; private static bool _clutterComplete; internal static void Start(FehuVanillaBiomesPlugin plugin) { _plugin = plugin; } internal static void Stop() { if ((Object)(object)_plugin != (Object)null && _populationCoroutine != null) { ((MonoBehaviour)_plugin).StopCoroutine(_populationCoroutine); } _populationCoroutine = null; if ((Object)(object)_clutterRoot != (Object)null) { Object.Destroy((Object)(object)_clutterRoot); } _clutterRoot = null; _clutterComplete = false; _world = string.Empty; _completedWorld = string.Empty; _plugin = null; } internal static void ResetWorld(string world) { if ((Object)(object)_plugin != (Object)null && _populationCoroutine != null) { ((MonoBehaviour)_plugin).StopCoroutine(_populationCoroutine); } _populationCoroutine = null; if ((Object)(object)_clutterRoot != (Object)null) { Object.Destroy((Object)(object)_clutterRoot); } _clutterRoot = null; _clutterComplete = false; _completedWorld = string.Empty; _world = world; } internal static void Ensure(Heightmap map, TerrainComp compiler, string world, float centerX, float centerZ, float layerY) { if (!((Object)(object)_plugin == (Object)null) && !((Object)(object)map == (Object)null) && !((Object)(object)compiler == (Object)null) && !string.IsNullOrEmpty(world)) { if (!_clutterComplete) { BuildLocalClutter(map, world, centerX, centerZ, layerY); } if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer() && _populationCoroutine == null && !(_completedWorld == world)) { _populationCoroutine = ((MonoBehaviour)_plugin).StartCoroutine(PopulateServer(map, compiler, world, centerX, centerZ, layerY)); } } } internal static void OnHeightmapRegenerated(Heightmap map) { if (!((Object)(object)map == (Object)null) && !((Object)(object)map != (Object)(object)LargeElevatedMeadowsIsland.Heightmap) && _clutterComplete) { if ((Object)(object)_clutterRoot != (Object)null) { Object.Destroy((Object)(object)_clutterRoot); } _clutterRoot = null; _clutterComplete = false; } } private static IEnumerator PopulateServer(Heightmap map, TerrainComp compiler, string world, float centerX, float centerZ, float layerY) { List<ZDO> list = new List<ZDO>(); try { ZNetView component = ((Component)compiler).GetComponent<ZNetView>(); ZDO val = (((Object)(object)component != (Object)null) ? component.GetZDO() : null); if (val == null) { throw new InvalidOperationException("Large TerrainComp has no persistent ZDO."); } int duplicates; Dictionary<string, ZDO> dictionary = FindPopulationObjects(out duplicates); if (duplicates > 0) { throw new InvalidOperationException($"duplicate stable population slots detected: {duplicates}"); } if (val.GetBool("FVB_PopulationComplete", false) && val.GetInt("FVB_PopulationVersion", 0) == 1) { _completedWorld = world; int num = CountCategory(dictionary.Values, "tree"); int num2 = CountCategory(dictionary.Values, "bush"); int num3 = CountCategory(dictionary.Values, "rock"); Log($"COMPLETE restore=true; persistentObjects={dictionary.Count}; duplicatesSkipped={dictionary.Count}; trees={num}; bushes={num2}; rocks={num3}; clutterSlots={(_clutterComplete ? 160 : 0)}; locations=0; caveFeatures=0"); yield break; } Log(string.Format("BEGIN world={0}; identity={1}; version={2}; seed={3}; existingSlots={4}", world, "elevated-meadows-large-v1", 1, PopulationSeed(world), dictionary.Count)); List<ZoneVegetation> source = ZoneSystem.instance.m_vegetation.Where((ZoneVegetation definition) => definition != null && definition.m_enable && (Object)(object)definition.m_prefab != (Object)null && (definition.m_biome & 1) != 0 && (definition.m_biomeArea & 2) > 0).ToList(); List<ZoneVegetation> definitions = source.Where((ZoneVegetation definition) => IsTree(((Object)definition.m_prefab).name)).ToList(); List<ZoneVegetation> definitions2 = source.Where((ZoneVegetation definition) => IsBush(((Object)definition.m_prefab).name)).ToList(); List<ZoneVegetation> definitions3 = source.Where((ZoneVegetation definition) => IsRock(((Object)definition.m_prefab).name)).ToList(); Random random = new Random(PopulationSeed(world)); List<Vector3> occupied = new List<Vector3>(); int duplicatesSkipped = 0; int num4 = PlaceCategory("tree", definitions, 60, 4f, map, centerX, centerZ, layerY, random, occupied, dictionary, list, ref duplicatesSkipped); Log($"VEGETATION trees={num4}; treeDefinitions={Names(definitions)}"); int num5 = PlaceCategory("bush", definitions2, 48, 2f, map, centerX, centerZ, layerY, random, occupied, dictionary, list, ref duplicatesSkipped); Log($"VEGETATION bushes={num5}; bushDefinitions={Names(definitions2)}"); int num6 = PlaceCategory("rock", definitions3, 36, 3f, map, centerX, centerZ, layerY, random, occupied, dictionary, list, ref duplicatesSkipped); Log($"ROCKS rocks={num6}; rockDefinitions={Names(definitions3)}"); Log("LOCATIONS locations=0; status=deferred; reason=vanilla location identity and generation are X/Z-zone scoped"); Log("CAVE caveFeatures=0; status=deferred; reason=no audited persistent vanilla shelter assembly is safe for first population pass"); Log("ANIMALS mode=vanilla-biome-routing; globalSpawnTablesModified=false"); val.Set("FVB_PopulationVersion", 1); val.Set("FVB_PopulationComplete", true); _completedWorld = world; Log($"COMPLETE trees={num4}; bushes={num5}; rocks={num6}; clutterSlots={(_clutterComplete ? 160 : 0)}; persistentObjects={dictionary.Count + list.Count}; locations=0; caveFeatures=0; duplicatesSkipped={duplicatesSkipped}"); } catch (Exception ex) { Rollback(list); LogError("population transaction rolled back; completion marker NOT written: " + ex); } finally { _populationCoroutine = null; } } private static int PlaceCategory(string category, List<ZoneVegetation> definitions, int cap, float spacing, Heightmap map, float centerX, float centerZ, float layerY, Random random, List<Vector3> occupied, Dictionary<string, ZDO> existing, List<ZDO> created, ref int duplicatesSkipped) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_00af: 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) if (definitions.Count == 0) { return 0; } Shuffle(definitions, random); int num = 0; int num2 = 0; foreach (ZoneVegetation definition in definitions) { int num3 = DefinitionGroupBudget(definition, random); for (int i = 0; i < num3; i++) { if (num >= cap) { break; } Vector2 groupCenter = RandomFootprint(random, centerX, centerZ, 57f); int num4 = Math.Max(1, random.Next(Math.Max(1, definition.m_groupSizeMin), Math.Max(1, definition.m_groupSizeMax) + 1)); for (int j = 0; j < num4; j++) { if (num >= cap) { break; } string text = $"{category}:{num2++:D4}"; Placement placement; if (existing.ContainsKey(text)) { duplicatesSkipped++; num++; } else if (TryPlacement(definition, map, groupCenter, centerX, centerZ, layerY, random, occupied, spacing, out placement)) { ZDO val = SpawnPersistent(definition, placement, text, category); if (val != null) { created.Add(val); occupied.Add(placement.Position); num++; } } } } } return num; } private static int DefinitionGroupBudget(ZoneVegetation definition, Random random) { if (definition.m_max < 1f) { return (random.NextDouble() <= (double)definition.m_max) ? 1 : 0; } int num = Math.Max(0, Mathf.FloorToInt(definition.m_min * 4f)); int num2 = Math.Max(num, Mathf.CeilToInt(definition.m_max * 4f)); return Math.Min(24, random.Next(num, num2 + 1)); } private static bool TryPlacement(ZoneVegetation definition, Heightmap map, Vector2 groupCenter, float centerX, float centerZ, float layerY, Random random, List<Vector3> occupied, float spacing, out Placement placement) { //IL_005e: 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_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00df: 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_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Unknown result type (might be due to invalid IL or missing references) //IL_02e4: Unknown result type (might be due to invalid IL or missing references) //IL_02e6: Unknown result type (might be due to invalid IL or missing references) //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_02fc: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_0301: Unknown result type (might be due to invalid IL or missing references) //IL_0321: Unknown result type (might be due to invalid IL or missing references) //IL_0326: Unknown result type (might be due to invalid IL or missing references) placement = default(Placement); float num3 = default(float); for (int i = 0; i < 24; i++) { float num = (float)(random.NextDouble() * Math.PI * 2.0); float num2 = definition.m_groupRadius * Mathf.Sqrt((float)random.NextDouble()); Vector3 point = new Vector3(groupCenter.x + Mathf.Cos(num) * num2, layerY, groupCenter.y + Mathf.Sin(num) * num2); if (!TerrainLayerRoutingPolicy.IntersectsFootprint(point.x, point.z, 0f, centerX, centerZ, 59f) || !Heightmap.GetHeight(point, ref num3)) { continue; } point.y = num3 + definition.m_groundOffset; if (map.IsCleared(point) || occupied.Any((Vector3 other) => HorizontalDistance(other, point) < spacing)) { continue; } float num4 = num3 - layerY; if (num4 < definition.m_minAltitude || num4 > definition.m_maxAltitude) { continue; } float vegetationMask = map.GetVegetationMask(point); if (definition.m_minVegetation != definition.m_maxVegetation && (vegetationMask < definition.m_minVegetation || vegetationMask > definition.m_maxVegetation)) { continue; } Vector3 val = SurfaceNormal(map, point); float y = val.y; float num5 = Mathf.Cos(definition.m_maxTilt * ((float)Math.PI / 180f)); float num6 = Mathf.Cos(definition.m_minTilt * ((float)Math.PI / 180f)); if (y < num5 || y > num6 || !PassTerrainDelta(definition, map, point)) { continue; } Vector2 val2 = new Vector2(point.x, point.z); float magnitude = ((Vector2)(ref val2)).magnitude; if ((definition.m_minDistanceFromCenter > 0f && magnitude < definition.m_minDistanceFromCenter) || (definition.m_maxDistanceFromCenter > 0f && magnitude > definition.m_maxDistanceFromCenter)) { continue; } if (definition.m_inForest) { float forestFactor = WorldGenerator.GetForestFactor(point); if (forestFactor < definition.m_forestTresholdMin || forestFactor > definition.m_forestTresholdMax) { continue; } } if ((!definition.m_surroundCheckVegetation || PassSurroundVegetation(definition, map, point)) && (!definition.m_blockCheck || !IsBlockedByNonTerrain(map, point))) { float num7 = (float)random.NextDouble() * 360f; float num8 = Mathf.Lerp(0f - definition.m_randTilt, definition.m_randTilt, (float)random.NextDouble()); float num9 = Mathf.Lerp(0f - definition.m_randTilt, definition.m_randTilt, (float)random.NextDouble()); Quaternion rotation = ((random.NextDouble() <= (double)definition.m_chanceToUseGroundTilt) ? (Quaternion.FromToRotation(Vector3.up, val) * Quaternion.Euler(0f, num7, 0f)) : Quaternion.Euler(num8, num7, num9)); float scale = Mathf.Lerp(definition.m_scaleMin, definition.m_scaleMax, (float)random.NextDouble()); placement = new Placement(point, rotation, scale); return true; } } return false; } private static bool PassTerrainDelta(ZoneVegetation definition, Heightmap map, Vector3 point) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_005a: 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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0075: 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) if (definition.m_terrainDeltaRadius <= 0f) { return true; } float num = float.MaxValue; float num2 = float.MinValue; Vector2[] array = (Vector2[])(object)new Vector2[4] { Vector2.left, Vector2.right, Vector2.up, Vector2.down }; float num3 = default(float); foreach (Vector2 val in array) { if (!Heightmap.GetHeight(point + new Vector3(val.x * definition.m_terrainDeltaRadius, 0f, val.y * definition.m_terrainDeltaRadius), ref num3)) { return false; } num = Mathf.Min(num, num3); num2 = Mathf.Max(num2, num3); } float num4 = num2 - num; if (num4 >= definition.m_minTerrainDelta) { return num4 <= definition.m_maxTerrainDelta; } return false; } private static bool PassSurroundVegetation(ZoneVegetation definition, Heightmap map, Vector3 point) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) if (definition.m_surroundCheckLayers <= 0 || definition.m_surroundCheckDistance <= 0f) { return true; } float num = 0f; int num2 = 0; for (int i = 1; i <= definition.m_surroundCheckLayers; i++) { for (int j = 0; j < 6; j++) { float num3 = (float)j / 6f * (float)Math.PI * 2f; float num4 = (float)i / (float)definition.m_surroundCheckLayers * definition.m_surroundCheckDistance; num += map.GetVegetationMask(point + new Vector3(Mathf.Sin(num3) * num4, 0f, Mathf.Cos(num3) * num4)); num2++; } } float num5 = ((num2 > 0) ? (num / (float)num2) : 0f); if (num5 >= definition.m_minVegetation) { return num5 <= definition.m_maxVegetation; } return false; } private static bool IsBlockedByNonTerrain(Heightmap map, Vector3 point) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: 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) Collider[] array = Physics.OverlapSphere(point + Vector3.up * 0.5f, 0.45f, -5, (QueryTriggerInteraction)1); foreach (Collider val in array) { if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).GetComponentInParent<Heightmap>() != (Object)(object)map) { return true; } } return false; } private static ZDO SpawnPersistent(ZoneVegetation definition, Placement placement, string slotId, string category) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) GameObject prefab = definition.m_prefab; ZNetView val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<ZNetView>() : null); if ((Object)(object)val == (Object)null) { return null; } int num = StableHash(((Object)prefab).name); if ((Object)(object)ZNetScene.instance.GetPrefab(((Object)prefab).name) != (Object)(object)prefab) { return null; } ZDO val2 = ZDOMan.instance.CreateNewZDO(placement.Position, num); if (val2 == null) { throw new InvalidOperationException("CreateNewZDO failed slot=" + slotId + "; prefab=" + ((Object)prefab).name); } val2.SetPrefab(num); val2.SetRotation(placement.Rotation); val2.Persistent = true; val2.Type = val.m_type; val2.Distant = val.m_distant; val2.Set("FVB_PopulationIslandId", "elevated-meadows-large-v1"); val2.Set("FVB_PopulationSlotId", slotId); val2.Set("FVB_PopulationCategory", category); val2.Set("FVB_PopulationVersion", 1); object? obj = CreateObjectMethod.Invoke(ZNetScene.instance, new object[1] { val2 }); GameObject val3 = (GameObject)((obj is GameObject) ? obj : null); ZNetView val4 = (((Object)(object)val3 != (Object)null) ? val3.GetComponent<ZNetView>() : null); if ((Object)(object)val4 == (Object)null || !val4.IsValid() || val4.GetZDO() == null) { ZDOMan.instance.DestroyZDO(val2); throw new InvalidOperationException("CreateObject validation failed slot=" + slotId + "; prefab=" + ((Object)prefab).name); } if (Mathf.Abs(placement.Scale - 1f) > 0.001f) { val4.SetLocalScale(Vector3.one * placement.Scale); } return val2; } private static Dictionary<string, ZDO> FindPopulationObjects(out int duplicates) { duplicates = 0; Dictionary<string, ZDO> dictionary = new Dictionary<string, ZDO>(StringComparer.Ordinal); if (!(ObjectsByIdField.GetValue(ZDOMan.instance) is Dictionary<ZDOID, ZDO> dictionary2)) { return dictionary; } foreach (ZDO value in dictionary2.Values) { if (value == null || value.GetString("FVB_PopulationIslandId", string.Empty) != "elevated-meadows-large-v1") { continue; } string text = value.GetString("FVB_PopulationSlotId", string.Empty); if (!string.IsNullOrEmpty(text)) { if (dictionary.ContainsKey(text)) { duplicates++; } else { dictionary.Add(text, value); } } } return dictionary; } private static int CountCategory(IEnumerable<ZDO> objects, string category) { return objects.Count((ZDO zdo) => zdo != null && string.Equals(zdo.GetString("FVB_PopulationCategory", string.Empty), category, StringComparison.Ordinal)); } private static void BuildLocalClutter(Heightmap map, string world, float centerX, float centerZ, float layerY) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result ty