Unify server and client implementations of windows
This commit is contained in:
parent
77f000ad2b
commit
0c6a973a69
@ -16,6 +16,7 @@ namespace TrueCraft.API.Windows
|
|||||||
int MinecraftWasWrittenByFuckingIdiotsLength { get; }
|
int MinecraftWasWrittenByFuckingIdiotsLength { get; }
|
||||||
ItemStack this[int index] { get; set; }
|
ItemStack this[int index] { get; set; }
|
||||||
bool Empty { get; }
|
bool Empty { get; }
|
||||||
|
short[] ReadOnlySlots { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Call this to "shift+click" an item from one area to another.
|
/// Call this to "shift+click" an item from one area to another.
|
||||||
|
@ -138,69 +138,17 @@ namespace TrueCraft.Client.Modules
|
|||||||
var packet = new ClickWindowPacket(id, SelectedSlot, e.Button == MouseButton.Right,
|
var packet = new ClickWindowPacket(id, SelectedSlot, e.Button == MouseButton.Right,
|
||||||
0, Keyboard.GetState().IsKeyDown(Keys.LeftShift) || Keyboard.GetState().IsKeyDown(Keys.RightShift),
|
0, Keyboard.GetState().IsKeyDown(Keys.LeftShift) || Keyboard.GetState().IsKeyDown(Keys.RightShift),
|
||||||
item.ID, item.Count, item.Metadata);
|
item.ID, item.Count, item.Metadata);
|
||||||
// Special cases (TODO: make this more abstract? Read-only slots?)
|
if (packet.SlotIndex == -999)
|
||||||
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 (HeldItem.Empty)
|
// Special case (throwing item) TODO
|
||||||
HeldItem = (ItemStack)item.Clone();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (item.CanMerge(HeldItem))
|
|
||||||
{
|
|
||||||
var held = HeldItem;
|
|
||||||
held.Count += item.Count;
|
|
||||||
HeldItem = held;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (HeldItem.Empty) // See InteractionHandler.cs (in the server) for an explanation
|
var backup = Game.Client.CurrentWindow.GetSlots();
|
||||||
{
|
var staging = (ItemStack)HeldItem.Clone();
|
||||||
if (!packet.Shift)
|
Window.HandleClickPacket(packet, Game.Client.CurrentWindow, ref staging); // just for updating staging
|
||||||
{
|
HeldItem = staging;
|
||||||
if (packet.RightClick)
|
Game.Client.CurrentWindow.SetSlots(backup);
|
||||||
{
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Game.Client.QueuePacket(packet);
|
Game.Client.QueuePacket(packet);
|
||||||
return true;
|
return true;
|
||||||
|
@ -140,6 +140,7 @@ namespace TrueCraft.Client
|
|||||||
GraphicalModules.Add(DebugInfoModule);
|
GraphicalModules.Add(DebugInfoModule);
|
||||||
|
|
||||||
InputModules.Add(windowModule);
|
InputModules.Add(windowModule);
|
||||||
|
InputModules.Add(DebugInfoModule);
|
||||||
InputModules.Add(ChatModule);
|
InputModules.Add(ChatModule);
|
||||||
InputModules.Add(new HUDModule(this, Pixel));
|
InputModules.Add(new HUDModule(this, Pixel));
|
||||||
InputModules.Add(new PlayerControlModule(this));
|
InputModules.Add(new PlayerControlModule(this));
|
||||||
|
@ -40,10 +40,10 @@ namespace TrueCraft.Core.Windows
|
|||||||
|
|
||||||
private bool Copying { get; set; }
|
private bool Copying { get; set; }
|
||||||
|
|
||||||
public const int HotbarIndex = 37;
|
public const short HotbarIndex = 37;
|
||||||
public const int CraftingGridIndex = 1;
|
public const short CraftingGridIndex = 1;
|
||||||
public const int CraftingOutputIndex = 0;
|
public const short CraftingOutputIndex = 0;
|
||||||
public const int MainIndex = 10;
|
public const short MainIndex = 10;
|
||||||
|
|
||||||
public override string Name
|
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; }
|
public override IWindowArea[] WindowAreas { get; protected set; }
|
||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
|
@ -50,11 +50,11 @@ namespace TrueCraft.Core.Windows
|
|||||||
|
|
||||||
private bool Copying { get; set; }
|
private bool Copying { get; set; }
|
||||||
|
|
||||||
public const int IngredientIndex = 0;
|
public const short IngredientIndex = 0;
|
||||||
public const int FuelIndex = 1;
|
public const short FuelIndex = 1;
|
||||||
public const int OutputIndex = 2;
|
public const short OutputIndex = 2;
|
||||||
public const int MainIndex = 3;
|
public const short MainIndex = 3;
|
||||||
public const int HotbarIndex = 30;
|
public const short HotbarIndex = 30;
|
||||||
|
|
||||||
public override string Name
|
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 override IWindowArea[] WindowAreas { get; protected set; }
|
||||||
|
|
||||||
public IWindowArea Ingredient
|
public IWindowArea Ingredient
|
||||||
|
@ -26,11 +26,11 @@ namespace TrueCraft.Core.Windows
|
|||||||
|
|
||||||
#region Variables
|
#region Variables
|
||||||
|
|
||||||
public const int HotbarIndex = 36;
|
public const short HotbarIndex = 36;
|
||||||
public const int CraftingGridIndex = 1;
|
public const short CraftingGridIndex = 1;
|
||||||
public const int CraftingOutputIndex = 0;
|
public const short CraftingOutputIndex = 0;
|
||||||
public const int ArmorIndex = 5;
|
public const short ArmorIndex = 5;
|
||||||
public const int MainIndex = 9;
|
public const short MainIndex = 9;
|
||||||
|
|
||||||
public override string Name
|
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; }
|
public override IWindowArea[] WindowAreas { get; protected set; }
|
||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
|
@ -5,6 +5,7 @@ using System.Text;
|
|||||||
using TrueCraft.API.Windows;
|
using TrueCraft.API.Windows;
|
||||||
using TrueCraft.API;
|
using TrueCraft.API;
|
||||||
using TrueCraft.API.Networking;
|
using TrueCraft.API.Networking;
|
||||||
|
using TrueCraft.Core.Networking.Packets;
|
||||||
|
|
||||||
namespace TrueCraft.Core.Windows
|
namespace TrueCraft.Core.Windows
|
||||||
{
|
{
|
||||||
@ -161,5 +162,94 @@ namespace TrueCraft.Core.Windows
|
|||||||
Client = null;
|
Client = null;
|
||||||
IsDisposed = true;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -201,94 +201,11 @@ namespace TrueCraft.Handlers
|
|||||||
server.GetEntityManagerForWorld(client.World).SpawnEntity(item);
|
server.GetEntityManagerForWorld(client.World).SpawnEntity(item);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
var staging = (ItemStack)client.ItemStaging.Clone();
|
||||||
|
Window.HandleClickPacket(packet, window, ref staging);
|
||||||
|
client.ItemStaging = staging;
|
||||||
if (packet.SlotIndex >= window.Length || packet.SlotIndex < 0)
|
if (packet.SlotIndex >= window.Length || packet.SlotIndex < 0)
|
||||||
return;
|
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()));
|
client.QueuePacket(new WindowItemsPacket(packet.WindowID, window.GetSlots()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user