namespace Minecraft.Server.FourKit.Inventory; using Minecraft.Server.FourKit.Entity; /// /// Represents a view linking two inventories and a single player /// (whose inventory may or may not be one of the two). /// public class InventoryView { /// /// Represents the raw slot ID for clicks outside the inventory window. /// public static readonly int OUTSIDE = -999; private readonly Inventory _topInventory; private readonly Inventory _bottomInventory; private readonly HumanEntity _player; private readonly InventoryType _type; /// /// Creates a new InventoryView linking two inventories and a player. /// /// The upper inventory. /// The lower inventory. /// The player viewing. /// The inventory type. public InventoryView(Inventory topInventory, Inventory bottomInventory, HumanEntity player, InventoryType type) { _topInventory = topInventory; _bottomInventory = bottomInventory; _player = player; _type = type; } /// /// Get the upper inventory involved in this transaction. /// /// The inventory. public virtual Inventory getTopInventory() => _topInventory; /// /// Get the lower inventory involved in this transaction. /// /// The inventory. public virtual Inventory getBottomInventory() => _bottomInventory; /// /// Get the player viewing. /// /// The player. public virtual HumanEntity getPlayer() => _player; /// /// Determine the type of inventory involved in the transaction. This indicates /// the window style being shown. It will never return PLAYER, since that is /// common to all windows. /// /// The inventory type. public virtual InventoryType getType() => _type; /// /// Sets one item in this inventory view by its raw slot ID. /// /// /// If slot ID -999 is chosen, it may be expected that the item is dropped /// on the ground. This is not required behaviour, however. /// /// The raw slot ID. /// The new item to put in the slot, or null to clear it. public void setItem(int slot, ItemStack? item) { if (slot == OUTSIDE) return; int topSize = _topInventory.getSize(); if (slot < topSize) _topInventory.setItem(slot, item); else _bottomInventory.setItem(slot - topSize, item); } /// /// Gets one item in this inventory view by its raw slot ID. /// /// The raw slot ID. /// The item currently in the slot. public ItemStack? getItem(int slot) { if (slot == OUTSIDE) return null; int topSize = _topInventory.getSize(); if (slot < topSize) return _topInventory.getItem(slot); return _bottomInventory.getItem(slot - topSize); } /// /// Sets the item on the cursor of one of the viewing players. /// /// The item to put on the cursor, or null to remove it. public void setCursor(ItemStack? item) { _player.setItemOnCursor(item); } /// /// Get the item on the cursor of one of the viewing players. /// /// The item on the player's cursor, or null if they aren't holding one. public ItemStack? getCursor() { return _player.getItemOnCursor(); } /// /// Converts a raw slot ID into its local slot ID into whichever of the two /// inventories the slot points to. /// /// The raw slot ID. /// The converted slot ID. public int convertSlot(int rawSlot) { int topSize = _topInventory.getSize(); if (rawSlot < topSize) return rawSlot; return rawSlot - topSize; } /// /// Closes the inventory view. /// public void close() { } /// /// Check the total number of slots in this view, combining the upper /// and lower inventories. /// /// The total size. public int countSlots() { return _topInventory.getSize() + _bottomInventory.getSize(); } /// /// Sets an extra property of this inventory if supported by that inventory, /// for example the state of a progress bar. /// /// The window property to update. /// The new value for the window property. /// true if the property was updated successfully. public bool setProperty(Property prop, int value) { return false; } /// /// Get the title of this inventory window. /// /// The title. public string getTitle() { return _topInventory.getTitle(); } /// /// Represents various extra properties of certain inventory windows. /// public enum Property { /// The progress of the down-pointing arrow in a brewing inventory. BREW_TIME, /// The progress of the flame in a furnace inventory. BURN_TIME, /// The progress of the right-pointing arrow in a furnace inventory. COOK_TIME, /// In an enchanting inventory, the top button's experience level value. ENCHANT_BUTTON1, /// In an enchanting inventory, the middle button's experience level value. ENCHANT_BUTTON2, /// In an enchanting inventory, the bottom button's experience level value. ENCHANT_BUTTON3, /// How many total ticks the current fuel should last. TICKS_FOR_CURRENT_FUEL } } /// /// Extension methods for . /// public static class InventoryViewPropertyExtensions { /// /// Gets the that this property belongs to. /// /// The property. /// The inventory type. public static InventoryType getType(this InventoryView.Property prop) => prop switch { InventoryView.Property.BREW_TIME => InventoryType.BREWING, InventoryView.Property.BURN_TIME => InventoryType.FURNACE, InventoryView.Property.COOK_TIME => InventoryType.FURNACE, InventoryView.Property.ENCHANT_BUTTON1 => InventoryType.ENCHANTING, InventoryView.Property.ENCHANT_BUTTON2 => InventoryType.ENCHANTING, InventoryView.Property.ENCHANT_BUTTON3 => InventoryType.ENCHANTING, InventoryView.Property.TICKS_FOR_CURRENT_FUEL => InventoryType.FURNACE, _ => InventoryType.CHEST, }; /// /// Gets the window-property id for this . /// /// The property. /// The id. public static int getId(this InventoryView.Property prop) => prop switch { InventoryView.Property.BREW_TIME => 0, InventoryView.Property.BURN_TIME => 0, InventoryView.Property.COOK_TIME => 2, InventoryView.Property.ENCHANT_BUTTON1 => 0, InventoryView.Property.ENCHANT_BUTTON2 => 1, InventoryView.Property.ENCHANT_BUTTON3 => 2, InventoryView.Property.TICKS_FOR_CURRENT_FUEL => 1, _ => -1, }; }