Decompiled source of LevelStrength v1.1.0

LevelStrength.dll

Decompiled 11 hours ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyCompany("LevelStrength")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("LevelStrength")]
[assembly: AssemblyTitle("LevelStrength")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[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 LevelStrength
{
	[BepInPlugin("pieter.valheim.levelstrength", "Level Strength", "1.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	[SynchronizationMode(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(TerrainComp), "InternalDoOperation")]
		private static class DoOperationPatch
		{
			[HarmonyPriority(0)]
			private static void Prefix(TerrainComp __instance, Vector3 pos, Settings modifier, out int __state)
			{
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_003a: Invalid comparison between Unknown and I4
				//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f7: 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_0107: Unknown result type (might be due to invalid IL or missing references)
				__state = 0;
				if (modifier == null || modifier.m_square || (!modifier.m_level && !modifier.m_smooth) || (!_includeCultivator.Value && modifier.m_paintCleared && (int)modifier.m_paintType == 1))
				{
					return;
				}
				float num = Mathf.Clamp01((float)_strength.Value / 100f);
				float num2 = Mathf.Max(8f, _maxHeightChange.Value);
				if (!(num <= 0f) || !(num2 <= 8f))
				{
					float num3 = (modifier.m_level ? modifier.m_levelRadius : 0f);
					float num4 = (modifier.m_smooth ? modifier.m_smoothRadius : 0f);
					if (!float.IsNaN(num4) && !float.IsInfinity(num4))
					{
						_log.LogDebug((object)$"Levelling: level radius {num3:0.##}, smooth radius {num4:0.##}, strength {num:P0}, max change {num2:0.#} m");
						Level(__instance, pos + Vector3.up * modifier.m_levelOffset, num3, num4, modifier.m_smoothPower, num, num2);
						__state = (modifier.m_level ? 1 : 0) | (modifier.m_smooth ? 2 : 0);
						modifier.m_level = false;
						modifier.m_smooth = false;
					}
				}
			}

			[HarmonyPriority(800)]
			private static void Postfix(TerrainComp __instance, Settings modifier, int __state)
			{
				Restore(__instance, modifier, __state);
			}

			private static Exception Finalizer(Exception __exception, TerrainComp __instance, Settings modifier, int __state)
			{
				if (__exception != null)
				{
					Restore(__instance, modifier, __state);
				}
				return __exception;
			}

			private static void Restore(TerrainComp comp, Settings modifier, int state)
			{
				if (state != 0)
				{
					if ((state & 1) != 0)
					{
						modifier.m_level = true;
					}
					if ((state & 2) != 0)
					{
						modifier.m_smooth = true;
					}
					LastOpRadius.Invoke(comp) = modifier.GetRadius();
				}
			}
		}

		public const string Guid = "pieter.valheim.levelstrength";

		public const string Name = "Level Strength";

		public const string Version = "1.1.0";

		private const string TerrainToolsGuid = "Searica.Valheim.TerrainTools";

		private const float VanillaMaxLevelDelta = 8f;

		private static ManualLogSource _log;

		private static ConfigEntry<int> _strength;

		private static ConfigEntry<float> _maxHeightChange;

		private static readonly FieldRef<TerrainComp, Heightmap> Hmap = AccessTools.FieldRefAccess<TerrainComp, Heightmap>("m_hmap");

		private static readonly FieldRef<TerrainComp, int> Width = AccessTools.FieldRefAccess<TerrainComp, int>("m_width");

		private static readonly FieldRef<TerrainComp, float[]> LevelDelta = AccessTools.FieldRefAccess<TerrainComp, float[]>("m_levelDelta");

		private static readonly FieldRef<TerrainComp, float[]> SmoothDelta = AccessTools.FieldRefAccess<TerrainComp, float[]>("m_smoothDelta");

		private static readonly FieldRef<TerrainComp, bool[]> Modified = AccessTools.FieldRefAccess<TerrainComp, bool[]>("m_modifiedHeight");

		private static readonly FieldRef<TerrainComp, float> LastOpRadius = AccessTools.FieldRefAccess<TerrainComp, float>("m_lastOpRadius");

		private static ConfigEntry<bool> _includeCultivator;

		private void Awake()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Expected O, but got Unknown
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Expected O, but got Unknown
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			_log = ((BaseUnityPlugin)this).Logger;
			ConfigurationManagerAttributes val = new ConfigurationManagerAttributes
			{
				IsAdminOnly = true
			};
			_strength = ((BaseUnityPlugin)this).Config.Bind<int>("Level ground", "Level strength", 0, new ConfigDescription("How strongly the outer ring of level-ground tools is pulled to the level height. 0 = vanilla, 100 = the whole area within the radius becomes exactly flat.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), new object[1] { val }));
			_maxHeightChange = ((BaseUnityPlugin)this).Config.Bind<float>("Level ground", "Max height change (m)", 8f, new ConfigDescription("How far one point of ground may be raised or lowered in total by levelling. Vanilla is 8 for levelling and only 1 for smoothing (the hoe's Level ground).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(8f, 32f), new object[1] { val }));
			_includeCultivator = ((BaseUnityPlugin)this).Config.Bind<bool>("Level ground", "Include cultivator", false, new ConfigDescription("Also apply the strength to the cultivator's Cultivate, which smooths the ground the same way.", (AcceptableValueBase)null, new object[1] { val }));
			new Harmony("pieter.valheim.levelstrength").PatchAll(typeof(DoOperationPatch));
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Level strength slider ready.");
		}

		private static void Level(TerrainComp comp, Vector3 worldPos, float levelRadius, float smoothRadius, float power, float strength, float maxChange)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			Heightmap val = Hmap.Invoke(comp);
			float[] array = LevelDelta.Invoke(comp);
			float[] array2 = SmoothDelta.Invoke(comp);
			bool[] array3 = Modified.Invoke(comp);
			if ((Object)(object)val == (Object)null || array == null || array2 == null || array3 == null)
			{
				return;
			}
			int num = default(int);
			int num2 = default(int);
			val.WorldToVertex(worldPos, ref num, ref num2);
			float num3 = worldPos.y - ((Component)comp).transform.position.y;
			float num4 = levelRadius / val.m_scale;
			float num5 = Mathf.Max(num4, smoothRadius / val.m_scale);
			int num6 = Mathf.CeilToInt(num5);
			int num7 = Width.Invoke(comp) + 1;
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor((float)num, (float)num2);
			for (int i = num2 - num6; i <= num2 + num6; i++)
			{
				for (int j = num - num6; j <= num + num6; j++)
				{
					if (j < 0 || i < 0 || j >= num7 || i >= num7)
					{
						continue;
					}
					float num8 = Vector2.Distance(val2, new Vector2((float)j, (float)i));
					if (!(num8 > num5))
					{
						float num9;
						if (num4 > 0f && num8 <= num4)
						{
							num9 = 1f;
						}
						else
						{
							float num10 = num8 / num5;
							num9 = Mathf.Lerp(1f - Mathf.Pow(num10, power), 1f, strength);
						}
						int num11 = i * num7 + j;
						float height = val.GetHeight(j, i);
						if ((num4 > 0f && num8 <= num4) || strength > 0f)
						{
							array[num11] += array2[num11] + (num3 - height) * num9;
							array2[num11] = 0f;
							array[num11] = Mathf.Clamp(array[num11], 0f - maxChange, maxChange);
						}
						else
						{
							array2[num11] = Mathf.Clamp(array2[num11] + (Mathf.Lerp(height, num3, num9) - height), -1f, 1f);
						}
						array3[num11] = true;
					}
				}
			}
		}
	}
}