Decompiled source of RugLift v1.3.1

RugLift.dll

Decompiled 37 minutes ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
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("RugLift")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("RugLift")]
[assembly: AssemblyTitle("RugLift")]
[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;
		}
	}
}
internal static class SettingOrder
{
	internal sealed class ConfigurationManagerAttributes
	{
		public int? Order;
	}

	internal static void Apply(ConfigFile config)
	{
		//IL_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: Expected O, but got Unknown
		FieldInfo fieldInfo = AccessTools.Field(typeof(ConfigEntryBase), "<Description>k__BackingField");
		if (fieldInfo == null)
		{
			return;
		}
		int num = 1000;
		foreach (ConfigDefinition item in config.Keys.ToList())
		{
			ConfigEntryBase val = config[item];
			ConfigDescription description = val.Description;
			object[] array = ((description != null) ? description.Tags : null) ?? new object[0];
			object obj = array.FirstOrDefault((object t) => t != null && t.GetType().Name == "ConfigurationManagerAttributes");
			if (obj != null)
			{
				FieldInfo fieldInfo2 = AccessTools.Field(obj.GetType(), "Order");
				if (fieldInfo2 != null && fieldInfo2.GetValue(obj) == null)
				{
					fieldInfo2.SetValue(obj, num);
				}
			}
			else
			{
				fieldInfo.SetValue(val, (object?)new ConfigDescription(((description != null) ? description.Description : null) ?? "", (description != null) ? description.AcceptableValues : null, array.Concat(new object[1]
				{
					new ConfigurationManagerAttributes
					{
						Order = num
					}
				}).ToArray()));
			}
			num--;
		}
	}
}
namespace RugLift
{
	[BepInPlugin("digi.valheim.ruglift", "Digi's Rug Lift", "1.3.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string Guid = "digi.valheim.ruglift";

		public const string Name = "Digi's Rug Lift";

		public const string Version = "1.3.1";

		private const string NordicRugsGuid = "sosal.nordicrugs";

		private const string MeshName = "NordicRugMesh";

		private const string WallSuffix = "_wall";

		private const string SidewaysSuffix = "_wall_side";

		private static ConfigEntry<float> _lift;

		private static ConfigEntry<bool> _wallRugs;

		private static ConfigEntry<bool> _sidewaysRugs;

		private static ConfigEntry<float> _wallGap;

		private static readonly Dictionary<string, string> RugNames = new Dictionary<string, string>();

		private static readonly FieldRef<Player, GameObject> Ghost = AccessTools.FieldRefAccess<Player, GameObject>("m_placementGhost");

		private static readonly MethodInfo PieceRayTest = AccessTools.Method(typeof(Player), "PieceRayTest", (Type[])null, (Type[])null);

		private void MigrateConfig()
		{
			string text = Path.Combine(Paths.ConfigPath, "digi.valheim.ruglift".Replace("digi.valheim.", "pieter.valheim.") + ".cfg");
			if (!File.Exists(((BaseUnityPlugin)this).Config.ConfigFilePath) && File.Exists(text))
			{
				File.Copy(text, ((BaseUnityPlugin)this).Config.ConfigFilePath);
				((BaseUnityPlugin)this).Config.Reload();
			}
		}

		private void Start()
		{
			SettingOrder.Apply(((BaseUnityPlugin)this).Config);
		}

		private void Awake()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected O, but got Unknown
			MigrateConfig();
			_lift = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Lift (m)", 0.03f, new ConfigDescription("How far Nordic Rugs float above the floor so stone floors do not poke through, in meters (0.03 = 3 cm, like normal rugs). 0 = off.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.1f), Array.Empty<object>()));
			_wallRugs = ((BaseUnityPlugin)this).Config.Bind<bool>("Wall rugs", "Add wall versions", true, "Add a \"(wall)\" version of every Nordic rug to the hammer's Furniture tab, to hang on walls. Needs a restart.");
			_sidewaysRugs = ((BaseUnityPlugin)this).Config.Bind<bool>("Wall rugs", "Add sideways wall versions", true, "Also add a \"(wall, sideways)\" version: the wall rug turned 90 degrees. Needs a restart.");
			_wallGap = ((BaseUnityPlugin)this).Config.Bind<float>("Wall rugs", "Gap from wall (m)", 0.03f, new ConfigDescription("How far wall rugs hang from the wall, in meters, so bumpy log walls do not poke through.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.2f), Array.Empty<object>()));
			_lift.SettingChanged += delegate
			{
				Piece[] array = Object.FindObjectsOfType<Piece>();
				for (int i = 0; i < array.Length; i++)
				{
					Apply(array[i]);
				}
			};
			Harmony.CreateAndPatchAll(typeof(Plugin), "digi.valheim.ruglift");
			if (_wallRugs.Value)
			{
				PrefabManager.OnVanillaPrefabsAvailable += AddWallRugs;
				PieceManager.OnPiecesRegistered += SortRugs;
			}
		}

		[HarmonyPatch(typeof(Piece), "Awake")]
		[HarmonyPostfix]
		private static void PieceAwake(Piece __instance)
		{
			Apply(__instance);
		}

		private static void Apply(Piece piece)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)piece == (Object)null) && !((Object)piece).name.Contains("_wall"))
			{
				Transform val = ((Component)piece).transform.Find("NordicRugMesh");
				if (!((Object)(object)val == (Object)null))
				{
					Vector3 localPosition = val.localPosition;
					val.localPosition = new Vector3(localPosition.x, _lift.Value, localPosition.z);
				}
			}
		}

		private void AddWallRugs()
		{
			PrefabManager.OnVanillaPrefabsAvailable -= AddWallRugs;
			if (!(AccessTools.Field(AccessTools.TypeByName("NordicRugs.RugCatalog"), "All")?.GetValue(null) is IEnumerable enumerable))
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"Wall rugs disabled, the Nordic Rugs catalog was not found.");
				return;
			}
			int num = 0;
			foreach (object item in enumerable)
			{
				try
				{
					Traverse obj = Traverse.Create(item);
					string value = obj.Property("PrefabName", (object[])null).GetValue<string>();
					string value2 = obj.Property("NameEn", (object[])null).GetValue<string>();
					bool value3 = obj.Property("Fur", (object[])null).GetValue<bool>();
					IReadOnlyDictionary<string, int> value4 = obj.Property("Recipe", (object[])null).GetValue<IReadOnlyDictionary<string, int>>();
					CustomPiece piece = PieceManager.Instance.GetPiece(value);
					if (!((Object)(object)((piece != null) ? piece.PiecePrefab : null) == (Object)null))
					{
						RugNames[value] = value2;
						if (AddWall(piece.PiecePrefab, value + "_wall", value2 + " (wall)", value3, value4, sideways: false))
						{
							num++;
						}
						if (_sidewaysRugs.Value && AddWall(piece.PiecePrefab, value + "_wall_side", value2 + " (wall, sideways)", value3, value4, sideways: true))
						{
							num++;
						}
					}
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not add a wall rug: " + ex.Message));
				}
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"Added {num} wall rugs (Furniture).");
		}

		private static void SortRugs()
		{
			PieceTable pieceTable = PieceManager.Instance.GetPieceTable("Hammer");
			if ((Object)(object)pieceTable == (Object)null || RugNames.Count == 0)
			{
				return;
			}
			List<GameObject> pieces = pieceTable.m_pieces;
			int num = pieces.FindIndex(IsRug);
			if (num >= 0)
			{
				List<GameObject> source = pieces.Where(IsRug).ToList();
				pieces.RemoveAll(IsRug);
				source = source.OrderBy<GameObject, string>((GameObject go) => RugNames[BaseName(((Object)go).name)], StringComparer.OrdinalIgnoreCase).ThenBy((GameObject go) => (!((Object)go).name.EndsWith("_wall_side")) ? (((Object)go).name.EndsWith("_wall") ? 1 : 0) : 2).ToList();
				pieces.InsertRange(Math.Min(num, pieces.Count), source);
			}
		}

		private static bool IsRug(GameObject go)
		{
			if ((Object)(object)go != (Object)null)
			{
				return RugNames.ContainsKey(BaseName(((Object)go).name));
			}
			return false;
		}

		private static string BaseName(string name)
		{
			if (!name.EndsWith("_wall_side"))
			{
				if (!name.EndsWith("_wall"))
				{
					return name;
				}
				return name.Substring(0, name.Length - "_wall".Length);
			}
			return name.Substring(0, name.Length - "_wall_side".Length);
		}

		[HarmonyPatch(typeof(Player), "UpdatePlacementGhost")]
		[HarmonyPostfix]
		private static void AlignToWall(Player __instance)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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)
			//IL_0066: 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_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: 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)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Ghost.Invoke(__instance);
			if ((Object)(object)val == (Object)null || !val.activeSelf || !((Object)val).name.Contains("_wall"))
			{
				return;
			}
			object[] array = new object[6] { null, null, null, null, null, false };
			if ((bool)PieceRayTest.Invoke(__instance, array))
			{
				Vector3 val2 = (Vector3)array[0];
				Vector3 val3 = (Vector3)array[1];
				if (!(Mathf.Abs(val3.y) > 0.5f))
				{
					Vector3 val4 = new Vector3(val3.x, 0f, val3.z);
					val3 = ((Vector3)(ref val4)).normalized;
					val.transform.rotation = Quaternion.LookRotation(-val3, Vector3.up);
					val.transform.position = val2 + val3 * _wallGap.Value;
				}
			}
		}

		private static bool AddWall(GameObject source, string prefabName, string name, bool fur, IReadOnlyDictionary<string, int> recipe, bool sideways)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Expected O, but got Unknown
			GameObject val = PrefabManager.Instance.CreateClonedPrefab(prefabName, source);
			MakeUpright(val, sideways);
			PieceConfig val2 = new PieceConfig
			{
				Name = name,
				Description = (fur ? "$nr_fur_description" : "$nr_description"),
				PieceTable = "Hammer",
				Category = "Furniture",
				CraftingStation = "piece_workbench"
			};
			foreach (KeyValuePair<string, int> item in recipe)
			{
				val2.AddRequirement(item.Key, item.Value, true);
			}
			return PieceManager.Instance.AddPiece(new CustomPiece(val, false, val2));
		}

		private static void MakeUpright(GameObject wall, bool sideways)
		{
			//IL_0082: 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_0034: 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_00a5: 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_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: 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_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			Transform val = wall.transform.Find("NordicRugMesh");
			if ((Object)(object)val != (Object)null)
			{
				val.localRotation = (sideways ? Quaternion.Euler(0f, 0f, 90f) : Quaternion.identity) * Quaternion.Euler(-90f, 0f, 0f);
				val.localPosition = new Vector3(0f, 0f, -0.005f);
			}
			BoxCollider component = wall.GetComponent<BoxCollider>();
			if ((Object)(object)component != (Object)null)
			{
				Vector3 size = component.size;
				component.size = (sideways ? new Vector3(size.z, size.x, size.y) : new Vector3(size.x, size.z, size.y));
				component.center = new Vector3(0f, 0f, (0f - size.y) / 2f);
			}
		}
	}
}