using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; 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] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.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.1")] [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.1"; 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 float ApplyLimit(float curHeight, float delta) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) Logging.Info((object)$"Apply Limit height: {curHeight} delta: {delta}", 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 val = (SE_Finder)(object)((statusEffect is SE_Finder) ? statusEffect : null); if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.m_beacon)) { Logging.Info((object)"Wishbone is in effect, checking for dig exceptions", 0); TombStone val2 = default(TombStone); if (!((Component)val.m_beacon).TryGetComponent(ref val2)) { if (Mathf.Clamp01(val.m_lastDistance / val.m_beacon.m_range) < 0.15f) { return Mathf.Clamp(num, -8f, Configs.RaiseLimit.Value); } } else { Logging.Info((object)"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 HasOre(DropTable? dropTable) { if (dropTable != null) { return dropTable.GetDropList().Any((GameObject drop) => ((Object)drop).name.Contains("Ore") || ((Object)drop).name.Contains("Scrap")); } return false; } static bool IsMinable(Collider hit) { GameObject gameObject = ((Component)hit).gameObject; if (!HasOre(gameObject.GetComponentInParent()?.m_dropItems) && !HasOre(gameObject.GetComponentInParent()?.m_dropItems) && !Object.op_Implicit((Object)(object)gameObject.GetComponentInParent())) { return Object.op_Implicit((Object)(object)gameObject.GetComponentInChildren()); } return true; } } [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(); } } }