Decompiled source of RainsCustomConsumables v0.0.1

RainsCustomConsumables.dll

Decompiled a day 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 System.Security;
using System.Security.Permissions;
using Custom_Consumables;
using Custom_Consumables.Logging;
using HarmonyLib;
using MelonLoader;
using Microsoft.CodeAnalysis;
using RainsCustomConsumables;
using ScheduleOne;
using ScheduleOne.DevUtilities;
using ScheduleOne.Equipping;
using ScheduleOne.ItemFramework;
using ScheduleOne.UI.Shop;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(global::Custom_Consumables.Custom_Consumables), "RainsCustomConsumables", "0.0.1", "RainingDeath", null)]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("RainsCustomConsumables")]
[assembly: AssemblyConfiguration("DebugMelon")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("RainsCarMod")]
[assembly: AssemblyTitle("RainsCustomConsumables")]
[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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Custom_Consumables
{
	public class Custom_Consumables : MelonMod
	{
		[CompilerGenerated]
		private sealed class <InitAfterRegistryReady>d__4 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Custom_Consumables <>4__this;

			private List<CustomShopItem>.Enumerator <>s__1;

			private CustomShopItem <item>5__2;

			private Dictionary<string, float>.Enumerator <>s__3;

			private string <shop>5__4;

			private float <price>5__5;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <InitAfterRegistryReady>d__4(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>s__1 = default(List<CustomShopItem>.Enumerator);
				<item>5__2 = null;
				<>s__3 = default(Dictionary<string, float>.Enumerator);
				<shop>5__4 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_003e: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if ((Object)(object)Singleton<Registry>.Instance == (Object)null)
				{
					MelonLogger.Msg("⏳ Waiting for Registry...");
					<>2__current = (object)new WaitForSeconds(1f);
					<>1__state = 1;
					return true;
				}
				<>s__1 = ItemDatabase.Items.GetEnumerator();
				try
				{
					while (<>s__1.MoveNext())
					{
						<item>5__2 = <>s__1.Current;
						RegistryManager.RegisterItem<Equippable>(<item>5__2.ID, <item>5__2.PrefabName, <item>5__2.AssetName);
						<>s__3 = <item>5__2.ShopPrices.GetEnumerator();
						try
						{
							while (<>s__3.MoveNext())
							{
								(<shop>5__4, <price>5__5) = (KeyValuePair<string, float>)(ref <>s__3.Current);
								ShopManager.AddItemToShop(<shop>5__4, <item>5__2.ID, <price>5__5);
								<shop>5__4 = null;
							}
						}
						finally
						{
							((IDisposable)<>s__3).Dispose();
						}
						<>s__3 = default(Dictionary<string, float>.Enumerator);
						<item>5__2 = null;
					}
				}
				finally
				{
					((IDisposable)<>s__1).Dispose();
				}
				<>s__1 = default(List<CustomShopItem>.Enumerator);
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public static Dictionary<string, GameObject> LoadedPrefabs = new Dictionary<string, GameObject>();

		private static AssetBundle? embeddedBundle;

		public override void OnApplicationStart()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			Harmony val = new Harmony("com.mod.customitems");
			val.PatchAll();
			LoadEmbeddedBundle();
			MelonCoroutines.Start(InitAfterRegistryReady());
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			string[] manifestResourceNames = executingAssembly.GetManifestResourceNames();
			foreach (string text in manifestResourceNames)
			{
				MelonLogger.Msg("\ud83d\udce6 Embedded Resource: " + text);
			}
		}

		private void LoadEmbeddedBundle()
		{
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			using Stream stream = executingAssembly.GetManifestResourceStream("RainsCarMod.Resources.customconsumables");
			if (stream == null)
			{
				MelonLogger.Error("[Custom_Consumables] ❌ Embedded AssetBundle not found.");
				return;
			}
			using MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			embeddedBundle = AssetBundle.LoadFromMemory(memoryStream.ToArray());
			if ((Object)(object)embeddedBundle == (Object)null)
			{
				MelonLogger.Error("[Custom_Consumables] ❌ Failed to load embedded AssetBundle.");
				return;
			}
			Object[] array = embeddedBundle.LoadAllAssets();
			foreach (Object val in array)
			{
				MelonLogger.Msg("\ud83d\udd38 Asset: " + val.name + " (Type: " + ((object)val).GetType().Name + ")");
				GameObject val2 = (GameObject)(object)((val is GameObject) ? val : null);
				if (val2 != null && !LoadedPrefabs.ContainsKey(((Object)val2).name))
				{
					LoadedPrefabs[((Object)val2).name] = val2;
					MelonLogger.Msg("✅ Loaded prefab: " + ((Object)val2).name);
				}
			}
		}

		[IteratorStateMachine(typeof(<InitAfterRegistryReady>d__4))]
		private IEnumerator InitAfterRegistryReady()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <InitAfterRegistryReady>d__4(0)
			{
				<>4__this = this
			};
		}

		public static T LoadAsset<T>(string assetName) where T : Object
		{
			AssetBundle? obj = embeddedBundle;
			return (obj != null) ? obj.LoadAsset<T>(assetName) : default(T);
		}
	}
	public static class RegistryManager
	{
		public static void RegisterItem<T>(string id, string prefabName, string definitionName) where T : Object
		{
			//IL_00a9: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Expected O, but got Unknown
			ScriptableObject obj = Custom_Consumables.LoadAsset<ScriptableObject>(definitionName);
			ItemDefinition val = (ItemDefinition)(object)((obj is ItemDefinition) ? obj : null);
			if ((Object)(object)val == (Object)null)
			{
				MelonLogger.Error("❌ Failed to load item definition: " + definitionName);
				return;
			}
			Registry instance = Singleton<Registry>.Instance;
			List<ItemRegister> list = typeof(Registry).GetField("ItemRegistry", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(instance) as List<ItemRegister>;
			if (list != null && list.Any((ItemRegister x) => x.ID == id))
			{
				MelonLogger.Warning("⚠\ufe0f Item '" + id + "' already registered.");
				return;
			}
			ItemRegister val2 = new ItemRegister
			{
				ID = id,
				Definition = val,
				AssetPath = prefabName
			};
			list?.Add(val2);
			typeof(Registry).GetMethod("AddToItemDictionary", BindingFlags.Instance | BindingFlags.NonPublic)?.Invoke(instance, new object[1] { val2 });
			MelonLogger.Msg("✅ Registered item '" + id + "'");
		}
	}
	public static class ShopManager
	{
		private static readonly Dictionary<string, List<ShopListing>> _customShopListings = new Dictionary<string, List<ShopListing>>();

		public static void AddItemToShop(string shopCode, string itemCode, float? price = null)
		{
			//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)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Expected O, but got Unknown
			Registry instance = Singleton<Registry>.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				MelonLogger.Error("❌ Registry singleton is not initialized.");
				return;
			}
			ItemRegister val = ((typeof(Registry).GetField("ItemRegistry", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(instance) is List<ItemRegister> source) ? ((IEnumerable<ItemRegister>)source).FirstOrDefault((Func<ItemRegister, bool>)((ItemRegister x) => x.ID == itemCode)) : null);
			if (val == null)
			{
				MelonLogger.Warning("⚠\ufe0f Could not find item '" + itemCode + "' to add to shop.");
				return;
			}
			ItemDefinition definition = val.Definition;
			StorableItemDefinition val2 = (StorableItemDefinition)(object)((definition is StorableItemDefinition) ? definition : null);
			if (val2 != null)
			{
				ShopListing val3 = new ShopListing
				{
					Item = val2,
					name = $"{((ItemDefinition)val2).Name} ({price ?? val2.BasePurchasePrice})"
				};
				if (price.HasValue)
				{
					typeof(ShopListing).GetField("OverridePrice", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(val3, true);
					typeof(ShopListing).GetField("OverriddenPrice", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(val3, price.Value);
				}
				if (!_customShopListings.ContainsKey(shopCode))
				{
					_customShopListings[shopCode] = new List<ShopListing>();
				}
				_customShopListings[shopCode].Add(val3);
				MelonLogger.Msg("\ud83d\uded2 Added '" + itemCode + "' to shop: " + shopCode);
			}
		}

		public static List<ShopListing> GetShopListings(string shopCode)
		{
			List<ShopListing> value;
			return _customShopListings.TryGetValue(shopCode, out value) ? value : null;
		}
	}
	[HarmonyPatch(typeof(ShopInterface))]
	public class ShopPatch
	{
		[HarmonyPatch("Awake")]
		[HarmonyPrefix]
		public static void InjectListings(ShopInterface __instance)
		{
			List<ShopListing> shopListings = ShopManager.GetShopListings(__instance.ShopCode);
			if (shopListings == null)
			{
				return;
			}
			foreach (ShopListing item in shopListings)
			{
				if (__instance.Listings.All((ShopListing x) => x.name != item.name))
				{
					__instance.Listings.Add(item);
				}
			}
		}
	}
	public static class ItemDatabase
	{
		public static readonly List<CustomShopItem> Items = new List<CustomShopItem>
		{
			new CustomShopItem("Ciggy", "Ciggy_equippable", "Ciggy_Weed", new Dictionary<string, float>
			{
				{ "gas_mart_central", 1f },
				{ "gas_mart_west", 1f },
				{ "dark_market_shop", 2f }
			}),
			new CustomShopItem("HorseDrink", "HorseDrink_Equippable", "HorseDrink", new Dictionary<string, float>
			{
				{ "gas_mart_central", 5f },
				{ "gas_mart_west", 5f },
				{ "dark_market_shop", 30f }
			}),
			new CustomShopItem("Coffee", "Coffee_equippable", "Coffee", new Dictionary<string, float>
			{
				{ "gas_mart_central", 1f },
				{ "gas_mart_west", 1f },
				{ "dark_market_shop", 5f }
			})
		};
	}
	public class CustomShopItem
	{
		public string ID { get; }

		public string PrefabName { get; }

		public string AssetName { get; }

		public Dictionary<string, float> ShopPrices { get; }

		public CustomShopItem(string id, string prefab, string asset, Dictionary<string, float> prices)
		{
			ID = id;
			PrefabName = prefab;
			AssetName = asset;
			ShopPrices = prices;
		}
	}
}
namespace Custom_Consumables.Logging
{
	public static class Log
	{
		public static void LogInfo(string message)
		{
			Melon<Core>.Logger.Msg(message);
		}

		public static void LogWarning(string message)
		{
			Melon<Core>.Logger.Warning(message);
		}

		public static void LogError(string message)
		{
			Melon<Core>.Logger.Error(message);
		}

		public static void LogFatal(string message)
		{
			Melon<Core>.Logger.BigError(message);
		}
	}
}
namespace RainsCustomConsumables
{
	public class Core : MelonMod
	{
		public override void OnInitializeMelon()
		{
			Log.LogInfo("Initializing RainsCustomConsumables...");
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}