Unify server and client implementations of windows

This commit is contained in:
Drew DeVault 2015-10-09 07:42:37 -04:00
parent 77f000ad2b
commit 0c6a973a69
8 changed files with 140 additions and 159 deletions

View File

@ -16,6 +16,7 @@ namespace TrueCraft.API.Windows
int MinecraftWasWrittenByFuckingIdiotsLength { get; }
ItemStack this[int index] { get; set; }
bool Empty { get; }
short[] ReadOnlySlots { get; }
/// <summary>
/// Call this to "shift+click" an item from one area to another.

View File

@ -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;

View File

@ -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));

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}
}
}
}
}
}

View File

@ -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()));
}