Decompiled source of TerrainReset v0.8.0

TerrainReset.dll

Decompiled 8 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using TMPro;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyVersion("1.0.0.0")]
public class AedenthornUtils
{
	public static bool IgnoreKeyPresses(bool extra = false)
	{
		int result;
		if (!extra)
		{
			if (!((Object)(object)ZNetScene.instance == (Object)null) && !((Object)(object)Player.m_localPlayer == (Object)null) && !Minimap.IsOpen() && !Console.IsVisible() && !TextInput.IsVisible() && !ZNet.instance.InPasswordDialog())
			{
				Chat instance = Chat.instance;
				if (instance == null || !instance.HasFocus())
				{
					result = (Menu.IsVisible() ? 1 : 0);
					goto IL_005f;
				}
			}
			result = 1;
			goto IL_005f;
		}
		int result2;
		if (!((Object)(object)ZNetScene.instance == (Object)null) && !((Object)(object)Player.m_localPlayer == (Object)null) && !Minimap.IsOpen() && !Console.IsVisible() && !TextInput.IsVisible() && !ZNet.instance.InPasswordDialog())
		{
			Chat instance2 = Chat.instance;
			if ((instance2 == null || !instance2.HasFocus()) && !StoreGui.IsVisible() && !InventoryGui.IsVisible() && !Menu.IsVisible())
			{
				TextViewer instance3 = TextViewer.instance;
				result2 = ((instance3 != null && instance3.IsVisible()) ? 1 : 0);
				goto IL_00d9;
			}
		}
		result2 = 1;
		goto IL_00d9;
		IL_005f:
		return (byte)result != 0;
		IL_00d9:
		return (byte)result2 != 0;
	}

	public static bool CheckKeyDown(string value)
	{
		try
		{
			return Input.GetKeyDown(value.ToLower());
		}
		catch
		{
			return false;
		}
	}

	public static bool CheckKeyHeld(string value, bool req = true)
	{
		try
		{
			return Input.GetKey(value.ToLower());
		}
		catch
		{
			return !req;
		}
	}
}
namespace TerrainReset;

