using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using InventoryFramework; using MelonLoader; 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: MelonInfo(typeof(Core), "InventoryFramework", "1.0.0", "gameknight963", null)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("InventoryFramework")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+5e9efc213261b9d7be313346e587c791a024c255")] [assembly: AssemblyProduct("InventoryFramework")] [assembly: AssemblyTitle("InventoryFramework")] [assembly: NeutralResourcesLanguage("en-US")] [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 InventoryFramework { public class Core : MelonMod { internal static Instance Logger; public override void OnInitializeMelon() { Logger = ((MelonBase)this).LoggerInstance; } public override void OnUpdate() { if (Input.GetMouseButtonDown(0)) { InventoryManager.Instance.UseItem(); } if (Input.GetMouseButtonDown(1)) { InventoryManager.Instance.AltUseItem(); } if (Input.anyKeyDown) { InventoryManager.Instance.KeyDown(); } } } public class Inventory { private readonly List _items = new List(); public IReadOnlyList Items => _items; public event Action? OnChanged; public event Action? OnCleared; public event Action? OnItemAdded; public event Action? OnItemRemoved; public event Action? OnItemQuantityChanged; public void AddItem(string id, int quantity = 1) { string id2 = id; ItemDefinition item = InventoryManager.Instance.GetItem(id2); InventoryItem inventoryItem = _items.FirstOrDefault((InventoryItem i) => i.Definition.Id == id2); if (inventoryItem != null) { inventoryItem.Quantity += quantity; this.OnItemQuantityChanged?.Invoke(inventoryItem); } else { InventoryItem inventoryItem2 = new InventoryItem(item, quantity); _items.Add(inventoryItem2); this.OnItemAdded?.Invoke(inventoryItem2); } this.OnChanged?.Invoke(); } public void RemoveItem(string id, int quantity = 1) { string id2 = id; InventoryItem inventoryItem = _items.FirstOrDefault((InventoryItem i) => i.Definition.Id == id2) ?? throw new InvalidOperationException("Item '" + id2 + "' not found in inventory."); inventoryItem.Quantity = Math.Max(0, inventoryItem.Quantity - quantity); if (inventoryItem.Quantity <= 0) { _items.Remove(inventoryItem); this.OnItemRemoved?.Invoke(inventoryItem); } else { this.OnItemQuantityChanged?.Invoke(inventoryItem); } this.OnChanged?.Invoke(); } public InventoryItem GetItem(string id) { string id2 = id; return _items.FirstOrDefault((InventoryItem i) => i.Definition.Id == id2) ?? throw new InvalidOperationException("Item '" + id2 + "' not found in inventory."); } public bool HasItem(string id, int quantity = 1) { string id2 = id; InventoryItem inventoryItem = _items.FirstOrDefault((InventoryItem i) => i.Definition.Id == id2); return inventoryItem != null && inventoryItem.Quantity >= quantity; } public void Clear() { this.OnCleared?.Invoke(); _items.Clear(); this.OnChanged?.Invoke(); } } public class InventoryItem { public ItemDefinition Definition { get; init; } public int Quantity { get; set; } public InventoryItem(ItemDefinition definition, int quantity) { Definition = definition; Quantity = quantity; } } public class InventoryManager { private Dictionary _registry = new Dictionary(); public static InventoryManager Instance { get; } = new InventoryManager(); public Inventory PlayerInventory { get; } = new Inventory(); public InventoryItem? SelectedItem { get; private set; } public IReadOnlyDictionary Registry => _registry; public event Action? OnItemSelected; public event Action? OnItemUsed; public event Action? OnItemAltUsed; public event Action? OnInventoryKeyDown; public event Action? OnItemRegistered; public void SelectItem(InventoryItem? item) { SelectedItem = item; this.OnItemSelected?.Invoke(item); } internal void UseItem() { this.OnItemUsed?.Invoke(SelectedItem); } internal void AltUseItem() { this.OnItemAltUsed?.Invoke(SelectedItem); } internal void KeyDown() { this.OnInventoryKeyDown?.Invoke(SelectedItem); } public void RegisterItem(ItemDefinition def) { if (_registry.ContainsKey(def.Id)) { throw new InvalidOperationException("Item '" + def.Id + "' already registered."); } _registry[def.Id] = def; InventoryLogger.Msg("Item registered: " + def.Id); this.OnItemRegistered?.Invoke(def); } public ItemDefinition GetItem(string id) { if (!_registry.TryGetValue(id, out ItemDefinition value)) { throw new InvalidOperationException("Item '" + id + "' not registered."); } return value; } } public class ItemDefinition { public string Id { get; private set; } public Sprite? Image { get; private set; } public string Name { get; private set; } public ItemDefinition(string id, string name, Sprite? image = null) { Id = id; Name = name; Image = image; } } internal class InventoryLogger { internal static void Msg(string msg) { Core.Logger.Msg(msg); } } }