diff --git a/TrueCraft.API/Windows/IWindow.cs b/TrueCraft.API/Windows/IWindow.cs index 371f96f..0f62225 100644 --- a/TrueCraft.API/Windows/IWindow.cs +++ b/TrueCraft.API/Windows/IWindow.cs @@ -16,6 +16,7 @@ namespace TrueCraft.API.Windows int MinecraftWasWrittenByFuckingIdiotsLength { get; } ItemStack this[int index] { get; set; } bool Empty { get; } + short[] ReadOnlySlots { get; } /// /// Call this to "shift+click" an item from one area to another. diff --git a/TrueCraft.Client/Modules/WindowModule.cs b/TrueCraft.Client/Modules/WindowModule.cs index baafb64..939de82 100644 --- a/TrueCraft.Client/Modules/WindowModule.cs +++ b/TrueCraft.Client/Modules/WindowModule.cs @@ -138,69 +138,17 @@ namespace TrueCraft.Client.Modules var packet = new ClickWindowPacket(id, SelectedSlot, e.Button == MouseButton.Right, 0, Keyboard.GetState().IsKeyDown(Keys.LeftShift) || Keyboard.GetState().IsKeyDown(Keys.RightShift), item.ID, item.Count, item.Metadata); - // Special cases (TODO: make this more abstract? Read-only slots?) - if ((Game.Client.CurrentWindow is InventoryWindow && SelectedSlot == InventoryWindow.CraftingOutputIndex) - || (Game.Client.CurrentWindow is CraftingBenchWindow && SelectedSlot == CraftingBenchWindow.CraftingOutputIndex) - || (Game.Client.CurrentWindow is FurnaceWindow && SelectedSlot == FurnaceWindow.OutputIndex)) + if (packet.SlotIndex == -999) { - if (HeldItem.Empty) - HeldItem = (ItemStack)item.Clone(); - else - { - if (item.CanMerge(HeldItem)) - { - var held = HeldItem; - held.Count += item.Count; - HeldItem = held; - } - } + // Special case (throwing item) TODO } else { - if (HeldItem.Empty) // See InteractionHandler.cs (in the server) for an explanation - { - if (!packet.Shift) - { - if (packet.RightClick) - { - var held = (ItemStack)item.Clone(); - held.Count = (sbyte)((held.Count / 2) + (item.Count % 2)); - HeldItem = held; - } - else - HeldItem = (ItemStack)item.Clone(); - } - } - else - { - if (item.Empty) - { - if (packet.RightClick) - { - var held = HeldItem; - held.Count--; - HeldItem = held; - } - else - HeldItem = ItemStack.EmptyStack; - } - else - { - if (item.CanMerge(HeldItem)) - { - if (packet.RightClick) - { - var held = HeldItem; - held.Count--; - HeldItem = held; - } - else - HeldItem = ItemStack.EmptyStack; - } - else - HeldItem = (ItemStack)item.Clone(); - } - } + var backup = Game.Client.CurrentWindow.GetSlots(); + var staging = (ItemStack)HeldItem.Clone(); + Window.HandleClickPacket(packet, Game.Client.CurrentWindow, ref staging); // just for updating staging + HeldItem = staging; + Game.Client.CurrentWindow.SetSlots(backup); } Game.Client.QueuePacket(packet); return true; diff --git a/TrueCraft.Client/TrueCraftGame.cs b/TrueCraft.Client/TrueCraftGame.cs index 86f138c..c4eecda 100644 --- a/TrueCraft.Client/TrueCraftGame.cs +++ b/TrueCraft.Client/TrueCraftGame.cs @@ -140,6 +140,7 @@ namespace TrueCraft.Client GraphicalModules.Add(DebugInfoModule); InputModules.Add(windowModule); + InputModules.Add(DebugInfoModule); InputModules.Add(ChatModule); InputModules.Add(new HUDModule(this, Pixel)); InputModules.Add(new PlayerControlModule(this)); diff --git a/TrueCraft.Core/Windows/CraftingBenchWindow.cs b/TrueCraft.Core/Windows/CraftingBenchWindow.cs index fff87e0..884e0ac 100644 --- a/TrueCraft.Core/Windows/CraftingBenchWindow.cs +++ b/TrueCraft.Core/Windows/CraftingBenchWindow.cs @@ -40,10 +40,10 @@ namespace TrueCraft.Core.Windows private bool Copying { get; set; } - public const int HotbarIndex = 37; - public const int CraftingGridIndex = 1; - public const int CraftingOutputIndex = 0; - public const int MainIndex = 10; + public const short HotbarIndex = 37; + public const short CraftingGridIndex = 1; + public const short CraftingOutputIndex = 0; + public const short MainIndex = 10; public override string Name { @@ -61,6 +61,14 @@ namespace TrueCraft.Core.Windows } } + public override short[] ReadOnlySlots + { + get + { + return new[] { CraftingOutputIndex }; + } + } + public override IWindowArea[] WindowAreas { get; protected set; } #region Properties diff --git a/TrueCraft.Core/Windows/FurnaceWindow.cs b/TrueCraft.Core/Windows/FurnaceWindow.cs index 537442f..ef9f07a 100644 --- a/TrueCraft.Core/Windows/FurnaceWindow.cs +++ b/TrueCraft.Core/Windows/FurnaceWindow.cs @@ -50,11 +50,11 @@ namespace TrueCraft.Core.Windows private bool Copying { get; set; } - public const int IngredientIndex = 0; - public const int FuelIndex = 1; - public const int OutputIndex = 2; - public const int MainIndex = 3; - public const int HotbarIndex = 30; + public const short IngredientIndex = 0; + public const short FuelIndex = 1; + public const short OutputIndex = 2; + public const short MainIndex = 3; + public const short HotbarIndex = 30; public override string Name { @@ -72,6 +72,14 @@ namespace TrueCraft.Core.Windows } } + public override short[] ReadOnlySlots + { + get + { + return new[] { OutputIndex }; + } + } + public override IWindowArea[] WindowAreas { get; protected set; } public IWindowArea Ingredient diff --git a/TrueCraft.Core/Windows/InventoryWindow.cs b/TrueCraft.Core/Windows/InventoryWindow.cs index 6fa4aa9..646bcc2 100644 --- a/TrueCraft.Core/Windows/InventoryWindow.cs +++ b/TrueCraft.Core/Windows/InventoryWindow.cs @@ -26,11 +26,11 @@ namespace TrueCraft.Core.Windows #region Variables - public const int HotbarIndex = 36; - public const int CraftingGridIndex = 1; - public const int CraftingOutputIndex = 0; - public const int ArmorIndex = 5; - public const int MainIndex = 9; + public const short HotbarIndex = 36; + public const short CraftingGridIndex = 1; + public const short CraftingOutputIndex = 0; + public const short ArmorIndex = 5; + public const short MainIndex = 9; public override string Name { @@ -48,6 +48,14 @@ namespace TrueCraft.Core.Windows } } + public override short[] ReadOnlySlots + { + get + { + return new[] { CraftingOutputIndex }; + } + } + public override IWindowArea[] WindowAreas { get; protected set; } #region Properties diff --git a/TrueCraft.Core/Windows/Window.cs b/TrueCraft.Core/Windows/Window.cs index 7192fa1..4b7b26d 100644 --- a/TrueCraft.Core/Windows/Window.cs +++ b/TrueCraft.Core/Windows/Window.cs @@ -5,6 +5,7 @@ using System.Text; using TrueCraft.API.Windows; using TrueCraft.API; using TrueCraft.API.Networking; +using TrueCraft.Core.Networking.Packets; namespace TrueCraft.Core.Windows { @@ -161,5 +162,94 @@ namespace TrueCraft.Core.Windows Client = null; IsDisposed = true; } + + public virtual short[] ReadOnlySlots + { + get { return new short[0]; } + } + + public static void HandleClickPacket(ClickWindowPacket packet, IWindow window, ref ItemStack itemStaging) + { + if (packet.SlotIndex >= window.Length || packet.SlotIndex < 0) + return; + var existing = window[packet.SlotIndex]; + if (window.ReadOnlySlots.Contains(packet.SlotIndex)) + { + if (itemStaging.ID == existing.ID || itemStaging.Empty) + { + if (itemStaging.Empty) + itemStaging = existing; + else + itemStaging.Count += existing.Count; + window[packet.SlotIndex] = ItemStack.EmptyStack; + } + return; + } + if (itemStaging.Empty) // Picking up something + { + if (packet.Shift) + { + window.MoveToAlternateArea(packet.SlotIndex); + } + else + { + if (packet.RightClick) + { + sbyte mod = (sbyte)(existing.Count % 2); + existing.Count /= 2; + itemStaging = existing; + itemStaging.Count += mod; + window[packet.SlotIndex] = existing; + } + else + { + itemStaging = window[packet.SlotIndex]; + window[packet.SlotIndex] = ItemStack.EmptyStack; + } + } + } + else // Setting something down + { + if (existing.Empty) // Replace empty slot + { + if (packet.RightClick) + { + var newItem = (ItemStack)itemStaging.Clone(); + newItem.Count = 1; + itemStaging.Count--; + window[packet.SlotIndex] = newItem; + } + else + { + window[packet.SlotIndex] = itemStaging; + itemStaging = ItemStack.EmptyStack; + } + } + else + { + if (existing.CanMerge(itemStaging)) // Merge items + { + // TODO: Consider the maximum stack size + if (packet.RightClick) + { + existing.Count++; + itemStaging.Count--; + window[packet.SlotIndex] = existing; + } + else + { + existing.Count += itemStaging.Count; + window[packet.SlotIndex] = existing; + itemStaging = ItemStack.EmptyStack; + } + } + else // Swap items + { + window[packet.SlotIndex] = itemStaging; + itemStaging = existing; + } + } + } + } } } diff --git a/TrueCraft/Handlers/InteractionHandlers.cs b/TrueCraft/Handlers/InteractionHandlers.cs index 759343b..dacb393 100644 --- a/TrueCraft/Handlers/InteractionHandlers.cs +++ b/TrueCraft/Handlers/InteractionHandlers.cs @@ -201,94 +201,11 @@ namespace TrueCraft.Handlers server.GetEntityManagerForWorld(client.World).SpawnEntity(item); return; } + var staging = (ItemStack)client.ItemStaging.Clone(); + Window.HandleClickPacket(packet, window, ref staging); + client.ItemStaging = staging; if (packet.SlotIndex >= window.Length || packet.SlotIndex < 0) return; - ItemStack existing = window[packet.SlotIndex]; - ItemStack held = client.ItemStaging; - if (packet.SlotIndex == InventoryWindow.CraftingOutputIndex - && (window is InventoryWindow || window is CraftingBenchWindow)) - { - // Stupid special case because Minecraft was written by morons - if (held.ID == existing.ID || held.Empty) - { - if (held.Empty) - held = existing; - else - held.Count += existing.Count; - client.ItemStaging = held; - window[packet.SlotIndex] = ItemStack.EmptyStack; - } - client.QueuePacket(new WindowItemsPacket(packet.WindowID, window.GetSlots())); - return; - } - if (client.ItemStaging.Empty) // Picking up something - { - if (packet.Shift) - { - window.MoveToAlternateArea(packet.SlotIndex); - } - else - { - if (packet.RightClick) - { - sbyte mod = (sbyte)(existing.Count % 2); - existing.Count /= 2; - held = existing; - held.Count += mod; - client.ItemStaging = held; - window[packet.SlotIndex] = existing; - } - else - { - client.ItemStaging = window[packet.SlotIndex]; - window[packet.SlotIndex] = ItemStack.EmptyStack; - } - } - } - else // Setting something down - { - if (existing.Empty) // Replace empty slot - { - if (packet.RightClick) - { - var newItem = (ItemStack)client.ItemStaging.Clone(); - newItem.Count = 1; - held.Count--; - window[packet.SlotIndex] = newItem; - client.ItemStaging = held; - } - else - { - window[packet.SlotIndex] = client.ItemStaging; - client.ItemStaging = ItemStack.EmptyStack; - } - } - else - { - if (existing.CanMerge(client.ItemStaging)) // Merge items - { - // TODO: Consider the maximum stack size - if (packet.RightClick) - { - existing.Count++; - held.Count--; - window[packet.SlotIndex] = existing; - client.ItemStaging = held; - } - else - { - existing.Count += client.ItemStaging.Count; - window[packet.SlotIndex] = existing; - client.ItemStaging = ItemStack.EmptyStack; - } - } - else // Swap items - { - window[packet.SlotIndex] = client.ItemStaging; - client.ItemStaging = existing; - } - } - } client.QueuePacket(new WindowItemsPacket(packet.WindowID, window.GetSlots())); }