Decompiled source of ZenTerrain v1.0.2

plugins/ZenTerrain.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;
using Zen;
using Zen.Lib;
using Zen.Lib.Config;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("ZenTerrain")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ZenTerrain")]
[assembly: AssemblyCopyright("Copyright \ufffd  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("0.0.1.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.1.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ZenTerrain
{
	internal static class Configs
	{
		public static readonly ConfigEntry<float> RaiseLimit;

		public static readonly ConfigEntry<float> DigLimit;

		public static readonly ConfigEntry<float> BuriedSearchRadius;

		public static readonly ConfigEntry<bool> AllowDigInTar;

		public static readonly ConfigEntry<KeyCode> AdminOverrideKey;

		static Configs()
		{
			AdminOverrideKey = Config.Define<KeyCode>(true, "Modification", "Admin Override Key", (KeyCode)304, "Admin can override the limits by being in God Mode and holding down this key when terraforming.");
			RaiseLimit = Config.Define<float>(true, "Modification", "Terrain Raise Limit", 0.5f, Config.AcceptRange<float>(0f, 8f), "Max height that terrain can be raised from default. (Vanilla: 8)");
			DigLimit = Config.Define<float>(true, "Modification", "Terrain Dig Limit", 1f, Config.AcceptRange<float>(0f, 8f), "Max depth that terrain can be lowered from default. (Vanilla: 8)");
			AllowDigInTar = Config.Define<bool>(true, "Modification", "Allow Dig In Tar", true, "Digging in tar is allowed.\r\nThe player must have their feet in tar to be able to dig without restriction.");
			BuriedSearchRadius = Config.Define<float>(true, "Modification", "Buried Search Radius", 3f, Config.AcceptRange<float>(0f, 8f), "Radius to search for buried objects that if found will allow bypass of digging restrictions.");
		}
	}
	[BepInPlugin("ZenDragon.ZenTerrain", "ZenTerrain", "1.0.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	internal class Plugin : ZenMod<Plugin>
	{
		public const string PluginName = "ZenTerrain";

		public const string PluginVersion = "1.0.2";

		public const string PluginGUID = "ZenDragon.ZenTerrain";

		protected override void Setup()
		{
		}

		protected override void TitleScene(bool isFirstBoot)
		{
		}

		protected override void WorldStart()
		{
		}

		protected override void Shutdown()
		{
		}

		protected override HelpInfo? GetHelpInfo()
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected O, but got Unknown
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine(HelpInfo.Format("Description", "Terrain modificaiton is limited.\r\nThe Wishbone can be used in some areas to assist with digging.", (string)null, true, false));
			stringBuilder.AppendLine(HelpInfo.Format<float>(Configs.DigLimit, true, true, true));
			stringBuilder.AppendLine(HelpInfo.Format<float>(Configs.RaiseLimit, true, true, true));
			if (Configs.AllowDigInTar.Value)
			{
				stringBuilder.AppendLine(HelpInfo.Format<bool>(Configs.AllowDigInTar, false, true, true));
			}
			return new HelpInfo("Terrain", stringBuilder.ToString());
		}
	}
	[HarmonyPatch]
	public static class TerrainLimit
	{
		public const float VanillaLimit = 8f;

		private static readonly Collider[] HitCache = (Collider[])(object)new Collider[64];

		private static readonly LayerMask SearchLayers = LayerMask.op_Implicit(LayerMask.GetMask(new string[3] { "Default", "Default_small", "static_solid" }));

		private static readonly int WishboneSE = StringExtensionMethods.GetStableHashCode("Wishbone");

		private static readonly HashSet<string> DiggableMaterials = new HashSet<string>
		{
			"TinOre", "TinScrap", "CopperOre", "CopperScrap", "BronzeOre", "BronzeScrap", "IronOre", "IronScrap", "SilverOre", "SilverScrap",
			"BlackMetalOre", "BlackMetalScrap", "FlametalOre", "FlametalScrap", "FlametalOreNew", "FlametalScrapNew", "BlackMarble"
		};

		private static float ApplyLimit(float curHeight, float delta)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: 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_016a: Unknown result type (might be due to invalid IL or missing references)
			bool flag = default(bool);
			InterpolatedString<Plugin> val = new InterpolatedString<Plugin>(28, 2, ref flag);
			if (flag)
			{
				val.AppendLiteral("Apply Limit height: ");
				val.AppendFormatted<float>(curHeight);
				val.AppendLiteral(" delta: ");
				val.AppendFormatted<float>(delta);
			}
			Logging<Plugin>.Info(val, 0);
			float num = curHeight + delta;
			if ((((Character)Player.m_localPlayer).InGodMode() && ZInput.GetKey(Configs.AdminOverrideKey.Value, true)) || ((Character)Player.m_localPlayer).InInterior())
			{
				return Mathf.Clamp(num, -8f, 8f);
			}
			StatusEffect statusEffect = ((Character)Player.m_localPlayer).GetSEMan().GetStatusEffect(WishboneSE);
			SE_Finder val2 = (SE_Finder)(object)((statusEffect is SE_Finder) ? statusEffect : null);
			if (Object.op_Implicit((Object)(object)val2) && Object.op_Implicit((Object)(object)val2.m_beacon))
			{
				Logging<Plugin>.Info("Wishbone is in effect, checking for dig exceptions", 0);
				TombStone val3 = default(TombStone);
				if (!((Component)val2.m_beacon).TryGetComponent<TombStone>(ref val3))
				{
					if (Mathf.Clamp01(val2.m_lastDistance / val2.m_beacon.m_range) < 0.15f)
					{
						return Mathf.Clamp(num, -8f, Configs.RaiseLimit.Value);
					}
				}
				else
				{
					Logging<Plugin>.Info("Ignoring Tombstone for wishbone dig exceptions", 0);
				}
			}
			if (Configs.AllowDigInTar.Value && ((Character)Player.m_localPlayer).InTar() && ((Character)Player.m_localPlayer).InLiquidDepth() > 0.2f)
			{
				return Mathf.Clamp(num, -8f, Configs.RaiseLimit.Value);
			}
			int num2 = Physics.OverlapSphereNonAlloc(((Component)Player.m_localPlayer).transform.position, Configs.BuriedSearchRadius.Value, HitCache, LayerMask.op_Implicit(SearchLayers));
			for (int i = 0; i < num2; i++)
			{
				if (IsMinable(HitCache[i]))
				{
					return Mathf.Clamp(num, -8f, Configs.RaiseLimit.Value);
				}
			}
			if (curHeight < 0f - Configs.DigLimit.Value)
			{
				if (delta > 0f)
				{
					return Mathf.Clamp(num, -8f, Configs.RaiseLimit.Value);
				}
				return curHeight;
			}
			if (curHeight > Configs.RaiseLimit.Value)
			{
				if (delta < 0f)
				{
					return Mathf.Clamp(num, 0f - Configs.DigLimit.Value, 8f);
				}
				return curHeight;
			}
			return Mathf.Clamp(num, 0f - Configs.DigLimit.Value, Configs.RaiseLimit.Value);
			static bool HasBeacon(GameObject obj)
			{
				if (!Object.op_Implicit((Object)(object)obj.GetComponentInParent<Beacon>(true)))
				{
					return Object.op_Implicit((Object)(object)obj.GetComponentInChildren<Beacon>(true));
				}
				return true;
			}
			static bool HasDiggable(DropTable? dropTable)
			{
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: 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_0054: Unknown result type (might be due to invalid IL or missing references)
				if (dropTable == null)
				{
					return false;
				}
				bool flag2 = default(bool);
				foreach (DropData drop in dropTable.m_drops)
				{
					string name = ((Object)drop.m_item).name;
					if (DiggableMaterials.Contains(name))
					{
						InterpolatedString<Plugin> val4 = new InterpolatedString<Plugin>(16, 1, ref flag2);
						if (flag2)
						{
							val4.AppendLiteral("Found diggable: ");
							val4.AppendFormatted(name);
						}
						Logging<Plugin>.Info(val4, 0);
						return true;
					}
				}
				Logging<Plugin>.Info("Not diggable", 0);
				return false;
			}
			static bool IsMinable(Collider hit)
			{
				GameObject gameObject = ((Component)hit).gameObject;
				if (!HasBeacon(gameObject))
				{
					if (TryGetMineRockDropTable(gameObject, out var dropItems))
					{
						return HasDiggable(dropItems);
					}
					return false;
				}
				return true;
			}
			static bool TryGetMineRockDropTable(GameObject obj, out DropTable? dropItems)
			{
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0028: 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_008d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0092: Unknown result type (might be due to invalid IL or missing references)
				//IL_0067: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
				//IL_0109: Unknown result type (might be due to invalid IL or missing references)
				//IL_0123: 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_0153: Unknown result type (might be due to invalid IL or missing references)
				bool flag2 = default(bool);
				InterpolatedString<Plugin> val4 = new InterpolatedString<Plugin>(27, 1, ref flag2);
				if (flag2)
				{
					val4.AppendLiteral("Check for mine components: ");
					val4.AppendFormatted(((Object)obj).name);
				}
				Logging<Plugin>.Info(val4, 0);
				MineRock componentInParent = obj.GetComponentInParent<MineRock>(true);
				if (Object.op_Implicit((Object)(object)componentInParent))
				{
					val4 = new InterpolatedString<Plugin>(16, 1, ref flag2);
					if (flag2)
					{
						val4.AppendLiteral("Found MineRock: ");
						val4.AppendFormatted(((Object)componentInParent).name);
					}
					Logging<Plugin>.Info(val4, 0);
					dropItems = componentInParent.m_dropItems;
					return true;
				}
				MineRock5 componentInParent2 = obj.GetComponentInParent<MineRock5>(true);
				if (Object.op_Implicit((Object)(object)componentInParent2))
				{
					val4 = new InterpolatedString<Plugin>(17, 1, ref flag2);
					if (flag2)
					{
						val4.AppendLiteral("Found MineRock5: ");
						val4.AppendFormatted(((Object)componentInParent2).name);
					}
					Logging<Plugin>.Info(val4, 0);
					dropItems = componentInParent2.m_dropItems;
					return true;
				}
				Destructible componentInParent3 = obj.GetComponentInParent<Destructible>(true);
				if (Object.op_Implicit((Object)(object)componentInParent3) && Object.op_Implicit((Object)(object)componentInParent3.m_spawnWhenDestroyed))
				{
					val4 = new InterpolatedString<Plugin>(20, 1, ref flag2);
					if (flag2)
					{
						val4.AppendLiteral("Found Destructible: ");
						val4.AppendFormatted(((Object)componentInParent3).name);
					}
					Logging<Plugin>.Info(val4, 0);
					if (TryGetMineRockDropTable(componentInParent3.m_spawnWhenDestroyed, out dropItems))
					{
						val4 = new InterpolatedString<Plugin>(12, 1, ref flag2);
						if (flag2)
						{
							val4.AppendLiteral("Drop Items: ");
							val4.AppendFormatted<int>(dropItems?.m_drops.Count ?? 0);
						}
						Logging<Plugin>.Info(val4, 0);
						return true;
					}
				}
				dropItems = null;
				return false;
			}
		}

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(TerrainComp), "RaiseTerrain")]
		public static IEnumerable<CodeInstruction> TerrainComp_RaiseTerrain_Transpiler(IEnumerable<CodeInstruction> codes, ILGenerator gen)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Expected O, but got Unknown
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Expected O, but got Unknown
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			Func<float, float, float> func = ApplyLimit;
			CodeMatch[] array = (CodeMatch[])(object)new CodeMatch[3]
			{
				CodeMatch.op_Implicit(OpCodes.Ldloc_S),
				CodeMatch.op_Implicit(OpCodes.Add),
				CodeMatch.op_Implicit(OpCodes.Stind_R4)
			};
			CodeMatch[] array2 = (CodeMatch[])(object)new CodeMatch[3]
			{
				new CodeMatch((OpCode?)OpCodes.Ldc_R4, (object)(-8f), (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldc_R4, (object)8f, (string)null),
				new CodeMatch((OpCode?)OpCodes.Call, (object)typeof(Mathf).GetMethod("Clamp", new Type[3]
				{
					typeof(float),
					typeof(float),
					typeof(float)
				}), (string)null)
			};
			return new CodeMatcher(codes, gen).MatchStartForward(array).ThrowIfInvalid("Unable to match first sequence").Set(OpCodes.Ldc_R4, (object)0f)
				.MatchStartForward(array2)
				.ThrowIfInvalid("Unable to match second sequence")
				.SetAndAdvance(OpCodes.Ldloc_S, (object)(byte)14)
				.SetAndAdvance(OpCodes.Nop, (object)null)
				.Set(OpCodes.Call, (object)func.Method)
				.InstructionEnumeration();
		}
	}
}