Decompiled source of AdvancedTerrainModifiers v1.4.0
TerrainTools.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.CodeDom.Compiler; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using TerrainTools.Configs; using TerrainTools.Extensions; using TerrainTools.Helpers; using TerrainTools.Visualization; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("TerrainTools")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("TerrainTools")] [assembly: AssemblyCopyright("Copyright © 2023")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")] [assembly: AssemblyFileVersion("1.4.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.4.0.0")] [module: UnverifiableCode] namespace MVBP.Extensions { internal static class GameObjectExtensions { internal static GameObject DeepCopy(this GameObject obj) { bool activeSelf = obj.activeSelf; obj.SetActive(false); GameObject result = Object.Instantiate<GameObject>(obj); obj.SetActive(activeSelf); return result; } public static bool HasAnyComponent(this GameObject gameObject, params Type[] components) { foreach (Type type in components) { if (Object.op_Implicit((Object)(object)gameObject.GetComponent(type))) { return true; } } return false; } public static bool HasAnyComponent(this GameObject gameObject, params string[] componentNames) { foreach (string text in componentNames) { if (Object.op_Implicit((Object)(object)gameObject.GetComponent(text))) { return true; } } return false; } public static bool HasAllComponents(this GameObject gameObject, params string[] componentNames) { foreach (string text in componentNames) { if (!Object.op_Implicit((Object)(object)gameObject.GetComponent(text))) { return false; } } return true; } public static bool HasAllComponents(this GameObject gameObject, params Type[] components) { foreach (Type type in components) { if (!Object.op_Implicit((Object)(object)gameObject.GetComponent(type))) { return false; } } return true; } public static bool HasAnyComponentInChildren(this GameObject gameObject, bool includeInactive = false, params Type[] components) { foreach (Type type in components) { if (Object.op_Implicit((Object)(object)gameObject.GetComponentInChildren(type, includeInactive))) { return true; } } return false; } public static Transform FindDeepChild(this GameObject gameObject, string childName, IterativeSearchType searchType = 1) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) return gameObject.transform.FindDeepChild(childName, searchType); } public static void DestroyComponentsInChildren<T>(this GameObject gameObject, bool includeInactive = false) where T : Component { T[] componentsInChildren = gameObject.GetComponentsInChildren<T>(includeInactive); for (int i = 0; i < componentsInChildren.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren[i]); } } } internal static class StringExtensions { internal static bool ContainsAny(this string str, params string[] substrings) { foreach (string value in substrings) { if (str.Contains(value)) { return true; } } return false; } internal static bool EndsWithAny(this string str, params string[] suffixes) { foreach (string value in suffixes) { if (str.EndsWith(value)) { return true; } } return false; } internal static bool StartsWithAny(this string str, params string[] suffixes) { foreach (string value in suffixes) { if (str.StartsWith(value)) { return true; } } return false; } internal static string RemoveSuffix(this string s, string suffix) { if (s.EndsWith(suffix)) { return s.Substring(0, s.Length - suffix.Length); } return s; } internal static string RemovePrefix(this string s, string prefix) { if (s.StartsWith(prefix)) { return s.Substring(prefix.Length, s.Length - prefix.Length); } return s; } internal static string CapitalizeFirstLetter(this string s) { if (s.Length == 0) { return s; } if (s.Length == 1) { return $"{char.ToUpper(s[0])}"; } return char.ToUpper(s[0]) + s.Substring(1); } } public static class TransformExtensions { public static Transform FindDeepChild(this Transform transform, string childName, IterativeSearchType searchType = 1) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) return Utils.FindChild(transform, childName, searchType); } } } namespace TerrainTools { [BepInPlugin("Searica.Valheim.TerrainTools", "AdvancedTerrainModifiers", "1.4.0")] [BepInDependency("com.jotunn.jotunn", "2.21.3")] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] internal sealed class TerrainTools : BaseUnityPlugin { internal const string Author = "Searica"; public const string PluginName = "AdvancedTerrainModifiers"; public const string PluginGUID = "Searica.Valheim.TerrainTools"; public const string PluginVersion = "1.4.0"; private static readonly string MainSection = ConfigManager.SetStringPriority("Global", 10); private static readonly string RadiusSection = ConfigManager.SetStringPriority("Radius", 8); private static readonly string HardnessSection = ConfigManager.SetStringPriority("Hardness", 6); private static readonly string ShovelSection = ConfigManager.SetStringPriority("Shovel", 4); private static readonly string HoeSection = ConfigManager.SetStringPriority("Hoe", 2); private static readonly string CultivatorSection = ConfigManager.SetStringPriority("Cultivator", 0); internal static bool UpdatePlugin = false; private static ConfigEntry<bool> hoverInfoEnabled; private static readonly Dictionary<string, ConfigEntry<bool>> ToolConfigEntries = new Dictionary<string, ConfigEntry<bool>>(); private static ConfigEntry<bool> enableRadiusModifier; private static ConfigEntry<KeyCode> radiusModKey; private static ConfigEntry<float> radiusScrollScale; private static ConfigEntry<float> maxRadius; private static ConfigEntry<bool> enableHardnessModifier; private static ConfigEntry<KeyCode> hardnessModKey; private static ConfigEntry<float> hardnessScrollScale; private static ConfigEntry<bool> enableShovel; internal static bool IsHoverInforEnabled => hoverInfoEnabled.Value; internal static bool IsEnableRadiusModifier => enableRadiusModifier.Value; internal static float MaxRadius => maxRadius.Value; internal static KeyCode RadiusKey => radiusModKey.Value; internal static float RadiusScrollScale => radiusScrollScale.Value; internal static bool IsEnableHardnessModifier => enableHardnessModifier.Value; internal static KeyCode HardnessKey => hardnessModKey.Value; internal static float HardnessScrollScale => hardnessScrollScale.Value; internal static bool IsShovelEnabled => enableShovel.Value; private static string GetSectionName(string pieceTable) { if (pieceTable == PieceTables.Hoe) { return HoeSection; } if (pieceTable == PieceTables.Cultivator) { return CultivatorSection; } if (pieceTable == "_ShovelPieceTable") { return ShovelSection; } return MainSection; } internal static bool IsToolEnabled(string toolName) { if (ToolConfigEntries.TryGetValue(toolName, out var value)) { return value?.Value ?? false; } return false; } public void Awake() { Log.Init(((BaseUnityPlugin)this).Logger); ConfigManager.Init("Searica.Valheim.TerrainTools", ((BaseUnityPlugin)this).Config); SetUpConfigEntries(); Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "Searica.Valheim.TerrainTools"); Game.isModded = true; PrefabManager.OnVanillaPrefabsAvailable += Shovel.CreateShovel; PieceManager.OnPiecesRegistered += InitManager.InitToolPieces; _ = GUIManager.Instance; ConfigManager.SetupWatcher(); ConfigManager.CheckForConfigManager(); ConfigManager.OnConfigFileReloaded += delegate { if (UpdatePlugin) { InitManager.UpdatePlugin(); UpdatePlugin = false; } }; ConfigManager.OnConfigWindowClosed += delegate { if (UpdatePlugin) { InitManager.UpdatePlugin(); } }; SynchronizationManager.OnConfigurationSynchronized += delegate { if (UpdatePlugin) { InitManager.UpdatePlugin(); UpdatePlugin = false; } }; } public void OnDestroy() { ConfigManager.Save(); } internal static void SetUpConfigEntries() { Log.Verbosity = ConfigManager.BindConfig(MainSection, "Verbosity", LogLevel.Low, "Low will log basic information about the mod. Medium will log information that is useful for troubleshooting. High will log a lot of information, do not set it to this without good reason as it will slow Down your game.", null, synced: false); hoverInfoEnabled = ConfigManager.BindConfig(MainSection, "HoverInfo", value: true, "Set to true/enabled to show terrain height when using square terrain tools."); enableRadiusModifier = ConfigManager.BindConfig(RadiusSection, ConfigManager.SetStringPriority("RadiusModifier", 1), value: true, "Set to true/enabled to allow modifying the radius of terrain tools using the scroll wheel. Note: Radius cannot be changed on square terraforming tools."); radiusModKey = ConfigManager.BindConfig<KeyCode>(RadiusSection, "RadiusModKey", (KeyCode)308, "Modifier key that must be held down when using scroll wheel to change the radius of terrain tools.", null, synced: false); radiusScrollScale = ConfigManager.BindConfig(RadiusSection, "RadiusScrollScale", 0.1f, "Scroll wheel change scale, larger magnitude means the radius will change faster and negative sign will reverse the direction you need to scroll to increase the radius.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-1f, 1f), synced: false); maxRadius = ConfigManager.BindConfig(RadiusSection, "MaxRadius", 10f, "Maximum radius of terrain tools.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(4f, 20f)); enableHardnessModifier = ConfigManager.BindConfig(HardnessSection, ConfigManager.SetStringPriority("HardnessModifier", 1), value: true, "Set to true/enabled to allow modifying the hardness of terrain tools using the scroll wheel. Note: Hardness cannot be changed on square terraforming tools and tools that do not alter ground height do not have a hardness."); hardnessModKey = ConfigManager.BindConfig<KeyCode>(HardnessSection, "HardnessModKey", (KeyCode)306, "Modifier key that must be held down when using scroll wheel to change the hardness of terrain tools.", null, synced: false); hardnessScrollScale = ConfigManager.BindConfig(HardnessSection, "HardnessScrollScale", 0.1f, "Scroll wheel change scale, larger magnitude means the hardness will change faster and negative sign will reverse the direction you need to scroll to increase the hardness.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-1f, 1f), synced: false); enableShovel = ConfigManager.BindConfig(ShovelSection, ConfigManager.SetStringPriority("Shovel", 1), value: true, "Set to true/enabled to allow crafting the shovel. Setting to false/disabled will prevent crafting new shovels but will not affect existing shovels in the world."); enableShovel.SettingChanged += SetUpdatePlugin; foreach (string key in ToolConfigs.ToolConfigsMap.Keys) { ConfigEntry<bool> val = ConfigManager.BindConfig(GetSectionName(ToolConfigs.ToolConfigsMap[key].pieceTable), key, value: true, "Set to true/enabled to add this terrain tool. Set to false/disabled to remove it."); val.SettingChanged += SetUpdatePlugin; ToolConfigEntries.Add(key, val); } ConfigManager.Save(); } private static void SetUpdatePlugin(object obj, EventArgs e) { UpdatePlugin = !UpdatePlugin || UpdatePlugin; } } internal enum LogLevel { Low, Medium, High } internal static class Log { private static ManualLogSource logSource; internal static ConfigEntry<LogLevel> Verbosity { get; set; } internal static LogLevel VerbosityLevel => Verbosity.Value; internal static void Init(ManualLogSource logSource) { Log.logSource = logSource; } internal static void LogDebug(object data) { logSource.LogDebug(data); } internal static void LogError(object data) { logSource.LogError(data); } internal static void LogFatal(object data) { logSource.LogFatal(data); } internal static void LogMessage(object data) { logSource.LogMessage(data); } internal static void LogWarning(object data) { logSource.LogWarning(data); } internal static void LogInfo(object data, LogLevel level = LogLevel.Low) { if (Verbosity == null || VerbosityLevel >= level) { logSource.LogInfo(data); } } internal static void LogGameObject(GameObject prefab, bool includeChildren = false) { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown LogInfo("***** " + ((Object)prefab).name + " *****"); Component[] components = prefab.GetComponents<Component>(); for (int i = 0; i < components.Length; i++) { LogComponent(components[i]); } if (!includeChildren) { return; } LogInfo("***** " + ((Object)prefab).name + " (children) *****"); foreach (Transform item in prefab.transform) { Transform val = item; LogInfo(" - " + ((Object)((Component)val).gameObject).name); components = ((Component)val).gameObject.GetComponents<Component>(); for (int i = 0; i < components.Length; i++) { LogComponent(components[i]); } } } internal static void LogComponent(Component compo) { LogInfo("--- " + ((object)compo).GetType().Name + ": " + ((Object)compo).name + " ---"); PropertyInfo[] properties = ((object)compo).GetType().GetProperties(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.SetField | BindingFlags.GetProperty | BindingFlags.SetProperty); foreach (PropertyInfo propertyInfo in properties) { LogInfo($" - {propertyInfo.Name} = {propertyInfo.GetValue(compo)}"); } FieldInfo[] fields = ((object)compo).GetType().GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.SetField | BindingFlags.GetProperty | BindingFlags.SetProperty); foreach (FieldInfo fieldInfo in fields) { LogInfo($" - {fieldInfo.Name} = {fieldInfo.GetValue(compo)}"); } } } } namespace TerrainTools.Visualization { public class HoverInfo { private readonly GameObject _gameObject; private readonly Transform _transform; private readonly TextMesh _textMesh; public string Text { get { return _textMesh.text; } set { _textMesh.text = value; } } public bool Enabled { get { return _gameObject.activeSelf; } set { _gameObject.SetActive(value); } } public Color Color { get { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return _textMesh.color; } set { //IL_0006: Unknown result type (might be due to invalid IL or missing references) _textMesh.color = value; } } public HoverInfo(Transform parentTransform) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_004f: 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_007b: 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_0097: Unknown result type (might be due to invalid IL or missing references) _gameObject = new GameObject(); _gameObject.transform.parent = parentTransform; _transform = _gameObject.transform; _textMesh = _gameObject.AddComponent<TextMesh>(); ((Component)_textMesh).transform.localPosition = Vector3.zero; ((Component)_textMesh).transform.localScale = new Vector3(0.1f / parentTransform.localScale.x, 0.1f / parentTransform.localScale.y, 0.1f / parentTransform.localScale.z); _textMesh.anchor = (TextAnchor)4; _textMesh.alignment = (TextAlignment)1; _textMesh.fontSize = 16; } public void RotateToPlayer() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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_0046: Unknown result type (might be due to invalid IL or missing references) Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(((Component)GameCamera.m_instance).transform.position.x, _transform.position.y, ((Component)GameCamera.m_instance).transform.position.z); _transform.LookAt(val, Vector3.up); _transform.Rotate(90f, 180f, 0f); } } internal static class IconCache { private static Texture2D _remove; private static Texture2D _cross; private static Texture2D _undo; private static Texture2D _redo; private static Texture2D _box; private static Texture2D _pavedRoadSquare; private static Texture2D _pavedRoadPath; private static Texture2D _pavedRoadPathSquare; private static Texture2D _mudRoadSquare; private static Texture2D _mudRoadPathSquare; private static Texture2D _replantSquare; private static Texture2D _cultivateSquare; private static Texture2D _cultivatePath; private static Texture2D _cultivatePathSquare; private static Texture2D _raiseSquare; private static Texture2D _lower; private static Texture2D _shovel; internal static Texture2D Shovel { get { if ((Object)(object)_shovel == (Object)null) { _shovel = LoadTextureFromResources("ShovelIcon.png"); } return _shovel; } } internal static Texture2D Lower { get { if ((Object)(object)_lower == (Object)null) { _lower = LoadTextureFromResources("lower_v2.png"); } return _lower; } } internal static Texture2D CultivateSquare { get { if ((Object)(object)_cultivateSquare == (Object)null) { _cultivateSquare = LoadTextureFromResources("cultivate_v2_square.png"); } return _cultivateSquare; } } internal static Texture2D CultivatePathSquare { get { if ((Object)(object)_cultivatePathSquare == (Object)null) { _cultivatePathSquare = LoadTextureFromResources("cultivate_v2_path_square.png"); } return _cultivatePathSquare; } } internal static Texture2D CultivatePath { get { if ((Object)(object)_cultivatePath == (Object)null) { _cultivatePath = LoadTextureFromResources("cultivate_v2_path.png"); } return _cultivatePath; } } internal static Texture2D ReplantSquare { get { if ((Object)(object)_replantSquare == (Object)null) { _replantSquare = LoadTextureFromResources("replant_v2_square.png"); } return _replantSquare; } } internal static Texture2D RaiseSquare { get { if ((Object)(object)_raiseSquare == (Object)null) { _raiseSquare = LoadTextureFromResources("raise_v2_square.png"); } return _raiseSquare; } } internal static Texture2D MudRoadPathSquare { get { if ((Object)(object)_mudRoadPathSquare == (Object)null) { _mudRoadPathSquare = LoadTextureFromResources("path_v2_square.png"); } return _mudRoadPathSquare; } } internal static Texture2D MudRoadSquare { get { if ((Object)(object)_mudRoadSquare == (Object)null) { _mudRoadSquare = LoadTextureFromResources("mud_road_v2_square.png"); } return _mudRoadSquare; } } internal static Texture2D PavedRoadPath { get { if ((Object)(object)_pavedRoadPath == (Object)null) { _pavedRoadPath = LoadTextureFromResources("paved_road_v2_path.png"); } return _pavedRoadPath; } } internal static Texture2D PavedRoadPathSquare { get { if ((Object)(object)_pavedRoadPathSquare == (Object)null) { _pavedRoadPathSquare = LoadTextureFromResources("paved_road_v2_path_square.png"); } return _pavedRoadPathSquare; } } internal static Texture2D PavedRoadSquare { get { if ((Object)(object)_pavedRoadSquare == (Object)null) { _pavedRoadSquare = LoadTextureFromResources("paved_road_v2_square.png"); } return _pavedRoadSquare; } } internal static Texture2D Remove { get { if ((Object)(object)_remove == (Object)null) { _remove = LoadTextureFromResources("remove.png"); } return _remove; } } internal static Texture2D Cross { get { if ((Object)(object)_cross == (Object)null) { _cross = LoadTextureFromResources("cross.png"); } return _cross; } } internal static Texture2D Undo { get { if ((Object)(object)_undo == (Object)null) { _undo = LoadTextureFromResources("undo.png"); } return _undo; } } internal static Texture2D Redo { get { if ((Object)(object)_redo == (Object)null) { _redo = LoadTextureFromResources("redo.png"); } return _redo; } } internal static Texture2D Box { get { if ((Object)(object)_box == (Object)null) { _box = LoadTextureFromResources("box.png"); } return _box; } } internal static Sprite LoadEmbeddedTextureAsSprite(string fileName) { //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) Texture2D val = LoadTextureFromResources(fileName); if ((Object)(object)val == (Object)null) { return null; } Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(0.5f, 0.5f); float num = 100f; return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), val2, num); } internal static Texture2D LoadTextureFromResources(string fileName) { //IL_009b: 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_00a7: Expected O, but got Unknown //IL_00a9: Expected O, but got Unknown string text = Path.GetExtension(fileName).ToLower(); if (text != ".png" && text != ".jpg") { Log.LogWarning("LoadTextureFromResources can only load png or jpg textures"); return null; } fileName = Path.GetFileNameWithoutExtension(fileName); string name2 = (from name in Assembly.GetExecutingAssembly().GetManifestResourceNames() where name.Contains(fileName) select name).FirstOrDefault(); Stream? manifestResourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(name2); byte[] array = new byte[manifestResourceStream.Length]; manifestResourceStream.Read(array, 0, array.Length); Texture2D val = new Texture2D(0, 0); ImageConversion.LoadImage(val, array); return val; } } public class Overlay { private GameObject GameObject { get; } private Particle[] Particles => (Particle[])(object)new Particle[2]; private Transform Transform { get; } public ParticleSystem ps { get; } public ParticleSystemRenderer psr { get; } public MainModule psm { get; } public bool Enabled { get { return GameObject.activeSelf; } set { GameObject.SetActive(value); } } public Vector3 Position { get { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return Transform.position; } set { //IL_0006: Unknown result type (might be due to invalid IL or missing references) Transform.position = value; } } public Vector3 LocalPosition { get { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return Transform.localPosition; } set { //IL_0006: Unknown result type (might be due to invalid IL or missing references) Transform.localPosition = value; } } public Quaternion Rotation { get { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return Transform.rotation; } set { //IL_0006: Unknown result type (might be due to invalid IL or missing references) Transform.rotation = value; } } public Color Color { get { //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) ps.GetParticles(Particles, 2); return Color32.op_Implicit(((Particle)(ref Particles[1])).GetCurrentColor(ps)); } } public Color StartColor { get { //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_0009: 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_0011: Unknown result type (might be due to invalid IL or missing references) MainModule val = psm; MinMaxGradient startColor = ((MainModule)(ref val)).startColor; return ((MinMaxGradient)(ref startColor)).color; } set { //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_0009: 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_0011: Unknown result type (might be due to invalid IL or missing references) MainModule val = psm; MinMaxGradient startColor = ((MainModule)(ref val)).startColor; ((MinMaxGradient)(ref startColor)).color = value; } } public float StartSize { get { //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_0009: 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) MainModule val = psm; MinMaxCurve startSize = ((MainModule)(ref val)).startSize; return ((MinMaxCurve)(ref startSize)).constant; } set { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) MainModule main = ps.main; ((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(value); } } public float StartSpeed { get { //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_0009: 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) MainModule val = psm; MinMaxCurve startSize = ((MainModule)(ref val)).startSize; return ((MinMaxCurve)(ref startSize)).constant; } set { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) MainModule main = ps.main; ((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(value); } } public float StartLifetime { get { //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_0009: 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) MainModule val = psm; MinMaxCurve startLifetime = ((MainModule)(ref val)).startLifetime; return ((MinMaxCurve)(ref startLifetime)).constant; } set { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) MainModule main = ps.main; ((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(value); } } public bool SizeOverLifetimeEnabled { get { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) SizeOverLifetimeModule sizeOverLifetime = ps.sizeOverLifetime; return ((SizeOverLifetimeModule)(ref sizeOverLifetime)).enabled; } set { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) SizeOverLifetimeModule sizeOverLifetime = ps.sizeOverLifetime; ((SizeOverLifetimeModule)(ref sizeOverLifetime)).enabled = value; } } public MinMaxCurve SizeOverLifetime { get { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: 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) SizeOverLifetimeModule sizeOverLifetime = ps.sizeOverLifetime; return ((SizeOverLifetimeModule)(ref sizeOverLifetime)).size; } set { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: 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) SizeOverLifetimeModule sizeOverLifetime = ps.sizeOverLifetime; ((SizeOverLifetimeModule)(ref sizeOverLifetime)).size = value; } } public Overlay(Transform transform) { Transform = transform; GameObject = ((Component)transform).gameObject; ps = ((Component)transform).GetComponentInChildren<ParticleSystem>(); psr = ((Component)transform).GetComponentInChildren<ParticleSystemRenderer>(); } } public abstract class OverlayVisualizer : MonoBehaviour { protected Overlay primary; protected Overlay secondary; protected Overlay tertiary; protected HoverInfo hoverInfo; internal static readonly Vector3 VerticalOffset = new Vector3(0f, 0.075f, 0f); private void Update() { //IL_007b: Unknown result type (might be due to invalid IL or missing references) if (primary == null) { Transform val = ((Component)this).transform.Find("_GhostOnly"); Transform val2 = Object.Instantiate<Transform>(val, ((Component)this).transform); Transform transform = Object.Instantiate<Transform>(val2, ((Component)this).transform); primary = new Overlay(val); secondary = new Overlay(val2); tertiary = new Overlay(transform); hoverInfo = new HoverInfo(val2); tertiary.StartColor = new Color(255f, 255f, 255f); primary.Enabled = false; secondary.Enabled = false; tertiary.Enabled = false; Initialize(); } OnRefresh(); } protected abstract void Initialize(); protected abstract void OnRefresh(); protected void SpeedUp(Overlay overlay) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_0041: Unknown result type (might be due to invalid IL or missing references) AnimationCurve val = new AnimationCurve(); val.AddKey(0f, 0f); val.AddKey(0.5f, 1f); MinMaxCurve sizeOverLifetime = default(MinMaxCurve); ((MinMaxCurve)(ref sizeOverLifetime))..ctor(1f, val); overlay.StartLifetime = 2f; overlay.SizeOverLifetime = sizeOverLifetime; } protected void Freeze(Overlay overlay) { overlay.StartSpeed = 0f; overlay.SizeOverLifetimeEnabled = false; } protected void VisualizeTerraformingBounds(Overlay overlay) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) overlay.StartSize = 3f; ((Renderer)overlay.psr).material.mainTexture = (Texture)(object)IconCache.Box; overlay.LocalPosition = VerticalOffset; } protected void VisualizeIconInsideTerraformingBounds(Overlay overlay, Texture iconTexture) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) overlay.StartSize = 2.5f; ((Renderer)overlay.psr).material.mainTexture = iconTexture; overlay.LocalPosition = VerticalOffset; } protected void VisualizeRecoloringBounds(Overlay overlay) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) overlay.StartSize = 4f; ((Renderer)overlay.psr).material.mainTexture = (Texture)(object)IconCache.Box; overlay.LocalPosition = VerticalOffset; } protected void VisualizeIconInsideRecoloringBounds(Overlay overlay, Texture iconTexture) { //IL_0023: 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_002d: Unknown result type (might be due to invalid IL or missing references) overlay.StartSize = 3f; ((Renderer)overlay.psr).material.mainTexture = iconTexture; overlay.Position = ((Component)this).transform.position + VerticalOffset; } } public abstract class HoverInfoEnabled : OverlayVisualizer { protected override void Initialize() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) hoverInfo.Color = secondary.StartColor; } protected override void OnRefresh() { //IL_002e: 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_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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_0054: 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) hoverInfo.Enabled = TerrainTools.IsHoverInforEnabled; if (hoverInfo.Enabled) { hoverInfo.RotateToPlayer(); Vector3 val = secondary.Position - OverlayVisualizer.VerticalOffset; hoverInfo.Text = $"x: {val.x:0}, y: {val.y:0.000}, z: {val.z:0}"; } } } [HarmonyPatch(typeof(Piece), "SetInvalidPlacementHeightlight")] public static class OverlayVisualizationRedshiftHeigthlightBlocker { private static bool Prefix(Piece __instance) { return !Object.op_Implicit((Object)(object)((Component)__instance).GetComponentInChildren<OverlayVisualizer>()); } } public class LevelGroundOverlayVisualizer : HoverInfoEnabled { protected override void Initialize() { base.Initialize(); SpeedUp(secondary); VisualizeTerraformingBounds(secondary); } protected override void OnRefresh() { base.OnRefresh(); primary.Enabled = false; secondary.Enabled = true; } } public class RaiseGroundOverlayVisualizer : HoverInfoEnabled { protected override void Initialize() { base.Initialize(); Freeze(secondary); Freeze(tertiary); VisualizeTerraformingBounds(secondary); VisualizeTerraformingBounds(tertiary); } protected override void OnRefresh() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0048: 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_0052: 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_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: 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_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) base.OnRefresh(); primary.Enabled = true; secondary.Enabled = true; GroundLevelSpinner.Refresh(); secondary.LocalPosition = new Vector3(0f, GroundLevelSpinner.Value, 0f); Vector3 val = secondary.Position - OverlayVisualizer.VerticalOffset; if (GroundLevelSpinner.Value > 0f) { float y = secondary.LocalPosition.y; hoverInfo.Text = $"x: {val.x:0}, y: {val.y - y:0.000}, z: {val.z:0}\n\nh: +{y:0.000}"; } else { hoverInfo.Text = $"x: {val.x:0}, y: {val.y:0.000}, z: {val.z:0}"; } tertiary.Enabled = true; } } public class SquarePathOverlayVisualizer : HoverInfoEnabled { protected override void Initialize() { base.Initialize(); SpeedUp(secondary); VisualizeRecoloringBounds(secondary); } protected override void OnRefresh() { base.OnRefresh(); primary.Enabled = false; secondary.Enabled = true; } } public class CultivateOverlayVisualizer : HoverInfoEnabled { protected override void Initialize() { base.Initialize(); SpeedUp(secondary); VisualizeRecoloringBounds(secondary); } protected override void OnRefresh() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) base.OnRefresh(); primary.Enabled = false; secondary.Enabled = true; hoverInfo.Color = secondary.Color; } } public class SeedGrassOverlayVisualizer : HoverInfoEnabled { protected override void Initialize() { //IL_0043: Unknown result type (might be due to invalid IL or missing references) base.Initialize(); Freeze(secondary); VisualizeRecoloringBounds(secondary); primary.StartSize = 4f; primary.LocalPosition = new Vector3(0f, 2.5f, 0f); } protected override void OnRefresh() { base.OnRefresh(); primary.Enabled = true; secondary.Enabled = true; } } public class RemoveModificationsOverlayVisualizer : OverlayVisualizer { protected override void Initialize() { Freeze(primary); SpeedUp(secondary); VisualizeTerraformingBounds(primary); VisualizeIconInsideTerraformingBounds(secondary, (Texture)(object)IconCache.Cross); } protected override void OnRefresh() { primary.Enabled = true; secondary.Enabled = true; } } public abstract class UndoRedoModificationsOverlayVisualizer : OverlayVisualizer { protected override void Initialize() { Freeze(primary); Freeze(secondary); VisualizeRecoloringBounds(primary); VisualizeIconInsideRecoloringBounds(secondary, (Texture)(object)Icon()); } protected override void OnRefresh() { primary.Enabled = true; secondary.Enabled = true; } protected abstract Texture2D Icon(); } public class UndoModificationsOverlayVisualizer : UndoRedoModificationsOverlayVisualizer { protected override Texture2D Icon() { return IconCache.Undo; } } public class RedoModificationsOverlayVisualizer : UndoRedoModificationsOverlayVisualizer { protected override Texture2D Icon() { return IconCache.Redo; } } } namespace TerrainTools.Properties { [GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [DebuggerNonUserCode] [CompilerGenerated] internal class Resources { private static ResourceManager resourceMan; private static CultureInfo resourceCulture; [EditorBrowsable(EditorBrowsableState.Advanced)] internal static ResourceManager ResourceManager { get { if (resourceMan == null) { resourceMan = new ResourceManager("TerrainTools.Properties.Resources", typeof(Resources).Assembly); } return resourceMan; } } [EditorBrowsable(EditorBrowsableState.Advanced)] internal static CultureInfo Culture { get { return resourceCulture; } set { resourceCulture = value; } } internal static Bitmap box => (Bitmap)ResourceManager.GetObject("box", resourceCulture); internal static Bitmap cross => (Bitmap)ResourceManager.GetObject("cross", resourceCulture); internal static Bitmap cultivate_v2_path => (Bitmap)ResourceManager.GetObject("cultivate_v2_path", resourceCulture); internal static Bitmap cultivate_v2_path_square => (Bitmap)ResourceManager.GetObject("cultivate_v2_path_square", resourceCulture); internal static Bitmap cultivate_v2_square => (Bitmap)ResourceManager.GetObject("cultivate_v2_square", resourceCulture); internal static Bitmap lower_v2 => (Bitmap)ResourceManager.GetObject("lower_v2", resourceCulture); internal static Bitmap mud_road_v2_square => (Bitmap)ResourceManager.GetObject("mud_road_v2_square", resourceCulture); internal static Bitmap path_v2_square => (Bitmap)ResourceManager.GetObject("path_v2_square", resourceCulture); internal static Bitmap paved_road_v2_path => (Bitmap)ResourceManager.GetObject("paved_road_v2_path", resourceCulture); internal static Bitmap paved_road_v2_path_square => (Bitmap)ResourceManager.GetObject("paved_road_v2_path_square", resourceCulture); internal static Bitmap paved_road_v2_square => (Bitmap)ResourceManager.GetObject("paved_road_v2_square", resourceCulture); internal static Bitmap raise => (Bitmap)ResourceManager.GetObject("raise", resourceCulture); internal static Bitmap raise_v2_square => (Bitmap)ResourceManager.GetObject("raise_v2_square", resourceCulture); internal static Bitmap redo => (Bitmap)ResourceManager.GetObject("redo", resourceCulture); internal static Bitmap remove => (Bitmap)ResourceManager.GetObject("remove", resourceCulture); internal static Bitmap replant_v2_square => (Bitmap)ResourceManager.GetObject("replant_v2_square", resourceCulture); internal static Bitmap ShovelIcon => (Bitmap)ResourceManager.GetObject("ShovelIcon", resourceCulture); internal static Bitmap smooth => (Bitmap)ResourceManager.GetObject("smooth", resourceCulture); internal static Bitmap undo => (Bitmap)ResourceManager.GetObject("undo", resourceCulture); internal Resources() { } } } namespace TerrainTools.Patches { [HarmonyPatch(typeof(GameCamera))] internal static class GameCameraPatch { [HarmonyTranspiler] [HarmonyPatch("UpdateCamera")] private static IEnumerable<CodeInstruction> UpdateCameraTranspiler(IEnumerable<CodeInstruction> instructions) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.Method(typeof(Player), "CanRotatePiece", (Type[])null, (Type[])null), (string)null) }).SetInstructionAndAdvance(Transpilers.EmitDelegate<Func<Player, bool>>((Func<Player, bool>)UpdateCamera_BlockScroll_Delegate)).InstructionEnumeration(); } private static bool UpdateCamera_BlockScroll_Delegate(Player localPlayer) { Piece val = ((localPlayer != null) ? localPlayer.GetSelectedPiece() : null); if ((Object)(object)((val != null) ? ((Component)val).gameObject : null) != (Object)null && (Object.op_Implicit((Object)(object)((Component)val).gameObject.GetComponentInChildren<RaiseGroundOverlayVisualizer>()) || RadiusModifier.ShouldModifyRadius() || HardnessModifier.ShouldModifyHardness())) { return true; } return localPlayer.CanRotatePiece(); } } [HarmonyPatch] internal class PlayerPatch { [HarmonyFinalizer] [HarmonyPatch(typeof(Player), "UpdatePlacementGhost")] private static void UpdatePlacementGhostPostfix(Player __instance) { //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_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)__instance) && ((Character)__instance).InPlaceMode() && !((Character)__instance).IsDead() && Object.op_Implicit((Object)(object)__instance.m_placementGhost) && Object.op_Implicit((Object)(object)__instance.m_placementGhost.GetComponent<OverlayVisualizer>())) { Vector3 position = __instance.m_placementGhost.transform.position; position.x = RoundToNearest(position.x, 1f); position.z = RoundToNearest(position.z, 1f); __instance.m_placementGhost.transform.position = position; } } private static float RoundToNearest(float x, float precision) { if (precision <= 0f) { return x; } float num = Mathf.Sign(x); int num2 = (int)Mathf.Abs(x * 1000f); int num3 = num2 / 1000; int num4 = num2 % 1000; int num5 = (int)(precision * 1000f / 2f); if (num4 < num5) { return num * (float)num3; } return num * ((float)num3 + precision); } } } namespace TerrainTools.Helpers { public static class GroundLevelSpinner { public const string MouseScrollWheel = "Mouse ScrollWheel"; public const float ScrollPrecision = 0.05f; public const float SuperiorScrollPrecisionMultiplier = 0.2f; public const float MaxSpinner = 1f; public const float MinSpinner = 0f; public static float Value { get; private set; } = 1f; public static void Refresh() { float num = ScrollDelta(); if (num > 0f) { Up(num); } if (num < 0f) { Down(num); } } private static float ScrollDelta() { float num = Input.GetAxis("Mouse ScrollWheel"); if (num != 0f) { num = ((num > 0f) ? 0.05f : (-0.05f)); } return num; } private static void Up(float scrollDelta) { if (Value + scrollDelta > 1f) { Value = 1f; } else { Value = Mathf.Round((Value + scrollDelta) * 100f) / 100f; } } private static void Down(float scrollDelta) { if (Value + scrollDelta < 0f) { Value = 0f; } else { Value = Mathf.Round((Value + scrollDelta) * 100f) / 100f; } } } [HarmonyPatch] internal static class HardnessModifier { private static bool SmoothToolIsInUse; private static float lastModdedSmoothPwr; private static float lastTotalSmoothDelta; private const float MinSmoothPwr = 1f; private const float MaxSmoothPwr = 30f; private static bool RaiseToolIsInUse; private static float lastModdedRaisePwr; private static float lastTotalRaiseDelta; private const float MinRaisePwr = 0.05f; private const float MaxRaisePwr = 1f; private const float DisplayThreshold = 0.9f; private static float lastDisplayedSmoothHardness; private static float lastDisplayedRaiseHardness; [HarmonyPrefix] [HarmonyPriority(300)] [HarmonyPatch(typeof(Player), "Update")] private static void UpdatePrefix(Player __instance) { //IL_009a: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)__instance) || (Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return; } if (!((Character)__instance).InPlaceMode() || Hud.IsPieceSelectionVisible()) { if (SmoothToolIsInUse) { SmoothToolIsInUse = false; lastModdedSmoothPwr = 0f; lastTotalSmoothDelta = 0f; lastDisplayedSmoothHardness = -1f; SetPower(__instance, 0f); } if (RaiseToolIsInUse) { RaiseToolIsInUse = false; lastModdedRaisePwr = 0f; lastTotalRaiseDelta = 0f; lastDisplayedRaiseHardness = -1f; SetPower(__instance, 0f); } } else if (ShouldModifyHardness()) { SetPower(__instance, Input.mouseScrollDelta.y * TerrainTools.HardnessScrollScale); } } internal static bool ShouldModifyHardness() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (TerrainTools.IsEnableHardnessModifier && Input.GetKey(TerrainTools.HardnessKey)) { return Input.mouseScrollDelta.y != 0f; } return false; } [HarmonyPrefix] [HarmonyPriority(600)] [HarmonyPatch(typeof(TerrainOp), "Awake")] private static void AwakePrefix(TerrainOp __instance) { if (Object.op_Implicit((Object)(object)__instance) && Object.op_Implicit((Object)(object)((Component)__instance).gameObject) && !Object.op_Implicit((Object)(object)((Component)__instance).gameObject.GetComponent<OverlayVisualizer>())) { if (__instance.m_settings.m_raise) { __instance.m_settings.m_raisePower = ModifyRaisePower(__instance.m_settings.m_raisePower, lastTotalRaiseDelta); Log.LogInfo($"Applying raise Power {__instance.m_settings.m_raisePower}", LogLevel.Medium); } if (__instance.m_settings.m_smooth) { __instance.m_settings.m_smoothPower = ModifySmoothPower(__instance.m_settings.m_smoothPower, lastTotalSmoothDelta); Log.LogInfo($"Applying smooth Power {__instance.m_settings.m_smoothPower}", LogLevel.Medium); } } } private static void SetPower(Player player, float delta) { Piece selectedPiece = player.GetSelectedPiece(); if (!Object.op_Implicit((Object)(object)selectedPiece) || !Object.op_Implicit((Object)(object)((Component)selectedPiece).gameObject) || Object.op_Implicit((Object)(object)((Component)selectedPiece).gameObject.GetComponent<OverlayVisualizer>())) { return; } TerrainOp component = ((Component)selectedPiece).gameObject.GetComponent<TerrainOp>(); if (!Object.op_Implicit((Object)(object)component)) { return; } SetSmoothPower(component, delta); SetRaisePower(component, delta); List<string> list = new List<string>(); if (SmoothToolIsInUse) { float smoothPowerDisplayValue = GetSmoothPowerDisplayValue(lastModdedSmoothPwr); if (Mathf.Abs(smoothPowerDisplayValue - lastDisplayedSmoothHardness) > 0.9f) { lastDisplayedSmoothHardness = Mathf.Round(smoothPowerDisplayValue); list.Add($"Terrain tool smoothing hardness: {smoothPowerDisplayValue:0}%"); } } if (RaiseToolIsInUse) { float raisePowerDisplayValue = GetRaisePowerDisplayValue(lastModdedRaisePwr); if (Mathf.Abs(raisePowerDisplayValue - lastDisplayedRaiseHardness) > 0.9f) { lastDisplayedRaiseHardness = Mathf.Round(raisePowerDisplayValue); list.Add($"Terrain tool raise hardness: {raisePowerDisplayValue:0}%"); } } if (SmoothToolIsInUse || RaiseToolIsInUse) { Sprite icon = player.m_placementGhost.GetComponent<Piece>().m_icon; if ((Object)(object)icon != (Object)null && list.Count > 0) { ((Character)player).Message((MessageType)2, string.Join("\n", list.ToArray()), 0, icon); } } } private static void SetSmoothPower(TerrainOp terrainOp, float delta) { if (terrainOp.m_settings.m_smooth) { Log.LogInfo($"Adjusting Smooth Power by {delta}", LogLevel.High); if (!SmoothToolIsInUse) { SmoothToolIsInUse = true; lastModdedSmoothPwr = ModifySmoothPower(terrainOp.m_settings.m_smoothPower, delta); } else { lastModdedSmoothPwr = ModifySmoothPower(lastModdedSmoothPwr, delta); } lastTotalSmoothDelta += delta; Log.LogInfo($"Total smooth power delta {lastTotalSmoothDelta}", LogLevel.High); } } private static void SetRaisePower(TerrainOp terrainOp, float delta) { if (terrainOp.m_settings.m_raise) { delta = ConvertSmoothDeltaToRaiseDelta(delta); Log.LogInfo($"Adjusting Raise Power by {delta}", LogLevel.High); if (!RaiseToolIsInUse) { RaiseToolIsInUse = true; lastModdedRaisePwr = ModifyRaisePower(terrainOp.m_settings.m_raisePower, delta); } else { lastModdedRaisePwr = ModifyRaisePower(lastModdedRaisePwr, delta); } lastTotalRaiseDelta += delta; Log.LogInfo($"Total raise power delta {lastTotalRaiseDelta}", LogLevel.High); } } private static float ConvertSmoothDeltaToRaiseDelta(float delta) { float num = delta / 29f; return -1f * num * 0.95f; } private static float GetSmoothPowerDisplayValue(float power) { return (power - 1f) / 29f * 100f; } private static float GetRaisePowerDisplayValue(float power) { return (1f - power) / 0.95f * 100f; } private static float ModifySmoothPower(float power, float delta) { return Mathf.Clamp(power + delta, 1f, 30f); } private static float ModifyRaisePower(float power, float delta) { return Mathf.Clamp(power + delta, 0.05f, 1f); } } internal static class InitManager { private static bool HasInitialized = false; internal static readonly Dictionary<string, GameObject> ToolRefs = new Dictionary<string, GameObject>(); private static readonly Dictionary<string, List<int>> InsertionIndexes = new Dictionary<string, List<int>>(); internal static void InitToolPieces() { if (HasInitialized) { return; } FixVanillaToolDescriptions(); foreach (string key in ToolConfigs.ToolConfigsMap.Keys) { try { ToolDB toolDB = ToolConfigs.ToolConfigsMap[key]; toolDB.prefab = MakeToolPiece(toolDB); } catch { Log.LogWarning("Failed to create: " + key); } } HasInitialized = true; UpdateTools(); } internal static void FixVanillaToolDescriptions() { SetDescription("mud_road_v2", "Levels ground based on player position. Use shift + click to level ground based on where you are pointing (this will smooth the terrain)."); SetDescription("raise_v2", "Raise grounds up to a maximum of 8 m above it's original height."); SetDescription("path_v2", "Creates a dirt path without affecting ground height."); SetDescription("paved_road_v2", "Creates a paved path and levels ground based on player position. Use shift+click to level ground based on where you are pointing (this will smooth the terrain)."); SetDescription("cultivate_v2", "Cultivates ground and levels ground based on player position. Use shift + click to level ground based on where you are pointing (this will smooth the terrain)."); SetDescription("replant_v2", "Replants terrain without affecting ground height."); } private static void SetDescription(string prefabName, string description) { GameObject prefab = PrefabManager.Instance.GetPrefab(prefabName); Piece val = ((prefab != null) ? prefab.GetComponent<Piece>() : null); if ((Object)(object)val != (Object)null) { val.m_description = description; } else { Log.LogWarning("Could not set description for: " + prefabName); } } internal static void UpdatePlugin() { UpdateTools(); UpdateShovelRecipe(); ConfigManager.Save(); TerrainTools.UpdatePlugin = false; } private static void UpdateTools() { if (!HasInitialized) { return; } ForceUnequipTerrainTools(); foreach (ToolDB value in ToolConfigs.ToolConfigsMap.Values) { RemovePieceInPieceTable(value); } foreach (string key in ToolConfigs.ToolConfigsMap.Keys) { if (TerrainTools.IsToolEnabled(key)) { ToolDB toolDB = ToolConfigs.ToolConfigsMap[key]; RegisterPieceInPieceTable(toolDB.prefab, toolDB.pieceTable, null, toolDB.insertIndex); } } } internal static void UpdatePieceTables() { foreach (string key in ToolConfigs.ToolConfigsMap.Keys) { try { ToolDB toolDB = ToolConfigs.ToolConfigsMap[key]; toolDB.prefab = MakeToolPiece(toolDB); RegisterPieceInPieceTable(toolDB.prefab, toolDB.pieceTable, null, toolDB.insertIndex); } catch { Log.LogWarning("Failed to create: " + key); } } } private static void UpdateShovelRecipe() { if (Shovel.TryGetShovel(out var shovel)) { shovel.Recipe.Recipe.m_enabled = TerrainTools.IsShovelEnabled; } } private static void ForceUnequipTerrainTools() { if (!Object.op_Implicit((Object)(object)Player.m_localPlayer)) { return; } ItemData rightItem = ((Humanoid)Player.m_localPlayer).GetRightItem(); if (rightItem != null) { if (rightItem.m_shared.m_name == "$item_cultivator") { Log.LogWarning("AdvancedTerrainModifiers updated through config change, unequipping cultivator"); ((Humanoid)Player.m_localPlayer).HideHandItems(false, true); } if (rightItem.m_shared.m_name == "$item_hoe") { Log.LogWarning("AdvancedTerrainModifiers updated through config change, unequipping hoe"); ((Humanoid)Player.m_localPlayer).HideHandItems(false, true); } } } internal static GameObject MakeToolPiece(ToolDB toolDB) { //IL_0066: 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_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) if (PieceManager.Instance.GetPiece(toolDB.pieceName) != null) { return null; } GameObject val = PrefabManager.Instance.CreateClonedPrefab(toolDB.name, toolDB.basePrefab); if ((Object)(object)val == (Object)null) { return null; } Piece component = val.GetComponent<Piece>(); component.m_icon = Sprite.Create(toolDB.icon, new Rect(0f, 0f, (float)((Texture)toolDB.icon).width, (float)((Texture)toolDB.icon).height), Vector2.zero); component.m_name = toolDB.pieceName; component.m_description = toolDB.pieceDesc; if (toolDB.requirements != null) { component.m_resources = toolDB.requirements; } Settings settings = val.GetComponent<TerrainOp>().m_settings; settings.m_level = UpdateValueIfNeeded(settings.m_level, toolDB.level); settings.m_levelRadius = UpdateValueIfNeeded(settings.m_levelRadius, toolDB.levelRadius); settings.m_raise = UpdateValueIfNeeded(settings.m_raise, toolDB.raise); settings.m_raiseRadius = UpdateValueIfNeeded(settings.m_raiseRadius, toolDB.raiseRadius); settings.m_raisePower = UpdateValueIfNeeded(settings.m_raisePower, toolDB.raisePower); settings.m_raiseDelta = UpdateValueIfNeeded(settings.m_raiseDelta, toolDB.raiseDelta); settings.m_smooth = UpdateValueIfNeeded(settings.m_smooth, toolDB.smooth); settings.m_smoothRadius = UpdateValueIfNeeded(settings.m_smoothRadius, toolDB.smoothRadius); settings.m_smoothPower = UpdateValueIfNeeded(settings.m_smoothPower, toolDB.smoothPower); settings.m_paintCleared = UpdateValueIfNeeded(settings.m_paintCleared, toolDB.clearPaint); settings.m_paintRadius = UpdateValueIfNeeded(settings.m_paintRadius, toolDB.paintRadius); if (toolDB.overlayType != null) { val.AddComponent(toolDB.overlayType); } if (toolDB.invertGhost) { Transform val2 = val.transform.Find("_GhostOnly"); if ((Object)(object)val2 != (Object)null) { val2.localRotation = Quaternion.Euler(270f, 0f, 0f); val2.localPosition += new Vector3(0f, 2f, 0f); } } return val; } private static T UpdateValueIfNeeded<T>(T source, T? newValue) where T : struct { if (!newValue.HasValue) { return source; } return newValue.Value; } private static T UpdateValueIfNeeded<T>(T source, T newValue) { if (newValue == null) { return source; } return newValue; } private static void RegisterPieceInPieceTable(GameObject prefab, string pieceTable, string category, int position = -1) { //IL_00c8: 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) Piece component = prefab.GetComponent<Piece>(); if ((Object)(object)component == (Object)null) { throw new Exception("Prefab " + ((Object)prefab).name + " has no Piece component attached"); } PieceTable pieceTable2 = PieceManager.Instance.GetPieceTable(pieceTable); if ((Object)(object)pieceTable2 == (Object)null) { throw new Exception("Could not find PieceTable " + pieceTable); } if (pieceTable2.m_pieces.Contains(prefab)) { Log.LogDebug("Already added piece " + ((Object)prefab).name); return; } int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)prefab).name); if ((Object)(object)ZNetScene.instance != (Object)null && !ZNetScene.instance.m_namedPrefabs.ContainsKey(stableHashCode)) { PrefabManager.Instance.RegisterToZNetScene(prefab); } if (!string.IsNullOrEmpty(category)) { component.m_category = PieceManager.Instance.AddPieceCategory(pieceTable, category); } if (!InsertionIndexes.ContainsKey(pieceTable)) { InsertionIndexes[pieceTable] = new List<int>(); } int num = 0; if (position >= 0) { num = position + InsertionIndexes[pieceTable].Where((int x) => x <= position).Count(); } else if (num >= pieceTable2.m_pieces.Count && pieceTable2.m_pieces.Count != 0) { Log.LogWarning("Piece insertion index is out of bounds"); } if (position >= 0 && num < pieceTable2.m_pieces.Count) { pieceTable2.m_pieces.Insert(num, prefab); InsertionIndexes[pieceTable].Add(position); } else { pieceTable2.m_pieces.Add(prefab); InsertionIndexes[pieceTable].Add(pieceTable2.m_pieces.Count - 1); } Log.LogDebug("Added piece " + ((Object)prefab).name + " | Token: " + PieceExtension.TokenName(component)); } private static void RemovePieceInPieceTable(ToolDB toolDB) { GameObject prefab = toolDB.prefab; if (!Object.op_Implicit((Object)(object)prefab)) { return; } PieceTable pieceTable = PieceManager.Instance.GetPieceTable(toolDB.pieceTable); if ((Object)(object)pieceTable == (Object)null) { throw new Exception("Could not find PieceTable " + toolDB.pieceTable); } int num = pieceTable.m_pieces.IndexOf(prefab); if (num < 0) { return; } pieceTable.m_pieces.Remove(prefab); Log.LogDebug("Removed piece " + ((Object)prefab).name); List<int> list = InsertionIndexes[toolDB.pieceTable]; if (!list.Contains(num)) { return; } list.Remove(num); for (int i = 0; i < list.Count; i++) { if (list[i] > num) { list[i]--; } } } } [HarmonyPatch(typeof(PreciseTerrainModifier))] public static class PreciseTerrainModifier { public const int FixedRadius = 1; public static bool IsPrecisionModifier(float radius) { return radius == float.NegativeInfinity; } [HarmonyPrefix] [HarmonyPatch(typeof(ClutterSystem), "ResetGrass")] private static void ResetGrassPrefix(ClutterSystem __instance, Vector3 center, ref float radius) { if (IsPrecisionModifier(radius)) { radius = 1f; } } [HarmonyPrefix] [HarmonyPatch(typeof(TerrainComp), "ApplyOperation")] private static void ApplyOperationPrefix(TerrainOp modifier) { if (Object.op_Implicit((Object)(object)modifier) && Object.op_Implicit((Object)(object)((Component)modifier).gameObject) && Object.op_Implicit((Object)(object)((Component)modifier).gameObject.GetComponentInChildren<OverlayVisualizer>())) { if (modifier.m_settings.m_smooth) { modifier.m_settings.m_smoothRadius = float.NegativeInfinity; } if (modifier.m_settings.m_raise && modifier.m_settings.m_raiseDelta >= 0f) { modifier.m_settings.m_raiseRadius = float.NegativeInfinity; modifier.m_settings.m_raiseDelta = GroundLevelSpinner.Value; } if (modifier.m_settings.m_paintCleared) { modifier.m_settings.m_paintRadius = float.NegativeInfinity; } } } [HarmonyPrefix] [HarmonyPatch(typeof(TerrainComp), "RPC_ApplyOperation")] private static void RPC_ApplyOperationPrefix(TerrainComp __instance) { if (Object.op_Implicit((Object)(object)__instance) && Object.op_Implicit((Object)(object)__instance.m_nview) && !__instance.m_nview.IsOwner()) { __instance.m_nview.ClaimOwnership(); } } [HarmonyPrefix] [HarmonyPatch(typeof(TerrainComp), "InternalDoOperation")] private static void InternalDoOperationPrefix(TerrainComp __instance, Vector3 pos, Settings modifier) { //IL_0021: 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) if (!modifier.m_level && !modifier.m_raise && !modifier.m_smooth && !modifier.m_paintCleared) { RemoveTerrainModifications(__instance, pos); PreciseRecolorTerrain(__instance, pos, (PaintType)3); } } [HarmonyPostfix] [HarmonyPatch(typeof(TerrainComp), "InternalDoOperation")] private static void InternalDoOperationPostfix(TerrainComp __instance) { if (IsPrecisionModifier(__instance.m_lastOpRadius)) { __instance.m_lastOpRadius = 1f; } } [HarmonyPrefix] [HarmonyPatch(typeof(TerrainComp), "SmoothTerrain")] private static bool PreciseSmoothTerrian(TerrainComp __instance, Vector3 worldPos, float radius) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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_0053: Unknown result type (might be due to invalid IL or missing references) if (!IsPrecisionModifier(radius)) { return true; } Log.LogInfo("PreciseSmoothTerrain", LogLevel.Medium); int num = __instance.m_width + 1; int num2 = default(int); int num3 = default(int); __instance.m_hmap.WorldToVertex(worldPos, ref num2, ref num3); float num4 = worldPos.y - ((Component)__instance).transform.position.y; Log.LogInfo($"worldPos: {worldPos}, xPos: {num2}, yPos: {num3}, referenceH: {num4}", LogLevel.Medium); FindExtrema(num2, num, out var xMin, out var xMax); FindExtrema(num3, num, out var xMin2, out var xMax2); for (int i = xMin; i <= xMax; i++) { for (int j = xMin2; j <= xMax2; j++) { int num5 = j * num + i; float height = __instance.m_hmap.GetHeight(i, j); float num6 = num4 - height; float num7 = __instance.m_smoothDelta[num5]; __instance.m_smoothDelta[num5] = Mathf.Clamp(num7 + num6, -1f, 1f); __instance.m_modifiedHeight[num5] = true; Log.LogInfo($"tilePos: ({i}, {j}), tileH: {height}, deltaH: {num6}, prevSmoothDelta: {num7}, newSmoothDelta {__instance.m_smoothDelta[num5]}", LogLevel.Medium); } } Log.LogInfo("[SUCCESS] Smooth Terrain Modification", LogLevel.Medium); return false; } [HarmonyPrefix] [HarmonyPatch(typeof(TerrainComp), "RaiseTerrain")] private static bool RaiseTerrainPrefix(TerrainComp __instance, Vector3 worldPos, float radius, float delta) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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_0053: Unknown result type (might be due to invalid IL or missing references) if (!IsPrecisionModifier(radius)) { return true; } Log.LogInfo("[INIT] Raise Terrain Modification", LogLevel.Medium); int num = __instance.m_width + 1; int num2 = default(int); int num3 = default(int); __instance.m_hmap.WorldToVertex(worldPos, ref num2, ref num3); float num4 = worldPos.y - ((Component)__instance).transform.position.y; Log.LogInfo($"worldPos: {worldPos}, xPos: {num2}, yPos: {num3}, delta: {delta}, refHeight: {num4}", LogLevel.Medium); FindExtrema(num2, num, out var xMin, out var xMax); FindExtrema(num3, num, out var xMin2, out var xMax2); for (int i = xMin; i <= xMax; i++) { for (int j = xMin2; j <= xMax2; j++) { float height = __instance.m_hmap.GetHeight(i, j); float num5 = num4 + delta; if (delta < 0f && num5 > height) { continue; } if (delta >= 0f) { if (num5 < height) { continue; } if (num5 > height + delta) { num5 = height + delta; } } int num6 = j * num + i; float num7 = num5 - height + __instance.m_smoothDelta[num6]; __instance.m_smoothDelta[num6] = 0f; __instance.m_levelDelta[num6] += num7; __instance.m_levelDelta[num6] = Mathf.Clamp(__instance.m_levelDelta[num6], -8f, 8f); __instance.m_modifiedHeight[num6] = true; } } Log.LogInfo("[SUCCESS] Raise Terrain Modification", LogLevel.Medium); return false; } [HarmonyPrefix] [HarmonyPatch(typeof(TerrainComp), "PaintCleared")] private static bool PaintClearedPrefix(TerrainComp __instance, Vector3 worldPos, float radius, PaintType paintType, bool heightCheck) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) if (!IsPrecisionModifier(radius)) { return true; } PreciseRecolorTerrain(__instance, worldPos, paintType, heightCheck); return false; } public static void RemoveTerrainModifications(TerrainComp comp, Vector3 worldPos) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) Log.LogInfo("[INIT] Remove Terrain Modifications", LogLevel.Medium); int num = comp.m_width + 1; int num2 = default(int); int num3 = default(int); comp.m_hmap.WorldToVertex(worldPos, ref num2, ref num3); Log.LogInfo($"worldPos: {worldPos}, vertexPos: ({num2}, {num3})", LogLevel.Medium); FindExtrema(num2, num, out var xMin, out var xMax); FindExtrema(num3, num, out var xMin2, out var xMax2); for (int i = xMin; i <= xMax; i++) { for (int j = xMin2; j <= xMax2; j++) { int num4 = j * num + i; comp.m_levelDelta[num4] = 0f; comp.m_smoothDelta[num4] = 0f; comp.m_modifiedHeight[num4] = false; Log.LogInfo($"tilePos: ({i}, {j}), tileIndex: {num4}", LogLevel.Medium); } } Log.LogInfo("[SUCCESS] Remove Terrain Modifications", LogLevel.Medium); } public static void PreciseRecolorTerrain(TerrainComp comp, Vector3 worldPos, PaintType paintType, bool heightCheck = false) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0048: 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_004f: 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) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Invalid comparison between Unknown and I4 //IL_0093: 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_00f2: Unknown result type (might be due to invalid IL or missing references) Log.LogInfo("[INIT] PreciseRecolorTerrain", LogLevel.Medium); worldPos.x -= 0.5f; worldPos.z -= 0.5f; int num = comp.m_width + 1; int num2 = default(int); int num3 = default(int); comp.m_hmap.WorldToVertexMask(worldPos, ref num2, ref num3); new Vector2((float)num2, (float)num3); Color val = ResolveColor(paintType); bool flag = (int)paintType == 3; FindExtrema(num2, num, out var xMin, out var xMax); FindExtrema(num3, num, out var xMin2, out var xMax2); for (int i = xMin + 1; i <= xMax; i++) { for (int j = xMin2 + 1; j <= xMax2; j++) { val.a = comp.m_hmap.GetPaintMask(i, j).a; int num4 = j * num + i; comp.m_paintMask[num4] = val; comp.m_modifiedPaint[num4] = !flag; Log.LogInfo($"tilePos: ({i}, {j}), tileIndex: {num4}, tileColor: {val}", LogLevel.Medium); } } Log.LogInfo("[SUCCESS] Color Terrain Modification", LogLevel.Medium); } public static Color ResolveColor(PaintType paintType) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected I4, but got Unknown //IL_0018: 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_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_0030: Unknown result type (might be due to invalid IL or missing references) return (Color)((int)paintType switch { 0 => Heightmap.m_paintMaskDirt, 1 => Heightmap.m_paintMaskCultivated, 2 => Heightmap.m_paintMaskPaved, 3 => Heightmap.m_paintMaskNothing, _ => Heightmap.m_paintMaskNothing, }); } public static void FindExtrema(int x, int worldSize, out int xMin, out int xMax) { xMin = Mathf.Max(0, x - 1); xMax = Mathf.Min(x + 1, worldSize - 1); } } [HarmonyPatch] internal static class RadiusModifier { private static bool RadiusToolIsInUse = false; private static float lastOriginalRadius; private static float lastModdedRadius; private static float lastTotalDelta; private static Vector3 lastGhostScale = Vector3.zero; private const float MinRadius = 0.5f; private const float Tolerance = 0.01f; [HarmonyPrefix] [HarmonyPatch(typeof(Player), "Update")] private static void UpdatePrefix(Player __instance) { //IL_0050: 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) //IL_006e: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)__instance) || (Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return; } TerrainOp terrainOp; if (!((Character)__instance).InPlaceMode() || Hud.IsPieceSelectionVisible()) { if (RadiusToolIsInUse) { RadiusToolIsInUse = false; lastOriginalRadius = 0f; lastModdedRadius = 0f; lastTotalDelta = 0f; lastGhostScale = Vector3.zero; } } else if (IsValidSelectedPiece(__instance, out terrainOp)) { if (ShouldModifyRadius()) { SetRadius(terrainOp, Input.mouseScrollDelta.y * TerrainTools.RadiusScrollScale); } RefreshGhostScale(__instance); } } internal static bool IsValidSelectedPiece(Player player, out TerrainOp terrainOp) { Piece selectedPiece = player.GetSelectedPiece(); if (!Object.op_Implicit((Object)(object)selectedPiece) || !Object.op_Implicit((Object)(object)((Component)selectedPiece).gameObject) || Object.op_Implicit((Object)(object)((Component)selectedPiece).gameObject.GetComponent<OverlayVisualizer>())) { terrainOp = null; return false; } terrainOp = ((Component)selectedPiece).gameObject.GetComponent<TerrainOp>(); if (!Object.op_Implicit((Object)(object)terrainOp)) { return false; } return true; } internal static bool ShouldModifyRadius() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (TerrainTools.IsEnableRadiusModifier && Input.GetKey(TerrainTools.RadiusKey)) { return Input.mouseScrollDelta.y != 0f; } return false; } [HarmonyPrefix] [HarmonyPriority(700)] [HarmonyPatch(typeof(TerrainOp), "Awake")] private static void AwakePrefix(TerrainOp __instance) { if (Object.op_Implicit((Object)(object)__instance) && Object.op_Implicit((Object)(object)((Component)__instance).gameObject) && !Object.op_Implicit((Object)(object)((Component)__instance).gameObject.GetComponent<OverlayVisualizer>())) { if (__instance.m_settings.m_level) { __instance.m_settings.m_levelRadius = ModifyRadius(__instance.m_settings.m_levelRadius, lastTotalDelta); Log.LogInfo($"Applying level radius {__instance.m_settings.m_levelRadius}", LogLevel.Medium); } if (__instance.m_settings.m_raise) { __instance.m_settings.m_raiseRadius = ModifyRadius(__instance.m_settings.m_raiseRadius, lastTotalDelta); Log.LogInfo($"Applying raise radius {__instance.m_settings.m_raiseRadius}", LogLevel.Medium); } if (__instance.m_settings.m_smooth) { __instance.m_settings.m_smoothRadius = ModifyRadius(__instance.m_settings.m_smoothRadius, lastTotalDelta); Log.LogInfo($"Applying smooth radius {__instance.m_settings.m_smoothRadius}", LogLevel.Medium); } if (__instance.m_settings.m_paintCleared) { __instance.m_settings.m_paintRadius = ModifyRadius(__instance.m_settings.m_paintRadius, lastTotalDelta); Log.LogInfo($"Applying paint radius {__instance.m_settings.m_paintRadius}", LogLevel.Medium); } } } private static float ModifyRadius(float radius, float delta) { return Mathf.Clamp(radius + delta, 0.5f, TerrainTools.MaxRadius); } private static void SetRadius(TerrainOp terrainOp, float delta) { //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) Log.LogInfo($"Adjusting radius by {delta}", LogLevel.High); if (!RadiusToolIsInUse && Object.op_Implicit((Object)(object)terrainOp)) { if (TryGetMaximumRadius(terrainOp, out var maxRadius)) { RadiusToolIsInUse = true; lastOriginalRadius = maxRadius; lastModdedRadius = ModifyRadius(maxRadius, delta); lastTotalDelta += delta; } } else { lastModdedRadius = ModifyRadius(lastModdedRadius, delta); lastTotalDelta += delta; } Log.LogInfo($"total delta {lastTotalDelta}", LogLevel.High); lastGhostScale = new Vector3(lastModdedRadius / lastOriginalRadius, lastModdedRadius / lastOriginalRadius, lastModdedRadius / lastOriginalRadius); } private static void RefreshGhostScale(Player player) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: 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_0060: 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_0091: Unknown result type (might be due to invalid IL or missing references) if (!RadiusToolIsInUse || !Object.op_Implicit((Object)(object)player.m_placementGhost)) { return; } Transform val = player.m_placementGhost.transform.Find("_GhostOnly"); if (Object.op_Implicit((Object)(object)val)) { ParticleSystem componentInChildren = ((Component)val).GetComponentInChildren<ParticleSystem>(); if (Object.op_Implicit((Object)(object)componentInChildren) && !(lastGhostScale == Vector3.zero) && Vector3.Distance(((Component)componentInChildren).transform.localScale, lastGhostScale) > 0.01f) { Log.LogInfo($"Adjusting ghost scale to {lastGhostScale}x", LogLevel.High); ((Component)componentInChildren).transform.localScale = lastGhostScale; } } } private static bool TryGetMaximumRadius(TerrainOp terrainOp, out float maxRadius) { maxRadius = 0f; if (terrainOp.m_settings.m_level && maxRadius < terrainOp.m_settings.m_levelRadius) { maxRadius = terrainOp.m_settings.m_levelRadius; } if (terrainOp.m_settings.m_raise && maxRadius < terrainOp.m_settings.m_raiseRadius) { maxRadius = terrainOp.m_settings.m_raiseRadius; } if (terrainOp.m_settings.m_smooth && maxRadius < terrainOp.m_settings.m_smoothRadius) { maxRadius = terrainOp.m_settings.m_smoothRadius; } if (terrainOp.m_settings.m_paintCleared && maxRadius < terrainOp.m_settings.m_paintRadius) { maxRadius = terrainOp.m_settings.m_paintRadius; } return maxRadius != 0f; } } internal static class Shovel { private static bool HasBeenCreated; internal const string ShovelPrefabName = "ATM_Shovel"; internal const string ShovelPieceTable = "_ShovelPieceTable"; internal static CustomItem shovel; internal static bool TryGetShovel(out CustomItem shovel) { shovel = ItemManager.Instance.GetItem("ATM_Shovel"); return shovel != null; } internal static void CreateShovel() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //IL_003e: 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_006f: 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_0087: Expected O, but got Unknown //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown if (!HasBeenCreated) { GameObject obj = CreateShovelPrefab(); CreatePieceTable(); List<RequirementConfig> list = new List<RequirementConfig> { new RequirementConfig("Wood", 5, 1, false), new RequirementConfig("Iron", 2, 1, false) }; ItemConfig val = new ItemConfig { Name = "Shovel", Description = "", CraftingStation = CraftingStations.Forge, PieceTable = "_ShovelPieceTable", RepairStation = CraftingStations.Forge, Requirements = list.ToArray() }; shovel = new CustomItem(obj, true, val); shovel.Recipe.Recipe.m_enabled = TerrainTools.IsShovelEnabled; ItemManager.Instance.AddItem(shovel); HasBeenCreated = true; } } private static void CreatePieceTable() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown PieceTableConfig val = new PieceTableConfig { CanRemovePieces = false, UseCategories = true, UseCustomCategories = false }; CustomPieceTable val2 = new CustomPieceTable("_ShovelPieceTable", val); PieceManager.Instance.AddPieceTable(val2); } private static GameObject CreateShovelPrefab() { //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_02c9: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_02ee: Unknown result type (might be due to invalid IL or missing references) //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_0318: Unknown result type (might be due to invalid IL or missing references) //IL_037f: Unknown result type (might be due to invalid IL or missing references) //IL_0384: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011c: 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_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0177: 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_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) GameObject val = PrefabManager.Instance.CreateClonedPrefab("ATM_Shovel", "Hoe"); object obj; if (val == null) { obj = null; } else { Transform transform = val.transform; if (transform == null) { obj = null; } else { Transform obj2 = transform.Find("collider"); obj = ((obj2 != null) ? ((Component)obj2).gameObject : null); } } GameObject val2 = (GameObject)obj; object obj3; if (val == null) { obj3 = null; } else { Transform transform2 = val.transform; if (transform2 == null) { obj3 = null; } else { Transform obj4 = transform2.Find("collider (1)"); obj3 = ((obj4 != null) ? ((Component)obj4).gameObject : null); } } GameObject val3 = (GameObject)obj3; object obj5; if (val == null) { obj5 = null; } else { Transform transform3 = val.transform; if (transform3 == null) { obj5 = null; } else { Transform obj6 = transform3.Find("attach"); obj5 = ((obj6 != null) ? ((Component)obj6).gameObject : null); } } GameObject val4 = (GameObject)obj5; object obj7; if (val4 == null) { obj7 = null; } else { Transform transform4 = val4.transform; if (transform4 == null) { obj7 = null; } else { Transform obj8 = transform4.Find("visual"); obj7 = ((obj8 != null) ? ((Component)obj8).gameObject : null); } } GameObject val5 = (GameObject)obj7; if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null || (Object)(object)val4 == (Object)null || (Object)(object)val5 == (Object)null) { Log.LogWarning("Failed to create shovel"); return null; } Vector3 val6 = val4.transform.localPosition + val5.transform.localPosition; Quaternion val7 = val4.transform.localRotation * val5.transform.localRotation; try { object obj9; if (val5 == null) { obj9 = null; } else { Transform transform5 = val5.transform; if (transform5 == null) { obj9 = null; } else { Transform obj10 = transform5.Find("blade"); obj9 = ((obj10 != null) ? ((Component)obj10).gameObject : null); } } GameObject val8 = (GameObject)obj9; val8.transform.localPosition = new Vector3(0f, -0.01f, 0.815f); val8.transform.localRotation = Quaternion.identity; val8.transform.localScale = new Vector3(0.225f, 0.08f, 0.6f); ((Renderer)val8.GetComponent<MeshRenderer>()).sharedMaterial = Cache.GetPrefab<Material>("iron"); val3.transform.localPosition = val6 + val8.transform.localPosition; val3.transform.localRotation = val7 * val8.transform.localRotation; val3.transform.localScale = val8.transform.localScale; BoxCollider component = val3.GetComponent<BoxCollider>(); component.center = Vector3.zero; component.size = Vector3.one * 1.1f; } catch { Log.LogWarning("Failed to modify shovel blade"); } try { object obj12; if (val5 == null) { obj12 = null; } else { Transform transform6 = val5.transform; if (transform6 == null) { obj12 = null; } else { Transform obj13 = transform6.Find("handle"); obj12 = ((obj13 != null) ? ((Component)obj13).gameObject : null); } } GameObject val9 = (GameObject)obj12; Vector3 localScale = val9.transform.localScale; localScale.z = 1.6f; val9.transform.localScale = localScale; val2.transform.localPosition = val6 + val9.transform.localPosition; val2.transform.localRotation = val7 * val9.transform.localRotation; val2.transform.localScale = val9.transform.localScale; BoxCollider component2 = val2.GetComponent<BoxCollider>(); component2.center = Vector3.zero; component2.size = new Vector3(1.5f, 1.5f, 1.025f); } catch { Log.LogWarning("Failed to modify shovel handle"); } try { ItemDrop val10 = default(ItemDrop); if (val.TryGetComponent<ItemDrop>(ref val10)) { SharedData val11 = val10?.m_itemData?.m_shared; if (val11 != null) { Texture2D val12 = IconCache.Shovel; Sprite val13 = Sprite.Create(val12, new Rect(0f, 0f, (float)((Texture)val12).width, (float)((Texture)val12).height), Vector2.zero); val11.m_icons = (Sprite[])(object)new Sprite[1] { val13 }; } } } catch { Log.LogWarning("Failed to create shovel icon"); } return val; } } } namespace TerrainTools.Extensions { internal static class EventExtensions { public static void SafeInvoke(this Action events) { if (events == null) { return; } Delegate[] invocationList = events.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { Action action = (Action)invocationList[i]; try { action(); } catch (Exception ex) { Log.LogWarning($"Exception thrown at event {new StackFrame(1).GetMethod().Name} in {action.Method.DeclaringType.Name}.{action.Method.Name}:\n{ex}"); } } } public static void SafeInvoke<TArg1>(this Action<TArg1> events, TArg1 arg1) { if (events == null) { return; } Delegate[] invocationList = events.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { Action<TArg1> action = (Action<TArg1>)invocationList[i]; try { action(arg1); } catch (Exception ex) { Log.LogWarning($"Exception thrown at event {new StackFrame(1).GetMethod().Name} in {action.Method.DeclaringType.Name}.{action.Method.Name}:\n{ex}"); } } } public static void SafeInvoke<TArg1, TArg2>(this Action<TArg1, TArg2> events, TArg1 arg1, TArg2 arg2) { if (events == null) { return; } Delegate[] invocationList = events.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { Action<TArg1, TArg2> action = (Action<TArg1, TArg2>)invocationList[i]; try { action(arg1, arg2); } catch (Exception ex) { Log.LogWarning($"Exception thrown at event {new StackFrame(1).GetMethod().Name} in {action.Method.DeclaringType.Name}.{action.Method.Name}:\n{ex}"); } } } public static void SafeInvoke<TEventArg>(this EventHandler<TEventArg> events, object sender, TEventArg arg1) { if (events == null) { return; } Delegate[] invocationList = events.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { EventHandler<TEventArg> eventHandler = (EventHandler<TEventArg>)invocationList[i]; try { eventHandler(sender, arg1); } catch (Exception ex) { Log.LogWarning($"Exception thrown at event {new StackFrame(1).GetMethod().Name} in {eventHandler.Method.DeclaringType.Name}.{eventHandler.Method.Name}:\n{ex}"); } } } } internal static class TypeExtensions { internal static List<T> GetAllPublicConstantValues<T>(this Type type) { return (from fi in type.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy) where fi.IsLiteral && !fi.IsInitOnly && fi.FieldType == typeof(T) select fi into x select (T)x.GetRawConstantValue()).ToList(); } internal static List<T> GetAllPublicStaticValues<T>(this Type type) { return (from fi in type.GetFields(BindingFlags.Static | BindingFlags.Public) where fi.FieldType == typeof(T) select fi into x select (T)x.GetValue(null)).ToList(); } } internal static class GenericExtensions { private const BindingFlags AllBindings = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.SetField | BindingFlags.GetProperty | BindingFlags.SetProperty; public static void CopyFields(this object target, object source) { if (target == null || source == null) { throw new Exception("Target or/and Source Objects are null"); } Type type = source.GetType(); FieldInfo[] fields = target.GetType().GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.SetField | BindingFlags.GetProperty | BindingFlags.SetProperty); foreach (FieldInfo fieldInfo in fields) { FieldInfo field = type.GetField(fieldInfo.Name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.SetField | BindingFlags.GetProperty | BindingFlags.SetProperty); if (!(field == null) && field.IsInitOnly && field.FieldType.IsAssignableFrom(fieldInfo.FieldType)) { field.SetValue(source, fieldInfo.GetValue(target)); } } } internal static T Ref<T>(this T o) where T : Object { if (!Object.op_Implicit((Object)(object)o)) { return default(T); } return o; } } internal static class IEnumerableExtensions { internal static void Dispose(this IEnumerable<IDisposable> collection) { foreach (IDisposable item in collection) { if (item != null) { try { item.Dispose(); } catch (Exception) { Log.LogWarning("Could not dispose of item"); } } } } } internal static class ReflectionUtils { public const BindingFlags AllBindings = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.SetField | BindingFlags.GetProperty | BindingFlags.SetProperty; internal static MethodInfo GetMethod(Type type, string name, Type[] types) { MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.SetField | BindingFlags.GetProperty | BindingFlags.SetProperty); foreach (MethodInfo methodInfo in methods) { if (methodInfo.Name == name && HasMatchingParameterTypes(0, types, methodInfo.GetParameters())) { return methodInfo; } } return null; } internal static MethodInfo GetGenericMethod(Type type, string name, int genericParameterCount, Type[] types) { MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.SetField | BindingFlags.GetProperty | BindingFlags.SetProperty); foreach (MethodInfo methodInfo in methods) { if (methodInfo.IsGenericMethod && methodInfo.ContainsGenericParameters && methodInfo.Name == name && HasMatchingParameterTypes(genericParameterCount, types, methodInfo.GetParameters())) { return methodInfo; } } return null; } private static bool HasMatchingParameterTypes(int genericParameterCount, Type[] types, ParameterInfo[] parameters) { if (parameters.Length < genericParameterCount || parameters.Length != types.Length) { return false; } int num = 0; for (int i = 0; i < parameters.Length; i++) { if (parameters[i].ParameterType.IsGenericParameter) { num++; } else if (types[i] != parameters[i].ParameterType) { return false; } } if (num != genericParameterCount) { return false; } return true; } } } namespace TerrainTools.Configs { internal static class ConfigManager { private static string ConfigFileName; private static string ConfigFileFullPath; private static ConfigFile configFile; private static BaseUnityPlugin ConfigurationManager; private const string ConfigManagerGUID = "com.bepis.bepinex.configurationmanager"; private static readonly ConfigurationManagerAttributes AdminConfig = new ConfigurationManagerAttributes { IsAdminOnly = true }; private static readonly ConfigurationManagerAttributes ClientConfig = new ConfigurationManagerAttributes { IsAdminOnly = false }; private const char ZWS = '\u200b'; internal static event Action OnConfigWindowClosed; internal static event Action OnConfigFileReloaded; private static void InvokeOnConfigWindowClosed() { ConfigManager.OnConfigWindowClosed?.SafeInvoke(); } private static void InvokeOnConfigFileReloaded() { ConfigManager.OnConfigFileReloaded?.SafeInvoke(); } internal static ConfigEntry<T> BindConfig<T>(string section, string name, T value, string description, AcceptableValueBase acceptVals = null, bool synced = true) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown string extendedDescription = GetExtendedDescription(description, synced); return configFile.Bind<T>(section, name, value, new ConfigDescription(extendedDescription, acceptVals, new object[1] { synced ? AdminConfig : ClientConfig })); } internal static string SetStringPriority(string sectionName, int priority) { if (priority == 0) { return sectionName; } return new string('\u200b', priority) + sectionName; } internal static string GetExtendedDescription(string description, bool synchronizedSetting) { return description + (synchronizedSetting ? " [Synced with Server]" : " [Not Synced with Server]"); } internal static void Init(string GUID, ConfigFile config) { configFile = config; configFile.SaveOnConfigSet = false; ConfigFileName = GUID + ".cfg"; ConfigFileFullPath = Path.Combine(Paths.ConfigPath, ConfigFileName); } private static bool DisableSaveOnConfigSet() { bool saveOnConfigSet = configFile.SaveOnConfigSet; configFile.SaveOnConfigSet = false; return saveOnConfigSet; } internal static void SaveOnConfigSet(bool value) { configFile.SaveOnConfigSet = value; } interna