Decompiled source of AdvancedHeightMap v0.1.0

AdvancedHeightMap.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using AdvancedHeightMap.Helpers;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Configs;
using HarmonyLib;
using Jotunn.Extensions;
using Jotunn.Utils;
using Logging;
using Microsoft.CodeAnalysis;
using SoftReferenceableAssets;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("AdvancedHeightMap")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AdvancedHeightMap")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("08a6f7d7-cf93-4931-aecd-abf2ce6ed34c")]
[assembly: AssemblyFileVersion("0.1.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.0.0")]
[module: UnverifiableCode]
[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 Logging
{
	internal static class Log
	{
		internal enum InfoLevel
		{
			Low,
			Medium,
			High
		}

		private static ManualLogSource logSource;

		internal static ConfigEntry<InfoLevel> Verbosity { get; set; }

		internal static InfoLevel VerbosityLevel => Verbosity.Value;

		internal static bool IsVerbosityLow => Verbosity.Value >= InfoLevel.Low;

		internal static bool IsVerbosityMedium => Verbosity.Value >= InfoLevel.Medium;

		internal static bool IsVerbosityHigh => Verbosity.Value >= InfoLevel.High;

		internal static void Init(ManualLogSource logSource)
		{
			Log.logSource = logSource;
		}

		internal static void LogDebug(object data)
		{
			logSource.LogDebug(data);
		}

		internal static void LogError(object data)
		{
			logSource.LogError(data);
		}

		internal static void LogFatal(object data)
		{
			logSource.LogFatal(data);
		}

		internal static void LogMessage(object data)
		{
			logSource.LogMessage(data);
		}

		internal static void LogWarning(object data)
		{
			logSource.LogWarning(data);
		}

		internal static void LogInfo(object data, InfoLevel level = InfoLevel.Low)
		{
			if (Verbosity == null || VerbosityLevel >= level)
			{
				logSource.LogInfo(data);
			}
		}

		internal static void LogGameObject(GameObject prefab, bool includeChildren = false)
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			LogInfo("***** " + ((Object)prefab).name + " *****");
			Component[] components = prefab.GetComponents<Component>();
			for (int i = 0; i < components.Length; i++)
			{
				LogComponent(components[i]);
			}
			if (!includeChildren)
			{
				return;
			}
			LogInfo("***** " + ((Object)prefab).name + " (children) *****");
			foreach (Transform item in prefab.transform)
			{
				Transform val = item;
				if (Object.op_Implicit((Object)(object)val))
				{
					LogInfo(" - " + ((Object)val).name);
					components = ((Component)val).GetComponents<Component>();
					for (int i = 0; i < components.Length; i++)
					{
						LogComponent(components[i]);
					}
				}
			}
		}

		internal static void LogComponent(Component compo)
		{
			if (!Object.op_Implicit((Object)(object)compo))
			{
				return;
			}
			try
			{
				LogInfo("--- " + ((object)compo).GetType().Name + ": " + ((Object)compo).name + " ---");
			}
			catch (Exception ex)
			{
				LogError(ex.ToString());
				LogWarning("Could not get type name for component!");
				return;
			}
			try
			{
				foreach (PropertyInfo declaredProperty in AccessTools.GetDeclaredProperties(((object)compo).GetType()))
				{
					try
					{
						LogInfo($" - {declaredProperty.Name} = {declaredProperty.GetValue(compo)}");
					}
					catch (Exception ex2)
					{
						LogError(ex2.ToString());
						LogWarning("Could not get property: " + declaredProperty.Name + " for component!");
					}
				}
			}
			catch (Exception ex3)
			{
				LogError(ex3.ToString());
				LogWarning("Could not get properties for component!");
			}
			try
			{
				foreach (FieldInfo declaredField in AccessTools.GetDeclaredFields(((object)compo).GetType()))
				{
					try
					{
						LogInfo($" - {declaredField.Name} = {declaredField.GetValue(compo)}");
					}
					catch (Exception ex4)
					{
						LogError(ex4.ToString());
						LogWarning("Could not get field: " + declaredField.Name + " for component!");
					}
				}
			}
			catch (Exception ex5)
			{
				LogError(ex5.ToString());
				LogWarning("Could not get fields for component!");
			}
		}
	}
}
namespace Configs
{
	public static class ConfigFileExtensions
	{
		public static bool DisableSaveOnConfigSet(this ConfigFile configFile)
		{
			bool saveOnConfigSet = configFile.SaveOnConfigSet;
			configFile.SaveOnConfigSet = false;
			return saveOnConfigSet;
		}
	}
	internal static class SafeInvokeEvent
	{
		internal static void SafeInvoke(this Action events)
		{
			if (events == null)
			{
				return;
			}
			Delegate[] invocationList = events.GetInvocationList();
			for (int i = 0; i < invocationList.Length; i++)
			{
				Action action = (Action)invocationList[i];
				try
				{
					action();
				}
				catch (Exception arg)
				{
					Log.LogWarning("Exception thrown at event " + new StackFrame(1).GetMethod().Name + $" in {action.Method.DeclaringType.Name}.{action.Method.Name}:\n{arg}");
				}
			}
		}
	}
}
namespace AdvancedHeightMap
{
	[BepInPlugin("Searica.Valheim.AdvancedHeightMap", "AdvancedHeightMap", "0.1.0")]
	[BepInDependency("com.jotunn.jotunn", "2.30.2")]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	[SynchronizationMode(/*Could not decode attribute arguments.*/)]
	internal sealed class AdvancedHeightMap : BaseUnityPlugin
	{
		public const string PluginName = "AdvancedHeightMap";

