public static void HandlePacketPlayerItemPlacement(Client client, PlayerBlockPlacementPacket packet) { Player player = client.Owner; // if(!Permissions.CanPlayerBuild(Username)) return; if (player.Inventory.Slots[player.Inventory.ActiveSlot].Type <= 255) return; int x = packet.X; int y = packet.Y; int z = packet.Z; BlockData.Blocks adjacentBlockType = (BlockData.Blocks)player.World.GetBlockId(x, y, z); // Get block being built against. // Placed Item Info int px, py, pz; short pType = player.Inventory.Slots[player.Inventory.ActiveSlot].Type; short pMetaData = player.Inventory.Slots[player.Inventory.ActiveSlot].Durability; player.World.FromFace(x, y, z, packet.Face, out px, out py, out pz); switch (packet.Face) { case BlockFace.Held: return; // TODO: Process buckets, food, etc. } switch (adjacentBlockType) { case BlockData.Blocks.Air: case BlockData.Blocks.Water: case BlockData.Blocks.Lava: case BlockData.Blocks.Still_Water: case BlockData.Blocks.Still_Lava: return; } switch ((BlockData.Items)pType) { case BlockData.Items.Diamond_Hoe: case BlockData.Items.Gold_Hoe: case BlockData.Items.Iron_Hoe: case BlockData.Items.Stone_Hoe: case BlockData.Items.Wooden_Hoe: if (adjacentBlockType == BlockData.Blocks.Dirt || adjacentBlockType == BlockData.Blocks.Grass) { // Think the client has a Notch bug where hoe's durability is not updated properly. px = x; py = y; pz = z; player.World.SetBlockAndData(px, py, pz, (byte)BlockData.Blocks.Soil, 0x00); } break; case BlockData.Items.Sign: if (packet.Face == BlockFace.Up) // Floor Sign { // Get the direction the player is facing. switch (client.FacingDirection(8)) { case "N": pMetaData = (byte)MetaData.SignPost.North; break; case "NE": pMetaData = (byte)MetaData.SignPost.Northeast; break; case "E": pMetaData = (byte)MetaData.SignPost.East; break; case "SE": pMetaData = (byte)MetaData.SignPost.Southeast; break; case "S": pMetaData = (byte)MetaData.SignPost.South; break; case "SW": pMetaData = (byte)MetaData.SignPost.Southwest; break; case "W": pMetaData = (byte)MetaData.SignPost.West; break; case "NW": pMetaData = (byte)MetaData.SignPost.Northwest; break; default: return; } player.World.SetBlockAndData(px, py, pz, (byte)BlockData.Blocks.Sign_Post, (byte)pMetaData); } else // Wall Sign { switch (packet.Face) { case BlockFace.East: pMetaData = (byte)MetaData.SignWall.East; break; case BlockFace.West: pMetaData = (byte)MetaData.SignWall.West; break; case BlockFace.North: pMetaData = (byte)MetaData.SignWall.North; break; case BlockFace.South: pMetaData = (byte)MetaData.SignWall.South; break; case BlockFace.Down: return; } player.World.SetBlockAndData(px, py, pz, (byte)BlockData.Blocks.Wall_Sign, (byte)pMetaData); } break; case BlockData.Items.Seeds: if (adjacentBlockType == BlockData.Blocks.Soil && packet.Face == BlockFace.Down) { player.World.SetBlockAndData(px, py, pz, (byte)BlockData.Blocks.Crops, 0x00); } break; case BlockData.Items.Redstone: player.World.SetBlockAndData(px, py, pz, (byte)BlockData.Blocks.Redstone_Wire, 0x00); break; case BlockData.Items.Minecart: case BlockData.Items.Boat: case BlockData.Items.Storage_Minecart: case BlockData.Items.Powered_Minecart: // TODO: Create new object break; case BlockData.Items.Iron_Door: case BlockData.Items.Wooden_Door: { if (!BlockData.Air.Contains((BlockData.Blocks)player.World.GetBlockId(px, py + 1, pz))) return; switch (client.FacingDirection(4)) // Built on floor, set by facing dir { case "N": pMetaData = (byte)MetaData.Door.Northwest; break; case "W": pMetaData = (byte)MetaData.Door.Southwest; break; case "S": pMetaData = (byte)MetaData.Door.Southeast; break; case "E": pMetaData = (byte)MetaData.Door.Northeast; break; default: return; } if ((BlockData.Items)pType == BlockData.Items.Iron_Door) { player.World.SetBlockAndData(px, py + 1, pz, (byte)BlockData.Blocks.Iron_Door, (byte)MetaData.Door.IsTopHalf); player.World.SetBlockAndData(px, py, pz, (byte)BlockData.Blocks.Iron_Door, (byte)pMetaData); } else { player.World.SetBlockAndData(px, py + 1, pz, (byte)BlockData.Blocks.Wooden_Door, (byte)MetaData.Door.IsTopHalf); player.World.SetBlockAndData(px, py, pz, (byte)BlockData.Blocks.Wooden_Door, (byte)pMetaData); } player.World.Update(px, py + 1, pz); } break; case BlockData.Items.Shears: if (adjacentBlockType == BlockData.Blocks.Leaves) { // TODO: Set correct leaves type (durability?): 0 basic leaves, 1 pine, 2 birch player.Server.DropItem(player.World, x, y, z, new ItemStack((short)BlockData.Blocks.Leaves, 1, 0)); player.World.SetBlockAndData(x, y, z, 0, 0); player.World.Update(x, y, z); } break; } if (player.GameMode == 0) { if (!player.Inventory.DamageItem(player.Inventory.ActiveSlot)) // If item isn't durable, remove it. player.Inventory.RemoveItem(player.Inventory.ActiveSlot); } player.World.Update(px, py, pz); }
public static void HandlePacketPlayerItemPlacement(Client client, PlayerBlockPlacementPacket packet) { Player player = client.Owner; // if(!Permissions.CanPlayerBuild(Username)) return; if (player.Inventory.Slots[player.Inventory.ActiveSlot].Type <= 255) return; UniversalCoords packetCoords = UniversalCoords.FromWorld(packet.X, packet.Y, packet.Z); BlockData.Blocks adjacentBlockType = (BlockData.Blocks)player.World.GetBlockId(packetCoords); // Get block being built against. byte adjacentBlockData = player.World.GetBlockData(packetCoords); // Placed Item Info short pType = player.Inventory.Slots[player.Inventory.ActiveSlot].Type; short pMetaData = player.Inventory.Slots[player.Inventory.ActiveSlot].Durability; UniversalCoords coordsFromFace = player.World.FromFace(packetCoords, packet.Face); switch (packet.Face) { case BlockFace.Held: return; // TODO: Process buckets, food, etc. } switch (adjacentBlockType) { case BlockData.Blocks.Air: case BlockData.Blocks.Water: case BlockData.Blocks.Lava: case BlockData.Blocks.Still_Water: case BlockData.Blocks.Still_Lava: return; } switch ((BlockData.Items)pType) { case BlockData.Items.Diamond_Hoe: case BlockData.Items.Gold_Hoe: case BlockData.Items.Iron_Hoe: case BlockData.Items.Stone_Hoe: case BlockData.Items.Wooden_Hoe: if (adjacentBlockType == BlockData.Blocks.Dirt || adjacentBlockType == BlockData.Blocks.Grass) { // Think the client has a Notch bug where hoe's durability is not updated properly. player.World.SetBlockAndData(packetCoords, (byte)BlockData.Blocks.Soil, 0x00); } break; case BlockData.Items.Sign: if (packet.Face == BlockFace.Up) // Floor Sign { // Get the direction the player is facing. switch (client.FacingDirection(8)) { case "N": pMetaData = (byte)MetaData.SignPost.North; break; case "NE": pMetaData = (byte)MetaData.SignPost.Northeast; break; case "E": pMetaData = (byte)MetaData.SignPost.East; break; case "SE": pMetaData = (byte)MetaData.SignPost.Southeast; break; case "S": pMetaData = (byte)MetaData.SignPost.South; break; case "SW": pMetaData = (byte)MetaData.SignPost.Southwest; break; case "W": pMetaData = (byte)MetaData.SignPost.West; break; case "NW": pMetaData = (byte)MetaData.SignPost.Northwest; break; default: return; } player.World.SetBlockAndData(coordsFromFace, (byte)BlockData.Blocks.Sign_Post, (byte)pMetaData); } else // Wall Sign { switch (packet.Face) { case BlockFace.East: pMetaData = (byte)MetaData.SignWall.East; break; case BlockFace.West: pMetaData = (byte)MetaData.SignWall.West; break; case BlockFace.North: pMetaData = (byte)MetaData.SignWall.North; break; case BlockFace.South: pMetaData = (byte)MetaData.SignWall.South; break; case BlockFace.Down: return; } player.World.SetBlockAndData(coordsFromFace, (byte)BlockData.Blocks.Wall_Sign, (byte)pMetaData); } break; case BlockData.Items.Seeds: if (adjacentBlockType == BlockData.Blocks.Soil && packet.Face == BlockFace.Down) { player.World.SetBlockAndData(coordsFromFace, (byte)BlockData.Blocks.Crops, 0x00); } break; case BlockData.Items.Reeds: StructBlock block = new StructBlock(coordsFromFace, (byte)BlockData.Blocks.Reed, 0x00, player.World); StructBlock targetBlock = new StructBlock(packetCoords, (byte)adjacentBlockType, adjacentBlockData, player.World); BlockHelper.Instance((byte)BlockData.Blocks.Reed).Place(block, targetBlock, packet.Face); break; case BlockData.Items.Redstone: player.World.SetBlockAndData(coordsFromFace, (byte)BlockData.Blocks.Redstone_Wire, 0x00); break; case BlockData.Items.Minecart: case BlockData.Items.Boat: case BlockData.Items.Storage_Minecart: case BlockData.Items.Powered_Minecart: // TODO: Create new object break; case BlockData.Items.Iron_Door: case BlockData.Items.Wooden_Door: { byte blockId = player.World.GetBlockId(coordsFromFace.WorldX, coordsFromFace.WorldY + 1, coordsFromFace.WorldZ); if (!BlockHelper.Instance(blockId).IsAir) return; switch (client.FacingDirection(4)) // Built on floor, set by facing dir { case "N": pMetaData = (byte)MetaData.Door.Northwest; break; case "W": pMetaData = (byte)MetaData.Door.Southwest; break; case "S": pMetaData = (byte)MetaData.Door.Southeast; break; case "E": pMetaData = (byte)MetaData.Door.Northeast; break; default: return; } if ((BlockData.Items)pType == BlockData.Items.Iron_Door) { player.World.SetBlockAndData(coordsFromFace.WorldX, coordsFromFace.WorldY + 1, coordsFromFace.WorldZ, (byte)BlockData.Blocks.Iron_Door, (byte)MetaData.Door.IsTopHalf); player.World.SetBlockAndData(coordsFromFace, (byte)BlockData.Blocks.Iron_Door, (byte)pMetaData); } else { player.World.SetBlockAndData(coordsFromFace.WorldX, coordsFromFace.WorldY + 1, coordsFromFace.WorldZ, (byte)BlockData.Blocks.Wooden_Door, (byte)MetaData.Door.IsTopHalf); player.World.SetBlockAndData(coordsFromFace, (byte)BlockData.Blocks.Wooden_Door, (byte)pMetaData); } player.World.Update(UniversalCoords.FromWorld(coordsFromFace.WorldX, coordsFromFace.WorldY + 1, coordsFromFace.WorldZ)); } break; } if (player.GameMode == 0) { if (!player.Inventory.DamageItem(player.Inventory.ActiveSlot)) // If item isn't durable, remove it. player.Inventory.RemoveItem(player.Inventory.ActiveSlot); } player.World.Update(coordsFromFace); }