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 RaiseLimit; public static readonly ConfigEntry DigLimit; public static readonly ConfigEntry BuriedSearchRadius; public static readonly ConfigEntry AllowDigInTar; public static readonly ConfigEntry AdminOverrideKey; static Configs() { AdminOverrideKey = Config.Define(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(true, "Modification", "Terrain Raise Limit", 0.5f, Config.AcceptRange(0f, 8f), "Max height that terrain can be raised from default. (Vanilla: 8)"); DigLimit = Config.Define(true, "Modification", "Terrain Dig Limit", 1f, Config.AcceptRange(0f, 8f), "Max depth that terrain can be lowered from default. (Vanilla: 8)"); AllowDigInTar = Config.Define(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(true, "Modification", "Buried Search Radius", 3f, Config.AcceptRange(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 { 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(Configs.DigLimit, true, true, true)); stringBuilder.AppendLine(HelpInfo.Format(Configs.RaiseLimit, true, true, true)); if (Configs.AllowDigInTar.Value) { stringBuilder.AppendLine(HelpInfo.Format(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 DiggableMaterials = new HashSet { "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 val = new InterpolatedString(28, 2, ref flag); if (flag) { val.AppendLiteral("Apply Limit height: "); val.AppendFormatted(curHeight); val.AppendLiteral(" delta: "); val.AppendFormatted(delta); } Logging.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.Info("Wishbone is in effect, checking for dig exceptions", 0); TombStone val3 = default(TombStone); if (!((Component)val2.m_beacon).TryGetComponent(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.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(true))) { return Object.op_Implicit((Object)(object)obj.GetComponentInChildren(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 val4 = new InterpolatedString(16, 1, ref flag2); if (flag2) { val4.AppendLiteral("Found diggable: "); val4.AppendFormatted(name); } Logging.Info(val4, 0); return true; } } Logging.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 val4 = new InterpolatedString(27, 1, ref flag2); if (flag2) { val4.AppendLiteral("Check for mine components: "); val4.AppendFormatted(((Object)obj).name); } Logging.Info(val4, 0); MineRock componentInParent = obj.GetComponentInParent(true); if (Object.op_Implicit((Object)(object)componentInParent)) { val4 = new InterpolatedString(16, 1, ref flag2); if (flag2) { val4.AppendLiteral("Found MineRock: "); val4.AppendFormatted(((Object)componentInParent).name); } Logging.Info(val4, 0); dropItems = componentInParent.m_dropItems; return true; } MineRock5 componentInParent2 = obj.GetComponentInParent(true); if (Object.op_Implicit((Object)(object)componentInParent2)) { val4 = new InterpolatedString(17, 1, ref flag2); if (flag2) { val4.AppendLiteral("Found MineRock5: "); val4.AppendFormatted(((Object)componentInParent2).name); } Logging.Info(val4, 0); dropItems = componentInParent2.m_dropItems; return true; } Destructible componentInParent3 = obj.GetComponentInParent(true); if (Object.op_Implicit((Object)(object)componentInParent3) && Object.op_Implicit((Object)(object)componentInParent3.m_spawnWhenDestroyed)) { val4 = new InterpolatedString(20, 1, ref flag2); if (flag2) { val4.AppendLiteral("Found Destructible: "); val4.AppendFormatted(((Object)componentInParent3).name); } Logging.Info(val4, 0); if (TryGetMineRockDropTable(componentInParent3.m_spawnWhenDestroyed, out dropItems)) { val4 = new InterpolatedString(12, 1, ref flag2); if (flag2) { val4.AppendLiteral("Drop Items: "); val4.AppendFormatted(dropItems?.m_drops.Count ?? 0); } Logging.Info(val4, 0); return true; } } dropItems = null; return false; } } [HarmonyTranspiler] [HarmonyPatch(typeof(TerrainComp), "RaiseTerrain")] public static IEnumerable TerrainComp_RaiseTerrain_Transpiler(IEnumerable 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 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(); } } }