		internal const string Author = "Searica";

		public const string PluginGUID = "Searica.Valheim.AdvancedHeightMap";

		public const string PluginVersion = "0.1.0";

		internal static AdvancedHeightMap Instance;

		internal static ConfigFile ConfigFile;

		internal static ConfigFileWatcher ConfigFileWatcher;

		internal const string MainConfigSection = "AdvancedHeightMap";

		internal static ConfigEntry<float> MaxHeightChange;

		internal static ConfigEntry<float> MinHeightChange;

		internal static bool BoundConfigs;

		internal static float GetMaxHeightChange()
		{
			return MaxHeightChange.Value;
		}

		internal static float GetMinHeightChange()
		{
			return MinHeightChange.Value;
		}

		public void Awake()
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			Instance = this;
			ConfigFile = ((BaseUnityPlugin)this).Config;
			Log.Init(((BaseUnityPlugin)this).Logger);
			((BaseUnityPlugin)this).Config.DisableSaveOnConfigSet();
			SetUpConfigEntries();
			((BaseUnityPlugin)this).Config.Save();
			((BaseUnityPlugin)this).Config.SaveOnConfigSet = true;
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "Searica.Valheim.AdvancedHeightMap");
			Game.isModded = true;
			ConfigFileWatcher = new ConfigFileWatcher(((BaseUnityPlugin)this).Config, 1000L);
		}

		internal void SetUpConfigEntries()
		{
			Log.Verbosity = ConfigFileExtensions.BindConfigInOrder<Log.InfoLevel>(((BaseUnityPlugin)this).Config, "AdvancedHeightMap", "Verbosity", Log.InfoLevel.Low, "Low will log basic information about the mod. Medium will log information that is useful for troubleshooting. High will log a lot of information, do not set it to this without good reason as it will slow Down your game.", false, false, true, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			MaxHeightChange = ConfigFileExtensions.BindConfigInOrder<float>(((BaseUnityPlugin)this).Config, "AdvancedHeightMap", "MaxHeightChange", 200f, "How high you can raise terrain up relative to the heightmap's original position. Vanilla default is 8", true, false, true, (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 200f), (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			MinHeightChange = ConfigFileExtensions.BindConfigInOrder<float>(((BaseUnityPlugin)this).Config, "AdvancedHeightMap", "MinHeightChange", -200f, "How far you can dig down relative to the heightmap's original position. Vanilla default is -8", true, false, true, (AcceptableValueBase)(object)new AcceptableValueRange<float>(-200f, -1f), (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			BoundConfigs = true;
		}

		public void OnDestroy()
		{
			((BaseUnityPlugin)this).Config.Save();
		}
	}
	public static class AdvancedHeightMapAPI
	{
		public static float GetMaxHeightChange()
		{
			if (AdvancedHeightMap.BoundConfigs)
			{
				return AdvancedHeightMap.MaxHeightChange.Value;
			}
			return 8f;
		}

		public static float GetMinHeightChange()
		{
			if (AdvancedHeightMap.BoundConfigs)
			{
				return AdvancedHeightMap.MinHeightChange.Value;
			}
			return 8f;
		}
	}
	[HarmonyPatch]
	internal static class HeightMapPatches
	{
		private static readonly MethodInfo ClampMethod = AccessTools.Method(typeof(Mathf), "Clamp", new Type[3]
		{
			typeof(float),
			typeof(float),
			typeof(float)
		}, (Type[])null);

		private static readonly CodeMatch[] TargetMatches = (CodeMatch[])(object)new CodeMatch[3]
		{
			new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction instruction) => CodeInstructionExtensions.LoadsConstant(instruction, -8.0)), (string)null),
			new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction instruction) => CodeInstructionExtensions.LoadsConstant(instruction, 8.0)), (string)null),
			new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction instruction) => CodeInstructionExtensions.Calls(instruction, ClampMethod)), (string)null)
		};

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(TerrainComp), "RaiseTerrain")]
		private static IEnumerable<CodeInstruction> ChangeRaiseTerrainLimits(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher((IEnumerable<CodeInstruction>)PatchHelper.Copy(instructions), (ILGenerator)null);
			if (val.TryMatchStartForward("RaiseTerrain Transpiler", TargetMatches))
			{
				val.SetInstructionAndAdvance(Transpilers.EmitDelegate<Func<float>>((Func<float>)AdvancedHeightMap.GetMinHeightChange));
				val.SetInstructionAndAdvance(Transpilers.EmitDelegate<Func<float>>((Func<float>)AdvancedHeightMap.GetMaxHeightChange));
				return val.InstructionEnumeration();
			}
			return instructions;
		}

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(TerrainComp), "LevelTerrain")]
		private static IEnumerable<CodeInstruction> ChangeLevelTerrainLimits(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher((IEnumerable<CodeInstruction>)PatchHelper.Copy(instructions), (ILGenerator)null);
			if (val.TryMatchStartForward("LevelTerrain Transpiler", TargetMatches))
			{
				val.SetInstructionAndAdvance(Transpilers.EmitDelegate<Func<float>>((Func<float>)AdvancedHeightMap.GetMinHeightChange));
				val.SetInstructionAndAdvance(Transpilers.EmitDelegate<Func<float>>((Func<float>)AdvancedHeightMap.GetMaxHeightChange));
				return val.InstructionEnumeration();
			}
			return instructions;
		}

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(TerrainComp), "ApplyToHeightmap")]
		private static IEnumerable<CodeInstruction> ChangeApplyToHeightmapLimits(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected O, but got Unknown
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Expected O, but got Unknown
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher((IEnumerable<CodeInstruction>)PatchHelper.Copy(instructions), (ILGenerator)null);
			CodeMatch[] matches = (CodeMatch[])(object)new CodeMatch[2]
			{
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction instruction) => CodeInstructionExtensions.LoadsConstant(instruction, 8.0)), (string)null),
				new CodeMatch((OpCode?)OpCodes.Sub, (object)null, (string)null)
			};
			CodeMatch[] matches2 = (CodeMatch[])(object)new CodeMatch[2]
			{
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction instruction) => CodeInstructionExtensions.LoadsConstant(instruction, 8.0)), (string)null),
				new CodeMatch((OpCode?)OpCodes.Add, (object)null, (string)null)
			};
			if (val.TryMatchStartForward("ApplyToHeightMap Change Min Depth Transpiler", matches))
			{
				val.SetInstructionAndAdvance(Transpilers.EmitDelegate<Func<float>>((Func<float>)AdvancedHeightMap.GetMinHeightChange));
				val.SetInstructionAndAdvance(new CodeInstruction(OpCodes.Add, (object)null));
			}
			if (val.TryMatchStartForward("ApplyToHeightMap Change Max Height Transpiler", matches2))
			{
				val.SetInstructionAndAdvance(Transpilers.EmitDelegate<Func<float>>((Func<float>)AdvancedHeightMap.GetMaxHeightChange));
			}
			if (val.IsValid)
			{
				return val.InstructionEnumeration();
			}
			return instructions;
		}
	}
}
namespace AdvancedHeightMap.Helpers
{
	internal static class PatchHelper
	{
		internal const int AnyCount = -1;

