1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
--- a/net/minecraft/server/EntityItem.java
+++ b/net/minecraft/server/EntityItem.java
@@ -4,15 +4,18 @@
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+import org.bukkit.event.player.PlayerPickupItemEvent; // CraftBukkit
+
public class EntityItem extends Entity {
private static final Logger b = LogManager.getLogger();
private int age;
- private int pickupDelay;
+ public int pickupDelay; // CraftBukkit - public
private int e;
private String f;
private String g;
public float a;
+ private int lastTick = MinecraftServer.currentTick; // CraftBukkit
public EntityItem(World world, double d0, double d1, double d2) {
super(world);
@@ -28,6 +31,11 @@
public EntityItem(World world, double d0, double d1, double d2, ItemStack itemstack) {
this(world, d0, d1, d2);
+ // CraftBukkit start - Can't set null items in the datawatcher
+ if (itemstack == null || itemstack.getItem() == null) {
+ return;
+ }
+ // CraftBukkit end
this.setItemStack(itemstack);
}
@@ -52,9 +60,12 @@
this.die();
} else {
super.t_();
- 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;
@@ -90,12 +101,21 @@
this.motY *= -0.5D;
}
+ /* Craftbukkit start - moved up
if (this.age != -32768) {
++this.age;
}
+ // Craftbukkit end */
+
this.W();
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();
}
@@ -183,6 +203,11 @@
} else if (this.getItemStack() != null && 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.ac();
this.e = (int) ((float) this.e - f);
if (this.e <= 0) {
@@ -228,7 +253,18 @@
NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("Item");
- this.setItemStack(ItemStack.createStack(nbttagcompound1));
+ // CraftBukkit start - Handle missing "Item" compounds
+ if (nbttagcompound1 != null) {
+ ItemStack itemstack = ItemStack.createStack(nbttagcompound1);
+ if (itemstack != null) {
+ this.setItemStack(itemstack);
+ } else {
+ this.die();
+ }
+ } else {
+ this.die();
+ }
+ // CraftBukkit end
if (this.getItemStack() == null) {
this.die();
}
@@ -240,6 +276,26 @@
ItemStack itemstack = this.getItemStack();
int i = itemstack.count;
+ // CraftBukkit start - fire PlayerPickupItemEvent
+ int canHold = entityhuman.inventory.canHold(itemstack);
+ int remaining = itemstack.count - canHold;
+
+ if (this.pickupDelay <= 0 && canHold > 0) {
+ itemstack.count = 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.count = 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.g == null || 6000 - this.age <= 200 || this.g.equals(entityhuman.getName())) && entityhuman.inventory.pickup(itemstack)) {
if (itemstack.getItem() == Item.getItemOf(Blocks.LOG)) {
entityhuman.b((Statistic) AchievementList.g);
|