Decompiled source of PickupableCart v1.0.0

PickupableCart.dll

Decompiled 3 hours ago
using System;
using System.Collections;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("McHorse")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+6eea91c704222039a55ddc94191373befb3a3782")]
[assembly: AssemblyProduct("PickupableCart")]
[assembly: AssemblyTitle("PickupableCart")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.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 PickupableCart
{
	internal static class CartTemplateCache
	{
		private static Item? _templateItem;

		internal static Item? TemplateItem => _templateItem;

		internal static Item? ResolveItem()
		{
			if ((Object)(object)_templateItem != (Object)null)
			{
				return _templateItem;
			}
			PhysGrabCart[] array = Object.FindObjectsOfType<PhysGrabCart>(true);
			foreach (PhysGrabCart val in array)
			{
				if (val.isSmallCart)
				{
					ItemAttributes component = ((Component)val).GetComponent<ItemAttributes>();
					if ((Object)(object)component != (Object)null && (Object)(object)component.item != (Object)null)
					{
						_templateItem = component.item;
						return _templateItem;
					}
				}
			}
			Item val2 = FindBestScoredCartItemAsset();
			if ((Object)(object)val2 != (Object)null)
			{
				_templateItem = val2;
				return _templateItem;
			}
			Item[] array2 = Resources.FindObjectsOfTypeAll<Item>();
			foreach (Item val3 in array2)
			{
				if (!((Object)(object)val3 == (Object)null))
				{
					string text = ((Object)val3).name ?? "";
					string text2 = val3.itemName ?? "";
					if (text.IndexOf("cart", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("cart", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						_templateItem = val3;
						return _templateItem;
					}
				}
			}
			return null;
		}

		private static Item? FindBestScoredCartItemAsset()
		{
			Item result = null;
			int num = int.MinValue;
			Item[] array = Resources.FindObjectsOfTypeAll<Item>();
			foreach (Item val in array)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				string text = ((Object)val).name ?? "";
				string text2 = val.itemName ?? "";
				if (text.IndexOf("cart", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("cart", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					int num2 = ScoreCartItemName(text + " " + text2);
					if (num2 > num)
					{
						num = num2;
						result = val;
					}
				}
			}
			return result;
		}

		private static int ScoreCartItemName(string combined)
		{
			string text = combined.ToLowerInvariant();
			int num = 0;
			if (text.Contains("pocket"))
			{
				num += 100;
			}
			if (text.Contains("small"))
			{
				num += 80;
			}
			if (text.Contains("medium"))
			{
				num += 40;
			}
			if (text.Contains("item cart"))
			{
				num += 25;
			}
			if (text.Contains("large"))
			{
				num -= 120;
			}
			if (text.Contains("cannon"))
			{
				num -= 80;
			}
			if (text.Contains("laser"))
			{
				num -= 80;
			}
			return num;
		}

		internal static void ClearTemplate()
		{
			_templateItem = null;
		}
	}
	internal static class EmbeddedCartIcon
	{
		private static Sprite? _sprite;

		internal static Sprite? GetSprite()
		{
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Expected O, but got Unknown
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_sprite != (Object)null)
			{
				return _sprite;
			}
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			string text = executingAssembly.GetManifestResourceNames().FirstOrDefault((string n) => n.EndsWith("CartIcon.png", StringComparison.OrdinalIgnoreCase));
			if (text == null)
			{
				PickupableCart.Logger.LogError((object)"Embedded resource CartIcon.png not found. Ensure CartIcon.png is included as EmbeddedResource in the project.");
				return null;
			}
			using Stream stream = executingAssembly.GetManifestResourceStream(text);
			if (stream == null)
			{
				return null;
			}
			using MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			byte[] array = memoryStream.ToArray();
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true);
			if (!ImageConversion.LoadImage(val, array, false))
			{
				PickupableCart.Logger.LogError((object)"CartIcon.png could not be decoded as a PNG.");
				Object.Destroy((Object)(object)val);
				return null;
			}
			((Object)val).name = "PickupableCart_CartIcon";
			((Texture)val).wrapModeU = (TextureWrapMode)1;
			((Texture)val).wrapModeV = (TextureWrapMode)1;
			((Texture)val).filterMode = (FilterMode)2;
			((Texture)val).anisoLevel = 0;
			val.Apply(true, false);
			_sprite = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0);
			((Object)_sprite).name = "PickupableCart_CartIcon";
			return _sprite;
		}
	}
	internal sealed class LargeCartIconSync : MonoBehaviour
	{
		private IEnumerator Start()
		{
			ItemAttributes mine = ((Component)this).GetComponent<ItemAttributes>();
			if (!((Object)(object)mine == (Object)null))
			{
				yield return null;
				yield return null;
				Sprite sprite = EmbeddedCartIcon.GetSprite();
				if ((Object)(object)sprite == (Object)null)
				{
					PickupableCart.Logger.LogWarning((object)"Large cart has no custom icon (embedded CartIcon.png missing or invalid).");
				}
				else
				{
					ApplyIcon(mine, sprite);
				}
			}
		}

		private static void ApplyIcon(ItemAttributes mine, Sprite sprite)
		{
			mine.icon = sprite;
			RefreshInventoryIconIfShowing(mine);
		}

		private static void RefreshInventoryIconIfShowing(ItemAttributes mine)
		{
			ItemEquippable component = ((Component)mine).GetComponent<ItemEquippable>();
			if ((Object)(object)component == (Object)null || !component.IsEquipped() || (Object)(object)Inventory.instance == (Object)null)
			{
				return;
			}
			foreach (InventorySpot allSpot in Inventory.instance.GetAllSpots())
			{
				if ((Object)(object)allSpot == (Object)null || (Object)(object)allSpot.CurrentItem != (Object)(object)component)
				{
					continue;
				}
				allSpot.UpdateUI();
				break;
			}
		}
	}
	internal sealed class LargeCartPickupInjected : MonoBehaviour
	{
	}
	[BepInPlugin("McHorse.PickupableCart", "PickupableCart", "1.0")]
	public class PickupableCart : BaseUnityPlugin
	{
		internal static PickupableCart Instance { get; private set; }

		internal static ManualLogSource Logger => Instance._logger;

		private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger;

		internal Harmony? Harmony { get; set; }

		private void Awake()
		{
			Instance = this;
			((Component)this).gameObject.transform.parent = null;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			Patch();
			Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!");
		}

		internal void Patch()
		{
			//IL_001a: 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)
			//IL_0021: Expected O, but got Unknown
			//IL_0026: Expected O, but got Unknown
			if (Harmony == null)
			{
				Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
				Harmony val2 = val;
				Harmony = val;
			}
			Harmony.PatchAll();
		}

		internal void Unpatch()
		{
			Harmony? harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
}
namespace PickupableCart.Patches
{
	[HarmonyPatch(typeof(ItemAttributes), "ShopInTruckLogic")]
	internal static class ItemAttributesShopInTruckLogicPatch
	{
		[HarmonyPrefix]
		private static bool SkipWhenInjectedCartHasNoRoomVolume(ItemAttributes __instance)
		{
			if ((Object)(object)((Component)__instance).GetComponent<LargeCartPickupInjected>() == (Object)null || (Object)(object)((Component)__instance).GetComponent<RoomVolumeCheck>() != (Object)null)
			{
				return true;
			}
			if (!SemiFunc.RunIsShop())
			{
				if ((Object)(object)RunManager.instance == (Object)null)
				{
					return false;
				}
				if (!RunManager.instance.levelIsShop)
				{
					return true;
				}
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(ItemAttributes), "Start")]
	internal static class ItemAttributesStartPatch
	{
		private const string LargeCartItemDisplayName = "C.A.R.T.";

		[HarmonyPrefix]
		private static void AssignTemplateItemForInjectedLargeCart(ItemAttributes __instance)
		{
			if (!((Object)(object)((Component)__instance).GetComponent<LargeCartPickupInjected>() == (Object)null) && !((Object)(object)__instance.item != (Object)null))
			{
				Item val = CartTemplateCache.ResolveItem();
				if ((Object)(object)val == (Object)null)
				{
					PickupableCart.Logger.LogError((object)"No Item ScriptableObject found for injected large cart (no small cart in scene and no Item asset with 'cart' in name). Large cart inventory may crash or fail.");
				}
				else
				{
					__instance.item = val;
				}
			}
		}

		[HarmonyPostfix]
		private static void OverrideDisplayNameForInjectedLargeCart(ItemAttributes __instance)
		{
			if (!((Object)(object)((Component)__instance).GetComponent<LargeCartPickupInjected>() == (Object)null))
			{
				Traverse.Create((object)__instance).Field("itemName").SetValue((object)"C.A.R.T.");
			}
		}

		[HarmonyPostfix]
		private static void EnsurePhysGrabObjectForInjectedLargeCart(ItemAttributes __instance)
		{
			if ((Object)(object)((Component)__instance).GetComponent<LargeCartPickupInjected>() == (Object)null)
			{
				return;
			}
			Traverse val = Traverse.Create((object)__instance);
			if (val.Field("physGrabObject").GetValue() == null)
			{
				PhysGrabObject val2 = ((Component)__instance).GetComponent<PhysGrabObject>() ?? ((Component)__instance).GetComponentInParent<PhysGrabObject>();
				if ((Object)(object)val2 != (Object)null)
				{
					val.Field("physGrabObject").SetValue((object)val2);
				}
			}
		}
	}
	[HarmonyPatch(typeof(PhysGrabCart), "Start")]
	internal static class PhysGrabCartStartPatch
	{
		[HarmonyPrefix]
		private static void InjectLargeCartInventoryComponents(PhysGrabCart __instance)
		{
			if (!__instance.isSmallCart && !((Object)(object)((Component)__instance).GetComponent<ItemEquippable>() != (Object)null))
			{
				GameObject gameObject = ((Component)__instance).gameObject;
				gameObject.AddComponent<LargeCartPickupInjected>();
				gameObject.AddComponent<ItemEquippable>();
				gameObject.AddComponent<ItemAttributes>();
				gameObject.AddComponent<LargeCartIconSync>();
				PickupableCart.Logger.LogDebug((object)("Injected inventory components on large cart: " + ((Object)gameObject).name));
			}
		}
	}
}