		internal static List<CodeInstruction> Copy(IEnumerable<CodeInstruction> instructions)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			List<CodeInstruction> list = ((instructions is ICollection<CodeInstruction> collection) ? new List<CodeInstruction>(collection.Count) : new List<CodeInstruction>());
			foreach (CodeInstruction instruction in instructions)
			{
				list.Add(new CodeInstruction(instruction));
			}
			return list;
		}

		internal static IEnumerable<CodeInstruction> ReplaceCalls(IEnumerable<CodeInstruction> instructions, MethodInfo original, MethodInfo replacement, string site, int expected = -1)
		{
			if (original == null || replacement == null)
			{
				Log.LogWarning(site + ": a method this fix needs could not be resolved, so it is inactive here.");
				return instructions;
			}
			List<CodeInstruction> list = Copy(instructions);
			int num = 0;
			for (int i = 0; i < list.Count; i++)
			{
				if (CodeInstructionExtensions.Calls(list[i], original))
				{
					list[i].opcode = OpCodes.Call;
					list[i].operand = replacement;
					num++;
				}
			}
			if ((expected == -1) ? (num > 0) : (num == expected))
			{
				return list;
			}
			string text = ((expected == -1) ? "at least 1" : expected.ToString());
			Log.LogWarning(site + ": expected " + text + " call(s) to " + original.DeclaringType?.Name + "." + original.Name + ", " + $"found {num}, so this fix is inactive here. Another mod has most likely already " + "rewritten the method - if so, nothing is wrong.");
			return instructions;
		}

