public static void CreativeInventoryAction(RemoteClient client, MinecraftServer server, IPacket _packet) { var packet = (CreativeInventoryActionPacket)_packet; if (packet.Slot == -1) { var entity = new ItemEntity(client.Entity.Position + new Vector3(0, client.Entity.Size.Height, 0), packet.Item); entity.Velocity = MathHelper.FowardVector(client.Entity.Yaw) * new Vector3(0.25); server.EntityManager.SpawnEntity(client.Entity.World, entity); } else if (packet.Slot < client.Entity.Inventory.Length && packet.Slot > 0) { client.Entity.Inventory[packet.Slot] = packet.Item; if (packet.Slot == client.Entity.SelectedSlot) { var clients = server.EntityManager.GetKnownClients(client.Entity); foreach (var _client in clients) { _client.SendPacket(new EntityEquipmentPacket(client.Entity.EntityId, EntityEquipmentPacket.EntityEquipmentSlot.HeldItem, client.Entity.Inventory[packet.Slot])); } } } }
public void OnPickUpItem(ItemEntity item) { if (PickUpItem != null) PickUpItem(this, new EntityEventArgs(item)); }
public static void ClickWindow(RemoteClient client, MinecraftServer server, IPacket _packet) { try { client.PlayerManager.SendInventoryUpdates = false; var packet = (ClickWindowPacket)_packet; Window window = null; if (packet.WindowId == 0) window = client.Entity.Inventory; // TODO: Fetch appropriate furnace/crafting bench/etc window if (window == null) return; var heldItem = client.Entity.ItemInMouse; ItemStack clickedItem = ItemStack.EmptyStack; if (packet.SlotIndex >= 0 && packet.SlotIndex < client.Entity.Inventory.Length) clickedItem = client.Entity.Inventory[packet.SlotIndex]; switch (packet.Action) { case ClickWindowPacket.ClickAction.LeftClick: if (heldItem.Empty) // Pick up item { client.Entity.ItemInMouse = clickedItem; client.Entity.Inventory[packet.SlotIndex] = ItemStack.EmptyStack; } else { if (clickedItem.Empty) { client.Entity.Inventory[packet.SlotIndex] = heldItem; client.Entity.ItemInMouse = ItemStack.EmptyStack; } else if (heldItem.CanMerge(clickedItem)) { // Attempt to combine stacks var newSize = clickedItem.Count + heldItem.Count; //var maxSize = Item.GetMaximumStackSize(new ItemDescriptor(clickedItem.Id, clickedItem.Metadata)); var maxSize = 64; // TODO if (newSize < maxSize) { clickedItem.Count = (sbyte)newSize; client.Entity.Inventory[packet.SlotIndex] = clickedItem; client.Entity.ItemInMouse = ItemStack.EmptyStack; } else { // Merge and leave a little left over newSize = newSize - maxSize; clickedItem.Count = (sbyte)maxSize; heldItem.Count = (sbyte)newSize; client.Entity.Inventory[packet.SlotIndex] = clickedItem; client.Entity.ItemInMouse = heldItem; } } else { // Swap stacks with the mouse and the clicked slot client.Entity.ItemInMouse = clickedItem; client.Entity.Inventory[packet.SlotIndex] = heldItem; } } break; case ClickWindowPacket.ClickAction.RightClick: if (heldItem.Empty) // Pick up half a stack { var heldCount = (sbyte)(clickedItem.Count / 2 + (clickedItem.Count % 2)); var leftCount = (sbyte)(clickedItem.Count / 2); client.Entity.ItemInMouse = new ItemStack(clickedItem.Id, heldCount, clickedItem.Metadata); var old = client.Entity.Inventory[packet.SlotIndex]; client.Entity.Inventory[packet.SlotIndex] = new ItemStack(old.Id, leftCount, old.Metadata, old.Nbt); } else { // Drop one in, or attempt to merge if (clickedItem.Empty) { clickedItem = (ItemStack)heldItem.Clone(); clickedItem.Count = 1; client.Entity.Inventory[packet.SlotIndex] = clickedItem; heldItem.Count--; client.Entity.ItemInMouse = heldItem; } else if (heldItem.CanMerge(clickedItem)) { // Merge one item in //var maxSize = Item.GetMaximumStackSize(new ItemDescriptor(clickedItem.Id, clickedItem.Metadata)); var maxSize = 64; // TODO if (clickedItem.Count < maxSize) { clickedItem.Count++; heldItem.Count--; client.Entity.ItemInMouse = heldItem; client.Entity.Inventory[packet.SlotIndex] = clickedItem; } } else { // Swap stacks with the mouse and the clicked slot client.Entity.ItemInMouse = clickedItem; client.Entity.Inventory[packet.SlotIndex] = heldItem; } } break; case ClickWindowPacket.ClickAction.ShiftLeftClick: case ClickWindowPacket.ClickAction.ShiftRightClick: window.MoveToAlternateArea(packet.SlotIndex); break; case ClickWindowPacket.ClickAction.Drop: if (!heldItem.Empty) { var drop = (ItemStack)heldItem.Clone(); drop.Count = 1; var entity = new ItemEntity(client.Entity.Position + new Vector3(0, client.Entity.Size.Height, 0), drop); entity.Velocity = MathHelper.FowardVector(client.Entity.Yaw) * new Vector3(0.25); server.EntityManager.SpawnEntity(client.Entity.World, entity); heldItem.Count--; client.Entity.ItemInMouse = heldItem; } break; case ClickWindowPacket.ClickAction.DropAll: if (!heldItem.Empty) { var entity = new ItemEntity(client.Entity.Position + new Vector3(0, client.Entity.Size.Height, 0), heldItem); entity.Velocity = MathHelper.FowardVector(client.Entity.Yaw) * new Vector3(0.25); server.EntityManager.SpawnEntity(client.Entity.World, entity); client.Entity.ItemInMouse = ItemStack.EmptyStack; } break; case ClickWindowPacket.ClickAction.StartLeftClickPaint: case ClickWindowPacket.ClickAction.StartRightClickPaint: client.PaintedSlots = new List<short>(); break; case ClickWindowPacket.ClickAction.LeftMousePaintProgress: case ClickWindowPacket.ClickAction.RightMousePaintProgress: if (!client.PaintedSlots.Contains(packet.SlotIndex)) client.PaintedSlots.Add(packet.SlotIndex); break; case ClickWindowPacket.ClickAction.EndLeftMousePaint: FinishPaint(client, heldItem, false); break; case ClickWindowPacket.ClickAction.EndRightMousePaint: FinishPaint(client, heldItem, true); break; } } finally { client.PlayerManager.SendInventoryUpdates = true; } }
public static void PlayerDigging(RemoteClient client, MinecraftServer server, IPacket _packet) { var packet = (PlayerBlockActionPacket)_packet; var position = new Coordinates3D(packet.X, packet.Y, packet.Z); // TODO: Enforce line-of-sight var block = client.World.GetBlockInfo(position); short damage; switch (packet.Action) { case PlayerBlockActionPacket.BlockAction.StartDigging: if (client.Entity.Position.DistanceTo(position) <= client.MaxDigDistance) { // TODO: Block stuff if (client.GameMode == GameMode.Creative || client.Entity.Abilities.InstantMine)// || Block.GetBlockHardness(block.BlockId) == 0) { client.World.SetBlockId(position, 0); client.World.SetMetadata(position, 0); } else { int time = Block.GetHarvestTime(block.BlockId, client.Entity.SelectedItem.Id, client.World, client.Entity, out damage); client.ExpectedMiningEnd = DateTime.Now.AddMilliseconds(time - (client.Ping + 100)); client.ExpectedBlockToMine = position; var knownClients = server.EntityManager.GetKnownClients(client.Entity); client.BlockBreakStageTime = time / 8; client.BlockBreakStartTime = DateTime.Now; foreach (var c in knownClients) c.SendPacket(new BlockBreakAnimationPacket(client.Entity.EntityId, position.X, position.Y, position.Z, 0)); } } break; case PlayerBlockActionPacket.BlockAction.CancelDigging: { client.BlockBreakStartTime = null; var knownClients = server.EntityManager.GetKnownClients(client.Entity); foreach (var c in knownClients) c.SendPacket(new BlockBreakAnimationPacket(client.Entity.EntityId, position.X, position.Y, position.Z, 0xFF)); // reset } break; case PlayerBlockActionPacket.BlockAction.FinishDigging: if (client.Entity.Position.DistanceTo(position) <= client.MaxDigDistance) { client.BlockBreakStartTime = null; var knownClients = server.EntityManager.GetKnownClients(client.Entity); foreach (var c in knownClients) c.SendPacket(new BlockBreakAnimationPacket(client.Entity.EntityId, position.X, position.Y, position.Z, 0xFF)); // reset if (client.ExpectedMiningEnd > DateTime.Now || client.ExpectedBlockToMine != position) return; Block.GetHarvestTime(block.BlockId, client.Entity.SelectedItem.Id, client.World, client.Entity, out damage); if (damage != 0) { var slot = client.Entity.Inventory[client.Entity.SelectedSlot]; if (!slot.Empty) { if (slot.AsItem() != null) { var item = slot.AsItem().Value; if (Item.GetToolType(item.ItemId) != null) { bool destroyed = Item.Damage(ref item, damage); slot.Metadata = item.Metadata; if (destroyed) client.Entity.Inventory[client.Entity.SelectedSlot] = ItemStack.EmptyStack; else client.Entity.Inventory[client.Entity.SelectedSlot] = slot; } } } } client.World.MineBlock(position); client.Entity.FoodExhaustion += 0.025f; } break; case PlayerBlockActionPacket.BlockAction.DropItem: case PlayerBlockActionPacket.BlockAction.DropItemStack: var SlotItem = client.Entity.Inventory[client.Entity.SelectedSlot]; if (!SlotItem.Empty) { var ItemCopy = (ItemStack)SlotItem.Clone(); if (packet.Action == PlayerBlockActionPacket.BlockAction.DropItemStack) client.Entity.Inventory[client.Entity.SelectedSlot] = ItemStack.EmptyStack; else { ItemCopy.Count = 1; SlotItem.Count--; // Decrease the player's item by 1 if (SlotItem.Count == 0) client.Entity.Inventory[client.Entity.SelectedSlot] = ItemStack.EmptyStack; else client.Entity.Inventory[client.Entity.SelectedSlot] = SlotItem; } var entity = new ItemEntity(client.Entity.Position + new Vector3(0, client.Entity.Size.Height, 0), ItemCopy); entity.Velocity = MathHelper.FowardVector(client.Entity.Yaw) * new Vector3(0.25); server.EntityManager.SpawnEntity(client.World, entity); } break; } }