2022-10-02 18:31:08 +08:00
|
|
|
|
using System.Collections.Generic;
|
2020-03-26 15:01:42 +08:00
|
|
|
|
|
|
|
|
|
|
namespace MinecraftClient.Inventory
|
|
|
|
|
|
{
|
2020-03-28 15:01:08 +01:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Represents a Minecraft inventory (player inventory, chest, etc.)
|
|
|
|
|
|
/// </summary>
|
2020-03-26 15:01:42 +08:00
|
|
|
|
public class Container
|
|
|
|
|
|
{
|
2020-03-28 15:01:08 +01:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// ID of the container on the server
|
|
|
|
|
|
/// </summary>
|
2020-03-26 15:01:42 +08:00
|
|
|
|
public int ID;
|
2020-03-28 15:01:08 +01:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Type of container
|
|
|
|
|
|
/// </summary>
|
2020-03-26 15:01:42 +08:00
|
|
|
|
public ContainerType Type;
|
2020-03-28 15:01:08 +01:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// title of container
|
|
|
|
|
|
/// </summary>
|
2022-10-02 18:31:08 +08:00
|
|
|
|
public string? Title;
|
2020-03-28 15:01:08 +01:00
|
|
|
|
|
2022-07-01 18:59:58 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// state of container
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public int StateID;
|
|
|
|
|
|
|
2020-03-28 15:01:08 +01:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Container Items
|
|
|
|
|
|
/// </summary>
|
2020-03-26 15:01:42 +08:00
|
|
|
|
public Dictionary<int, Item> Items;
|
2020-03-28 15:01:08 +01:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Create an empty container with ID, Type and Title
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="id">Container ID</param>
|
|
|
|
|
|
/// <param name="type">Container Type</param>
|
|
|
|
|
|
/// <param name="title">Container Title</param>
|
2020-03-26 15:01:42 +08:00
|
|
|
|
public Container(int id, ContainerType type, string title)
|
|
|
|
|
|
{
|
|
|
|
|
|
ID = id;
|
|
|
|
|
|
Type = type;
|
|
|
|
|
|
Title = title;
|
2020-03-28 15:01:08 +01:00
|
|
|
|
Items = new Dictionary<int, Item>();
|
2020-03-26 15:01:42 +08:00
|
|
|
|
}
|
2020-03-28 15:01:08 +01:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Create a container with ID, Type, Title and Items
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="id">Container ID</param>
|
|
|
|
|
|
/// <param name="type">Container Type</param>
|
|
|
|
|
|
/// <param name="title">Container Title</param>
|
|
|
|
|
|
/// <param name="items">Container Items (key: slot ID, value: item info)</param>
|
2022-10-02 18:31:08 +08:00
|
|
|
|
public Container(int id, ContainerType type, string? title, Dictionary<int, Item> items)
|
2020-03-26 15:01:42 +08:00
|
|
|
|
{
|
|
|
|
|
|
ID = id;
|
|
|
|
|
|
Type = type;
|
|
|
|
|
|
Title = title;
|
|
|
|
|
|
Items = items;
|
|
|
|
|
|
}
|
2020-03-28 15:01:08 +01:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Create an empty container with ID, Type and Title
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="id">Container ID</param>
|
|
|
|
|
|
/// <param name="type">Container Type</param>
|
|
|
|
|
|
/// <param name="title">Container title</param>
|
2020-03-26 17:15:00 +08:00
|
|
|
|
public Container(int id, ContainerTypeOld type, string title)
|
2020-03-26 15:01:42 +08:00
|
|
|
|
{
|
|
|
|
|
|
ID = id;
|
|
|
|
|
|
Title = title;
|
2020-03-26 17:15:00 +08:00
|
|
|
|
Type = ConvertType.ToNew(type);
|
2020-03-28 15:01:08 +01:00
|
|
|
|
Items = new Dictionary<int, Item>();
|
2020-03-26 15:01:42 +08:00
|
|
|
|
}
|
2020-03-28 15:01:08 +01:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Create an empty container with ID, Type and Title
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="id">Container ID</param>
|
|
|
|
|
|
/// <param name="typeID">Container Type</param>
|
|
|
|
|
|
/// <param name="title">Container Title</param>
|
2020-03-26 15:01:42 +08:00
|
|
|
|
public Container(int id, int typeID, string title)
|
|
|
|
|
|
{
|
|
|
|
|
|
ID = id;
|
|
|
|
|
|
Type = GetContainerType(typeID);
|
|
|
|
|
|
Title = title;
|
2020-03-28 15:01:08 +01:00
|
|
|
|
Items = new Dictionary<int, Item>();
|
2020-03-26 15:01:42 +08:00
|
|
|
|
}
|
2020-03-28 15:01:08 +01:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Create an empty container with Type
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="type">Container Type</param>
|
2020-03-26 15:01:42 +08:00
|
|
|
|
public Container(ContainerType type)
|
|
|
|
|
|
{
|
2020-03-28 15:01:08 +01:00
|
|
|
|
ID = -1;
|
2020-03-26 15:01:42 +08:00
|
|
|
|
Type = type;
|
2020-03-28 15:01:08 +01:00
|
|
|
|
Title = null;
|
|
|
|
|
|
Items = new Dictionary<int, Item>();
|
2020-03-26 15:01:42 +08:00
|
|
|
|
}
|
2020-03-28 15:01:08 +01:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Create an empty container with T^ype and Items
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="type">Container Type</param>
|
|
|
|
|
|
/// <param name="items">Container Items (key: slot ID, value: item info)</param>
|
2020-03-26 15:01:42 +08:00
|
|
|
|
public Container(ContainerType type, Dictionary<int, Item> items)
|
|
|
|
|
|
{
|
2020-03-28 15:01:08 +01:00
|
|
|
|
ID = -1;
|
2020-03-26 15:01:42 +08:00
|
|
|
|
Type = type;
|
2020-03-28 15:01:08 +01:00
|
|
|
|
Title = null;
|
2020-03-26 15:01:42 +08:00
|
|
|
|
Items = items;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-03-28 15:01:08 +01:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Get container type from Type ID
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="typeID">Container Type ID</param>
|
|
|
|
|
|
/// <returns>Container Type</returns>
|
2020-03-26 15:01:42 +08:00
|
|
|
|
public static ContainerType GetContainerType(int typeID)
|
|
|
|
|
|
{
|
|
|
|
|
|
// https://wiki.vg/Inventory didn't state the inventory ID, assume that list start with 0
|
2022-10-02 18:31:08 +08:00
|
|
|
|
return typeID switch
|
2020-03-26 15:01:42 +08:00
|
|
|
|
{
|
2022-10-02 18:31:08 +08:00
|
|
|
|
0 => ContainerType.Generic_9x1,
|
|
|
|
|
|
1 => ContainerType.Generic_9x2,
|
|
|
|
|
|
2 => ContainerType.Generic_9x3,
|
|
|
|
|
|
3 => ContainerType.Generic_9x4,
|
|
|
|
|
|
4 => ContainerType.Generic_9x5,
|
|
|
|
|
|
5 => ContainerType.Generic_9x6,
|
|
|
|
|
|
6 => ContainerType.Generic_3x3,
|
|
|
|
|
|
7 => ContainerType.Anvil,
|
|
|
|
|
|
8 => ContainerType.Beacon,
|
|
|
|
|
|
9 => ContainerType.BlastFurnace,
|
|
|
|
|
|
10 => ContainerType.BrewingStand,
|
|
|
|
|
|
11 => ContainerType.Crafting,
|
|
|
|
|
|
12 => ContainerType.Enchantment,
|
|
|
|
|
|
13 => ContainerType.Furnace,
|
|
|
|
|
|
14 => ContainerType.Grindstone,
|
|
|
|
|
|
15 => ContainerType.Hopper,
|
|
|
|
|
|
16 => ContainerType.Lectern,
|
|
|
|
|
|
17 => ContainerType.Loom,
|
|
|
|
|
|
18 => ContainerType.Merchant,
|
|
|
|
|
|
19 => ContainerType.ShulkerBox,
|
|
|
|
|
|
20 => ContainerType.Smoker,
|
|
|
|
|
|
21 => ContainerType.Cartography,
|
|
|
|
|
|
22 => ContainerType.Stonecutter,
|
|
|
|
|
|
_ => ContainerType.Unknown,
|
|
|
|
|
|
};
|
2020-03-26 15:01:42 +08:00
|
|
|
|
}
|
2020-07-09 22:21:39 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Search an item in the container
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="itemType">The item to search</param>
|
|
|
|
|
|
/// <returns>An array of slot ID</returns>
|
|
|
|
|
|
public int[] SearchItem(ItemType itemType)
|
|
|
|
|
|
{
|
2022-10-02 18:31:08 +08:00
|
|
|
|
List<int> result = new();
|
2020-07-09 22:21:39 +08:00
|
|
|
|
if (Items != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var item in Items)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (item.Value.Type == itemType)
|
|
|
|
|
|
result.Add(item.Key);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return result.ToArray();
|
|
|
|
|
|
}
|
2020-07-21 16:22:45 +08:00
|
|
|
|
|
2020-07-23 20:32:02 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// List empty slots in the container
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns>An array of slot ID</returns>
|
|
|
|
|
|
/// <remarks>Also depending on the container type, some empty slots cannot be used e.g. armor slots. This might cause issues.</remarks>
|
|
|
|
|
|
public int[] GetEmpytSlots()
|
2020-07-21 16:22:45 +08:00
|
|
|
|
{
|
2022-10-02 18:31:08 +08:00
|
|
|
|
List<int> result = new();
|
2020-07-21 16:22:45 +08:00
|
|
|
|
for (int i = 0; i < Type.SlotCount(); i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
result.Add(i);
|
|
|
|
|
|
}
|
|
|
|
|
|
foreach (var item in Items)
|
|
|
|
|
|
{
|
|
|
|
|
|
result.Remove(item.Key);
|
|
|
|
|
|
}
|
|
|
|
|
|
return result.ToArray();
|
|
|
|
|
|
}
|
2021-05-11 14:02:47 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Check the given slot ID is a hotbar slot and give the hotbar number
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="slotId">The slot ID to check</param>
|
|
|
|
|
|
/// <param name="hotbar">Zero-based, 0-8. -1 if not a hotbar</param>
|
|
|
|
|
|
/// <returns>True if given slot ID is a hotbar slot</returns>
|
|
|
|
|
|
public bool IsHotbar(int slotId, out int hotbar)
|
|
|
|
|
|
{
|
|
|
|
|
|
int hotbarStart = Type.SlotCount() - 9;
|
|
|
|
|
|
// Remove offhand slot
|
|
|
|
|
|
if (Type == ContainerType.PlayerInventory)
|
|
|
|
|
|
hotbarStart--;
|
|
|
|
|
|
if ((slotId >= hotbarStart) && (slotId <= hotbarStart + 9))
|
|
|
|
|
|
{
|
|
|
|
|
|
hotbar = slotId - hotbarStart;
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
hotbar = -1;
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2020-03-26 15:01:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|