--- a/net/minecraft/server/EntityItem.java +++ b/net/minecraft/server/EntityItem.java @@ -4,6 +4,7 @@ import javax.annotation.Nullable; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.bukkit.event.player.PlayerPickupItemEvent; // CraftBukkit public class EntityItem extends Entity { @@ -15,6 +16,7 @@ private String g; private String h; public float a; + private int lastTick = MinecraftServer.currentTick - 1; // CraftBukkit public EntityItem(World world, double d0, double d1, double d2) { super(world); @@ -54,9 +56,12 @@ this.die(); } else { super.B_(); - if (this.pickupDelay > 0 && this.pickupDelay != 32767) { - --this.pickupDelay; - } + // CraftBukkit start - Use wall time for pickup and despawn timers + int elapsedTicks = MinecraftServer.currentTick - this.lastTick; + if (this.pickupDelay != 32767) this.pickupDelay -= elapsedTicks; + if (this.age != -32768) this.age += elapsedTicks; + this.lastTick = MinecraftServer.currentTick; + // CraftBukkit end this.lastX = this.locX; this.lastY = this.locY; @@ -104,9 +109,11 @@ this.motY *= -0.5D; } + /* Craftbukkit start - moved up if (this.age != -32768) { ++this.age; } + // Craftbukkit end */ this.aq(); if (!this.world.isClientSide) { @@ -121,6 +128,12 @@ } if (!this.world.isClientSide && this.age >= 6000) { + // CraftBukkit start - fire ItemDespawnEvent + if (org.bukkit.craftbukkit.event.CraftEventFactory.callItemDespawnEvent(this).isCancelled()) { + this.age = 0; + return; + } + // CraftBukkit end this.die(); } @@ -162,6 +175,7 @@ } else if (itemstack1.getCount() + itemstack.getCount() > itemstack1.getMaxStackSize()) { return false; } else { + if (org.bukkit.craftbukkit.event.CraftEventFactory.callItemMergeEvent(this, entityitem).isCancelled()) return false; // CraftBukkit itemstack1.add(itemstack.getCount()); entityitem.pickupDelay = Math.max(entityitem.pickupDelay, this.pickupDelay); entityitem.age = Math.min(entityitem.age, this.age); @@ -208,6 +222,11 @@ } else if (!this.getItemStack().isEmpty() && this.getItemStack().getItem() == Items.NETHER_STAR && damagesource.isExplosion()) { return false; } else { + // CraftBukkit start + if (org.bukkit.craftbukkit.event.CraftEventFactory.handleNonLivingEntityDamageEvent(this, damagesource, f)) { + return false; + } + // CraftBukkit end this.ax(); this.f = (int) ((float) this.f - f); if (this.f <= 0) { @@ -270,6 +289,26 @@ Item item = itemstack.getItem(); int i = itemstack.getCount(); + // CraftBukkit start - fire PlayerPickupItemEvent + int canHold = entityhuman.inventory.canHold(itemstack); + int remaining = i - canHold; + + if (this.pickupDelay <= 0 && canHold > 0) { + itemstack.setCount(canHold); + PlayerPickupItemEvent event = new PlayerPickupItemEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), (org.bukkit.entity.Item) this.getBukkitEntity(), remaining); + // event.setCancelled(!entityhuman.canPickUpLoot); TODO + this.world.getServer().getPluginManager().callEvent(event); + itemstack.setCount(canHold + remaining); + + if (event.isCancelled()) { + return; + } + + // Possibly < 0; fix here so we do not have to modify code below + this.pickupDelay = 0; + } + // CraftBukkit end + if (this.pickupDelay == 0 && (this.h == null || 6000 - this.age <= 200 || this.h.equals(entityhuman.getName())) && entityhuman.inventory.pickup(itemstack)) { entityhuman.receive(this, i); if (itemstack.isEmpty()) {