From 65c8df24b60443ee2c7932fd68d498694ec5ede2 Mon Sep 17 00:00:00 2001 From: durron597 Date: Sat, 8 Jan 2011 05:49:42 -0500 Subject: [PATCH] Partial Player Item, Block RightClick, Block Place --- .../java/net/minecraft/server/ItemBlock.java | 108 ++++++++++++++ .../java/net/minecraft/server/ItemBucket.java | 133 ++++++++++++++++++ .../minecraft/server/NetServerHandler.java | 119 ++++++++++------ 3 files changed, 315 insertions(+), 45 deletions(-) create mode 100644 src/main/java/net/minecraft/server/ItemBlock.java create mode 100644 src/main/java/net/minecraft/server/ItemBucket.java diff --git a/src/main/java/net/minecraft/server/ItemBlock.java b/src/main/java/net/minecraft/server/ItemBlock.java new file mode 100644 index 0000000000..350cd2f4d6 --- /dev/null +++ b/src/main/java/net/minecraft/server/ItemBlock.java @@ -0,0 +1,108 @@ +package net.minecraft.server; + +import org.bukkit.BlockFace; +import org.bukkit.craftbukkit.CraftBlock; +import org.bukkit.craftbukkit.CraftItemStack; +import org.bukkit.craftbukkit.CraftPlayer; +import org.bukkit.event.Event.Type; +import org.bukkit.event.block.BlockPlacedEvent; + + +public class ItemBlock extends Item { + + private int a; + + public ItemBlock(int i) { + super(i); + a = i + 256; + a(Block.m[i + 256].a(2)); + } + + public boolean a(ItemStack itemstack, EntityPlayer entityplayer, World world, int i, int j, int k, int l) { + // Craftbukkit start + // Bail if we have nothing of the item in hand + if (itemstack.a == 0) { + return false; + } + + // Craftbukkit store info of the clicked block + CraftBlock blockClicked = (CraftBlock) ((WorldServer) world).getWorld().getBlockAt(i, j, k); + BlockFace faceClicked = CraftBlock.notchToBlockFace(l); + + if (world.a(i, j, k) == Block.aS.bh) { + l = 0; + } else { + if (l == 0) { + j--; + } + if (l == 1) { + j++; + } + if (l == 2) { + k--; + } + if (l == 3) { + k++; + } + if (l == 4) { + i--; + } + if (l == 5) { + i++; + } + } + + // CraftBukkit store the old data so we can undo it + int oldMaterial = world.a(i, j, k); + int oldData = world.b(i, j, k); + + if (world.a(a, i, j, k, false)) { + Block block = Block.m[a]; + + // This executes the placement of the block + if (world.d(i, j, k, a)) { + CraftBlock placedBlock = (CraftBlock) blockClicked.getFace(faceClicked) ; + CraftItemStack itemInHand = new CraftItemStack(itemstack); + CraftPlayer thePlayer = new CraftPlayer(((WorldServer) world).getServer(), (EntityPlayerMP) entityplayer); + + int xFromSpawn = (int) MathHelper.e(i - world.m); + int distanceFromSpawn = (int) MathHelper.e(k - world.o); + + if (xFromSpawn > distanceFromSpawn) { + distanceFromSpawn = xFromSpawn; + } + + // Craftbukkit hardcoded Spawn distance for now + boolean canBuild = distanceFromSpawn > 16 || thePlayer.isOp(); + + BlockPlacedEvent bpe = new BlockPlacedEvent(Type.BLOCK_PLACED, placedBlock, blockClicked, itemInHand, thePlayer, canBuild); + + if (bpe.isCancelled() || !bpe.canBuild()) { + // Craftbukkit Undo! + + // Specialcase iceblocks, replace with 'glass' first (so it doesn't explode into water) + if (this.a == 79) { + world.a(i, j, k, 20); + } + world.a(i, j, k, oldMaterial); + world.c(i, j, k, oldData); + } else { + world.g(i, j, k); + world.g(i, j, k, this.a); + + Block.m[a].c(world, i, j, k, l); + // Craftbukkit Decompiler doesn't record the downcast. Oops. + Block.m[a].a(world, i, j, k, (EntityLiving) entityplayer); + world.a((float) i + 0.5F, (float) j + 0.5F, (float) k + 0.5F, block.bq.c(), (block.bq.a() + 1.0F) / 2.0F, block.bq.b() * 0.8F); + itemstack.a--; + } + } + } + return true; + } + + public String a() { + return Block.m[a].e(); + } +} + diff --git a/src/main/java/net/minecraft/server/ItemBucket.java b/src/main/java/net/minecraft/server/ItemBucket.java new file mode 100644 index 0000000000..e653e36af5 --- /dev/null +++ b/src/main/java/net/minecraft/server/ItemBucket.java @@ -0,0 +1,133 @@ +package net.minecraft.server; + + +import java.util.Random; + +import org.bukkit.BlockFace; +import org.bukkit.craftbukkit.CraftBlock; +import org.bukkit.craftbukkit.CraftItemStack; +import org.bukkit.craftbukkit.CraftPlayer; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.event.Event.Type; +import org.bukkit.event.player.PlayerItemEvent; + + +public class ItemBucket extends Item { + + private int a; + + public ItemBucket(int i, int j) { + super(i); + aX = 1; + aY = 64; + a = j; + } + + public ItemStack a(ItemStack itemstack, World world, EntityPlayer entityplayer) { + float f = 1.0F; + float f1 = entityplayer.y + (entityplayer.w - entityplayer.y) * f; + float f2 = entityplayer.x + (entityplayer.v - entityplayer.x) * f; + double d = entityplayer.m + (entityplayer.p - entityplayer.m) * (double) f; + double d1 = (entityplayer.n + (entityplayer.q - entityplayer.n) * (double) f + 1.6200000000000001D) - (double) entityplayer.H; + double d2 = entityplayer.o + (entityplayer.r - entityplayer.o) * (double) f; + Vec3D vec3d = Vec3D.b(d, d1, d2); + float f3 = MathHelper.b(-f2 * 0.01745329F - 3.141593F); + float f4 = MathHelper.a(-f2 * 0.01745329F - 3.141593F); + float f5 = -MathHelper.b(-f1 * 0.01745329F); + float f6 = MathHelper.a(-f1 * 0.01745329F); + float f7 = f4 * f5; + float f8 = f6; + float f9 = f3 * f5; + double d3 = 5D; + Vec3D vec3d1 = vec3d.c((double) f7 * d3, (double) f8 * d3, (double) f9 * d3); + MovingObjectPosition movingobjectposition = world.a(vec3d, vec3d1, a == 0); + + if (movingobjectposition == null) { + return itemstack; + } + if (movingobjectposition.a == 0) { + int i = movingobjectposition.b; + int j = movingobjectposition.c; + int k = movingobjectposition.d; + + if (!world.a(entityplayer, i, j, k)) { + return itemstack; + } + + // Craftbukkit start + // Craftbukkit Click == placed when handling an empty bucket! + CraftWorld theWorld = ((WorldServer) world).getWorld(); + CraftBlock blockClicked = (CraftBlock) theWorld.getBlockAt(i, j, k); + BlockFace direction = CraftBlock.notchToBlockFace(movingobjectposition.e); + CraftPlayer thePlayer = new CraftPlayer(((WorldServer) world).getServer(), (EntityPlayerMP) entityplayer); + CraftItemStack itemInHand = new CraftItemStack(itemstack); + + if (a == 0) { + if (world.c(i, j, k) == Material.f && world.b(i, j, k) == 0) { + PlayerItemEvent pie = new PlayerItemEvent(Type.PLAYER_ITEM, thePlayer, itemInHand, blockClicked, direction); + + if (!pie.isCancelled()) { + world.d(i, j, k, 0); + return new ItemStack(Item.av); + } else { + return itemstack; + } + } + if (world.c(i, j, k) == Material.g && world.b(i, j, k) == 0) { + PlayerItemEvent pie = new PlayerItemEvent(Type.PLAYER_ITEM, thePlayer, itemInHand, blockClicked, direction); + + if (!pie.isCancelled()) { + world.d(i, j, k, 0); + return new ItemStack(Item.aw); + } else { + return itemstack; + } + } + } else { + if (a < 0) { + return new ItemStack(Item.au); + } + if (movingobjectposition.e == 0) { + j--; + } + if (movingobjectposition.e == 1) { + j++; + } + if (movingobjectposition.e == 2) { + k--; + } + if (movingobjectposition.e == 3) { + k++; + } + if (movingobjectposition.e == 4) { + i--; + } + if (movingobjectposition.e == 5) { + i++; + } + if (world.e(i, j, k) || !world.c(i, j, k).a()) { + if (world.q.d && a == Block.A.bh) { + world.a(d + 0.5D, d1 + 0.5D, d2 + 0.5D, "random.fizz", 0.5F, 2.6F + (world.l.nextFloat() - world.l.nextFloat()) * 0.8F); + for (int l = 0; l < 8; l++) { + world.a("largesmoke", (double) i + Math.random(), (double) j + Math.random(), (double) k + Math.random(), 0.0D, 0.0D, 0.0D); + } + } else { + // Craftbukkit bucket empty. + PlayerItemEvent pie = new PlayerItemEvent(Type.PLAYER_ITEM, thePlayer, itemInHand, blockClicked, direction); + + if (!pie.isCancelled()) { + world.b(i, j, k, a, 0); + } else { + return itemstack; + } + } + return new ItemStack(Item.au); + } + } + } else if (a == 0 && (movingobjectposition.g instanceof EntityCow)) { + return new ItemStack(Item.aE); + } + return itemstack; + } +} + diff --git a/src/main/java/net/minecraft/server/NetServerHandler.java b/src/main/java/net/minecraft/server/NetServerHandler.java index 0bdaa96576..57eb5c46fb 100644 --- a/src/main/java/net/minecraft/server/NetServerHandler.java +++ b/src/main/java/net/minecraft/server/NetServerHandler.java @@ -2,13 +2,15 @@ package net.minecraft.server; import java.util.*; import java.util.logging.Logger; + +import org.bukkit.BlockFace; import org.bukkit.Location; import org.bukkit.craftbukkit.CraftBlock; import org.bukkit.craftbukkit.CraftItemStack; import org.bukkit.craftbukkit.CraftPlayer; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.event.Event.Type; -import org.bukkit.event.player.PlayerBlockItemEvent; +import org.bukkit.event.block.BlockRightClickedEvent; import org.bukkit.event.player.PlayerChatEvent; import org.bukkit.event.player.PlayerItemEvent; import org.bukkit.event.player.PlayerMoveEvent; @@ -293,10 +295,40 @@ implements ICommandListener { d.e.B = false; } + // Craftbukkit start - store the last block right clicked and what type it was + CraftBlock lastRightClicked; + int lastMaterial; + public void a(Packet15Place packet15place) { ItemStack itemstack = e.an.e(); - boolean flag = d.e.B = d.f.g(e.aw); + // Craftbukkit we don't check spawn protection here anymore + /* boolean flag = */d.e.B = d.f.g(e.aw); + CraftBlock blockClicked = null; + BlockFace blockFace = null; + + if (packet15place.d == 255) { + // Craftbukkit ITEM_USE -- if we have a lastRightClicked then it could be a usable location + if (packet15place.e != null && packet15place.e.c == lastMaterial) { + blockClicked = lastRightClicked; + } else if (lastMaterial == 0) { + blockClicked = lastRightClicked; + } + lastRightClicked = null; + lastMaterial = 0; + } else { + // Craftbukkit RIGHTCLICK or BLOCK_PLACE .. or nothing + blockClicked = (CraftBlock) d.e.getWorld().getBlockAt(packet15place.a, packet15place.b, packet15place.c); + lastRightClicked = blockClicked; + lastMaterial = (packet15place.e == null) ? 0 : packet15place.e.c; + } + + if (blockClicked != null && itemstack != null) { + blockFace = CraftBlock.notchToBlockFace(packet15place.d); + } else { + blockFace = BlockFace.Self; + } + // Craftbukkit if rightclick decremented the item, always send the update packet. // this is not here for Craftbukkit's own functionality; rather it is to fix // a notch bug where the item doesn't update correctly. @@ -309,15 +341,24 @@ implements ICommandListener { CraftItemStack craftItem = new CraftItemStack(itemstack); CraftPlayer player = new CraftPlayer(server, e); - PlayerItemEvent pie = new PlayerItemEvent(Type.PLAYER_ITEM, player, craftItem); - - // We still call this event even in spawn protection. - server.getPluginManager().callEvent(pie); + PlayerItemEvent pie = new PlayerItemEvent(Type.PLAYER_ITEM, player, craftItem, blockClicked, blockFace); + // Craftbukkit We still call this event even in spawn protection. + // Don't call this event if using Buckets / signs + switch (craftItem.getType()) { + case Sign: + case Bucket: + case WaterBucket: + case LavaBucket: + server.getPluginManager().callEvent(pie); + } + if (!pie.isCancelled()) { int itemstackAmount = itemstack.a; e.c.a(e, d.e, itemstack); - // Craftbukkit notch decrements the counter by 1 in the above method with food, snowballs and so forth + // Craftbukkit notch decrements the counter by 1 in the above method with food, + // snowballs and so forth, but he does it in a place that doesnt cause the + // inventory update packet to get sent always = (itemstack.a != itemstackAmount); } } else { @@ -335,46 +376,34 @@ implements ICommandListener { // Craftbukkit start CraftItemStack craftItem = new CraftItemStack(itemstack); CraftPlayer player = new CraftPlayer(server, e); - CraftBlock blockClicked = (CraftBlock) d.e.getWorld().getBlockAt(l, i1, j1); - boolean canBuild = (i2 > 16) || flag; - PlayerBlockItemEvent pbie = new PlayerBlockItemEvent(Type.PLAYER_BLOCKITEM, player, craftItem, blockClicked, CraftBlock.notchToBlockFace(k1), canBuild); - - // We still call this event even in spawn protection. - server.getPluginManager().callEvent(pbie); +// boolean canBuild = (i2 > 16) || flag; + BlockRightClickedEvent brce = new BlockRightClickedEvent(Type.BLOCK_RIGHTCLICKED, blockClicked, blockFace, craftItem, player); + server.getPluginManager().callEvent(brce); - if (!pbie.isCancelled()) { - // Note: this is the spawn protection check - if (pbie.canBuild()) { - e.c.a(e, d.e, itemstack, l, i1, j1, k1); - } else { - // Craftbukkit This fixes another notch bug. No point in - // sending the block update packets when you weren't allowed to place! - d.e.B = false; - return; - } - - // These are the response packets back to the client - e.a.b(new Packet53BlockChange(l, i1, j1, d.e)); - if (k1 == 0) { - i1--; - } - if (k1 == 1) { - i1++; - } - if (k1 == 2) { - j1--; - } - if (k1 == 3) { - j1++; - } - if (k1 == 4) { - l--; - } - if (k1 == 5) { - l++; - } - e.a.b(new Packet53BlockChange(l, i1, j1, d.e)); + // Craftbukkit WE HAVE MOVED THE SPAWN PROTECTION CHECK DOWN INTO CLASS ItemBlock!!! + e.c.a(e, d.e, itemstack, l, i1, j1, k1); + + // These are the response packets back to the client + e.a.b(new Packet53BlockChange(l, i1, j1, d.e)); + if (k1 == 0) { + i1--; } + if (k1 == 1) { + i1++; + } + if (k1 == 2) { + j1--; + } + if (k1 == 3) { + j1++; + } + if (k1 == 4) { + l--; + } + if (k1 == 5) { + l++; + } + e.a.b(new Packet53BlockChange(l, i1, j1, d.e)); } if (itemstack != null && itemstack.a == 0) { e.an.a[e.an.c] = null;