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; } } } }
public override bool MouseButtonDown(GameTime gameTime, MouseButtonEventArgs e) { if (Game.Client.CurrentWindow == null) return false; var id = Game.Client.CurrentWindow.ID; if (id == -1) id = 0; // Minecraft is stupid var item = ItemStack.EmptyStack; if (SelectedSlot > -1) item = Game.Client.CurrentWindow[SelectedSlot]; 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); if (packet.SlotIndex == -999) { // Special case (throwing item) TODO } else { var backup = Game.Client.CurrentWindow.GetSlots(); var staging = (ItemStack)HeldItem.Clone(); Window.HandleClickPacket(packet, Game.Client.CurrentWindow, ref staging); HeldItem = staging; Game.Client.CurrentWindow.SetSlots(backup); } Game.Client.QueuePacket(packet); return true; }