using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using InfinityHammer; using InfinityTools; using Microsoft.CodeAnalysis; using ServerDevcommands; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.SceneManagement; using WorldEditCommands; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyFileVersion("1.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [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 InfinityHammerAddon { [BepInPlugin("sighsorry.InfinityHammerAddon", "InfinityHammerAddon", "1.0.0")] [BepInDependency("infinity_hammer", "1.79.7")] [BepInDependency("server_devcommands", "1.108.5")] [BepInDependency("world_edit_commands", "1.73.1")] public sealed class Plugin : BaseUnityPlugin { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__9_0; internal void b__9_0(ConsoleEventArgs args) { if (!Enabled.Value || Faulted || !Configuration.Enabled || !Configuration.ToolsEnabled) { throw new InvalidOperationException("Infinity Hammer addon tools are not enabled for this player."); } TerrainEdits.Execute(args); } } internal const string Guid = "sighsorry.InfinityHammerAddon"; internal const string Version = "1.0.0"; internal static ConfigEntry Enabled; internal static ConfigEntry DefaultSoftness; internal static bool Faulted; private static ConsoleCommand? _command; private readonly Harmony _harmony = new Harmony("sighsorry.InfinityHammerAddon"); private void Awake() { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown Enabled = ((BaseUnityPlugin)this).Config.Bind("General", "Enabled", true, "Enhance the existing default Infinity Hammer tools. Adds no menu entries."); DefaultSoftness = ((BaseUnityPlugin)this).Config.Bind("Level", "EdgeSoftness", 0.5f, new ConfigDescription("Initial circular Level edge softness. Alt + wheel adjusts it for the current selection.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); _harmony.PatchAll(); } private void Update() { if (Faulted) { return; } try { ToolEnhancements.UpdateInput(); } catch (Exception ex) { Faulted = true; ToolEnhancements.Clear(); ((BaseUnityPlugin)this).Logger.LogError((object)("Addon input disabled after an unexpected error; native IH tools remain available. " + ex)); } } internal static void RegisterCommand() { //IL_0042: 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_004d: Expected O, but got Unknown if (_command != null) { return; } if (Terminal.commands.ContainsKey("iha_terrain")) { throw new InvalidOperationException("Another plugin already registered iha_terrain."); } object obj = <>c.<>9__9_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { if (!Enabled.Value || Faulted || !Configuration.Enabled || !Configuration.ToolsEnabled) { throw new InvalidOperationException("Infinity Hammer addon tools are not enabled for this player."); } TerrainEdits.Execute(args); }; <>c.<>9__9_0 = val; obj = (object)val; } Helper.Command("iha_terrain", "Addon terrain edit: level softness=0..1 / paintonly / clearvegetation", (ConsoleEvent)obj); _command = Terminal.commands["iha_terrain"]; } private void OnDestroy() { _harmony.UnpatchSelf(); ToolEnhancements.Clear(); TerrainPreview.Dispose(); if (_command != null && Terminal.commands.TryGetValue("iha_terrain", out var value) && value == _command) { Terminal.commands.Remove("iha_terrain"); } _command = null; } } [HarmonyPatch(typeof(Terminal), "InitTerminal")] internal static class RegisterAddonCommand { private static void Postfix() { Plugin.RegisterCommand(); } } internal static class TerrainEdits { private const float MaxExtent = 128f; private const float MaxCoordinate = 20000f; private const float MaxDelta = 8f; internal static void Execute(ConsoleEventArgs args) { //IL_05b2: Unknown result type (might be due to invalid IL or missing references) //IL_0599: 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_0053: Expected O, but got Unknown //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_0322: Unknown result type (might be due to invalid IL or missing references) //IL_0327: Unknown result type (might be due to invalid IL or missing references) //IL_0329: Unknown result type (might be due to invalid IL or missing references) //IL_0337: Unknown result type (might be due to invalid IL or missing references) //IL_0345: Unknown result type (might be due to invalid IL or missing references) //IL_041a: Unknown result type (might be due to invalid IL or missing references) //IL_0353: Unknown result type (might be due to invalid IL or missing references) //IL_0464: Unknown result type (might be due to invalid IL or missing references) //IL_0565: Unknown result type (might be due to invalid IL or missing references) //IL_05e0: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)Player.m_localPlayer) || !Object.op_Implicit((Object)(object)ZoneSystem.instance) || !Object.op_Implicit((Object)(object)ZNet.instance) || !Object.op_Implicit((Object)(object)ZNetScene.instance)) { throw new InvalidOperationException("Terrain editing requires a loaded player world."); } ValidateArguments(args.Args, out var paintOnly, out var clearVegetation, out var softness); TerrainParameters val = new TerrainParameters(args); ValidateParameters(val, paintOnly, clearVegetation, softness); bool flag = paintOnly || clearVegetation; float num = ((val.Radius != null) ? val.Radius.Max : (Mathf.Max(val.Width.Max, val.Depth.Max) * (Mathf.Abs(Mathf.Sin(val.Angle)) + Mathf.Abs(Mathf.Cos(val.Angle))))); RequireLoadedArea(val.Position, num + 1f); TerrainComp[] array = ((val.Radius != null) ? Terrain.GetCompilers(val.Position, val.Radius) : Terrain.GetCompilers(val.Position, val.Width, val.Depth, val.Angle)).Distinct().ToArray(); if (array.Length == 0) { throw new InvalidOperationException("No terrain is loaded in the selected area."); } TerrainComp[] array2 = array; foreach (TerrainComp obj in array2) { RequireCompiler(obj); obj.m_nview.ClaimOwnership(); } array2 = array; foreach (TerrainComp obj2 in array2) { RequireOwnership(obj2); obj2.CheckLoad(); obj2.m_hmap.Poke(false); RequireCompiler(obj2); } List list = new List(); List list2 = new List(); array2 = array; foreach (TerrainComp val2 in array2) { if (val.Radius != null) { if (flag) { Terrain.GetPaintNodesWithCircle(list2, val2, val.Position, val.Radius); } else { Terrain.GetHeightNodesWithCircle(list, val2, val.Position, val.Radius); } } else if (flag) { Terrain.GetPaintNodesWithRect(list2, val2, val.Position, val.Width, val.Depth, val.Angle); } else { Terrain.GetHeightNodesWithRect(list, val2, val.Position, val.Width, val.Depth, val.Angle); } } if (list.Count == 0 && list2.Count == 0) { throw new InvalidOperationException("The selected area contains no terrain nodes."); } foreach (HeightNode item in list) { TerrainComp compiler = ((TerrainNode)item).Compiler; if (!Finite(compiler.m_levelDelta[((TerrainNode)item).Index]) || !Finite(compiler.m_smoothDelta[((TerrainNode)item).Index]) || !Finite(compiler.m_hmap.m_heights[((TerrainNode)item).Index])) { throw new InvalidOperationException("The selected terrain contains non-finite height data."); } } if (clearVegetation) { foreach (PaintNode item2 in list2) { TerrainComp compiler2 = ((TerrainNode)item2).Compiler; int num2 = compiler2.m_width + 1; Color paintMask = compiler2.m_hmap.GetPaintMask(((TerrainNode)item2).Index % num2, ((TerrainNode)item2).Index / num2); if (!Finite(paintMask.r) || !Finite(paintMask.g) || !Finite(paintMask.b) || !Finite(paintMask.a)) { throw new InvalidOperationException("The selected terrain contains non-finite paint data."); } } } array = list.Select((HeightNode n) => ((TerrainNode)n).Compiler).Concat(list2.Select((PaintNode n) => ((TerrainNode)n).Compiler)).Distinct() .ToArray(); array2 = array; for (int i = 0; i < array2.Length; i++) { RequireOwnership(array2[i]); } Dictionary data = Terrain.GetData(list, list2); Dictionary dictionary = null; try { if (paintOnly) { Terrain.ClearPaint(list2, val.Position, num); } else if (clearVegetation) { ApplyClearVegetation(list2); } else if (softness.HasValue) { ApplySoftLevel(list, val.Level.Value, softness.Value); } else { Terrain.LevelTerrain(list, val.Position, num, val.Smooth, val.Level.Value); foreach (HeightNode item3 in list) { TerrainComp compiler3 = ((TerrainNode)item3).Compiler; compiler3.m_levelDelta[((TerrainNode)item3).Index] = Mathf.Clamp(compiler3.m_levelDelta[((TerrainNode)item3).Index], -8f, 8f); compiler3.m_modifiedHeight[((TerrainNode)item3).Index] = compiler3.m_levelDelta[((TerrainNode)item3).Index] != 0f; } } dictionary = Terrain.GetData(list, list2); array2 = array; for (int i = 0; i < array2.Length; i++) { RequireOwnership(array2[i]); } array2 = array; for (int i = 0; i < array2.Length; i++) { Terrain.Save(array2[i]); } ClutterSystem instance = ClutterSystem.instance; if (instance != null) { instance.ResetGrass(val.Position, num); } } catch (Exception ex) { try { array2 = array; for (int i = 0; i < array2.Length; i++) { RequireOwnership(array2[i]); } Terrain.ApplyData(data, val.Position, num); } catch (Exception ex2) { if (dictionary != null) { AddUndo(data, dictionary, val.Position, num); } throw new AggregateException("Terrain save and restoration failed; check the terrain and use undo after it is loaded again.", ex, ex2); } throw; } AddUndo(data, dictionary, val.Position, num); } private static void AddUndo(Dictionary before, Dictionary after, Vector3 position, float radius) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown UndoManager.Add((IUndoAction)new UndoAction((IEnumerable)Array.Empty(), (IEnumerable)(object)new UndoTerrain[1] { new UndoTerrain(before, after, position, radius) })); } private static void ApplySoftLevel(List nodes, float altitude, float softness) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) foreach (HeightNode node in nodes) { float levelFalloff = GetLevelFalloff(((TerrainNode)node).Distance, softness); if (!(levelFalloff <= 0f)) { TerrainComp compiler = ((TerrainNode)node).Compiler; int index = ((TerrainNode)node).Index; float num = ((Component)compiler.m_hmap).transform.position.y + compiler.m_hmap.m_heights[index]; compiler.m_levelDelta[index] = Mathf.Clamp(compiler.m_levelDelta[index] + compiler.m_smoothDelta[index] + (altitude - num) * levelFalloff, -8f, 8f); compiler.m_smoothDelta[index] = 0f; compiler.m_modifiedHeight[index] = compiler.m_levelDelta[index] != 0f; } } } private static float GetLevelFalloff(float normalizedDistance, float softness) { if (softness <= 0f) { return 1f; } float num = Mathf.Pow(1f - softness, 1.5f); if (normalizedDistance <= num) { return 1f; } return Mathf.Pow(Mathf.Clamp01((1f - normalizedDistance) / Mathf.Max(1f - num, 1E-06f)), 1f / Mathf.Lerp(1f, 4f, softness)); } private static void ApplyClearVegetation(List nodes) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) foreach (PaintNode node in nodes) { TerrainComp compiler = ((TerrainNode)node).Compiler; int num = compiler.m_width + 1; Color paintMask = compiler.m_hmap.GetPaintMask(((TerrainNode)node).Index % num, ((TerrainNode)node).Index / num); float num2 = Mathf.Pow(1f - Mathf.Clamp01(((TerrainNode)node).Distance), 0.1f); if (!(num2 <= 0f)) { compiler.m_paintMask[((TerrainNode)node).Index] = Color.Lerp(paintMask, Color.clear, num2); compiler.m_modifiedPaint[((TerrainNode)node).Index] = true; } } } private static void RequireLoadedArea(Vector3 position, float radius) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_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_00cd: 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_00c0: 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_005d: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) Vector2i zone = ZoneSystem.GetZone(position - new Vector3(radius, 0f, radius)); Vector2i zone2 = ZoneSystem.GetZone(position + new Vector3(radius, 0f, radius)); Vector3 referencePosition = ZNet.instance.GetReferencePosition(); Vector2i val = default(Vector2i); for (int i = zone.x; i <= zone2.x; i++) { for (int j = zone.y; j <= zone2.y; j++) { ((Vector2i)(ref val))..ctor(i, j); Heightmap val2 = Heightmap.FindHeightmap(ZoneSystem.GetZonePos(val)); if (!ZoneSystem.instance.IsZoneLoaded(val) || !ZNetScene.InActiveArea(val, referencePosition) || !Object.op_Implicit((Object)(object)val2) || val2.IsDistantLod || ZoneSystem.GetZone(((Component)val2).transform.position) != val) { throw new InvalidOperationException("The complete terrain area must be loaded and active. Move closer or reduce the range, then retry."); } } } } private static void RequireCompiler(TerrainComp compiler) { if (!Object.op_Implicit((Object)(object)compiler) || !compiler.m_initialized || !Object.op_Implicit((Object)(object)compiler.m_nview) || !compiler.m_nview.IsValid() || !Object.op_Implicit((Object)(object)compiler.m_hmap) || compiler.m_width <= 0 || compiler.m_width > 128) { throw new InvalidOperationException("A selected terrain compiler is not ready; retry once the area has loaded."); } int num = (compiler.m_width + 1) * (compiler.m_width + 1); if (compiler.m_levelDelta.Length != num || compiler.m_smoothDelta.Length != num || compiler.m_modifiedHeight.Length != num || compiler.m_modifiedPaint.Length != num || compiler.m_paintMask.Length != num || compiler.m_hmap.m_heights.Count != num) { throw new InvalidOperationException("A selected terrain compiler has an unsupported node layout."); } } private static void RequireOwnership(TerrainComp compiler) { RequireCompiler(compiler); if (!compiler.m_nview.IsOwner()) { throw new InvalidOperationException("Terrain ownership is not ready. No edit was started; retry shortly."); } } private static void ValidateParameters(TerrainParameters pars, bool paintOnly, bool clearVegetation, float? softness) { if (!Finite(pars.Position.x) || !Finite(pars.Position.y) || !Finite(pars.Position.z) || Mathf.Abs(pars.Position.x) > 20000f || Mathf.Abs(pars.Position.z) > 20000f || Mathf.Abs(pars.Position.y) > 20000f || !Finite(pars.Angle) || !Finite(pars.Smooth) || pars.Smooth < 0f || pars.Smooth > 1f) { throw new InvalidOperationException("Position, angle and smoothing must be finite and within the supported limits."); } if (pars.Radius != null) { ValidateRange(pars.Radius); } else { ValidateRange(pars.Width); ValidateRange(pars.Depth); } if ((paintOnly ? 1 : 0) + (clearVegetation ? 1 : 0) + (pars.Level.HasValue ? 1 : 0) != 1) { throw new InvalidOperationException("Use exactly one operation: level, paintonly or clearvegetation."); } if (pars.Level.HasValue && (!Finite(pars.Level.Value) || Mathf.Abs(pars.Level.Value) > 20000f)) { throw new InvalidOperationException("The target height must be finite and within the supported limits."); } if (softness.HasValue && (paintOnly || clearVegetation || pars.Radius == null)) { throw new InvalidOperationException("Nonlinear softness is supported only for circular level edits."); } if (softness.HasValue && pars.Smooth != 0f) { throw new InvalidOperationException("Use softness or smooth, not both."); } if ((paintOnly || clearVegetation) && pars.Smooth != 0f) { throw new InvalidOperationException("Paint-only reset and Clear Vegetation do not support the smooth parameter."); } } private static void ValidateRange(Range range) { if (!Finite(range.Min) || !Finite(range.Max) || range.Min < 0f || range.Min > range.Max || range.Max <= 0f || range.Max > 128f) { throw new InvalidOperationException("Terrain radius and rectangle half-extents must be greater than zero and no larger than 128 metres."); } } private static void ValidateArguments(string[] args, out bool paintOnly, out bool clearVegetation, out float? softness) { paintOnly = false; clearVegetation = false; softness = null; HashSet hashSet = new HashSet(StringComparer.OrdinalIgnoreCase); for (int i = 1; i < args.Length; i++) { if (string.IsNullOrWhiteSpace(args[i])) { continue; } string[] array = args[i].Split(new char[1] { '=' }); string text = array[0].ToLowerInvariant(); string text2 = ((array.Length == 2) ? array[1] : null); if (array.Length > 2 || !hashSet.Add(text)) { throw new InvalidOperationException("Invalid or duplicate terrain argument: " + args[i]); } if (((text == "id" || text == "ignore") && text2 != null) || (text == "blockcheck" && string.Equals(text2, "off", StringComparison.OrdinalIgnoreCase)) || (text == "chance" && text2 != null && ReadNumber(text2) == 1f)) { continue; } switch (text) { case "paintonly": if (text2 != null) { throw new InvalidOperationException("Use paintonly without a value."); } paintOnly = true; break; case "clearvegetation": if (text2 != null) { throw new InvalidOperationException("Use clearvegetation without a value."); } clearVegetation = true; break; case "level": if (text2 != null) { ReadNumber(text2); } break; case "softness": softness = ReadNumber(text2); if (softness < 0f || softness > 1f) { throw new InvalidOperationException("Softness must be between 0 and 1."); } break; case "smooth": ReadNumber(text2); break; case "circle": if (text2 != null) { ValidateRangeText(text2); } break; case "rect": if (text2 != null) { string[] array2 = text2.Split(new char[1] { ',' }); if (array2.Length > 2) { throw new InvalidOperationException("Use rect=width,depth."); } string[] array3 = array2; for (int j = 0; j < array3.Length; j++) { ValidateRangeText(array3[j]); } } break; case "offset": case "from": case "step": case "to": { if (text2 == null) { throw new InvalidOperationException("Missing value for " + text); } string[] array4 = text2.Split(new char[1] { ',' }); if (array4.Length < 1 || array4.Length > 3) { throw new InvalidOperationException("Invalid coordinate value for " + text); } string[] array3 = array4; for (int j = 0; j < array3.Length; j++) { ReadNumber(array3[j]); } break; } case "angle": if (text2 == null || !new string[8] { "n", "ne", "e", "se", "s", "sw", "w", "nw" }.Contains(text2.ToLowerInvariant())) { ReadNumber(text2); } break; default: throw new InvalidOperationException("Unsupported addon terrain argument: " + text + ". Use the original terrain command for filters and other operations."); } } } private static void ValidateRangeText(string value) { Match match = Regex.Match(value, "\\A([+]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?:[eE][+]?\\d+)?)(?:[-;]([+]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?:[eE][+]?\\d+)?))?\\z"); if (!match.Success) { throw new InvalidOperationException("Invalid non-negative terrain range: " + value); } ReadNumber(match.Groups[1].Value); if (match.Groups[2].Success) { ReadNumber(match.Groups[2].Value); } } private static float ReadNumber(string? value) { if (value == null || !float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out var result) || !Finite(result)) { throw new InvalidOperationException("Invalid finite number: " + value); } return result; } private static bool Finite(float value) { if (!float.IsNaN(value)) { return !float.IsInfinity(value); } return false; } } internal static class TerrainPreview { private const int MaxMarkers = 2048; private const float SurfaceOffset = 0.06f; private const float MovingRefresh = 1f / 30f; private const float StationaryRefresh = 0.25f; private static readonly Color PreviewColor = new Color(1f, 0.15f, 0.8f, 0.9f); private static readonly List Heightmaps = new List(); private static readonly HashSet SeenNodes = new HashSet(); private static readonly List Vertices = new List(8192); private static readonly List Indices = new List(12288); private static readonly List Colors = new List(8192); private static GameObject? _root; private static LineRenderer? _outline; private static LineRenderer? _startMarker; private static MeshRenderer? _nodesRenderer; private static Mesh? _nodesMesh; private static Material? _material; private static ZNetScene? _world; private static Vector3 _lastStart; private static Vector3 _lastEnd; private static float _lastSize; private static float _lastRefresh; private static int _lastKind; private static int _sceneHandle; internal static void ShowCircle(Vector3 center, float radius, bool showNodes) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) if (!IsFinite(center) || !ValidSize(radius) || !EnsureResources()) { Hide(); } else { if (!ShouldRefresh((!showNodes) ? 1 : 2, center, center, radius)) { return; } CollectHeightmaps(center, radius); int num = Mathf.Clamp(Mathf.CeilToInt(radius * (float)Math.PI * 2f), 64, 768); _outline.positionCount = num; _outline.loop = true; for (int i = 0; i < num; i++) { float num2 = (float)i * (float)Math.PI * 2f / (float)num; Vector3 val = center + new Vector3(Mathf.Cos(num2) * radius, 0f, Mathf.Sin(num2) * radius); if (TryGetSurfaceHeight(val, out var height)) { val.y = height; } val.y += 0.06f; _outline.SetPosition(i, val); } ((Renderer)_startMarker).enabled = false; ((Renderer)_nodesRenderer).enabled = showNodes && DrawPaintNodes(center, radius); _root.SetActive(true); } } internal static void ShowSlope(Vector3 start, Vector3 end, float halfWidth) { //IL_0000: 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_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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_0045: 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_0057: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: 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_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: 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_0100: 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) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0117: 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_0128: 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_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_016e: 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_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0188: 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_0197: Unknown result type (might be due to invalid IL or missing references) if (!IsFinite(start) || !IsFinite(end) || !ValidSize(halfWidth) || !EnsureResources()) { Hide(); } else { if (!ShouldRefresh(3, start, end, halfWidth)) { return; } Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(end.x - start.x, 0f, end.z - start.z); if (!IsFinite(val) || ((Vector3)(ref val)).sqrMagnitude > 16777216f) { Hide(); return; } Vector3 val2; if (!(((Vector3)(ref val)).sqrMagnitude > 0.0001f)) { val2 = Vector3.right * halfWidth; } else { Vector3 val3 = new Vector3(val.z, 0f, 0f - val.x); val2 = ((Vector3)(ref val3)).normalized * halfWidth; } Vector3 val4 = val2; Vector3 val5 = Vector3.up * 0.06f; _outline.positionCount = 4; _outline.loop = true; _outline.SetPosition(0, start - val4 + val5); _outline.SetPosition(1, end - val4 + val5); _outline.SetPosition(2, end + val4 + val5); _outline.SetPosition(3, start + val4 + val5); _startMarker.positionCount = 16; _startMarker.loop = true; for (int i = 0; i < 16; i++) { float num = (float)i * (float)Math.PI / 8f; _startMarker.SetPosition(i, start + val5 + new Vector3(Mathf.Cos(num), 0f, Mathf.Sin(num)) * 0.25f); } ((Renderer)_startMarker).enabled = true; ((Renderer)_nodesRenderer).enabled = false; _root.SetActive(true); } } internal static void Hide() { if (_world != null && (!Object.op_Implicit((Object)(object)ZNetScene.instance) || _world != ZNetScene.instance)) { Dispose(); return; } if (Object.op_Implicit((Object)(object)_root)) { _root.SetActive(false); } _lastKind = 0; } internal static void Dispose() { SceneManager.sceneUnloaded -= OnSceneUnloaded; if (Object.op_Implicit((Object)(object)_root)) { Object.Destroy((Object)(object)_root); } if (Object.op_Implicit((Object)(object)_nodesMesh)) { Object.Destroy((Object)(object)_nodesMesh); } if (Object.op_Implicit((Object)(object)_material)) { Object.Destroy((Object)(object)_material); } _root = null; _outline = null; _startMarker = null; _nodesRenderer = null; _nodesMesh = null; _material = null; _world = null; _lastKind = 0; Heightmaps.Clear(); SeenNodes.Clear(); Vertices.Clear(); Indices.Clear(); Colors.Clear(); } private static bool EnsureResources() { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0068: 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_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Expected O, but got Unknown //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00de: 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_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0113: 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_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_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Expected O, but got Unknown ZNetScene instance = ZNetScene.instance; if (!Object.op_Implicit((Object)(object)instance)) { Dispose(); return false; } if (_world != instance || !Object.op_Implicit((Object)(object)_root)) { Dispose(); } if (Object.op_Implicit((Object)(object)_root)) { return true; } Shader val = Shader.Find("Sprites/Default"); if (!Object.op_Implicit((Object)(object)val)) { return false; } _world = instance; _material = new Material(val) { name = "InfinityHammerAddon.Preview", hideFlags = (HideFlags)52, color = Color.white }; _root = new GameObject("InfinityHammerAddon.Preview") { hideFlags = (HideFlags)52 }; _root.SetActive(false); Scene scene = _root.scene; _sceneHandle = ((Scene)(ref scene)).handle; SceneManager.sceneUnloaded += OnSceneUnloaded; _outline = CreateLine("Range", PreviewColor); _startMarker = CreateLine("SlopeStart", Color.white); GameObject val2 = new GameObject("PaintNodes") { hideFlags = (HideFlags)52 }; val2.transform.SetParent(_root.transform, false); _nodesRenderer = val2.AddComponent(); ((Renderer)_nodesRenderer).sharedMaterial = _material; ((Renderer)_nodesRenderer).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)_nodesRenderer).receiveShadows = false; ((Renderer)_nodesRenderer).enabled = false; _nodesMesh = new Mesh { name = "InfinityHammerAddon.PaintNodes", hideFlags = (HideFlags)52 }; _nodesMesh.MarkDynamic(); val2.AddComponent().sharedMesh = _nodesMesh; return true; } private static LineRenderer CreateLine(string name, Color color) { //IL_0001: 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_000e: 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_0055: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name) { hideFlags = (HideFlags)52 }; val.transform.SetParent(_root.transform, false); LineRenderer obj = val.AddComponent(); ((Renderer)obj).sharedMaterial = _material; obj.useWorldSpace = true; obj.widthMultiplier = 0.05f; obj.numCornerVertices = 2; obj.startColor = color; obj.endColor = color; ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj).receiveShadows = false; return obj; } private static void OnSceneUnloaded(Scene scene) { if (((Scene)(ref scene)).handle == _sceneHandle || !Object.op_Implicit((Object)(object)ZNetScene.instance)) { Dispose(); } } private static bool ShouldRefresh(int kind, Vector3 start, Vector3 end, float size) { //IL_0011: 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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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) float num = Time.unscaledTime - _lastRefresh; bool flag = ((Vector3)(ref _lastStart)).Equals(start) && ((Vector3)(ref _lastEnd)).Equals(end) && _lastSize == size; if (_lastKind == kind && _root.activeSelf && num >= 0f && num < (flag ? 0.25f : (1f / 30f))) { return false; } _lastKind = kind; _lastStart = start; _lastEnd = end; _lastSize = size; _lastRefresh = Time.unscaledTime; return true; } private static void CollectHeightmaps(Vector3 center, float radius) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) Heightmaps.Clear(); Heightmap.FindHeightmap(center, radius + 1f, Heightmaps); Heightmaps.RemoveAll((Heightmap hmap) => !IsReady(hmap)); } private static bool IsReady(Heightmap hmap) { if (Object.op_Implicit((Object)(object)hmap) && ((Behaviour)hmap).isActiveAndEnabled && !hmap.IsDistantLod && hmap.m_width > 0 && hmap.m_width <= 1024 && ValidSize(hmap.m_scale) && hmap.m_heights != null) { return hmap.m_heights.Count == (hmap.m_width + 1) * (hmap.m_width + 1); } return false; } private static bool DrawPaintNodes(Vector3 center, float radius) { //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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: 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_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_011f: 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_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) Vertices.Clear(); Indices.Clear(); Colors.Clear(); SeenNodes.Clear(); if (!Object.op_Implicit((Object)(object)ZNet.instance)) { return false; } Vector3 referencePosition = ZNet.instance.GetReferencePosition(); Vector3 val = default(Vector3); foreach (Heightmap heightmap in Heightmaps) { if (!ZNetScene.InActiveArea(ZoneSystem.GetZone(((Component)heightmap).transform.position), referencePosition)) { continue; } Vector3 position = ((Component)heightmap).transform.position; float num = position.x - (float)(heightmap.m_width / 2) * heightmap.m_scale; float num2 = position.z - (float)(heightmap.m_width / 2) * heightmap.m_scale; int num3 = Mathf.Clamp(Mathf.FloorToInt((center.x - radius - num) / heightmap.m_scale), 0, heightmap.m_width); int num4 = Mathf.Clamp(Mathf.CeilToInt((center.x + radius - num) / heightmap.m_scale), 0, heightmap.m_width); int num5 = Mathf.Clamp(Mathf.FloorToInt((center.z - radius - num2) / heightmap.m_scale), 0, heightmap.m_width); int num6 = Mathf.Clamp(Mathf.CeilToInt((center.z + radius - num2) / heightmap.m_scale), 0, heightmap.m_width); for (int i = num3; i <= num4; i++) { for (int j = num5; j <= num6; j++) { ((Vector3)(ref val))..ctor(position.x + (float)(i - heightmap.m_width / 2) * heightmap.m_scale, position.y + heightmap.GetHeight(i, j), position.z + (float)(j - heightmap.m_width / 2) * heightmap.m_scale); if (!(Utils.DistanceXZ(center, val) > radius) && IsFinite(val) && SeenNodes.Add(new Vector2(val.x, val.z))) { if (SeenNodes.Count > 2048) { return false; } val.y += 0.06f; AddMarker(val); } } } } if (Vertices.Count == 0) { return false; } _nodesMesh.Clear(); _nodesMesh.SetVertices(Vertices); _nodesMesh.SetColors(Colors); _nodesMesh.SetTriangles(Indices, 0); _nodesMesh.RecalculateBounds(); return true; } private static void AddMarker(Vector3 center) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: 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_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_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) int count = Vertices.Count; Vertices.Add(center + new Vector3(-0.08f, 0f, -0.08f)); Vertices.Add(center + new Vector3(-0.08f, 0f, 0.08f)); Vertices.Add(center + new Vector3(0.08f, 0f, 0.08f)); Vertices.Add(center + new Vector3(0.08f, 0f, -0.08f)); for (int i = 0; i < 4; i++) { Colors.Add(PreviewColor); } Indices.Add(count); Indices.Add(count + 1); Indices.Add(count + 2); Indices.Add(count); Indices.Add(count + 2); Indices.Add(count + 3); } private static bool TryGetSurfaceHeight(Vector3 point, out float height) { //IL_001e: 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_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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_0108: Unknown result type (might be due to invalid IL or missing references) foreach (Heightmap heightmap in Heightmaps) { Vector3 position = ((Component)heightmap).transform.position; float num = (point.x - position.x) / heightmap.m_scale + (float)(heightmap.m_width / 2); float num2 = (point.z - position.z) / heightmap.m_scale + (float)(heightmap.m_width / 2); if (!(num < 0f) && !(num2 < 0f) && !(num > (float)heightmap.m_width) && !(num2 > (float)heightmap.m_width)) { int num3 = Mathf.Min(Mathf.FloorToInt(num), heightmap.m_width - 1); int num4 = Mathf.Min(Mathf.FloorToInt(num2), heightmap.m_width - 1); float num5 = num - (float)num3; float num6 = num2 - (float)num4; float height2 = heightmap.GetHeight(num3, num4); float height3 = heightmap.GetHeight(num3 + 1, num4); float height4 = heightmap.GetHeight(num3, num4 + 1); float height5 = heightmap.GetHeight(num3 + 1, num4 + 1); height = position.y + ((num5 + num6 <= 1f) ? (height2 + (height3 - height2) * num5 + (height4 - height2) * num6) : (height5 + (height4 - height5) * (1f - num5) + (height3 - height5) * (1f - num6))); return IsFinite(height); } } height = 0f; return false; } private static bool ValidSize(float size) { if (IsFinite(size) && size > 0f) { return size <= 4096f; } return false; } private static bool IsFinite(float value) { if (!float.IsNaN(value)) { return !float.IsInfinity(value); } return false; } private static bool IsFinite(Vector3 value) { //IL_0000: 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_001a: Unknown result type (might be due to invalid IL or missing references) if (IsFinite(value.x) && IsFinite(value.y)) { return IsFinite(value.z); } return false; } } internal static class ToolEnhancements { private enum Kind { Level, Paint, Reset, Slope } private sealed class ToolInfo { internal readonly Kind Kind; internal readonly int Paint; internal ToolInfo(Kind kind, int paint = 0) { Kind = kind; Paint = paint; } } private static readonly string[] PaintNames = new string[10] { "Grass", "Dirt", "Cultivate", "Pave", "DarkGrass", "PatchyGrass", "MossyPaving", "DirtPaving", "DarkPaving", "ClearVegetation" }; private static readonly string[] PaintValues = new string[10] { "grass", "dirt", "cultivated", "paved", "grass_dark", "patches", "paved_moss", "paved_dirt", "paved_dark", "" }; private static readonly ConditionalWeakTable Recognized = new ConditionalWeakTable(); private static ToolSelection? _selection; private static ToolInfo? _info; private static ZNetScene? _world; private static Vector3? _slopeStart; private static bool _paintOnly; private static int _paint; private static float _softness; private static int _wheelFrame = -1; private static int _altFrame = -1; internal static void Recognize(Tool tool, ToolData data) { if (data.commands != null) { return; } string text = Regex.Replace(data.command.Trim(), "\\s+", " "); ToolInfo toolInfo = null; if (data.name == "Level" && text == "terrain level smooth=?.5:0 ") { toolInfo = new ToolInfo(Kind.Level); } if (data.name == "Reset" && text == "terrain reset ") { toolInfo = new ToolInfo(Kind.Reset); } if (data.name == "Slope" && text == "terrain slope " && data.targetEdge == "true") { toolInfo = new ToolInfo(Kind.Slope); } for (int i = 0; i < PaintValues.Length - 1; i++) { if (data.name == PaintNames[i] && text == "terrain paint=" + PaintValues[i] + " ") { toolInfo = new ToolInfo(Kind.Paint, i); } } if (toolInfo != null) { Recognized.Add(tool, toolInfo); } } private static bool RefreshSelection() { Player localPlayer = Player.m_localPlayer; if (Plugin.Enabled.Value && !Plugin.Faulted && Object.op_Implicit((Object)(object)localPlayer) && Object.op_Implicit((Object)(object)ZNetScene.instance) && ((Character)localPlayer).InPlaceMode() && Configuration.Enabled && Configuration.ToolsEnabled) { BaseSelection obj = Selection.Get(); ToolSelection val = (ToolSelection)(object)((obj is ToolSelection) ? obj : null); if (val != null && Recognized.TryGetValue(val.Tool, out ToolInfo value)) { if (_selection != val || _world != ZNetScene.instance) { Clear(); _selection = val; _info = value; _world = ZNetScene.instance; _paint = value.Paint; _softness = Plugin.DefaultSoftness.Value; } return true; } } Clear(); return false; } internal static void Clear() { if (_selection != null && Object.op_Implicit((Object)(object)Ruler.Projector)) { Ruler.Projector.SetActive(true); } _selection = null; _info = null; _world = null; _slopeStart = null; _paintOnly = false; _wheelFrame = -1; _altFrame = -1; TerrainPreview.Hide(); } private static bool CanInput() { if (!Console.IsVisible() && (!Object.op_Implicit((Object)(object)Chat.instance) || !Chat.instance.HasFocus()) && !TextInput.IsVisible() && !Menu.IsVisible() && !InventoryGui.IsVisible()) { if (Object.op_Implicit((Object)(object)Hud.instance)) { return !Hud.instance.m_pieceSelectionWindow.activeSelf; } return true; } return false; } private static bool BareAlt() { if ((Input.GetKey((KeyCode)308) || Input.GetKey((KeyCode)307)) && !Input.GetKey((KeyCode)306) && !Input.GetKey((KeyCode)305) && !Input.GetKey((KeyCode)304)) { return !Input.GetKey((KeyCode)303); } return false; } internal static void UpdateInput() { if (!RefreshSelection() || !CanInput()) { return; } if (_altFrame != Time.frameCount && BareAlt() && (Input.GetKeyDown((KeyCode)308) || Input.GetKeyDown((KeyCode)307))) { _altFrame = Time.frameCount; if (_info.Kind == Kind.Slope) { _slopeStart = null; } if (_info.Kind == Kind.Reset) { _paintOnly = !_paintOnly; Message(_paintOnly ? "Reset: paint only" : "Reset: terrain + paint"); } } ConsumeWheel(); } internal static bool ConsumeWheel() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) if (!RefreshSelection() || !CanInput() || !BareAlt() || Input.mouseScrollDelta.y == 0f || (_info.Kind != Kind.Paint && (_info.Kind != Kind.Level || (int)Ruler.Shape != 0))) { return false; } if (_wheelFrame == Time.frameCount) { return true; } if (HasNativeWheelConflict()) { return false; } _wheelFrame = Time.frameCount; int num = ((Input.mouseScrollDelta.y > 0f) ? 1 : (-1)); if (_info.Kind == Kind.Level) { _softness = Mathf.Clamp01(_softness + (float)num * 0.05f); Message("Level edge softness: " + _softness.ToString("0.00", CultureInfo.InvariantCulture)); } else { _paint = (_paint + num + PaintValues.Length) % PaintValues.Length; Message("Paint: " + PaintNames[_paint]); } return true; } private static bool HasNativeWheelConflict() { foreach (CommandBind bestWheelCommand in BindManager.GetBestWheelCommands()) { string text = Aliasing.Plain(bestWheelCommand.Command).Trim(); if (text.IndexOf(';') >= 0 || MultiCommands.Split(text).Length != 1) { return true; } int i; for (i = 0; i < text.Length && !char.IsWhiteSpace(text[i]); i++) { } string text2 = text.Substring(0, i); if (!text2.Equals("_bind_command_radius_mouse_wheel", StringComparison.OrdinalIgnoreCase) && !text2.Equals("hammer_zoom_x", StringComparison.OrdinalIgnoreCase)) { return true; } } return false; } internal static bool BeforePlace(ToolSelection selection, GameObject obj) { //IL_003c: 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_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0076: 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_0089: 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_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) UpdateInput(); if (!RefreshSelection() || selection != _selection || _info.Kind != Kind.Slope) { return true; } if (Object.op_Implicit((Object)(object)obj.GetComponent())) { return true; } Vector3 position = HammerHelper.GetPlacementGhost().transform.position; if (!_slopeStart.HasValue) { _slopeStart = position; Message("Slope start set. Click the end point; Alt cancels."); Object.Destroy((Object)(object)obj); return false; } Vector3 value = _slopeStart.Value; float num = Utils.DistanceXZ(value, position); float x = Scaling.Get().X; if (!Finite(value) || !Finite(position) || float.IsNaN(x) || float.IsInfinity(x) || x <= 0f || x > 128f || num < 0.25f || num > 256f) { Message("Slope requires distinct points within 256 m and a half-width of at most 128 m."); Object.Destroy((Object)(object)obj); return false; } obj.AddComponent().Command = "terrain slope from=" + Coordinates(value) + " to=" + Coordinates(position) + " rect=" + Number(x) + "," + Number(num / 2f); _slopeStart = null; return false; } internal static void AfterPlace(ToolSelection selection, GameObject obj) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) if (_selection != selection || _info == null || !Object.op_Implicit((Object)(object)obj)) { return; } PlacedCommand component = obj.GetComponent(); if (!Object.op_Implicit((Object)(object)component) || component.Command.Contains(";")) { return; } string command = component.Command; if (_info.Kind == Kind.Level && (int)Ruler.Shape == 0 && command.StartsWith("terrain level ", StringComparison.Ordinal)) { string text = Regex.Replace(command.Substring("terrain level ".Length), "(?:^|\\s)smooth=\\S+", ""); component.Command = "iha_terrain level softness=" + Number(_softness) + " " + text; } else if (_info.Kind == Kind.Reset && _paintOnly && command.StartsWith("terrain reset ", StringComparison.Ordinal)) { component.Command = "iha_terrain paintonly " + command.Substring("terrain reset ".Length); } else if (_info.Kind == Kind.Paint && command.StartsWith("terrain paint=", StringComparison.Ordinal)) { int num = command.IndexOf(' ', "terrain paint=".Length); if (num >= 0) { string text2 = command.Substring(num + 1); component.Command = ((_paint == PaintValues.Length - 1) ? ("iha_terrain clearvegetation " + text2) : ("terrain paint=" + PaintValues[_paint] + " " + text2)); } } } internal static bool BeforeRuler() { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) UpdateInput(); if (!RefreshSelection() || _info.Kind != Kind.Slope) { return true; } if (Object.op_Implicit((Object)(object)Ruler.Projector)) { Ruler.Projector.SetActive(false); } if (!CanInput() || !Object.op_Implicit((Object)(object)Player.m_localPlayer.m_placementGhost)) { TerrainPreview.Hide(); return false; } Vector3 position = Player.m_localPlayer.m_placementGhost.transform.position; TerrainPreview.ShowSlope(_slopeStart ?? position, position, Scaling.Get().X); return false; } internal static void AfterRuler() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) if (_info == null || _info.Kind == Kind.Slope) { return; } if (!CanInput() || !Object.op_Implicit((Object)(object)Player.m_localPlayer) || !Object.op_Implicit((Object)(object)Player.m_localPlayer.m_placementGhost) || (int)Ruler.Shape != 0 || (_info.Kind != Kind.Paint && _info.Kind != Kind.Reset)) { TerrainPreview.Hide(); return; } if (Object.op_Implicit((Object)(object)Ruler.Projector)) { Ruler.Projector.SetActive(false); } TerrainPreview.ShowCircle(Player.m_localPlayer.m_placementGhost.transform.position, Scaling.Get().X, _info.Kind == Kind.Paint || _paintOnly); } internal static void Describe(Hud hud, Piece piece) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)piece) || !RefreshSelection() || !CanInput() || (Object)(object)piece != (Object)(object)((BaseSelection)_selection).GetSelectedPiece()) { return; } string text; switch (_info.Kind) { case Kind.Level: if ((int)Ruler.Shape != 0) { return; } text = "Level terrain — edge softness: " + _softness.ToString("0.00", CultureInfo.InvariantCulture) + "\nAlt + wheel: softness · Wheel: range\nCtrl: free mode · AltPlace: player height"; break; case Kind.Paint: text = "Paint: " + PaintNames[_paint] + "\nAlt + wheel: paint type · Wheel: range\nHold Alt: single use · Ctrl: free mode"; break; case Kind.Reset: text = "Reset: " + (_paintOnly ? "PAINT ONLY (height unchanged)" : "TERRAIN + PAINT") + "\nTap Alt: switch reset mode · Wheel: range\nHold Alt: single use · Ctrl: free mode"; break; default: text = "Slope: click the " + (_slopeStart.HasValue ? "END" : "START") + " point\nWheel: width · Alt: cancel"; break; } string text2 = ((_info.Kind == Kind.Slope) ? ("Width: " + Number(Scaling.Get().X * 2f) + " m") : Ruler.DescriptionScale(_selection)); string text3 = ((_info.Kind == Kind.Slope) ? "" : ("\n" + Ruler.DescriptionPosition())); hud.m_pieceDescription.text = text + "\n" + text2 + text3; } private static void Message(string message) { Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)2, message, 0, (Sprite)null); } } private static string Number(float value) { return value.ToString("R", CultureInfo.InvariantCulture); } private static string Coordinates(Vector3 value) { //IL_0008: 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_0034: Unknown result type (might be due to invalid IL or missing references) return Number(value.x) + "," + Number(value.z) + "," + Number(value.y); } private static bool Finite(Vector3 value) { //IL_0000: 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_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0034: 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) if (!float.IsNaN(value.x) && !float.IsNaN(value.y) && !float.IsNaN(value.z) && !float.IsInfinity(value.x) && !float.IsInfinity(value.y)) { return !float.IsInfinity(value.z); } return false; } } [HarmonyPatch(/*Could not decode attribute arguments.*/)] internal static class RecognizeDefaultTool { private static void Postfix(Tool __instance, ToolData data) { ToolEnhancements.Recognize(__instance, data); } } [HarmonyPatch(typeof(ToolSelection), "AfterPlace")] internal static class EnhanceToolPlacement { private static bool Prefix(ToolSelection __instance, GameObject obj, out bool __state) { __state = ToolEnhancements.BeforePlace(__instance, obj); return __state; } private static void Postfix(ToolSelection __instance, GameObject obj, bool __state) { if (__state) { ToolEnhancements.AfterPlace(__instance, obj); } } } [HarmonyPatch(typeof(Ruler), "Update")] internal static class EnhanceToolRuler { private static bool Prefix() { return ToolEnhancements.BeforeRuler(); } private static void Postfix() { ToolEnhancements.AfterRuler(); } } [HarmonyPatch(typeof(ScalingData), "ZoomX")] internal static class ReserveAltWheel { private static bool Prefix(ScalingData __instance) { if (__instance == Scaling.Get(true)) { return !ToolEnhancements.ConsumeWheel(); } return true; } } [HarmonyPatch(typeof(Hud), "SetupPieceInfo")] internal static class DescribeEnhancedTool { [HarmonyAfter(new string[] { "infinity_hammer" })] [HarmonyPriority(0)] private static void Postfix(Hud __instance, Piece piece) { ToolEnhancements.Describe(__instance, piece); } } }