--- a/net/minecraft/server/EntityItem.java +++ b/net/minecraft/server/EntityItem.java @@ -3,16 +3,21 @@ import java.util.Iterator; import java.util.UUID; import javax.annotation.Nullable; +// CraftBukkit start +import org.bukkit.event.entity.EntityPickupItemEvent; +import org.bukkit.event.player.PlayerPickupItemEvent; +// CraftBukkit end public class EntityItem extends Entity { private static final DataWatcherObject<ItemStack> b = DataWatcher.a(EntityItem.class, DataWatcherRegistry.g); - private int age; + public int age; // PAIL public int pickupDelay; private int e; private UUID f; private UUID g; public float a; + private int lastTick = MinecraftServer.currentTick - 1; // CraftBukkit public EntityItem(World world) { super(EntityTypes.ITEM, world); @@ -48,9 +53,12 @@ this.die(); } else { super.tick(); - 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; @@ -100,9 +108,11 @@ this.motY *= -0.5D; } + /* Craftbukkit start - moved up if (this.age != -32768) { ++this.age; } + // Craftbukkit end */ this.impulse |= this.at(); if (!this.world.isClientSide) { @@ -117,6 +127,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(); } @@ -165,6 +181,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); @@ -197,6 +214,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.aA(); this.e = (int) ((float) this.e - f); if (this.e <= 0) { @@ -255,6 +277,35 @@ 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); + // Call legacy event + PlayerPickupItemEvent playerEvent = new PlayerPickupItemEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), (org.bukkit.entity.Item) this.getBukkitEntity(), remaining); + playerEvent.setCancelled(!entityhuman.canPickUpLoot); + this.world.getServer().getPluginManager().callEvent(playerEvent); + if (playerEvent.isCancelled()) { + return; + } + + // Call newer event afterwards + EntityPickupItemEvent entityEvent = new EntityPickupItemEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), (org.bukkit.entity.Item) this.getBukkitEntity(), remaining); + entityEvent.setCancelled(!entityhuman.canPickUpLoot); + this.world.getServer().getPluginManager().callEvent(entityEvent); + if (entityEvent.isCancelled()) { + return; + } + + itemstack.setCount(canHold + remaining); + + // Possibly < 0; fix here so we do not have to modify code below + this.pickupDelay = 0; + } + // CraftBukkit end + if (this.pickupDelay == 0 && (this.g == null || 6000 - this.age <= 200 || this.g.equals(entityhuman.getUniqueID())) && entityhuman.inventory.pickup(itemstack)) { entityhuman.receive(this, i); if (itemstack.isEmpty()) { @@ -294,7 +345,9 @@ } public void setItemStack(ItemStack itemstack) { + com.google.common.base.Preconditions.checkArgument(!itemstack.isEmpty(), "Cannot drop air"); // CraftBukkit this.getDataWatcher().set(EntityItem.b, itemstack); + this.getDataWatcher().markDirty(EntityItem.b); // CraftBukkit - SPIGOT-4591, must mark dirty } @Nullable