Fork of Poseidon providing Bukkit #1060 to older Beta versions (b1.0-b1.7.3)
at develop 348 lines 14 kB view raw
1package net.minecraft.server; 2 3import org.bukkit.Bukkit; 4import org.bukkit.craftbukkit.CraftServer; 5import org.bukkit.craftbukkit.event.CraftEventFactory; 6import org.bukkit.event.Event; 7import org.bukkit.event.block.Action; 8import org.bukkit.event.block.BlockBreakEvent; 9import org.bukkit.event.block.BlockDamageEvent; 10import org.bukkit.event.player.PlayerInteractEvent; 11 12// CraftBukkit start 13 14import com.legacyminecraft.poseidon.packets.ArtificialPacket53BlockChange; 15// CraftBukkit end 16 17import uk.betacraft.uberbukkit.packet.Packet62Sound; 18import uk.betacraft.uberbukkit.packet.Packet63Digging; 19 20public class ItemInWorldManager { 21 22 private WorldServer world; 23 public EntityHuman player; 24 private int c = 0; 25 private long lastDigTick; 26 public int e; 27 public int f; 28 public int g; 29 private long currentTick; 30 private boolean i; 31 private int j; 32 private int k; 33 private int l; 34 private long m; 35 36 public double damageDealt; 37 public float delaySound; // uberbukkit 38 39 public ItemInWorldManager(WorldServer worldserver) { 40 this.world = worldserver; 41 this.delaySound = 0.0F; 42 } 43 44 // ======= UBERBUKKIT PRE-b1.3 AREA ======= 45 46 public void oldClick(int i, int j, int k, int l) { // UberBukkit add block face 47 int i1 = this.world.getTypeId(i, j, k); 48 49 // CraftBukkit start 50 PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_BLOCK, i, j, k, l, this.player.inventory.getItemInHand()); 51 52 if (event.useInteractedBlock() == Event.Result.DENY) { 53 // If we denied a door from opening, we need to send a correcting update to the client, as it already opened the door. 54 if (i1 == Block.WOODEN_DOOR.id) { 55 // For some reason *BOTH* the bottom/top part have to be marked updated. 56 boolean bottom = (this.world.getData(i, j, k) & 8) == 0; 57 ((EntityPlayer) this.player).netServerHandler.sendPacket(new Packet53BlockChange(i, j, k, this.world)); 58 ((EntityPlayer) this.player).netServerHandler.sendPacket(new Packet53BlockChange(i, j + (bottom ? 1 : -1), k, this.world)); 59 } else if (i1 == Block.TRAP_DOOR.id) { 60 ((EntityPlayer) this.player).netServerHandler.sendPacket(new Packet53BlockChange(i, j, k, this.world)); 61 } 62 } else { 63 if (i1 > 0 && this.damageDealt == 0.0F) { 64 Block.byId[i1].b(this.world, i, j, k, this.player); 65 } 66 // Allow fire punching to be blocked 67 this.world.douseFire(player, i, j, k, l); 68 } 69 // CraftBukkit end 70 71 if (i1 > 0 && Block.byId[i1].getDamage(this.player) >= 1.0F) { 72 this.c(i, j, k); 73 } 74 } 75 76 public void oldHaltBreak() { 77 this.damageDealt = 0.0F; 78 this.c = 0; 79 } 80 81 public void oldDig(int i, int j, int k, int l) { 82 if (this.c > 0) { 83 --this.c; 84 } else { 85 if (i == this.e && j == this.f && k == this.g) { 86 int i1 = this.world.getTypeId(i, j, k); 87 88 if (i1 == 0) { 89 return; 90 } 91 92 Block block = Block.byId[i1]; 93 94 this.damageDealt += block.getDamage(this.player); 95 96 // uberbukkit - play breaking sound for others 97 if (delaySound % 4.0F == 0.0F && block != null) { 98 this.world.makeSound((double) i + 0.5D, (double) j + 0.5D, (double) k + 0.5D, block.stepSound.getName(), (block.stepSound.getVolume1() + 1.0F) / 8.0F, block.stepSound.getVolume2() * 0.5F); 99 ((CraftServer) Bukkit.getServer()).getHandle().sendPacketNearby(player, i, j, k, 64D, player.dimension, new Packet63Digging(i, j, k, l, (float) this.damageDealt)); 100 } 101 102 delaySound++; 103 104 if (this.damageDealt >= 1.0F) { 105 this.c(i, j, k); 106 this.damageDealt = 0.0F; 107 this.c = 5; 108 delaySound = 0.0F; 109 } 110 } else { 111 this.damageDealt = 0.0F; 112 this.e = i; 113 this.f = j; 114 this.g = k; 115 delaySound = 0.0F; 116 } 117 } 118 } 119 120 // ======= END ======= 121 122 public void a() { 123 this.currentTick = System.currentTimeMillis(); // CraftBukkit 124 if (this.i) { 125 int i = (int) ((this.currentTick / 50) - (this.m / 50)); 126 int j = this.world.getTypeId(this.j, this.k, this.l); 127 128 if (j != 0) { 129 Block block = Block.byId[j]; 130 float f = block.getDamage(this.player) * (float) (i + 1); 131 132 if (f >= 1.0F) { 133 this.i = false; 134 this.c(this.j, this.k, this.l); 135 } 136 } else { 137 this.i = false; 138 } 139 } 140 } 141 142 // uberbukkit - make toolDamage from dig(...) accessible for getExpectedDigEnd() 143 public float toolDamage = 1.0F; 144 145 public void dig(int i, int j, int k, int l) { 146 // this.world.douseFire((EntityHuman) null, i, j, k, l); // CraftBukkit - moved down 147 this.lastDigTick = System.currentTimeMillis(); // CraftBukkit 148 int i1 = this.world.getTypeId(i, j, k); 149 150 // CraftBukkit start 151 // Swings at air do *NOT* exist. 152 if (i1 <= 0) { 153 return; 154 } 155 156 PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_BLOCK, i, j, k, l, this.player.inventory.getItemInHand()); 157 158 if (event.useInteractedBlock() == Event.Result.DENY) { 159 // If we denied a door from opening, we need to send a correcting update to the client, as it already opened the door. 160 if (i1 == Block.WOODEN_DOOR.id) { 161 // For some reason *BOTH* the bottom/top part have to be marked updated. 162 boolean bottom = (this.world.getData(i, j, k) & 8) == 0; 163 ((EntityPlayer) this.player).netServerHandler.sendPacket(new Packet53BlockChange(i, j, k, this.world)); 164 ((EntityPlayer) this.player).netServerHandler.sendPacket(new Packet53BlockChange(i, j + (bottom ? 1 : -1), k, this.world)); 165 } else if (i1 == Block.TRAP_DOOR.id) { 166 ((EntityPlayer) this.player).netServerHandler.sendPacket(new Packet53BlockChange(i, j, k, this.world)); 167 } 168 } else { 169 Block.byId[i1].b(this.world, i, j, k, this.player); 170 // Allow fire punching to be blocked 171 this.world.douseFire((EntityHuman) null, i, j, k, l); 172 } 173 174 // Handle hitting a block 175 toolDamage = Block.byId[i1].getDamage(this.player); 176 if (event.useItemInHand() == Event.Result.DENY) { 177 // If we 'insta destroyed' then the client needs to be informed. 178 if (toolDamage > 1.0f) { 179 ((EntityPlayer) this.player).netServerHandler.sendPacket(new Packet53BlockChange(i, j, k, this.world)); 180 } 181 return; 182 } 183 BlockDamageEvent blockEvent = CraftEventFactory.callBlockDamageEvent(this.player, i, j, k, this.player.inventory.getItemInHand(), toolDamage >= 1.0f); 184 185 if (blockEvent.isCancelled()) { 186 return; 187 } 188 189 if (blockEvent.getInstaBreak()) { 190 toolDamage = 2.0f; 191 } 192 193 Block block = Block.byId[i1]; 194 195 // uberbukkit - send digging sound 196 if (block != null) { 197 float vol1 = (block.stepSound.getVolume1() + 1.0F) / 8.0F; 198 199 ((CraftServer) Bukkit.getServer()).getHandle().sendPacketNearbyToScale(this.player, (double) i + 0.5D, (double) j + 0.5D, (double) k + 0.5D, vol1, ((WorldServer) this.player.world).dimension, new Packet62Sound(block.stepSound.getName(), (double) i + 0.5D, (double) j + 0.5D, (double) k + 0.5D, vol1, block.stepSound.getVolume2() * 0.5F)); 200 } 201 202 if (toolDamage >= 1.0F) { 203 // CraftBukkit end 204 this.c(i, j, k); 205 } else { 206 this.e = i; 207 this.f = j; 208 this.g = k; 209 } 210 } 211 212 public void a(int i, int j, int k) { 213 if (i == this.e && j == this.f && k == this.g) { 214 this.currentTick = System.currentTimeMillis(); // CraftBukkit 215 int l = (int) ((this.currentTick / 50) - (this.lastDigTick / 50)); 216 int i1 = this.world.getTypeId(i, j, k); 217 218 if (i1 != 0) { 219 Block block = Block.byId[i1]; 220 float f = block.getDamage(this.player) * (float) (l + 1); 221 222 if (f >= 0.7F) { 223 this.c(i, j, k); 224 } else if (!this.i) { 225 this.i = true; 226 this.j = i; 227 this.k = j; 228 this.l = k; 229 this.m = this.lastDigTick; 230 } 231 } 232 // CraftBukkit start - force blockreset to client 233 } else { 234 ((EntityPlayer) this.player).netServerHandler.sendPacket(new Packet53BlockChange(i, j, k, this.world)); 235 // CraftBukkit end 236 } 237 } 238 239 public long getExpectedDigEnd() { 240 return (long) (1F / toolDamage / 0.0214285703109844D) + this.lastDigTick; 241 } 242 243 public int getCurrentMagic() { 244 return (int) ((System.currentTimeMillis() / 50) - (this.lastDigTick / 50)); 245 } 246 247 public boolean b(int i, int j, int k) { 248 Block block = Block.byId[this.world.getTypeId(i, j, k)]; 249 int l = this.world.getData(i, j, k); 250 boolean flag = this.world.setTypeId(i, j, k, 0); 251 252 if (block != null && flag) { 253 block.postBreak(this.world, i, j, k, l); 254 } 255 256 return flag; 257 } 258 259 public boolean c(int i, int j, int k) { 260 // CraftBukkit start 261 if (this.player instanceof EntityPlayer) { 262 org.bukkit.block.Block block = this.world.getWorld().getBlockAt(i, j, k); 263 264 //Project Poseidon Start - Craft Bukkit backport 265 // Tell client the block is gone immediately then process events 266 if (world.getTileEntity(i, j, k) == null) { 267 ((EntityPlayer) this.player).netServerHandler.sendPacket(new ArtificialPacket53BlockChange(i, j, k, 0, 0)); 268 } 269 //Project Poseidon End 270 BlockBreakEvent event = new BlockBreakEvent(block, (org.bukkit.entity.Player) this.player.getBukkitEntity()); 271 this.world.getServer().getPluginManager().callEvent(event); 272 273 if (event.isCancelled()) { 274 return false; 275 } 276 } 277 // CraftBukkit end 278 279 int l = this.world.getTypeId(i, j, k); 280 int i1 = this.world.getData(i, j, k); 281 282 this.world.a(this.player, 2001, i, j, k, l + this.world.getData(i, j, k) * 256); 283 boolean flag = this.b(i, j, k); 284 ItemStack itemstack = this.player.G(); 285 286 if (flag && this.player.b(Block.byId[l])) { 287 Block.byId[l].a(this.world, this.player, i, j, k, i1); 288 ((EntityPlayer) this.player).netServerHandler.sendPacket(new Packet53BlockChange(i, j, k, this.world)); 289 } 290 291 if (itemstack != null) { 292 itemstack.a(l, i, j, k, this.player); 293 if (itemstack.count == 0) { 294 itemstack.a(this.player); 295 this.player.H(); 296 } 297 } 298 299 return flag; 300 } 301 302 public boolean useItem(EntityHuman entityhuman, World world, ItemStack itemstack) { 303 int i = itemstack.count; 304 ItemStack itemstack1 = itemstack.a(world, entityhuman); 305 306 if (itemstack1 == itemstack && (itemstack1 == null || itemstack1.count == i)) { 307 return false; 308 } else { 309 entityhuman.inventory.items[entityhuman.inventory.itemInHandIndex] = itemstack1; 310 if (itemstack1.count == 0) { 311 entityhuman.inventory.items[entityhuman.inventory.itemInHandIndex] = null; 312 } 313 314 return true; 315 } 316 } 317 318 public boolean interact(EntityHuman entityhuman, World world, ItemStack itemstack, int i, int j, int k, int l) { 319 int i1 = world.getTypeId(i, j, k); 320 321 // CraftBukkit start - Interact 322 boolean result = false; 323 if (i1 > 0) { 324 PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(entityhuman, Action.RIGHT_CLICK_BLOCK, i, j, k, l, itemstack); 325 if (event.useInteractedBlock() == Event.Result.DENY) { 326 // If we denied a door from opening, we need to send a correcting update to the client, as it already opened the door. 327 if (i1 == Block.WOODEN_DOOR.id) { 328 boolean bottom = (world.getData(i, j, k) & 8) == 0; 329 ((EntityPlayer) entityhuman).netServerHandler.sendPacket(new Packet53BlockChange(i, j + (bottom ? 1 : -1), k, world)); 330 } 331 result = (event.useItemInHand() != Event.Result.ALLOW); 332 } else { 333 result = Block.byId[i1].interact(world, i, j, k, entityhuman); 334 } 335 336 if (itemstack != null && !result) { 337 result = itemstack.placeItem(entityhuman, world, i, j, k, l); 338 } 339 340 // If we have 'true' and no explicit deny *or* an explicit allow -- run the item part of the hook 341 if (itemstack != null && ((!result && event.useItemInHand() != Event.Result.DENY) || event.useItemInHand() == Event.Result.ALLOW)) { 342 this.useItem(entityhuman, world, itemstack); 343 } 344 } 345 return result; 346 // CraftBukkit end 347 } 348}