		internal static IEnumerable<CodeInstruction> ReplaceAllMatches(IEnumerable<CodeInstruction> instructions, CodeMatch[] pattern, CodeInstruction[] replacement, string site, int expected = -1)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
			int num = 0;
			while (val.MatchStartForward(pattern).IsValid)
			{
				for (int i = 1; i < pattern.Length; i++)
				{
					CodeInstruction val2 = val.InstructionAt(i);
					if (val2.labels.Count != 0 || val2.blocks.Count != 0)
					{
						Log.LogWarning(site + ": a jump or exception block lands inside the code this fix rewrites, so it is inactive here. Another mod has most likely already rewritten the method - if so, nothing is wrong.");
						return instructions;
					}
				}
				CodeInstruction[] array = (CodeInstruction[])(object)new CodeInstruction[replacement.Length];
				for (int j = 0; j < array.Length; j++)
				{
					array[j] = replacement[j].Clone();
				}
				CodeInstructionExtensions.MoveBlocksFrom(CodeInstructionExtensions.MoveLabelsFrom(array[0], val.Instruction), val.Instruction);
				val.RemoveInstructions(pattern.Length).InsertAndAdvance(array);
				num++;
			}
			if ((expected == -1) ? (num > 0) : (num == expected))
			{
				return val.InstructionEnumeration();
			}
			string arg = ((expected == -1) ? "at least 1" : expected.ToString());
			Log.LogWarning($"{site}: expected {arg} match(es) of the code this fix rewrites, found {num}, " + "so this fix is inactive here. Another mod has most likely already rewritten the method - if so, nothing is wrong.");
			return instructions;
		}

		public static bool TryMatchStartForward(this CodeMatcher matcher, string failureMessage, params CodeMatch[] matches)
		{
			matcher.MatchStartForward(matches);
			if (matcher.IsInvalid)
			{
				Log.LogWarning(failureMessage + " Anchor instruction not found, it was likely consumed by another mod. Skipping this patch.");
				return false;
			}
			return true;
		}

		public static bool TryMatchStartForward(this CodeMatcher matcher, params CodeMatch[] matches)
		{
			matcher.MatchStartForward(matches);
			if (matcher.IsInvalid)
			{
				return false;
			}
			return true;
		}

		public static bool TryMatchStartBackwards(this CodeMatcher matcher, string failureMessage, params CodeMatch[] matches)
		{
			matcher.MatchStartBackwards(matches);
			if (matcher.IsInvalid)
			{
				Log.LogWarning(failureMessage + " Anchor instruction not found, it was likely consumed by another mod. Skipping this patch.");
				return false;
			}
			return true;
		}

		public static bool TryMatchStartBackwards(this CodeMatcher matcher, params CodeMatch[] matches)
		{
			matcher.MatchStartBackwards(matches);
			if (matcher.IsInvalid)
			{
				return false;
			}
			return true;
		}

		public static bool TryMatchEndForward(this CodeMatcher matcher, string failureMessage, params CodeMatch[] matches)
		{
			matcher.MatchEndForward(matches);
			if (matcher.IsInvalid)
			{
				Log.LogWarning(failureMessage + " Anchor instruction not found, it was likely consumed by another mod. Skipping this patch.");
				return false;
			}
			return true;
		}

		public static bool TryMatchEndForward(this CodeMatcher matcher, params CodeMatch[] matches)
		{
			matcher.MatchEndForward(matches);
			if (matcher.IsInvalid)
			{
				return false;
			}
			return true;
		}
	}
}
namespace AdvancedHeightMap.Extensions
{
	internal static class AssetBundleLoaderExtensions
	{
		private static readonly Dictionary<BundleLoader, HashSet<AssetID>> _bundleLoaderToAssetIDsMap = new Dictionary<BundleLoader, HashSet<AssetID>>();

