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); }
private void OnPlayerBlockPlacement(PlayerBlockPlacementPacket p) { if (PlayerBlockPlacement != null) PlayerBlockPlacement.Invoke(this, new PacketEventArgs<PlayerBlockPlacementPacket>(p)); }
public static void HandlePacketPlayerBlockPlacement(Client client, PlayerBlockPlacementPacket packet) { /* * Scenarios: * * 1) using an item against a block (e.g. stone and flint) * 2) placing a new block * 3) using a block: e.g. open/close door, open chest, open workbench, open furnace * * */ // if (!Permissions.CanPlayerBuild(Username)) return; // Using activeslot provides current item info wtihout having to maintain ActiveItem if (packet.X == -1 && packet.Y == -1 && packet.Z == -1 && packet.Face == BlockFace.Held) { // TODO: Implement item usage - food etc return; } int x = packet.X; int y = packet.Y; int z = packet.Z; Player player = client.Owner; BlockData.Blocks type = (BlockData.Blocks)player.World.GetBlockId(x, y, z); // Get block being built against. byte metadata = player.World.GetBlockData(x, y, z); StructBlock facingBlock = new StructBlock(x, y, z, (byte)type, metadata, player.World); int bx, by, bz; player.World.FromFace(x, y, z, packet.Face, out bx, out by, out bz); if (player.World.BlockHelper.Instance((byte)type) is IBlockInteractive) { (player.World.BlockHelper.Instance((byte)type) as IBlockInteractive).Interact(player, facingBlock); return; } if (player.Inventory.Slots[player.Inventory.ActiveSlot].Type <= 0 || player.Inventory.Slots[player.Inventory.ActiveSlot].Count < 1) return; // TODO: Neaten this out, or address via handler? if (player.Inventory.Slots[player.Inventory.ActiveSlot].Type > 255 || packet.Face == BlockFace.Held) // Client is using an Item. { HandlePacketPlayerItemPlacement(client, packet); return; } // Built Block Info byte bType = (byte)player.Inventory.Slots[player.Inventory.ActiveSlot].Type; byte bMetaData = (byte)player.Inventory.Slots[player.Inventory.ActiveSlot].Durability; StructBlock bBlock = new StructBlock(bx, by, bz, bType, bMetaData, player.World); player.World.BlockHelper.Instance(bType).Place(player, bBlock, facingBlock, packet.Face); }
public static void ReadPlayerBlockPlacement(Client client, PacketReader reader) { PlayerBlockPlacementPacket pb = new PlayerBlockPlacementPacket(); pb.Read(reader); if (!reader.Failed) Client.HandlePacketPlayerBlockPlacement(client, pb); }
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 baseBlockCoords = UniversalCoords.FromWorld(packet.X, packet.Y, packet.Z); Chunk chunk = player.World.GetChunk(baseBlockCoords); if (chunk == null) return; BlockData.Blocks baseBlockType = chunk.GetType(baseBlockCoords); // Get block being built against. byte baseBlockData = chunk.GetData(baseBlockCoords); StructBlock baseBlock = new StructBlock(baseBlockCoords, (byte)baseBlockType, (byte)baseBlockData, player.World); // Placed Item Info short pType = player.Inventory.Slots[player.Inventory.ActiveSlot].Type; short pMetaData = player.Inventory.Slots[player.Inventory.ActiveSlot].Durability; UniversalCoords newBlockCoords = player.World.FromFace(baseBlockCoords, packet.Face); StructBlock newBlock; byte newBlockId = 0; switch (packet.Face) { case BlockFace.Held: return; // TODO: Process buckets, food, etc. } switch (baseBlockType) { 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 (baseBlockType == BlockData.Blocks.Dirt || baseBlockType == BlockData.Blocks.Grass) { // Think the client has a Notch bug where hoe's durability is not updated properly. BlockHelper.Instance((byte)BlockData.Blocks.Soil).Spawn(baseBlock); } return; case BlockData.Items.Ink_Sack: if (pMetaData != 15) return; if (baseBlockType == BlockData.Blocks.Red_Mushroom || baseBlockType == BlockData.Blocks.Brown_Mushroom) { BlockBaseMushroom baseMushroom = (BlockBaseMushroom)BlockHelper.Instance((byte) baseBlockType); baseMushroom.Fertilize(player, baseBlock); } return; 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.Sign: if (packet.Face == BlockFace.Up) newBlockId = (byte)BlockData.Blocks.Sign_Post; else newBlockId = (byte)BlockData.Blocks.Wall_Sign; break; case BlockData.Items.Seeds: newBlockId = (byte)BlockData.Blocks.Crops; break; case BlockData.Items.Reeds: newBlockId = (byte)BlockData.Blocks.Reed; break; case BlockData.Items.Redstone: newBlockId = (byte)BlockData.Blocks.Redstone_Wire; break; case BlockData.Items.Iron_Door: newBlockId = (byte) BlockData.Blocks.Iron_Door; break; case BlockData.Items.Wooden_Door: newBlockId = (byte)BlockData.Blocks.Wooden_Door; break; } if (newBlockId != 0) { newBlock = new StructBlock(newBlockCoords, newBlockId, 0, player.World); BlockHelper.Instance(newBlockId).Place(player, newBlock, baseBlock, packet.Face); } }
public static void HandlePacketPlayerBlockPlacement(Client client, PlayerBlockPlacementPacket packet) { var baseBlockcoords = UniversalCoords.FromWorld(packet.X, packet.Y, packet.Z); var player = client.Owner; // Consume food, charge the bow etc if (packet.X == -1 && packet.Y == -1 && packet.Z == -1 && packet.Face == BlockFace.Held) { if (ItemHelper.IsVoid(player.Inventory.ActiveItem)) return; if (player.Inventory.ActiveItem is IItemConsumable) { var consumable = player.Inventory.ActiveItem as IItemConsumable; consumable.StartConsuming(); } return; } var chunk = player.World.GetChunk(baseBlockcoords) as Chunk; if (chunk == null) return; var baseBlockType = chunk.GetType(baseBlockcoords); // Get block being built against. byte baseBlockMeta = chunk.GetData(baseBlockcoords); var baseBlock = new StructBlock(baseBlockcoords, (byte)baseBlockType, baseBlockMeta, player.World); // Interaction with the blocks - chest, furnace, enchantment table etc if (BlockHelper.Instance.IsInteractive(baseBlockType)) { (BlockHelper.Instance.CreateBlockInstance(baseBlock.Type) as IBlockInteractive).Interact(client.Owner, baseBlock); return; } if (ItemHelper.IsVoid(player.Inventory.ActiveItem)) return; if (player.Inventory.ActiveItem is IItemUsable) { var consumable = player.Inventory.ActiveItem as IItemUsable; consumable.Use(baseBlock, packet.Face); //HandlePacketPlayerItemPlacement(client, packet); } if (player.Inventory.ActiveItem is IItemPlaceable) { var consumable = player.Inventory.ActiveItem as IItemPlaceable; consumable.Place(baseBlock, packet.Face); } }
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); }