Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Pit Construtor v1.1.1
PitConstrutor.dll
Decompiled a month ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using JetBrains.Annotations; using Microsoft.CodeAnalysis; using PitConstrutor.Terrain; using ServerSync; using SkillManager; using TMPro; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Pit Construtor")] [assembly: AssemblyDescription("Mod Pit Construtor para Valheim - Sistema completo de habilidade de Construção, durabilidade, altura de suporte e eficiência de martelo.")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Pit")] [assembly: AssemblyProduct("Pit Construtor")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("9BF5432D-9518-4D36-A6C2-A8C62D36B921")] [assembly: AssemblyFileVersion("1.1.1.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace PitConstrutor { [BepInPlugin("org.bepinex.plugins.pit_construtor", "Pit Construtor", "1.1.1")] [BepInIncompatibility("org.bepinex.plugins.valheim_plus")] [BepInIncompatibility("org.bepinex.plugins.building")] public class PitConstrutorPlugin : BaseUnityPlugin { private enum Toggle { On = 1, Off = 0 } private class ConfigurationManagerAttributes { [UsedImplicitly] public bool? ShowRangeAsPercent; } [HarmonyPatch(typeof(Player), "UpdatePlacement")] private static class ChangeStaminaUsage { private static float stamina; private static bool modified; private static void Prefix(Player __instance, out ItemData? __state) { __state = ((Humanoid)__instance).GetRightItem(); modified = false; if (__state?.m_shared != null && (__state.m_shared.m_name == "$item_hammer" || __state.m_shared.m_name == "$item_hoe" || __state.m_shared.m_name == "$item_cultivator") && __state.m_shared.m_attack != null) { stamina = __state.m_shared.m_attack.m_attackStamina; Attack attack = __state.m_shared.m_attack; attack.m_attackStamina *= Mathf.Max(0f, 1f - ((Character)(object)__instance).GetSkillFactor("Building") * (float)staminaReductionPerLevel.Value); modified = true; } } private static void Finalizer(ItemData? __state) { if (modified && __state?.m_shared?.m_attack != null) { __state.m_shared.m_attack.m_attackStamina = stamina; modified = false; } } } [HarmonyPatch(typeof(WearNTear), "OnPlaced")] public class AddZDO { public static bool forFree; [UsedImplicitly] private static void Postfix(WearNTear __instance) { if ((Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)__instance == (Object)null) { return; } ZNetView val = (((Object)(object)__instance.m_nview != (Object)null) ? __instance.m_nview : ((Component)__instance).GetComponent<ZNetView>()); if ((Object)(object)val != (Object)null) { ZDO zDO = val.GetZDO(); if (zDO != null) { float skillFactor = ((Character)(object)Player.m_localPlayer).GetSkillFactor("Building"); zDO.Set("BuildingSkill Level", skillFactor); __instance.m_health *= 1f + skillFactor * (healthFactor.Value - 1f); forFree = false; if (freeBuildLevelRequirement.Value > 0) { forFree = Random.Range((float)freeBuildLevelRequirement.Value / 100f, 5.5f) <= skillFactor; } zDO.Set("BuildingSkill FreeBuild", forFree); } } ((Character)(object)Player.m_localPlayer).RaiseSkill("Building"); } } [HarmonyPatch(typeof(WearNTear), "Awake")] private class IncreaseHealth { [UsedImplicitly] private static void Prefix(WearNTear __instance) { if ((Object)(object)__instance == (Object)null) { return; } ZNetView val = (((Object)(object)__instance.m_nview != (Object)null) ? __instance.m_nview : ((Component)__instance).GetComponent<ZNetView>()); if (!((Object)(object)val != (Object)null)) { return; } ZDO zDO = val.GetZDO(); if (zDO != null) { float num = zDO.GetFloat("BuildingSkill Level", 0f); if (num > 0f) { __instance.m_health *= 1f + num * (healthFactor.Value - 1f); } } } } [HarmonyPatch(typeof(WearNTear), "GetMaterialProperties")] private class BuildHigher { [UsedImplicitly] private static void Postfix(WearNTear __instance, ref float maxSupport, ref float minSupport, ref float horizontalLoss, ref float verticalLoss) { if (!((Object)(object)__instance == (Object)null)) { ZNetView obj = (((Object)(object)__instance.m_nview != (Object)null) ? __instance.m_nview : ((Component)__instance).GetComponent<ZNetView>()); float? obj2; if (obj == null) { obj2 = null; } else { ZDO zDO = obj.GetZDO(); obj2 = ((zDO != null) ? new float?(zDO.GetFloat("BuildingSkill Level", 0f)) : ((float?)null)); } float num = obj2 ?? ((Character)(object)Player.m_localPlayer)?.GetSkillFactor("Building") ?? 0f; if (num > 0f) { maxSupport *= 1f + num * (maximumSupportFactor.Value - 1f); horizontalLoss *= 1f - num * (1f - supportLossFactor.Value); verticalLoss *= 1f - num * (1f - supportLossFactor.Value); } } } } [HarmonyPatch(typeof(Player), "UpdatePlacement")] private class ResetFlag { private static void Finalizer() { AddZDO.forFree = false; } } [HarmonyPatch(typeof(Player), "ConsumeResources")] private class BuildingIsFree { private class SkipConsumeResourcesException : Exception { } [HarmonyPriority(800)] private static void Prefix() { if (AddZDO.forFree) { throw new SkipConsumeResourcesException(); } } private static Exception? Finalizer(Exception __exception) { if (!(__exception is SkipConsumeResourcesException)) { return __exception; } return null; } } [HarmonyPatch(typeof(Piece), "DropResources")] private class RecoverResources { private static bool Prefix(Piece __instance) { if ((Object)(object)__instance == (Object)null) { return true; } ZNetView val = (((Object)(object)__instance.m_nview != (Object)null) ? __instance.m_nview : ((Component)__instance).GetComponent<ZNetView>()); if ((Object)(object)val != (Object)null) { ZDO zDO = val.GetZDO(); if (zDO != null) { return !zDO.GetBool("BuildingSkill FreeBuild", false); } } return true; } } [HarmonyPatch(typeof(Player), "UpdatePlacement")] private static class ReduceHammerDurabilityLoss { private static bool reduced; private static void Prefix(Player __instance) { reduced = false; if (durabilityUsageLevelRequirement.Value > 0 && (Object)(object)__instance != (Object)null && (float)durabilityUsageLevelRequirement.Value <= ((Character)(object)__instance).GetSkillFactor("Building") * 100f) { ItemData rightItem = ((Humanoid)__instance).GetRightItem(); if (rightItem != null && rightItem.m_shared != null && (rightItem.m_shared.m_name == "$item_hammer" || rightItem.m_shared.m_name == "$item_hoe" || rightItem.m_shared.m_name == "$item_cultivator")) { SharedData shared = rightItem.m_shared; shared.m_useDurabilityDrain *= 0.7f; reduced = true; } } } private static void Finalizer(Player __instance) { if (reduced && (Object)(object)__instance != (Object)null) { ItemData rightItem = ((Humanoid)__instance).GetRightItem(); if (rightItem != null && rightItem.m_shared != null) { SharedData shared = rightItem.m_shared; shared.m_useDurabilityDrain /= 0.7f; reduced = false; } } } } [HarmonyPatch(typeof(Player), "PlacePiece")] private static class TerrainSynergySkillGain { [HarmonyPostfix] private static void Postfix(Player __instance, Piece piece) { if (!((Object)(object)__instance == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && (TerrainConfig.EnableTerrainSynergy == null || TerrainConfig.EnableTerrainSynergy.Value) && (Object)(object)piece != (Object)null && ((Object)(object)((Component)piece).GetComponent<TerrainOp>() != (Object)null || (Object)(object)((Component)piece).GetComponent<TerrainModifier>() != (Object)null || ((Object)(object)((Component)piece).gameObject != (Object)null && ((Object)(object)((Component)piece).gameObject.GetComponent<TerrainOp>() != (Object)null || (Object)(object)((Component)piece).gameObject.GetComponent<TerrainModifier>() != (Object)null)))) { ((Character)(object)__instance).RaiseSkill("Building"); } } } [HarmonyPatch(typeof(Skills), "IsSkillValid")] private static class EnsureBuildingSkillValid { [HarmonyPostfix] private static void Postfix(SkillType type, ref bool __result) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 if (!__result && (int)type == Math.Abs(StringExtensionMethods.GetStableHashCode("Building"))) { __result = true; } } } private const string ModName = "Pit Construtor"; private const string ModVersion = "1.1.1"; private const string ModGUID = "org.bepinex.plugins.pit_construtor"; private static readonly ConfigSync configSync = new ConfigSync("org.bepinex.plugins.pit_construtor") { DisplayName = "Pit Construtor", CurrentVersion = "1.1.1", MinimumRequiredVersion = "1.1.1" }; private static ConfigEntry<Toggle> serverConfigLocked = null; private static ConfigEntry<float> maximumSupportFactor = null; private static ConfigEntry<float> supportLossFactor = null; private static ConfigEntry<float> healthFactor = null; private static ConfigEntry<int> freeBuildLevelRequirement = null; private static ConfigEntry<int> durabilityUsageLevelRequirement = null; private static ConfigEntry<float> experienceGainedFactor = null; private static ConfigEntry<int> experienceLoss = null; private static ConfigEntry<int> staminaReductionPerLevel = null; private static Skill building = null; private ConfigEntry<T> config<T>(string group, string name, T value, ConfigDescription description, bool synchronizedSetting = true) { ConfigEntry<T> val = ((BaseUnityPlugin)this).Config.Bind<T>(group, name, value, description); configSync.AddConfigEntry<T>(val).SynchronizedConfig = synchronizedSetting; return val; } private ConfigEntry<T> config<T>(string group, string name, T value, string description, bool synchronizedSetting = true) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting); } public void Awake() { //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Expected O, but got Unknown //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Expected O, but got Unknown //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Expected O, but got Unknown //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Expected O, but got Unknown //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Expected O, but got Unknown //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Expected O, but got Unknown //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Expected O, but got Unknown //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Expected O, but got Unknown //IL_0346: Unknown result type (might be due to invalid IL or missing references) building = new Skill("Building", "building-icon.png"); building.Description.English("Increases the health of pieces built by you and you can build higher."); building.Name.German("Bauen"); building.Description.German("Erhöht die Lebenspunkte von Bauten, die von dir errichtet wurden und du kannst höher bauen."); building.Name.Portuguese_Brazilian("Construção"); building.Description.Portuguese_Brazilian("Aumenta a vida das peças construídas por você e permite construir estruturas mais altas."); building.Name.Portuguese_European("Construção"); building.Description.Portuguese_European("Aumenta a vida das peças construídas por você e permite construir estruturas mais altas."); building.Configurable = false; serverConfigLocked = config("1 - General", "Lock Configuration", Toggle.On, "If on, the configuration is locked and can be changed by server admins only."); configSync.AddLockingConfigEntry<Toggle>(serverConfigLocked); maximumSupportFactor = config("2 - Building", "Maximum Support Factor", 1.5f, new ConfigDescription("Maximum support factor for building pieces at skill level 100.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 5f), Array.Empty<object>())); supportLossFactor = config("2 - Building", "Support Loss Factor", 0.75f, new ConfigDescription("Support loss factor for vertical and horizontal building at skill level 100.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 1f), Array.Empty<object>())); healthFactor = config("2 - Building", "Health Factor", 3f, new ConfigDescription("Health factor for building pieces at skill level 100.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), Array.Empty<object>())); freeBuildLevelRequirement = config("2 - Building", "Free Build Level Requirement", 50, new ConfigDescription("Minimum required skill level to be able to receive free building pieces. 0 is disabled.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), new object[1] { new ConfigurationManagerAttributes { ShowRangeAsPercent = false } })); durabilityUsageLevelRequirement = config("2 - Building", "Durability Increase Level Requirement", 30, new ConfigDescription("Minimum required skill level to reduce the durability usage of hammers by 30%. 0 is disabled.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), new object[1] { new ConfigurationManagerAttributes { ShowRangeAsPercent = false } })); staminaReductionPerLevel = config("2 - Building", "Stamina Reduction per Level", 1, new ConfigDescription("Reduces the stamina usage while building. Percentage stamina reduction per level. 0 is disabled.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())); experienceGainedFactor = config("3 - Other", "Skill Experience Gain Factor", 1f, new ConfigDescription("Factor for experience gained for the building skill.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 5f), Array.Empty<object>())); experienceGainedFactor.SettingChanged += delegate { building.SkillGainFactor = experienceGainedFactor.Value; }; building.SkillGainFactor = experienceGainedFactor.Value; experienceLoss = config("3 - Other", "Skill Experience Loss", 0, new ConfigDescription("How much experience to lose in the building skill on death.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())); experienceLoss.SettingChanged += delegate { building.SkillLoss = experienceLoss.Value; }; building.SkillLoss = experienceLoss.Value; TerrainLog.Init(((BaseUnityPlugin)this).Logger); TerrainConfig.Init(((BaseUnityPlugin)this).Config, configSync); Assembly executingAssembly = Assembly.GetExecutingAssembly(); new Harmony("org.bepinex.plugins.pit_construtor").PatchAll(executingAssembly); } } } namespace PitConstrutor.Terrain { [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) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) 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>()) || (TerrainConfig.EnableRadiusModifier.Value && Input.GetKey(TerrainConfig.RadiusKey.Value)) || (TerrainConfig.EnableHardnessModifier.Value && Input.GetKey(TerrainConfig.HardnessKey.Value)))) { return true; } if ((Object)(object)localPlayer != (Object)null) { return localPlayer.CanRotatePiece(); } return false; } } [HarmonyPatch] internal static class PlayerPlacementGhostPatch { [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_004a: 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_006d: 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) //IL_00c4: 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; Heightmap val = Heightmap.FindHeightmap(position); if (Object.op_Implicit((Object)(object)val)) { int num = default(int); int num2 = default(int); val.WorldToVertex(position, ref num, ref num2); position.x = ((Component)val).transform.position.x + (float)(num - val.m_width / 2) * val.m_scale; position.z = ((Component)val).transform.position.z + (float)(num2 - val.m_width / 2) * val.m_scale; __instance.m_placementGhost.transform.position = position; } } } [HarmonyPostfix] [HarmonyPatch(typeof(Player), "Update")] private static void PlayerUpdatePostfix(Player __instance) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer) { RadiusModifier.Tick(__instance); HardnessModifier.Tick(__instance); } } } public static class GroundLevelSpinner { public const string MouseScrollWheel = "Mouse ScrollWheel"; public const float ScrollPrecision = 0.05f; 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); } else if (num < 0f) { Down(num); } } private static float ScrollDelta() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) if (TerrainConfig.EnableHardnessModifier != null && TerrainConfig.EnableHardnessModifier.Value && Input.GetKey(TerrainConfig.HardnessKey.Value)) { return 0f; } 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 = false; private static float lastModdedSmoothPwr; private static float lastTotalSmoothDelta; private const float MinSmoothPwr = 1f; private const float MaxSmoothPwr = 30f; private static bool RaiseToolIsInUse = false; private static TerrainOp? activeRaiseTool; 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 = -1f; private static float lastDisplayedRaiseHardness = -1f; internal static void Tick(Player __instance) { //IL_00a8: 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; } SelectRaiseTool(null); } else { Piece selectedPiece = __instance.GetSelectedPiece(); TerrainOp val = ((Object.op_Implicit((Object)(object)selectedPiece) && Object.op_Implicit((Object)(object)((Component)selectedPiece).gameObject)) ? ((Component)selectedPiece).gameObject.GetComponent<TerrainOp>() : null); SelectRaiseTool((Object.op_Implicit((Object)(object)val) && val.m_settings.m_raise) ? val : null); if (ShouldModifyHardness()) { SetPower(__instance, Input.mouseScrollDelta.y * TerrainConfig.HardnessScrollScale.Value); } } } internal static bool ShouldModifyHardness() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (TerrainConfig.EnableHardnessModifier.Value && Input.GetKey(TerrainConfig.HardnessKey.Value)) { return Input.mouseScrollDelta.y != 0f; } return false; } internal static float CurrentRaisePower(float defaultPower) { if (!RaiseToolIsInUse) { return ModifyRaisePower(defaultPower, 0f); } return lastModdedRaisePwr; } private static void SelectRaiseTool(TerrainOp? terrainOp) { if (!((Object)(object)activeRaiseTool == (Object)(object)terrainOp)) { activeRaiseTool = terrainOp; RaiseToolIsInUse = false; lastModdedRaisePwr = 0f; lastTotalRaiseDelta = 0f; lastDisplayedRaiseHardness = -1f; } } [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)) { return; } OverlayVisualizer component = ((Component)__instance).gameObject.GetComponent<OverlayVisualizer>(); if (!Object.op_Implicit((Object)(object)component) || component is RaiseGroundOverlayVisualizer) { if (__instance.m_settings.m_raise) { __instance.m_settings.m_raisePower = ModifyRaisePower(__instance.m_settings.m_raisePower, lastTotalRaiseDelta); } if (__instance.m_settings.m_smooth) { __instance.m_settings.m_smoothPower = ModifySmoothPower(__instance.m_settings.m_smoothPower, lastTotalSmoothDelta); } } } 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)) { return; } OverlayVisualizer component = ((Component)selectedPiece).gameObject.GetComponent<OverlayVisualizer>(); if (Object.op_Implicit((Object)(object)component) && !(component is RaiseGroundOverlayVisualizer)) { return; } TerrainOp component2 = ((Component)selectedPiece).gameObject.GetComponent<TerrainOp>(); if (!Object.op_Implicit((Object)(object)component2)) { return; } SetSmoothPower(component2, delta); SetRaisePower(component2, 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(string.Format("{0} {1:0}%", Localization.instance.Localize("$atmc_smoothing_hardness"), smoothPowerDisplayValue)); } } if (RaiseToolIsInUse) { float raisePowerDisplayValue = GetRaisePowerDisplayValue(lastModdedRaisePwr); if (Mathf.Abs(raisePowerDisplayValue - lastDisplayedRaiseHardness) > 0.9f) { lastDisplayedRaiseHardness = Mathf.Round(raisePowerDisplayValue); list.Add(string.Format("{0} {1:0}%", Localization.instance.Localize("$atmc_raise_hardness"), raisePowerDisplayValue)); } } if (SmoothToolIsInUse || RaiseToolIsInUse) { Piece val = (Object.op_Implicit((Object)(object)player.m_placementGhost) ? player.m_placementGhost.GetComponent<Piece>() : null); Sprite val2 = (Object.op_Implicit((Object)(object)val) ? val.m_icon : null); if ((Object)(object)val2 != (Object)null && list.Count > 0) { ((Character)player).Message((MessageType)2, string.Join("\n", list.ToArray()), 0, val2, false); } } } private static void SetSmoothPower(TerrainOp terrainOp, float delta) { if (terrainOp.m_settings.m_smooth) { float num = (SmoothToolIsInUse ? lastModdedSmoothPwr : terrainOp.m_settings.m_smoothPower); SmoothToolIsInUse = true; lastModdedSmoothPwr = ModifySmoothPower(num, delta); lastTotalSmoothDelta += lastModdedSmoothPwr - num; } } private static void SetRaisePower(TerrainOp terrainOp, float delta) { if (terrainOp.m_settings.m_raise) { SelectRaiseTool(terrainOp); delta = ConvertSmoothDeltaToRaiseDelta(delta); float num = (RaiseToolIsInUse ? lastModdedRaisePwr : terrainOp.m_settings.m_raisePower); RaiseToolIsInUse = true; lastModdedRaisePwr = ModifyRaisePower(num, delta); lastTotalRaiseDelta += lastModdedRaisePwr - num; } } 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); } } [HarmonyPatch(typeof(Heightmap), "RebuildRenderMesh")] internal static class HeightmapPaintGridPatch { [HarmonyPostfix] private static void Postfix(Heightmap __instance) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) if (__instance.m_isDistantLod || !Object.op_Implicit((Object)(object)__instance.m_renderMesh)) { return; } int num = __instance.m_width + 1; List<Vector2> s_tempUVs = Heightmap.s_tempUVs; if (num > 1 && __instance.m_renderMesh.vertexCount == num * num && s_tempUVs.Count == num * num) { for (int i = 0; i < s_tempUVs.Count; i++) { s_tempUVs[i] = new Vector2(PaintGridMath.TexelCenterUv(i % num, __instance.m_width), PaintGridMath.TexelCenterUv(i / num, __instance.m_width)); } __instance.m_renderMesh.SetUVs(0, s_tempUVs); } } } 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_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) _gameObject = new GameObject("HoverInfo"); _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 / Mathf.Max(0.001f, parentTransform.localScale.x), 0.1f / Mathf.Max(0.001f, parentTransform.localScale.y), 0.1f / Mathf.Max(0.001f, parentTransform.localScale.z)); _textMesh.anchor = (TextAnchor)4; _textMesh.alignment = (TextAlignment)1; _textMesh.fontSize = 16; } public void RotateToPlayer() { //IL_001a: 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_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)GameCamera.m_instance == (Object)null)) { 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? _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 MethodInfo? s_loadImageMethod; internal static Texture2D Remove => _remove ?? (_remove = LoadTexture("remove.png")); internal static Texture2D Box => _box ?? (_box = LoadTexture("box.png")); internal static Texture2D PavedRoadSquare => _pavedRoadSquare ?? (_pavedRoadSquare = LoadTexture("paved_road_v2_square.png")); internal static Texture2D PavedRoadPath => _pavedRoadPath ?? (_pavedRoadPath = LoadTexture("paved_road_v2_path.png")); internal static Texture2D PavedRoadPathSquare => _pavedRoadPathSquare ?? (_pavedRoadPathSquare = LoadTexture("paved_road_v2_path_square.png")); internal static Texture2D MudRoadSquare => _mudRoadSquare ?? (_mudRoadSquare = LoadTexture("mud_road_v2_square.png")); internal static Texture2D MudRoadPathSquare => _mudRoadPathSquare ?? (_mudRoadPathSquare = LoadTexture("path_v2_square.png")); internal static Texture2D ReplantSquare => _replantSquare ?? (_replantSquare = LoadTexture("replant_v2_square.png")); internal static Texture2D CultivateSquare => _cultivateSquare ?? (_cultivateSquare = LoadTexture("cultivate_v2_square.png")); internal static Texture2D CultivatePath => _cultivatePath ?? (_cultivatePath = LoadTexture("cultivate_v2_path.png")); internal static Texture2D CultivatePathSquare => _cultivatePathSquare ?? (_cultivatePathSquare = LoadTexture("cultivate_v2_path_square.png")); internal static Texture2D RaiseSquare => _raiseSquare ?? (_raiseSquare = LoadTexture("raise_v2_square.png")); internal static Texture2D Lower => _lower ?? (_lower = LoadTexture("lower_v2.png")); private static Texture2D LoadTexture(string fileName) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown //IL_0098: Expected O, but got Unknown Assembly executingAssembly = Assembly.GetExecutingAssembly(); string text = executingAssembly.GetManifestResourceNames().FirstOrDefault((string name) => name.EndsWith("." + fileName, StringComparison.OrdinalIgnoreCase) || name.EndsWith(fileName, StringComparison.OrdinalIgnoreCase)); if (text == null) { TerrainLog.LogWarning("Embedded texture not found: " + fileName); return new Texture2D(2, 2); } using Stream stream = executingAssembly.GetManifestResourceStream(text); if (stream == null) { TerrainLog.LogWarning("Could not open embedded stream: " + text); return new Texture2D(2, 2); } using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); LoadImageViaReflection(val, memoryStream.ToArray()); return val; } private static void LoadImageViaReflection(Texture2D tex, byte[] data) { if (s_loadImageMethod == null) { s_loadImageMethod = (Type.GetType("UnityEngine.ImageConversion, UnityEngine.ImageConversionModule") ?? Type.GetType("UnityEngine.ImageConversion, UnityEngine"))?.GetMethod("LoadImage", new Type[2] { typeof(Texture2D), typeof(byte[]) }); } s_loadImageMethod?.Invoke(null, new object[2] { tex, data }); } internal static Sprite CreateSprite(Texture2D texture) { //IL_0019: 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) return Sprite.Create(texture, new Rect(0f, 0f, (float)((Texture)texture).width, (float)((Texture)texture).height), new Vector2(0.5f, 0.5f)); } } public class Overlay { private Particle[] particles = (Particle[])(object)new Particle[2]; private GameObject GameObject { get; } 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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) int num = ps.GetParticles(particles, particles.Length); if (num <= 0) { return StartColor; } return Color32.op_Implicit(((Particle)(ref particles[Mathf.Min(1, num - 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_000a: Unknown result type (might be due to invalid IL or missing references) MainModule val = psm; ((MainModule)(ref val)).startColor = MinMaxGradient.op_Implicit(value); } } public Vector3 LocalScale { get { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return Transform.localScale; } set { //IL_0006: Unknown result type (might be due to invalid IL or missing references) Transform.localScale = 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_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_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) //IL_002e: Unknown result type (might be due to invalid IL or missing references) MainModule val = psm; MinMaxCurve startSize = ((MainModule)(ref val)).startSize; if (!Mathf.Approximately(((MinMaxCurve)(ref startSize)).constant, value)) { MainModule main = ps.main; ((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(value); if (particles.Length < ps.particleCount) { particles = (Particle[])(object)new Particle[ps.particleCount]; } int num = ps.GetParticles(particles, particles.Length); for (int i = 0; i < num; i++) { ((Particle)(ref particles[i])).startSize = value; } if (num > 0) { ps.SetParticles(particles, num); } } } } 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 startSpeed = ((MainModule)(ref val)).startSpeed; return ((MinMaxCurve)(ref startSpeed)).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) { //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) Transform = transform; GameObject = ((Component)transform).gameObject; ps = ((Component)transform).GetComponentInChildren<ParticleSystem>(); psr = ((Component)transform).GetComponentInChildren<ParticleSystemRenderer>(); if ((Object)(object)ps != (Object)null) { psm = ps.main; } } } public abstract class OverlayVisualizer : MonoBehaviour { protected Overlay? primary; protected Overlay? secondary; protected Overlay? tertiary; protected HoverInfo? hoverInfo; private readonly List<Heightmap> heightmaps = new List<Heightmap>(); internal static readonly Vector3 VerticalOffset = new Vector3(0f, 0.075f, 0f); private void Update() { //IL_0076: Unknown result type (might be due to invalid IL or missing references) if (primary == null) { Transform val = ((Component)this).transform.Find("_GhostOnly"); if ((Object)(object)val == (Object)null) { return; } 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 = Color.white; primary.Enabled = false; secondary.Enabled = false; tertiary.Enabled = false; Initialize(); } OnRefresh(); } protected abstract void Initialize(); protected abstract void OnRefresh(); 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 VisualizeRecoloringBounds(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 SnapToPaintGrid(Overlay core, Overlay feather) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: 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_00db: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) heightmaps.Clear(); Heightmap.FindHeightmap(((Component)this).transform.position, 1f, heightmaps); if (heightmaps.Count == 0) { core.LocalPosition = VerticalOffset; feather.LocalPosition = VerticalOffset; return; } Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(float.PositiveInfinity, float.PositiveInfinity); Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(float.NegativeInfinity, float.NegativeInfinity); float num = 0f; foreach (Heightmap heightmap in heightmaps) { if (PreciseTerrainModifier.TryGetPaintMaskWorldBounds(heightmap, ((Component)this).transform.position, 1, out var min, out var max)) { val = Vector2.Min(val, min); val2 = Vector2.Max(val2, max); num = Mathf.Max(num, heightmap.m_scale); } } if (float.IsPositiveInfinity(val.x)) { core.LocalPosition = VerticalOffset; feather.LocalPosition = VerticalOffset; } else { SetBounds(core, val - Vector2.one * num, val2 + Vector2.one * num); SetBounds(feather, val - Vector2.one * num * 2f, val2 + Vector2.one * num * 2f); } } private void SetBounds(Overlay overlay, Vector2 min, Vector2 max) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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_0070: 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_0083: Unknown result type (might be due to invalid IL or missing references) Vector2 val = max - min; float num = (overlay.StartSize = Mathf.Max(val.x, val.y)); overlay.LocalScale = new Vector3(val.x / num, 1f, val.y / num); overlay.Position = new Vector3((min.x + max.x) * 0.5f, ((Component)this).transform.position.y + VerticalOffset.y, (min.y + max.y) * 0.5f); } } public abstract class HoverInfoEnabled : OverlayVisualizer { protected override void Initialize() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) if (hoverInfo != null && secondary != null) { hoverInfo.Color = secondary.StartColor; } } protected override void OnRefresh() { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: 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_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) if (hoverInfo != null) { hoverInfo.Enabled = TerrainConfig.EnableHoverInfo.Value; if (hoverInfo.Enabled) { hoverInfo.RotateToPlayer(); Vector3 position = ((Component)this).transform.position; hoverInfo.Text = $"x: {position.x:0}, y: {position.y:0.000}, z: {position.z:0}"; } } } } public class LevelGroundOverlayVisualizer : HoverInfoEnabled { protected override void Initialize() { //IL_0060: Unknown result type (might be due to invalid IL or missing references) base.Initialize(); if (secondary != null && tertiary != null) { Freeze(secondary); Freeze(tertiary); VisualizeRecoloringBounds(secondary); VisualizeRecoloringBounds(tertiary); tertiary.StartColor = new Color(1f, 1f, 1f, 0.3f); } } protected override void OnRefresh() { if (secondary != null && tertiary != null && primary != null) { SnapToPaintGrid(secondary, tertiary); base.OnRefresh(); primary.Enabled = false; secondary.Enabled = true; tertiary.Enabled = true; } } } public class RaiseGroundOverlayVisualizer : HoverInfoEnabled { protected override void Initialize() { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) base.Initialize(); if (secondary != null && tertiary != null) { Freeze(secondary); Freeze(tertiary); VisualizeTerraformingBounds(secondary); VisualizeTerraformingBounds(tertiary); secondary.LocalScale = Vector3.one; tertiary.LocalScale = Vector3.one; } } protected override void OnRefresh() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) if (secondary == null || tertiary == null || primary == null) { return; } Heightmap val = Heightmap.FindHeightmap(((Component)this).transform.position); float num = (Object.op_Implicit((Object)(object)val) ? val.m_scale : 1f); TerrainOp component = ((Component)this).GetComponent<TerrainOp>(); float num2 = PreciseRaiseMath.SlopePivot(Object.op_Implicit((Object)(object)component) ? HardnessModifier.CurrentRaisePower(component.m_settings.m_raisePower) : 1f); secondary.StartSize = Mathf.Max(0.1f, 2f * num2 * num); tertiary.StartSize = 4f * num; base.OnRefresh(); primary.Enabled = false; secondary.Enabled = true; GroundLevelSpinner.Refresh(); Vector3 localPosition = secondary.LocalPosition; localPosition.y = OverlayVisualizer.VerticalOffset.y + GroundLevelSpinner.Value; secondary.LocalPosition = localPosition; Vector3 val2 = secondary.Position - OverlayVisualizer.VerticalOffset; if (hoverInfo != null) { if (GroundLevelSpinner.Value > 0f) { float value = GroundLevelSpinner.Value; hoverInfo.Text = $"x: {val2.x:0}, y: {val2.y - value:0.000}, z: {val2.z:0}\n\nh: +{value:0.000}"; } else { hoverInfo.Text = $"x: {val2.x:0}, y: {val2.y:0.000}, z: {val2.z:0}"; } } tertiary.Enabled = true; } } public class SquarePathOverlayVisualizer : HoverInfoEnabled { protected override void Initialize() { //IL_0060: Unknown result type (might be due to invalid IL or missing references) base.Initialize(); if (secondary != null && tertiary != null) { Freeze(secondary); Freeze(tertiary); VisualizeRecoloringBounds(secondary); VisualizeRecoloringBounds(tertiary); tertiary.StartColor = new Color(1f, 1f, 1f, 0.3f); } } protected override void OnRefresh() { if (secondary != null && tertiary != null && primary != null) { SnapToPaintGrid(secondary, tertiary); base.OnRefresh(); primary.Enabled = false; secondary.Enabled = true; tertiary.Enabled = true; } } } public class CultivateOverlayVisualizer : HoverInfoEnabled { protected override void Initialize() { //IL_0060: Unknown result type (might be due to invalid IL or missing references) base.Initialize(); if (secondary != null && tertiary != null) { Freeze(secondary); Freeze(tertiary); VisualizeRecoloringBounds(secondary); VisualizeRecoloringBounds(tertiary); tertiary.StartColor = new Color(1f, 1f, 1f, 0.3f); } } protected override void OnRefresh() { if (secondary != null && tertiary != null && primary != null) { SnapToPaintGrid(secondary, tertiary); base.OnRefresh(); primary.Enabled = false; secondary.Enabled = true; tertiary.Enabled = true; } } } public class SeedGrassOverlayVisualizer : HoverInfoEnabled { protected override void Initialize() { //IL_0060: Unknown result type (might be due to invalid IL or missing references) base.Initialize(); if (secondary != null && tertiary != null) { Freeze(secondary); Freeze(tertiary); VisualizeRecoloringBounds(secondary); VisualizeRecoloringBounds(tertiary); tertiary.StartColor = new Color(1f, 1f, 1f, 0.3f); } } protected override void OnRefresh() { if (secondary != null && tertiary != null && primary != null) { SnapToPaintGrid(secondary, tertiary); base.OnRefresh(); primary.Enabled = false; secondary.Enabled = true; tertiary.Enabled = true; } } } public class RemoveModificationsOverlayVisualizer : HoverInfoEnabled { protected override void Initialize() { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) base.Initialize(); if (secondary != null && tertiary != null) { Freeze(secondary); Freeze(tertiary); VisualizeTerraformingBounds(secondary); VisualizeTerraformingBounds(tertiary); secondary.StartColor = new Color(1f, 0.2f, 0.2f, 0.8f); tertiary.StartColor = new Color(1f, 0.2f, 0.2f, 0.3f); } } internal void SetScale(Vector3 scale) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) if (secondary != null) { secondary.LocalScale = scale; } if (tertiary != null) { tertiary.LocalScale = scale; } } protected override void OnRefresh() { if (secondary != null && tertiary != null && primary != null) { base.OnRefresh(); primary.Enabled = false; secondary.Enabled = true; tertiary.Enabled = true; } } } [HarmonyPatch(typeof(Piece), "SetInvalidPlacementHeightlight")] public static class OverlayVisualizationRedshiftHeigthlightBlocker { private static bool Prefix(Piece __instance) { return !Object.op_Implicit((Object)(object)((Component)__instance).GetComponentInChildren<OverlayVisualizer>()); } } internal static class PaintGridMath { internal static float TexelCenterUv(int index, int terrainWidth) { return ((float)index + 0.5f) / ((float)terrainWidth + 1f); } internal static void GetAxisIndices(int terrainWidth, int centerIndex, int radius, out int first, out int last) { first = Math.Max(0, centerIndex - radius); last = Math.Min(terrainWidth, centerIndex + radius); } internal static bool TryGetAxisBounds(int terrainWidth, float vertexScale, float zoneCenter, int firstPaintedTexel, int lastPaintedTexel, out float min, out float max) { if (firstPaintedTexel > lastPaintedTexel) { min = 0f; max = 0f; return false; } float num = (float)terrainWidth * vertexScale * 0.5f; float num2 = zoneCenter - num; min = num2 + (float)firstPaintedTexel * vertexScale; max = num2 + (float)lastPaintedTexel * vertexScale; return true; } } internal static class PreciseRaiseMath { internal const int ModifiedRadius = 1; internal const int InfluenceRadius = 2; internal const float MinPower = 0.05f; internal const float MaxPower = 1f; internal static bool TryGetTargetHeight(float tileHeight, float refHeight, float delta, float weight, out float targetHeight) { targetHeight = refHeight + delta; if (delta < 0f && targetHeight > tileHeight) { return false; } if (delta >= 0f) { if (targetHeight < tileHeight) { return false; } if (targetHeight > tileHeight + delta) { targetHeight = tileHeight + delta; } } if (weight < 1f) { targetHeight = tileHeight + (targetHeight - tileHeight) * weight; } return true; } internal static float Weight(int dx, int dz, float power) { int num = Math.Max(Math.Abs(dx), Math.Abs(dz)); if (num >= 2) { return 0f; } float num2 = SlopePivot(power); if ((float)num <= num2) { return 1f; } return (float)(2 - num) / (2f - num2); } internal static float SlopePivot(float power) { power = (float.IsNaN(power) ? 1f : Math.Max(0.05f, Math.Min(1f, power))); float num = (1f - power) / 0.95f; return 1f * num; } } [HarmonyPatch] public static class PreciseTerrainModifier { public const int FixedRadius = 1; public const int FixedPaintRadius = 1; private const int SettingsPayloadMagic = 1096043859; private const int SettingsPayloadVersion = 1; public static bool IsPrecisionModifier(float radius) { return float.IsNegativeInfinity(radius); } [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(TerrainComp __instance, TerrainOp modifier) { if (!Object.op_Implicit((Object)(object)modifier) || !Object.op_Implicit((Object)(object)((Component)modifier).gameObject)) { return; } if (Object.op_Implicit((Object)(object)__instance) && Object.op_Implicit((Object)(object)__instance.m_nview) && !__instance.m_nview.IsOwner()) { __instance.m_nview.ClaimOwnership(); } if (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; } } } [HarmonyPostfix] [HarmonyPatch(typeof(TerrainOp), "GetRadius")] private static void GetRadiusPostfix(TerrainOp __instance, ref float __result) { if (Object.op_Implicit((Object)(object)__instance)) { OverlayVisualizer component = ((Component)__instance).gameObject.GetComponent<OverlayVisualizer>(); if (component is RemoveModificationsOverlayVisualizer) { __result = Mathf.Max(__result, __instance.m_settings.m_levelRadius + 1f); } else if (component is RaiseGroundOverlayVisualizer) { __result = Mathf.Max(__result, 2f); } else if (Object.op_Implicit((Object)(object)component) && __instance.m_settings.m_paintCleared) { __result = Mathf.Max(__result, 1f); } } } [HarmonyPostfix] [HarmonyPatch(typeof(Settings), "GetRadius")] private static void GetSettingsRadiusPostfix(Settings __instance, ref float __result) { if (__instance.m_raise && IsPrecisionModifier(__instance.m_raiseRadius)) { __result = Mathf.Max(__result, 2f); } if ((__instance.m_smooth && IsPrecisionModifier(__instance.m_smoothRadius)) || (__instance.m_paintCleared && IsPrecisionModifier(__instance.m_paintRadius))) { __result = Mathf.Max(__result, 1f); } } private static void RemoveLegacyTerrainModifiers(Vector3 position, float radius) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) List<TerrainModifier> list = new List<TerrainModifier>(); TerrainModifier.GetModifiers(position, radius + 1f, list, (TerrainModifier)null); foreach (TerrainModifier item in list) { if (Object.op_Implicit((Object)(object)item) && Object.op_Implicit((Object)(object)item.m_nview) && !Object.op_Implicit((Object)(object)((Component)item).GetComponentInParent<Piece>()) && !Object.op_Implicit((Object)(object)((Component)item).GetComponentInParent<WearNTear>())) { item.m_nview.ClaimOwnership(); ZNetScene.instance.Destroy(((Component)item).gameObject); } } } [HarmonyPostfix] [HarmonyPatch(typeof(Settings), "Serialize")] private static void SerializeSettingsPostfix(Settings __instance, ZPackage pkg) { if (__instance != null && pkg != null) { pkg.Write(1096043859); pkg.Write(1); pkg.Write(__instance.m_levelRadius); pkg.Write(__instance.m_raiseRadius); pkg.Write(__instance.m_raisePower); pkg.Write(__instance.m_raiseDelta); pkg.Write(__instance.m_smoothRadius); pkg.Write(__instance.m_smoothPower); pkg.Write(__instance.m_paintRadius); } } [HarmonyPostfix] [HarmonyPatch(typeof(Settings), "Deserialize")] private static void DeserializeSettingsPostfix(ZPackage pkg, ref Settings __result) { if (__result != null && pkg != null && pkg.Size() - pkg.GetPos() >= 36) { int pos = pkg.GetPos(); if (pkg.ReadInt() != 1096043859 || pkg.ReadInt() != 1) { pkg.SetPos(pos); return; } Settings val = CopySettings(__result); val.m_levelRadius = pkg.ReadSingle(); val.m_raiseRadius = pkg.ReadSingle(); val.m_raisePower = pkg.ReadSingle(); val.m_raiseDelta = pkg.ReadSingle(); val.m_smoothRadius = pkg.ReadSingle(); val.m_smoothPower = pkg.ReadSingle(); val.m_paintRadius = pkg.ReadSingle(); __result = val; } } private static Settings CopySettings(Settings source) { //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_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001d: 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) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004d: 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_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: 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_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Expected O, but got Unknown return new Settings { m_levelOffset = source.m_levelOffset, m_level = source.m_level, m_levelRadius = source.m_levelRadius, m_square = source.m_square, m_raise = source.m_raise, m_raiseRadius = source.m_raiseRadius, m_raisePower = source.m_raisePower, m_raiseDelta = source.m_raiseDelta, m_smooth = source.m_smooth, m_smoothRadius = source.m_smoothRadius, m_smoothPower = source.m_smoothPower, m_paintCleared = source.m_paintCleared, m_paintHeightCheck = source.m_paintHeightCheck, m_paintType = source.m_paintType, m_paintRadius = source.m_paintRadius, m_paintStrength = source.m_paintStrength, m_paintExp = source.m_paintExp, m_paintCurve = source.m_paintCurve, m_rotation = source.m_rotation, m_sides = source.m_sides, m_addMedianMax = source.m_addMedianMax, m_centerMultiplicationFactor = source.m_centerMultiplicationFactor, m_pointMultiplicationFactor = source.m_pointMultiplicationFactor, m_halfOffset = source.m_halfOffset }; } [HarmonyPrefix] [HarmonyPatch(typeof(TerrainComp), "InternalDoOperation")] private static void InternalDoOperationPrefix(TerrainComp __instance, Vector3 pos, Settings modifier) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004a: 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) if (!modifier.m_level && !modifier.m_raise && !modifier.m_smooth && !modifier.m_paintCleared) { int num = Mathf.Clamp(Mathf.RoundToInt(modifier.m_levelRadius), 1, Mathf.CeilToInt(TerrainConfig.MaxRadius.Value)); RemoveLegacyTerrainModifiers(pos, num); RemoveTerrainModifications(__instance, pos, num); PreciseRecolorTerrain(__instance, pos, (PaintType)3, heightCheck: false, num); } } [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 PreciseSmoothTerrain(TerrainComp __instance, Vector3 worldPos, float radius) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) if (!IsPrecisionModifier(radius)) { return true; } int num = __instance.m_width + 1; int x = default(int); int x2 = default(int); __instance.m_hmap.WorldToVertex(worldPos, ref x, ref x2); float num2 = worldPos.y - ((Component)__instance).transform.position.y; FindExtrema(x, num, out var xMin, out var xMax); FindExtrema(x2, num, out var xMin2, out var xMax2); for (int i = xMin; i <= xMax; i++) { for (int j = xMin2; j <= xMax2; j++) { int num3 = j * num + i; float height = __instance.m_hmap.GetHeight(i, j); float num4 = num2 - height; float num5 = __instance.m_smoothDelta[num3]; __instance.m_smoothDelta[num3] = Mathf.Clamp(num5 + num4, -1f, 1f); __instance.m_modifiedHeight[num3] = true; } } return false; } [HarmonyPrefix] [HarmonyPatch(typeof(TerrainComp), "RaiseTerrain")] private static bool RaiseTerrainPrefix(TerrainComp __instance, Vector3 worldPos, float radius, float delta, float power) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) if (!IsPrecisionModifier(radius)) { return true; } int num = __instance.m_width + 1; int num2 = default(int); int num3 = default(int); __instance.m_hmap.WorldToVertex(worldPos, ref num2, ref num3); float refHeight = worldPos.y - ((Component)__instance).transform.position.y; FindExtrema(num2, num, 1, out var xMin, out var xMax); FindExtrema(num3, num, 1, 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 weight = PreciseRaiseMath.Weight(i - num2, j - num3, power); if (PreciseRaiseMath.TryGetTargetHeight(height, refHeight, delta, weight, out var targetHeight)) { int num4 = j * num + i; float num5 = targetHeight - height + __instance.m_smoothDelta[num4]; __instance.m_smoothDelta[num4] = 0f; __instance.m_levelDelta[num4] += num5; __instance.m_levelDelta[num4] = Mathf.Clamp(__instance.m_levelDelta[num4], -8f, 8f); __instance.m_modifiedHeight[num4] = true; } } } return false; } [HarmonyPrefix] [HarmonyPatch(typeof(TerrainComp), "PaintCleared")] private static bool PaintClearedPrefix(TerrainComp __instance, Vector3 worldPos, Settings settings) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (!IsPrecisionModifier(settings.m_paintRadius)) { return true; } PreciseRecolorTerrain(__instance, worldPos, settings.m_paintType, settings.m_paintHeightCheck); return false; } public static void RemoveTerrainModifications(TerrainComp comp, Vector3 worldPos, int radius = 1) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) int num = comp.m_width + 1; int x = default(int); int x2 = default(int); comp.m_hmap.WorldToVertex(worldPos, ref x, ref x2); FindExtrema(x, num, radius, out var xMin, out var xMax); FindExtrema(x2, num, radius, out var xMin2, out var xMax2); for (int i = xMin; i <= xMax; i++) { for (int j = xMin2; j <= xMax2; j++) { int num2 = j * num + i; comp.m_levelDelta[num2] = 0f; comp.m_smoothDelta[num2] = 0f; comp.m_modifiedHeight[num2] = false; } } } public static void PreciseRecolorTerrain(TerrainComp comp, Vector3 worldPos, PaintType paintType, bool heightCheck = false, int radius = 1) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //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_000d: 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_005e: 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) Color val = ResolveColor(paintType); GetPaintMaskBounds(comp.m_hmap, worldPos, radius, out var xStart, out var xMax, out var yStart, out var yMax); int num = comp.m_width + 1; for (int i = xStart; i <= xMax; i++) { for (int j = yStart; j <= yMax; j++) { val.a = comp.m_hmap.GetPaintMask(i, j).a; int num2 = j * num + i; comp.m_paintMask[num2] = val; comp.m_modifiedPaint[num2] = true; } } } public static void GetPaintMaskBounds(Heightmap heightmap, Vector3 worldPos, int radius, out int xStart, out int xMax, out int yStart, out int yMax) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) int centerIndex = default(int); int centerIndex2 = default(int); heightmap.WorldToVertex(worldPos, ref centerIndex, ref centerIndex2); PaintGridMath.GetAxisIndices(heightmap.m_width, centerIndex, radius, out xStart, out xMax); PaintGridMath.GetAxisIndices(heightmap.m_width, centerIndex2, radius, out yStart, out yMax); } public static bool TryGetPaintMaskWorldBounds(Heightmap heightmap, Vector3 worldPos, int radius, out Vector2 min, out Vector2 max) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0022: 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_0067: 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_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: 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_0091: Unknown result type (might be due to invalid IL or missing references) GetPaintMaskBounds(heightmap, worldPos, radius, out var xStart, out var xMax, out var yStart, out var yMax); float min2; float max2; bool num = PaintGridMath.TryGetAxisBounds(heightmap.m_width, heightmap.m_scale, ((Component)heightmap).transform.position.x, xStart, xMax, out min2, out max2); float min3; float max3; bool flag = PaintGridMath.TryGetAxisBounds(heightmap.m_width, heightmap.m_scale, ((Component)heightmap).transform.position.z, yStart, yMax, out min3, out max3); if (!num || !flag) { min = default(Vector2); max = default(Vector2); return false; } min = new Vector2(min2, min3); max = new Vector2(max2, max3); return true; } 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) return (Color)((int)paintType switch { 0 => Heightmap.m_paintMaskDirt, 1 => Heightmap.m_paintMaskCultivated, 2 => Heightmap.m_paintMaskPaved, _ => Heightmap.m_paintMaskNothing, }); } public static void FindExtrema(int x, int worldSize, out int xMin, out int xMax) { FindExtrema(x, worldSize, 1, out xMin, out xMax); } private static void FindExtrema(int x, int worldSize, int radius, out int xMin, out int xMax) { PaintGridMath.GetAxisIndices(worldSize - 1, x, radius, out xMin, out xMax); } } [HarmonyPatch] internal static class RadiusModifier { private static bool RadiusToolIsInUse = false; private static TerrainOp? activeRadiusTool; 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; internal static void Tick(Player __instance) { //IL_004b: 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()) { SelectRadiusTool(null); return; } if (!IsValidSelectedPiece(__instance, out TerrainOp terrainOp)) { SelectRadiusTool(null); return; } SelectRadiusTool(terrainOp); if (ShouldModifyRadius()) { SetRadius(terrainOp, Input.mouseScrollDelta.y * TerrainConfig.RadiusScrollScale.Value); } RefreshGhostScale(__instance); } private static void SelectRadiusTool(TerrainOp? terrainOp) { //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) if (!((Object)(object)activeRadiusTool == (Object)(object)terrainOp)) { activeRadiusTool = terrainOp; RadiusToolIsInUse = false; lastOriginalRadius = 0f; lastModdedRadius = 0f; lastTotalDelta = 0f; lastGhostScale = Vector3.zero; } } 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)) { terrainOp = null; return false; } OverlayVisualizer component = ((Component)selectedPiece).gameObject.GetComponent<OverlayVisualizer>(); if (Object.op_Implicit((Object)(object)component) && !(component is RemoveModificationsOverlayVisualizer)) { terrainOp = null; return false; } terrainOp = ((Component)selectedPiece).gameObject.GetComponent<TerrainOp>(); return (Object)(object)terrainOp != (Object)null; } internal static bool ShouldModifyRadius() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (TerrainConfig.EnableRadiusModifier.Value && Input.GetKey(TerrainConfig.RadiusKey.Value)) { 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)) { return; } OverlayVisualizer component = ((Component)__instance).gameObject.GetComponent<OverlayVisualizer>(); bool flag = component is RemoveModificationsOverlayVisualizer; if (!Object.op_Implicit((Object)(object)component) || flag) { if (flag) { __instance.m_settings.m_levelRadius = ModifyRadius(__instance.m_settings.m_levelRadius, lastTotalDelta); } if (__instance.m_settings.m_level) { __instance.m_settings.m_levelRadius = ModifyRadius(__instance.m_settings.m_levelRadius, lastTotalDelta); } if (__instance.m_settings.m_raise) { __instance.m_settings.m_raiseRadius = ModifyRadius(__instance.m_settings.m_raiseRadius, lastTotalDelta); } if (__instance.m_settings.m_smooth) { __instance.m_settings.m_smoothRadius = ModifyRadius(__instance.m_settings.m_smoothRadius, lastTotalDelta); } if (__instance.m_settings.m_paintCleared) { __instance.m_settings.m_paintRadius = ModifyRadius(__instance.m_settings.m_paintRadius, lastTotalDelta); } } } private static float ModifyRadius(float radius, float delta) { return Mathf.Clamp(radius + delta, 0.5f, TerrainConfig.MaxRadius.Value); } private static void SetRadius(TerrainOp terrainOp, float delta) { //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)terrainOp) && Object.op_Implicit((Object)(object)((Component)terrainOp).gameObject.GetComponent<RemoveModificationsOverlayVisualizer>())) { delta = Mathf.Sign(delta); } if (!RadiusToolIsInUse && Object.op_Implicit((Object)(object)terrainOp)) { if (TryGetMaximumRadius(terrainOp, out var maxRadius)) { RadiusToolIsInUse = true; lastOriginalRadius = maxRadius; lastModdedRadius = ModifyRadius(maxRadius, delta); lastTotalDelta += lastModdedRadius - maxRadius; } } else { float num = lastModdedRadius; lastModdedRadius = ModifyRadius(lastModdedRadius, delta); lastTotalDelta += lastModdedRadius - num; } if (lastOriginalRadius > 0.001f) { lastGhostScale = new Vector3(lastModdedRadius / lastOriginalRadius, lastModdedRadius / lastOriginalRadius, lastModdedRadius / lastOriginalRadius); } } private static void RefreshGhostScale(Player player) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0087: 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_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) if (!RadiusToolIsInUse || !Object.op_Implicit((Object)(object)player.m_placementGhost)) { return; } RemoveModificationsOverlayVisualizer component = player.m_placementGhost.GetComponent<RemoveModificationsOverlayVisualizer>(); if (Object.op_Implicit((Object)(object)component)) { TerrainOp component2 = player.m_placementGhost.GetComponent<TerrainOp>(); if (Object.op_Implicit((Object)(object)component2)) { component2.m_settings.m_levelRadius = lastModdedRadius; } component.SetScale(lastGhostScale); 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) { ((Component)componentInChildren).transform.localScale = lastGhostScale; } } } private static bool TryGetMaximumRadius(TerrainOp terrainOp, out float maxRadius) { maxRadius = 0f; if (Object.op_Implicit((Object)(object)((Component)terrainOp).gameObject.GetComponent<RemoveModificationsOverlayVisualizer>())) { maxRadius = terrainOp.m_settings.m_levelRadius; } 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 TerrainConfig { internal static ConfigEntry<bool> EnableRadiusModifier; internal static ConfigEntry<KeyCode> RadiusKey; internal static ConfigEntry<float> RadiusScrollScale; internal static ConfigEntry<float> MaxRadius; internal static ConfigEntry<bool> EnableHardnessModifier; internal static ConfigEntry<KeyCode> HardnessKey; internal static ConfigEntry<float> HardnessScrollScale; internal static ConfigEntry<bool> EnableHoverInfo; internal static ConfigEntry<bool> EnableTerrainSynergy; internal static ConfigEntry<bool> EnableSquareTools; internal static ConfigEntry<bool> EnablePrecisionRaise; internal static ConfigEntry<bool> EnableLowerGround; internal static ConfigEntry<bool> EnableRemoveModifications; internal static ConfigEntry<TerrainLog.InfoLevel> Verbosity; internal static void Init(ConfigFile config, ConfigSync configSync) { EnableRadiusModifier = Bind(config, configSync, "Terrain - Radius", "Enable Radius Modifier", value: true, "Permite alterar o raio das ferramentas de terreno usando Scroll do mouse.", synchronized: false); RadiusKey = Bind<KeyCode>(config, configSync, "Terrain - Radius", "Radius Key", (KeyCode)308, "Tecla para segurar enquanto usa a roda do mouse para alterar o raio.", synchronized: false); RadiusScrollScale = Bind(config, configSync, "Terrain - Radius", "Radius Scroll Scale", 0.5f, "Sensibilidade da mudanca de raio com o scroll.", synchronized: false); MaxRadius = Bind(config, configSync, "Terrain - Radius", "Max Radius", 10f, "Raio maximo permitido para ferramentas de terreno."); EnableHardnessModifier = Bind(config, configSync, "Terrain - Hardness", "Enable Hardness Modifier", value: true, "Permite alterar a dureza/sharpness das ferramentas de terreno com scroll.", synchronized: false); HardnessKey = Bind<KeyCode>(config, configSync, "Terrain - Hardness", "Hardness Key", (KeyCode)304, "Tecla para segurar enquanto usa a roda do mouse para alterar a dureza.", synchronized: false); HardnessScrollScale = Bind(config, configSync, "Terrain - Hardness", "Hardness Scroll Scale", 0.5f, "Sensibilidade da mudanca de dureza com o scroll.", synchronized: false); EnableHoverInfo = Bind(config, configSync, "Terrain - Interface", "Enable Hover Info", value: true, "Exibe informacoes de coordenadas e altura na ferramenta.", synchronized: false); EnableTerrainSynergy = Bind(config, configSync, "Terrain - Synergy", "Enable Terrain Building Synergy", value: true, "Terraplanar concede XP de Construcao e gasta menos vigor de acordo com a habilidade de Construcao."); EnableSquareTools = Bind(config, configSync, "Terrain - Tools", "Enable Square Tools", value: true, "Ativa as ferramentas de terreno no formato quadrado alinhadas ao grid do mundo."); EnablePrecisionRaise = Bind(config, configSync, "Terrain - Tools", "Enable Precision Raise", value: true, "Ativa a ferramenta de elevacao precisa com controle de altura no scroll."); EnableLowerGround = Bind(config, configSync, "Terrain - Tools", "Enable Lower Ground", value: true, "Ativa o modo de rebaixar terreno na enxada."); EnableRemoveModifications = Bind(config, configSync, "Terrain - Tools", "Enable Remove Modifications", value: true, "Ativa a ferramenta de restaurar terreno natural original."); Verbosity = Bind(config, configSync, "Terrain - Debug", "Verbosity", TerrainLog.InfoLevel.Low, "Nivel de detalhes no log de terreno.", synchronized: false); } private static ConfigEntry<T> Bind<T>(ConfigFile config, ConfigSync configSync, string group, string name, T value, string description, bool synchronized = true) { ConfigEntry<T> val = config.Bind<T>(group, name, value, description); configSync.AddConfigEntry<T>(val).SynchronizedConfig = synchronized; return val; } } internal static class TerrainLog { internal enum InfoLevel { Low, Medium, High } private static ManualLogSource? logSource; internal static void Init(ManualLogSource source) { logSource = source; } internal static void LogInfo(string message, InfoLevel level = InfoLevel.Low) { if (TerrainConfig.Verbosity == null || TerrainConfig.Verbosity.Value >= level) { ManualLogSource? obj = logSource; if (obj != null) { obj.LogInfo((object)message); } } } internal static void LogWarning(string message) { ManualLogSource? obj = logSource; if (obj != null) { obj.LogWarning((object)message); } } internal static void LogError(string message) { ManualLogSource? obj = logSource; if (obj != null) { obj.LogError((object)message); } } internal static void LogDebug(string message) { ManualLogSource? obj = logSource; if (obj != null) { obj.LogDebug((object)message); } } } [HarmonyPatch] internal static class TerrainPieceManager { private class ToolDef { public string name; public string basePrefab; public string nameToken; public string descToken; public Func<Texture2D> iconGetter; public bool isHoe; public Type? overlayType; public bool? level; public float? levelRadius; public bool? raise; public float? raiseRadius; public float? raisePower; public float? raiseDelta; public bool? smooth; public float? smoothRadius; public float? smoothPower; public bool? clearPaint; public float? paintRadius; public bool invertGhost; public Requirement[]? requirements; public ToolDef(string name, string basePrefab, string nameToken, string descToken, Func<Texture2D> iconGetter, bool isHoe, Type? overlayType = null, bool? level = null, float? levelRadius = null, bool? raise = null, float? raiseRadius = null, float? raisePower = null, float? raiseDelta = null, bool? smooth = null, float? smoothRadius = null, float? smoothPower = null, bool? clearPaint = null, float? paintRadius = null, bool invertGhost = false, Requirement[]? requirements = null) { this.name = name; this.basePrefab = basePrefab; this.nameToken = nameToken; this.descToken = descToken; this.iconGetter = iconGetter; this.isHoe = isHoe; this.overlayType = overlayType; this.level = level; this.levelRadius = levelRadius; this.raise = raise; this.raiseRadius = raiseRadius; this.raisePower = raisePower; this.raiseDelta = raiseDelta; this.smooth = smooth; this.smoothRadius = smoothRadius; this.smoothPower = smoothPower; this.clearPaint = clearPaint; this.paintRadius = paintRadius; this.invertGhost = invertGhost; this.requirements = requirements; } } private static bool piecesCreated = false; private static readonly List<GameObject> createdToolPrefabs = new List<GameObject>(); private static readonly Dictionary<string, GameObject> toolRefs = new Dictionary<string, GameObject>(); private static readonly List<ToolDef> tools = new List<ToolDef> { new ToolDef("mud_road_v2_sq", "mud_road_v2", "$atmc_level_square_name", "$atmc_level_square_desc", () => IconCache.MudRoadSquare, isHoe: true, typeof(LevelGroundOverlayVisualizer)), new ToolDef("raise_v2_precise", "raise_v2", "$atmc_raise_precision_name", "$atmc_raise_precision_desc", () => IconCache.RaiseSquare, isHoe: true, typeof(RaiseGroundOverlayVisualizer)), new ToolDef("lower_v2", "raise_v2", "$atmc_lower_name", "$atmc_lower_desc", () => IconCache.Lower, isHoe: true, null, null, null, null, 1.5f, 0.5f, -0.5f, null, null, null, null, null, invertGhost: true, Array.Empty<Requirement>()), new ToolDef("path_v2_square", "path_v2", "$atmc_path_square_name", "$atmc_path_square_desc", () => IconCache.MudRoadPathSquare, isHoe: true, typeof(SquarePathOverlayVisualizer)), new ToolDef("paved_road_v2_square", "paved_road_v2", "$atmc_paved_square_name", "$atmc_paved_square_desc", () => IconCache.PavedRoadSquare, isHoe: true, typeof(SquarePathOverlayVisualizer)), new ToolDef("paved_road_v2_path", "paved_road_v2", "$atmc_paved_path_name", "$atmc_paved_path_desc", () => IconCache.PavedRoadPath, isHoe: true, null, null, null, null, null, null, null, false), new ToolDef("paved_road_v2_path_square", "paved_road_v2", "$atmc_paved_path_square_name", "$atmc_paved_path_square_desc", () => IconCache.PavedRoadPathSquare, isHoe: true, typeof(SquarePathOverlayVisualizer), null, null, null, null, null, null, false), new ToolDef("remove_terrain_mods", "mud_road_v2", "$atmc_remove_name", "$atmc_remove_desc", () => IconCache.Remove, isHoe: true, typeof(RemoveModificationsOverlayVisualizer), false, 1f, false, null, null, null, false, null, null, false), new ToolDef("cultivate_v2_square", "cultivate_v2", "$atmc_cultivate_square_name", "$atmc_cultivate_square_desc", () => IconCache.CultivateSquare, isHoe: false, typeof(CultivateOverlayVisualizer)), new ToolDef("cultivate_v2_path", "cultivate_v2", "$atmc_cultivate_path_name", "$atmc_cultivate_path_desc", () => IconCache.CultivatePath, isHoe: false, null, null, null, null, null, null, null, false), new ToolDef("cultivate_v2_path_square", "cultivate_v2", "$atmc_cultivate_path_square_name", "$atmc_cultivate_path_square_desc", () => IconCache.CultivatePathSquare, isHoe: false, typeof(CultivateOverlayVisualizer), null, null, null, null, null, null, false), new ToolDef("replant_v2_square", "replant_v2", "$atmc_replant_square_name", "$atmc_replant_square_desc", () => IconCache.ReplantSquare, isHoe: false, typeof(SeedGrassOverlayVisualizer)) }; [HarmonyPostfix] [HarmonyPatch(typeof(Localization), "SetupLanguage")] private static void SetupLanguagePostfix(Localization __instance) { string selectedLanguage = __instance.GetSelectedLanguage(); bool isPortuguese = selectedLanguage.Equals("Portuguese_Brazilian", StringComparison.OrdinalIgnoreCase) || selectedLanguage.Equals("Portuguese", StringComparison.OrdinalIgnoreCase); Add("atmc_level_square_name", "Nivelar terreno (quadrado)", "Level ground (square)"); Add("atmc_level_square_desc", "Nivela o terreno alinhado ao grid do mundo com base na sua posição. Use Shift + clique para nivelar da posição apontada (suaviza o solo).", "Levels ground to the world grid based on player position. Use Shift + click to level from the pointed position instead (this smooths the terrain)."); Add("atmc_raise_precision_name", "Elevar terreno (precisão)", "Raise ground (precision)"); Add("atmc_raise_precision_desc", "Eleva o terreno mi