Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of InfinityHammerAddon v1.0.0
InfinityHammerAddon.dll
Decompiled 2 days agousing 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 <RegisterCommand>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<bool> Enabled; internal static ConfigEntry<float> 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<bool>("General", "Enabled", true, "Enhance the existing default Infinity Hammer tools. Adds no menu entries."); DefaultSoftness = ((BaseUnityPlugin)this).Config.Bind<float>("Level", "EdgeSoftness", 0.5f, new ConfigDescription("Initial circular Level edge softness. Alt + wheel adjusts it for the current selection.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); _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<HeightNode> list = new List<HeightNode>(); List<PaintNode> list2 = new List<PaintNode>(); 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<Vector3, TerrainUndoData> data = Terrain.GetData(list, list2); Dictionary<Vector3, TerrainUndoData> 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<Vector3, TerrainUndoData> before, Dictionary<Vector3, TerrainUndoData> 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<UndoData>)Array.Empty<UndoData>(), (IEnumerable<UndoTerrain>)(object)new UndoTerrain[1] { new UndoTerrain(before, after, position, radius) })); } private static void ApplySoftLevel(List<HeightNode> 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<PaintNode> 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<float> 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<string> hashSet = new HashSet<string>(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<Heightmap> Heightmaps = new List<Heightmap>(); private static readonly HashSet<Vector2> SeenNodes = new HashSet<Vector2>(); private static readonly List<Vector3> Vertices = new List<Vector3>(8192); private static readonly List<int> Indices = new List<int>(12288); private static readonly List<Color> Colors = new List<Color>(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<MeshRenderer>(); ((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<MeshFilter>().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<LineRenderer>(); ((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<Tool, ToolInfo> Recognized = new ConditionalWeakTable<Tool, ToolInfo>(); 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=<mod1>?.5:0 <area>") { toolInfo = new ToolInfo(Kind.Level); } if (data.name == "Reset" && text == "terrain reset <area>") { toolInfo = new ToolInfo(Kind.Reset); } if (data.name == "Slope" && text == "terrain slope <to>" && 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] + " <area>") { 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<ZNetView>())) { 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<PlacedCommand>().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<PlacedCommand>(); 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); } } }