[BepInPlugin("aedenthorn.TerrainReset", "Terrain Reset", "0.8.0")]
public class BepInExPlugin : BaseUnityPlugin
{
	[HarmonyPatch(typeof(TerrainComp), "DoOperation")]
	private static class DoOperation_Patch
	{
		private static bool Prefix(Vector3 pos, Settings modifier, bool ___m_initialized)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			if (!___m_initialized)
			{
				return false;
			}
			if (!modEnabled.Value || !modifier.m_smooth || !AedenthornUtils.CheckKeyHeld(modKey.Value))
			{
				return true;
			}
			ResetTerrain(pos, (toolRadius.Value > 0f) ? toolRadius.Value : modifier.GetRadius());
			return false;
		}
	}

	[HarmonyPatch(typeof(TerrainOp), "OnPlaced")]
	private static class OnPlaced_Patch
	{
		private static bool Prefix(Settings ___m_settings)
		{
			if (!modEnabled.Value || !___m_settings.m_smooth || !AedenthornUtils.CheckKeyHeld(modKey.Value))
			{
				return true;
			}
			return false;
		}
	}

	[HarmonyPatch(typeof(Terminal), "InputText")]
	private static class InputText_Patch
	{
		private static bool Prefix(Terminal __instance)
		{
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			if (!modEnabled.Value)
			{
				return true;
			}
			string text = ((TMP_InputField)__instance.m_input).text;
			if (text.ToLower().Equals(typeof(BepInExPlugin).Namespace.ToLower() + " reset"))
			{
				((BaseUnityPlugin)context).Config.Reload();
				((BaseUnityPlugin)context).Config.Save();
				Traverse.Create((object)__instance).Method("AddString", new object[1] { text }).GetValue();
				Traverse.Create((object)__instance).Method("AddString", new object[1] { ((BaseUnityPlugin)context).Info.Metadata.Name + " config reloaded" }).GetValue();
				return false;
			}
			if (text.ToLower().StartsWith(consoleCommand.Value + " "))
			{
				if (float.TryParse(text.ToLower().Split(new char[1] { ' ' })[1], out var result))
				{
					int num = ResetTerrain(((Component)Player.m_localPlayer).transform.position, result);
					Traverse.Create((object)__instance).Method("AddString", new object[1] { text }).GetValue();
					if (resetMessage.Value.Length > 0 && resetMessage.Value.Contains("{0}"))
					{
						Traverse.Create((object)__instance).Method("AddString", new object[1] { string.Format(resetMessage.Value, num) }).GetValue();
					}
				}
				else
				{
					Traverse.Create((object)__instance).Method("AddString", new object[1] { "Format error. Usage: " + consoleCommand.Value + " <radius>" }).GetValue();
				}
				return false;
			}
			return true;
		}
	}

	public static ConfigEntry<bool> modEnabled;

	public static ConfigEntry<bool> isDebug;

	public static ConfigEntry<int> nexusID;

	public static ConfigEntry<float> hotKeyRadius;

	public static ConfigEntry<float> toolRadius;

	public static ConfigEntry<string> hotKey;

	public static ConfigEntry<string> consoleCommand;

	public static ConfigEntry<string> resetMessage;

	public static ConfigEntry<string> modKey;

	private static BepInExPlugin context;

	public static void Dbgl(string str = "", bool pref = true)
	{
		if (isDebug.Value)
		{
			Debug.Log((object)((pref ? (typeof(BepInExPlugin).Namespace + " ") : "") + str));
		}
	}

	private void Awake()
	{
		context = this;
		modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable this mod");
		isDebug = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "IsDebug", true, "Enable debug logs");
		nexusID = ((BaseUnityPlugin)this).Config.Bind<int>("General", "NexusID", 1113, "Nexus mod ID for updates");
		hotKeyRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Config", "HotKeyRadius", 150f, "Reset radius for hotkey command");
		toolRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Config", "ToolRadius", 0f, "Reset radius for tool. Set to 0 to use the tool's actual radius.");
		hotKey = ((BaseUnityPlugin)this).Config.Bind<string>("Config", "HotKey", "", "Hotkey to reset terrain. Use https://docs.unity3d.com/Manual/class-InputManager.html");
		modKey = ((BaseUnityPlugin)this).Config.Bind<string>("Config", "ModKey", "left alt", "Modifer key to reset terrain when using the level ground hoe tool. Use https://docs.unity3d.com/Manual/class-InputManager.html");
		consoleCommand = ((BaseUnityPlugin)this).Config.Bind<string>("Config", "ConsoleCommand", "resetterrain", "Console command to reset terrain. Usage: <command> <radius>");
		resetMessage = ((BaseUnityPlugin)this).Config.Bind<string>("Config", "ResetMessage", "{0} edits reset.", "Reset message. {0} is replaced by the number of edits. Set to empty to disable message");
		Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
	}

	private void Update()
	{
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		if (modEnabled.Value && !AedenthornUtils.IgnoreKeyPresses(extra: true) && AedenthornUtils.CheckKeyDown(hotKey.Value) && Object.op_Implicit((Object)(object)Player.m_localPlayer))
		{
			int num = ResetTerrain(((Component)Player.m_localPlayer).transform.position, hotKeyRadius.Value);
			if (resetMessage.Value.Length > 0 && resetMessage.Value.Contains("{0}"))
			{
				((Character)Player.m_localPlayer).Message((MessageType)2, string.Format(resetMessage.Value, num), 0, (Sprite)null);
			}
		}
	}

	private static int ResetTerrain(Vector3 center, float radius)
	{
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		//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_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0125: Unknown result type (might be due to invalid IL or missing references)
		//IL_0175: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0422: Unknown result type (might be due to invalid IL or missing references)
		//IL_0305: Unknown result type (might be due to invalid IL or missing references)
		//IL_030a: Unknown result type (might be due to invalid IL or missing references)
		int num = 0;
		List<Heightmap> list = new List<Heightmap>();
		Heightmap.FindHeightmap(center, radius + 100f, list);
		List<TerrainModifier> allInstances = TerrainModifier.GetAllInstances();
		foreach (TerrainModifier item in allInstances)
		{
			Vector3 position = ((Component)item).transform.position;
			ZNetView component = ((Component)item).GetComponent<ZNetView>();
			if (!((Object)(object)component != (Object)null) || !component.IsValid() || !component.IsOwner() || !(Utils.DistanceXZ(position, center) <= radius))
			{
				continue;
			}
			num++;
			foreach (Heightmap item2 in list)
			{
				if (item2.TerrainVSModifier(item))
				{
					item2.Poke(true);
				}
			}
			component.Destroy();
		}
		Dbgl($"Reset {num} mod edits");
		using (List<Heightmap>.Enumerator enumerator3 = list.GetEnumerator())
		{
			int num2 = default(int);
			int num3 = default(int);
			while (enumerator3.MoveNext())
			{
				TerrainComp val = TerrainComp.FindTerrainCompiler(((Component)enumerator3.Current).transform.position);
				if (!Object.op_Implicit((Object)(object)val))
				{
					continue;
				}
				Traverse val2 = Traverse.Create((object)val);
				if (!val2.Field("m_initialized").GetValue<bool>())
				{
					continue;
				}
				enumerator3.Current.WorldToVertex(center, ref num2, ref num3);
				bool[] value = val2.Field("m_modifiedHeight").GetValue<bool[]>();
				float[] value2 = val2.Field("m_levelDelta").GetValue<float[]>();
				float[] value3 = val2.Field("m_smoothDelta").GetValue<float[]>();
				bool[] value4 = val2.Field("m_modifiedPaint").GetValue<bool[]>();
				Color[] value5 = val2.Field("m_paintMask").GetValue<Color[]>();
				int value6 = val2.Field("m_width").GetValue<int>();
				Dbgl($"Checking heightmap at {((Component)val).transform.position}");
				int num4 = 0;
				bool flag = false;
				int num5 = value6 + 1;
				for (int i = 0; i < num5; i++)
				{
					for (int j = 0; j < num5; j++)
					{
						int num6 = i * num5 + j;
						if (value[num6] && !(CoordDistance(num2, num3, j, i) > radius))
						{
							num++;
							num4++;
							flag = true;
							value[num6] = false;
							value2[num6] = 0f;
							value3[num6] = 0f;
						}
					}
				}
				num5 = value6;
				for (int k = 0; k < num5; k++)
				{
					for (int l = 0; l < num5; l++)
					{
						int num7 = k * num5 + l;
						if (value4[num7] && !(CoordDistance(num2, num3, l, k) > radius))
						{
							flag = true;
							value4[num7] = false;
							value5[num7] = Color.clear;
						}
					}
				}
				if (flag)
				{
					Dbgl($"\tReset {num4} comp edits");
					val2.Field("m_modifiedHeight").SetValue((object)value);
					val2.Field("m_levelDelta").SetValue((object)value2);
					val2.Field("m_smoothDelta").SetValue((object)value3);
					val2.Field("m_modifiedPaint").SetValue((object)value4);
					val2.Field("m_paintMask").SetValue((object)value5);
					val2.Method("Save", Array.Empty<object>()).GetValue();
					enumerator3.Current.Poke(true);
				}
			}
		}
		if (num > 0 && Object.op_Implicit((Object)(object)ClutterSystem.instance))
		{
			ClutterSystem.instance.ResetGrass(center, radius);
		}
		return num;
	}

	private static float CoordDistance(float x, float y, float rx, float ry)
	{
		float num = x - rx;
		float num2 = y - ry;
		return Mathf.Sqrt(num * num + num2 * num2);
	}
}