public static void HandleClickWindowPacket(IPacket _packet, IRemoteClient _client, IMultiplayerServer server) { var packet = (ClickWindowPacket)_packet; var client = (RemoteClient)_client; var window = client.CurrentWindow; if (packet.SlotIndex == -999) { // Throwing item ItemEntity item; if (packet.RightClick) { var spawned = client.ItemStaging; spawned.Count = 1; var inventory = client.ItemStaging; inventory.Count--; item = new ItemEntity(client.Entity.Position + new Vector3(0, PlayerEntity.Height, 0), spawned); client.ItemStaging = inventory; } else { item = new ItemEntity(client.Entity.Position + new Vector3(0, PlayerEntity.Height, 0), client.ItemStaging); client.ItemStaging = ItemStack.EmptyStack; } item.Velocity = MathHelper.FowardVector(client.Entity.Yaw) * 0.3; server.GetEntityManagerForWorld(client.World).SpawnEntity(item); return; } 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())); }