using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using AwesomeTechnologies.VegetationSystem; using BepInEx; using BepInEx.Configuration; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using Fusion; using HarmonyLib; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using Il2CppSystem.Reflection; using Microsoft.CodeAnalysis; using SSSGame; using Unity.Collections; using Unity.Mathematics; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("AskaTidyTerrain")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.1")] [assembly: AssemblyInformationalVersion("0.1.1+8edde25dd5244eb2a60169a7a69309ac44f0660f")] [assembly: AssemblyProduct("Aska Tidy Terrain")] [assembly: AssemblyTitle("AskaTidyTerrain")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace AskaTidyTerrain { internal static class ArmingReport { internal static int Armed; internal static int Attempted; internal static bool TryPatch(Harmony harmony, MethodBase target, string label, HarmonyMethod prefix = null, HarmonyMethod postfix = null) { //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Expected O, but got Unknown //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown Attempted++; bool flag = default(bool); if (target == null) { ManualLogSource log = Plugin.Log; BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(36, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[arm-fail] "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(label); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": target method not found"); } log.LogWarning(val); return false; } try { harmony.Patch(target, prefix, postfix, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Armed++; ManualLogSource log2 = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(8, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[armed] "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(label); } log2.LogInfo(val2); return true; } catch (Exception ex) { ManualLogSource log3 = Plugin.Log; bool flag2 = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(13, 2, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[arm-fail] "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(label); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log3.LogWarning(val); return false; } } internal static void LogTotal() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(30, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] armed "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Armed); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("/"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Attempted); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" patches."); } log.LogInfo(val); } } [HarmonyPatch(typeof(Character))] public static class CharacterSpawnPatch { [HarmonyPostfix] [HarmonyPatch("Spawned")] public static void Spawned(Character __instance) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown if (__instance.IsPlayer() && ((NetworkBehaviour)__instance).GetLocalAuthorityMask() == 1 && !((Object)(object)((Component)__instance).GetComponentInChildren() != (Object)null)) { GameObject val = new GameObject("TidyTerrain_Tool"); val.transform.SetParent(((Component)__instance).gameObject.transform, false); val.AddComponent(); ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(47, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[TidyTerrain] tool attached to local player '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(((Object)((Component)__instance).gameObject).name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'."); } log.LogInfo(val2); } } } internal static class GroundHeight { private const float RaycastStartHeightMeters = 200f; private const float RaycastMaxDistanceMeters = 400f; public static bool TrySampleGroundY(Vector3 atPos, Transform selfExclude, out float groundY) { //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Expected O, but got Unknown //IL_0007: 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_0019: 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_0024: 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_015f: 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_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) groundY = 0f; try { Il2CppStructArray val = Physics.RaycastAll(new Vector3(atPos.x, atPos.y + 200f, atPos.z), Vector3.down, 400f); int num = ((Il2CppArrayBase)(object)val)?.Length ?? 0; bool flag = false; float num2 = float.NegativeInfinity; bool flag2 = false; float num3 = float.NegativeInfinity; for (int i = 0; i < num; i++) { RaycastHit val2 = ((Il2CppArrayBase)(object)val)[i]; Collider collider = ((RaycastHit)(ref val2)).collider; if (!IsSameOrRelatedTransform(((Object)(object)collider != (Object)null) ? ((Component)collider).transform : null, selfExclude)) { if ((Object)(object)collider != (Object)null && (Object)(object)((Component)collider).gameObject.GetComponent() != (Object)null && (!flag || ((RaycastHit)(ref val2)).point.y > num2)) { flag = true; num2 = ((RaycastHit)(ref val2)).point.y; } if (!flag2 || ((RaycastHit)(ref val2)).point.y > num3) { flag2 = true; num3 = ((RaycastHit)(ref val2)).point.y; } } } if (flag) { groundY = num2; return true; } if (flag2) { groundY = num3; return true; } } catch (Exception ex) { ManualLogSource log = Plugin.Log; bool flag3 = default(bool); BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(43, 3, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[TidyTerrain] ground raycast at ("); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(atPos.x, "F2"); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(","); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(atPos.z, "F2"); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(") threw: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex); } log.LogError(val3); } return false; } private static bool IsSameOrRelatedTransform(Transform hitTransform, Transform selfExclude) { if ((Object)(object)hitTransform == (Object)null || (Object)(object)selfExclude == (Object)null) { return false; } if ((Object)(object)hitTransform == (Object)(object)selfExclude) { return true; } if (hitTransform.IsChildOf(selfExclude)) { return true; } if (selfExclude.IsChildOf(hitTransform)) { return true; } return false; } } internal static class LevelingCompletionPatch { private const float MaxRadiusMeters = 200f; private static bool _hasPending; private static float _minX = float.MaxValue; private static float _maxX = float.MinValue; private static float _minZ = float.MaxValue; private static float _maxZ = float.MinValue; private static float _lastY; private static float _lastLevelActivityTime; internal static void OnRunOnAreaPostfix(TerraformingToolOperation operation, float width, float height, float blendDistance, Vector3 position, float rotation) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Expected O, but got Unknown //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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_0038: 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) try { if ((int)operation == 2) { float num = width * 0.5f; float num2 = height * 0.5f; float num3 = position.x - num; float num4 = position.x + num; float num5 = position.z - num2; float num6 = position.z + num2; if (num3 < _minX) { _minX = num3; } if (num4 > _maxX) { _maxX = num4; } if (num5 < _minZ) { _minZ = num5; } if (num6 > _maxZ) { _maxZ = num6; } _lastY = position.y; _hasPending = true; _lastLevelActivityTime = Time.time; } } catch (Exception ex) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(63, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] LevelingCompletionPatch RunOnArea postfix threw: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex); } log.LogError(val); } } internal static void Tick() { //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Expected O, but got Unknown //IL_0066: Unknown result type (might be due to invalid IL or missing references) try { if (Plugin.ConfigEnabled.Value && Plugin.AutoResnap && _hasPending && !(Time.time - _lastLevelActivityTime < Plugin.AutoResnapDelay)) { float num = (_minX + _maxX) * 0.5f; float num2 = (_minZ + _maxZ) * 0.5f; Vector3 center = new Vector3(num, _lastY, num2); float num3 = _maxX - _minX; float num4 = _maxZ - _minZ; float num5 = 0.5f * Mathf.Sqrt(num3 * num3 + num4 * num4) + 2f; if (num5 > 200f) { num5 = 200f; } TidyTerrainService.ResnapRegion(center, num5); ResetAccumulator(); } } catch (Exception ex) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(52, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] LevelingCompletionPatch Tick() threw: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex); } log.LogError(val); } } private static void ResetAccumulator() { _hasPending = false; _minX = float.MaxValue; _maxX = float.MinValue; _minZ = float.MaxValue; _maxZ = float.MinValue; _lastY = 0f; } } [BepInPlugin("smithio.aska.tidyterrain", "Aska Tidy Terrain", "0.1.1")] public class Plugin : BasePlugin { public const string PluginGuid = "smithio.aska.tidyterrain"; public const string PluginName = "Aska Tidy Terrain"; public const string PluginVersion = "0.1.1"; internal static ManualLogSource Log; internal static ConfigEntry ConfigEnabled; internal static readonly bool Vegetation = true; internal static readonly bool WorldGen = true; internal static readonly bool Corpses = true; internal static readonly float Tolerance = 0.1f; internal static readonly float SinkOffset = 0.25f; internal static readonly bool AutoResnap = true; internal static readonly float AutoResnapDelay = 0.75f; public override void Load() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Expected O, but got Unknown //IL_00d4: Expected O, but got Unknown //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Expected O, but got Unknown Log = ((BasePlugin)this).Log; ConfigEnabled = ((BasePlugin)this).Config.Bind("TidyTerrain", "Enabled", true, "Master on/off switch for Tidy Terrain."); ClassInjector.RegisterTypeInIl2Cpp(); Harmony val = new Harmony("smithio.aska.tidyterrain"); Harmony.CreateAndPatchAll(typeof(CharacterSpawnPatch), (string)null); ArmingReport.TryPatch(val, AccessTools.Method(typeof(HeightmapTool), "RunOnArea", new Type[6] { typeof(TerraformingToolOperation), typeof(float), typeof(float), typeof(float), typeof(Vector3), typeof(float) }, (Type[])null), "SSSGame.HeightmapTool.RunOnArea", null, new HarmonyMethod(typeof(LevelingCompletionPatch), "OnRunOnAreaPostfix", (Type[])null)); ArmingReport.LogTotal(); ManualLogSource log = Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(10, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted("Aska Tidy Terrain"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" v"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted("0.1.1"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" loaded."); } log.LogInfo(val2); } } internal static class TidyTerrainService { private const float PositionMatchEpsilonMeters = 0.05f; private static VegetationSystemPro _vegetationSystemPro; private static readonly List _movedWorldGenPositions = new List(); private const float CellCenterMatchEpsilonMeters = 0.01f; public static int ResnapRegion(Vector3 center, float radius) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Expected O, but got Unknown //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) _movedWorldGenPositions.Clear(); Il2CppArrayBase val; bool movedWorldGen = default(bool); try { val = Object.FindObjectsOfType(); } catch (Exception ex) { ManualLogSource log = Plugin.Log; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(53, 1, ref movedWorldGen); if (movedWorldGen) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[TidyTerrain] FindObjectsOfType() threw: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex); } log.LogError(val2); return 0; } float num = radius * radius; int num2 = 0; foreach (ItemObject item in val) { if ((Object)(object)item == (Object)null) { continue; } string text = ""; try { Transform transform = ((Component)item).transform; if (!((Object)(object)transform == (Object)null)) { text = (((Object)(object)((Component)item).gameObject != (Object)null) ? ((Object)((Component)item).gameObject).name : text); Vector3 position = transform.position; float num3 = position.x - center.x; float num4 = position.z - center.z; if (!(num3 * num3 + num4 * num4 > num) && ResnapOne(item, out movedWorldGen)) { num2++; } } } catch (Exception ex2) { ManualLogSource log2 = Plugin.Log; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(35, 2, ref movedWorldGen); if (movedWorldGen) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[TidyTerrain] error processing '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("': "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex2); } log2.LogError(val2); } } if (Plugin.Corpses) { num2 += ResnapCorpsesInRegion(center, num); } if (_movedWorldGenPositions.Count > 0) { RefreshMovedWorldGenCells(); } return num2; } private static VegetationSystemPro GetVegetationSystemPro() { if ((Object)(object)_vegetationSystemPro == (Object)null) { _vegetationSystemPro = Object.FindObjectOfType(); } return _vegetationSystemPro; } private static void RefreshMovedWorldGenCells() { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Expected O, but got Unknown //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Expected O, but got Unknown //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_02fe: Expected O, but got Unknown //IL_032e: Unknown result type (might be due to invalid IL or missing references) //IL_0335: Expected O, but got Unknown //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) bool flag = default(bool); try { VegetationSystemPro vegetationSystemPro = GetVegetationSystemPro(); if ((Object)(object)vegetationSystemPro == (Object)null) { Plugin.Log.LogWarning((object)"[TidyTerrain] no VegetationSystemPro found in scene; world-gen array writes were made but not marked dirty."); _movedWorldGenPositions.Clear(); return; } List val; try { val = vegetationSystemPro.VegetationCellList; } catch (Exception ex) { ManualLogSource log = Plugin.Log; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(68, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[TidyTerrain] reading VegetationSystemPro.VegetationCellList threw: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex); } log.LogError(val2); val = null; } if (val == null || val.Count == 0) { Plugin.Log.LogWarning((object)"[TidyTerrain] VegetationCellList unavailable/empty; falling back to global SetVegetationCellsDirty()."); try { vegetationSystemPro.SetVegetationCellsDirty(); } catch (Exception ex2) { ManualLogSource log2 = Plugin.Log; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(56, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[TidyTerrain] fallback SetVegetationCellsDirty() threw: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex2); } log2.LogError(val2); } _movedWorldGenPositions.Clear(); return; } List list = new List(); bool flag2 = false; int num = 0; foreach (Vector3 movedWorldGenPosition in _movedWorldGenPositions) { VegetationCell val3 = null; try { for (int i = 0; i < val.Count; i++) { VegetationCell val4 = val[i]; if (val4 != null) { Bounds vegetationCellBounds = val4.VegetationCellBounds; if (movedWorldGenPosition.x >= ((Bounds)(ref vegetationCellBounds)).min.x && movedWorldGenPosition.x <= ((Bounds)(ref vegetationCellBounds)).max.x && movedWorldGenPosition.z >= ((Bounds)(ref vegetationCellBounds)).min.z && movedWorldGenPosition.z <= ((Bounds)(ref vegetationCellBounds)).max.z) { val3 = val4; break; } } } } catch (Exception ex3) { ManualLogSource log3 = Plugin.Log; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(63, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[TidyTerrain] scanning VegetationCellList for position "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(movedWorldGenPosition); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" threw: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex3); } log3.LogError(val2); val3 = null; } if (val3 == null) { flag2 = true; num++; continue; } bool flag3 = false; Bounds vegetationCellBounds2 = val3.VegetationCellBounds; Vector3 center = ((Bounds)(ref vegetationCellBounds2)).center; for (int j = 0; j < list.Count; j++) { vegetationCellBounds2 = list[j].VegetationCellBounds; if (Vector3.Distance(((Bounds)(ref vegetationCellBounds2)).center, center) <= 0.01f) { flag3 = true; break; } } if (!flag3) { list.Add(val3); } } int num2 = 0; foreach (VegetationCell item in list) { try { vegetationSystemPro.ClearCache(item); num2++; } catch (Exception ex4) { ManualLogSource log4 = Plugin.Log; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(48, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[TidyTerrain] ClearCache(VegetationCell) threw: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex4); } log4.LogError(val2); } } if (!flag2) { return; } Plugin.Log.LogWarning((object)"[TidyTerrain] one or more moved world-gen positions did not match a loaded VegetationCell; falling back to global SetVegetationCellsDirty() as a safety net."); try { vegetationSystemPro.SetVegetationCellsDirty(); } catch (Exception ex5) { ManualLogSource log5 = Plugin.Log; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(58, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[TidyTerrain] safety-net SetVegetationCellsDirty() threw: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex5); } log5.LogError(val2); } } catch (Exception ex6) { ManualLogSource log6 = Plugin.Log; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(49, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[TidyTerrain] RefreshMovedWorldGenCells() threw: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex6); } log6.LogError(val2); } finally { _movedWorldGenPositions.Clear(); } } private static int ResnapCorpsesInRegion(Vector3 center, float radiusSq) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Expected O, but got Unknown //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) Il2CppArrayBase val; bool flag = default(bool); try { val = Object.FindObjectsOfType(); } catch (Exception ex) { ManualLogSource log = Plugin.Log; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(61, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[TidyTerrain] FindObjectsOfType() threw: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex); } log.LogError(val2); return 0; } int num = 0; foreach (CreatureItemObject item in val) { if ((Object)(object)item == (Object)null) { continue; } string text = ""; try { Transform transform = ((Component)item).transform; if (!((Object)(object)transform == (Object)null)) { text = (((Object)(object)((Component)item).gameObject != (Object)null) ? ((Object)((Component)item).gameObject).name : text); Vector3 position = transform.position; float num2 = position.x - center.x; float num3 = position.z - center.z; if (!(num2 * num2 + num3 * num3 > radiusSq) && ResnapCorpse(item)) { num++; } } } catch (Exception ex2) { ManualLogSource log2 = Plugin.Log; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(42, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[TidyTerrain] error processing corpse '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("': "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex2); } log2.LogError(val2); } } return num; } private static bool ResnapCorpse(CreatureItemObject creatureObj) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Expected O, but got Unknown //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) bool fullyDead; try { fullyDead = creatureObj._fullyDead; } catch (Exception ex) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(59, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] reading CreatureItemObject._fullyDead threw: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex); } log.LogError(val); return false; } if (!fullyDead) { return false; } Transform transform; bool flag2 = default(bool); try { transform = ((Component)creatureObj).transform; if ((Object)(object)transform == (Object)null) { return false; } } catch (Exception ex2) { ManualLogSource log2 = Plugin.Log; BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(46, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] reading corpse transform threw: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex2); } log2.LogError(val); return false; } if (GroundHeight.TrySampleGroundY(transform.position, transform, out var groundY) && Mathf.Abs(transform.position.y - groundY) <= Plugin.Tolerance) { return false; } try { return creatureObj._SnapToTerrain(1f); } catch (Exception ex3) { ManualLogSource log3 = Plugin.Log; BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(55, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] CreatureItemObject._SnapToTerrain threw: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex3); } log3.LogError(val); return false; } } private static bool ResnapOne(ItemObject obj, out bool movedWorldGen) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Expected O, but got Unknown //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0165: 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) movedWorldGen = false; WorldItemInstance worldInstance; try { worldInstance = ((WorldItemObject)obj).WorldInstance; } catch (Exception ex) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(43, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] reading WorldInstance threw: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex); } log.LogError(val); return false; } if (worldInstance == null) { return false; } string name; bool flag2 = default(bool); try { name = ((MemberInfo)((Il2CppObjectBase)worldInstance).Cast().GetIl2CppType()).Name; } catch (Exception ex2) { ManualLogSource log2 = Plugin.Log; BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(53, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] reading WorldInstance real type threw: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex2); } log2.LogError(val); return false; } if (name != "InventoryItemInstance" && name != "BiomeItemInstance") { return false; } Vector3 position; try { position = worldInstance.GetPosition(); } catch (Exception ex3) { ManualLogSource log3 = Plugin.Log; BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(35, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] GetPosition() threw: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex3); } log3.LogError(val); return false; } if (!GroundHeight.TrySampleGroundY(((Component)obj).transform.position, ((Component)obj).transform, out var groundY)) { return false; } float num = groundY - Plugin.SinkOffset; if (Mathf.Abs(position.y - num) <= Plugin.Tolerance) { return false; } if (name == "InventoryItemInstance") { if (!Plugin.Vegetation) { return false; } return ResnapInventoryItemInstance(worldInstance, position, num); } if (!Plugin.WorldGen) { return false; } return movedWorldGen = ResnapBiomeItemInstance(worldInstance, ((Component)obj).transform, position, num); } private static string SafeName(ItemObject obj) { try { return ((Object)(object)((Component)obj).gameObject != (Object)null) ? ((Object)((Component)obj).gameObject).name : ""; } catch { return ""; } } private static string SafeName(CreatureItemObject obj) { try { return ((Object)(object)((Component)obj).gameObject != (Object)null) ? ((Object)((Component)obj).gameObject).name : ""; } catch { return ""; } } private static bool ResnapInventoryItemInstance(WorldItemInstance wi, Vector3 currentPos, float groundY) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown try { InventoryItemInstance obj = ((Il2CppObjectBase)wi).Cast(); Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(currentPos.x, groundY, currentPos.z); bool flag = true; bool flag2 = false; obj.SetPosition(ref val, ref flag, ref flag2); return true; } catch (Exception ex) { ManualLogSource log = Plugin.Log; bool flag3 = default(bool); BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(51, 1, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[TidyTerrain] InventoryItemInstance re-snap threw: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex); } log.LogError(val2); return false; } } private static bool ResnapBiomeItemInstance(WorldItemInstance wi, Transform objTransform, Vector3 currentPos, float groundY) { //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Expected O, but got Unknown //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0085: 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_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015d: 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_0173: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0192: 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_00e1: Expected O, but got Unknown bool flag = default(bool); try { BiomeItemInstancesBuffer buffer = ((Il2CppObjectBase)wi).Cast().GetBuffer(); if (buffer == null) { Plugin.Log.LogError((object)"[TidyTerrain] BiomeItemInstance.GetBuffer() returned null; skipping."); return false; } InstancesDataArrays instances = buffer.instances; if (instances == null) { Plugin.Log.LogError((object)"[TidyTerrain] buffer.instances is null; skipping."); return false; } NativeList positions = instances.positions; if (positions == null) { Plugin.Log.LogError((object)"[TidyTerrain] arrays.positions is null; skipping."); return false; } int num = -1; int length = positions.Length; for (int i = 0; i < length; i++) { float3 val = positions[i]; float num2 = val.x - currentPos.x; float num3 = val.z - currentPos.z; if (Mathf.Abs(num2) <= 0.05f && Mathf.Abs(num3) <= 0.05f) { num = i; break; } } if (num < 0) { ManualLogSource log = Plugin.Log; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(116, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[TidyTerrain] no VSP array slot position-matched '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(((Object)(object)((Component)objTransform).gameObject != (Object)null) ? ((Object)((Component)objTransform).gameObject).name : ""); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' "); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("(positions.Length="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(length); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("); skipping world-gen re-snap for this object."); } log.LogWarning(val2); return false; } float3 val3 = default(float3); ((float3)(ref val3))..ctor(currentPos.x, groundY, currentPos.z); positions[num] = val3; Vector3 val4 = default(Vector3); ((Vector3)(ref val4))..ctor(currentPos.x, groundY, currentPos.z); objTransform.position = val4; _movedWorldGenPositions.Add(val4); return true; } catch (Exception ex) { ManualLogSource log2 = Plugin.Log; BepInExErrorLogInterpolatedStringHandler val5 = new BepInExErrorLogInterpolatedStringHandler(47, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[TidyTerrain] BiomeItemInstance re-snap threw: "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted(ex); } log2.LogError(val5); return false; } } } public class TidyTerrainTool : MonoBehaviour { private void Update() { LevelingCompletionPatch.Tick(); _ = Plugin.ConfigEnabled.Value; } } public static class MyPluginInfo { public const string PLUGIN_GUID = "AskaTidyTerrain"; public const string PLUGIN_NAME = "Aska Tidy Terrain"; public const string PLUGIN_VERSION = "0.1.1"; } }