		private static Dictionary<BundleLoader, HashSet<AssetID>> GetBundleLoaderToAssetIDDependeciesMap()
		{
			//IL_001d: 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_0028: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: 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_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			if (_bundleLoaderToAssetIDsMap.Count == 0)
			{
				AssetLoader[] assetLoaders = AssetBundleLoader.Instance.m_assetLoaders;
				foreach (AssetLoader val in assetLoaders)
				{
					BundleLoader bundleLoaderFromAssetID = AssetBundleLoader.Instance.GetBundleLoaderFromAssetID(val.m_assetID);
					if (!_bundleLoaderToAssetIDsMap.TryGetValue(bundleLoaderFromAssetID, out var value))
					{
						value = new HashSet<AssetID>();
						_bundleLoaderToAssetIDsMap[bundleLoaderFromAssetID] = value;
					}
					value.Add(val.m_assetID);
				}
			}
			return _bundleLoaderToAssetIDsMap;
		}

		internal static BundleLoader GetBundleLoaderFromAssetID(this AssetBundleLoader assetBundleLoader, AssetID assetID)
		{
			//IL_0001: 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_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			AssetLoader loader = assetBundleLoader.GetLoader(assetID);
			return assetBundleLoader.m_bundleLoaders[loader.m_bundleLoaderIndex];
		}

		internal static HashSet<AssetID> GetDependenciesFromAssetID(this AssetBundleLoader assetBundleLoader, AssetID assetID)
		{
			//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_002b: Unknown result type (might be due to invalid IL or missing references)
			BundleLoader bundleLoaderFromAssetID = assetBundleLoader.GetBundleLoaderFromAssetID(assetID);
			List<AssetID> list = new List<AssetID>();
			Dictionary<BundleLoader, HashSet<AssetID>> bundleLoaderToAssetIDDependeciesMap = GetBundleLoaderToAssetIDDependeciesMap();
			int[] bundleLoaderIndicesOfThisAndDependencies = bundleLoaderFromAssetID.m_bundleLoaderIndicesOfThisAndDependencies;
			foreach (int num in bundleLoaderIndicesOfThisAndDependencies)
			{
				if (bundleLoaderToAssetIDDependeciesMap.TryGetValue(assetBundleLoader.m_bundleLoaders[num], out var value))
				{
					list.AddRange(value);
				}
			}
			return list.ToHashSet();
		}
	}
	internal static class GameObjectExtensions
	{
		public static bool IsRootPrefab(this GameObject go)
		{
			return !Object.op_Implicit((Object)(object)go.transform.parent);
		}
	}
}
namespace AdvancedHeightMap.API
{
	public static class AdvanedHeightMapInfo
	{
		public const string PluginGUID = "Searica.Valheim.AdvancedHeightMap";
	}
	public static class AdvancedHeightMapAPI
	{
		private const string ReceiverTypeName = "AdvancedHeightMap.API.APIReceiver";

		private const string ReceiverAssemblyName = "AdvancedHeightMap";

		private static readonly Type APIReceiver;

		private static readonly List<string> Unbound;

		private static readonly Func<int> getApiVersion;

		private static readonly Func<float> getMaxHeightChange;

		private static readonly Func<float> getMinHeightChange;

		public static bool IsAvailable => APIReceiver != null;

		public static int ReceiverApiVersion
		{
			get
			{
				if (getApiVersion == null)
				{
					return 0;
				}
				return getApiVersion();
			}
		}

		static AdvancedHeightMapAPI()
		{
			Unbound = new List<string>();
			APIReceiver = FindReceiver();
			if (!(APIReceiver == null))
			{
				getApiVersion = Bind<Func<int>>("GetApiVersion");
				getMaxHeightChange = Bind<Func<float>>("GetMaxHeightChange");
				getMinHeightChange = Bind<Func<float>>("GetMinHeightChange");
			}
		}

		private static Type FindReceiver()
		{
			Type type = null;
			try
			{
				type = Type.GetType("AdvancedHeightMap.API.APIReceiver, AdvancedHeightMap", throwOnError: false);
			}
			catch (Exception)
			{
			}
			if (type != null)
			{
				return type;
			}
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				if (!(assembly.GetName().Name != "AdvancedHeightMap"))
				{
					type = assembly.GetType("AdvancedHeightMap.API.APIReceiver", throwOnError: false);
					if (type != null)
					{
						return type;
					}
				}
			}
			return null;
		}

		private static T Bind<T>(string name) where T : class
		{
			MethodInfo method = typeof(T).GetMethod("Invoke");
			ParameterInfo[] parameters = method.GetParameters();
			Type[] array = new Type[parameters.Length];
			for (int i = 0; i < parameters.Length; i++)
			{
				array[i] = parameters[i].ParameterType;
			}
			MethodInfo method2 = APIReceiver.GetMethod(name, BindingFlags.Static | BindingFlags.Public, null, array, null);
			T obj = ((method2 != null && method2.ReturnType == method.ReturnType) ? (Delegate.CreateDelegate(typeof(T), method2, throwOnBindFailure: false) as T) : null);
			if (obj == null)
			{
				Unbound.Add(name);
			}
			return obj;
		}

		public static float GetMaxHeightChange()
		{
			if (getMaxHeightChange == null)
			{
				return 8f;
			}
			return getMaxHeightChange();
		}

		public static float GetMinHeightChange()
		{
			if (getMinHeightChange == null)
			{
				return -8f;
			}
			return getMinHeightChange();
		}
	}
	public static class APIReceiver
	{
		internal const int ApiVersion = 1;

		public static int GetApiVersion()
		{
			return 1;
		}

		public static float GetMaxHeightChange()
		{
			if (AdvancedHeightMap.BoundConfigs)
			{
				return AdvancedHeightMap.MaxHeightChange.Value;
			}
			return 8f;
		}

		public static float GetMinHeightChange()
		{
			if (AdvancedHeightMap.BoundConfigs)
			{
				return AdvancedHeightMap.MinHeightChange.Value;
			}
			return 8f;
		}
	}
}