summaryrefslogtreecommitdiffstats
path: root/nms-patches/EntityItem.patch
blob: 7fbea393b343a7703493aef66946487be2731ae6 (plain)
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
132
133
134
--- a/net/minecraft/server/EntityItem.java
+++ b/net/minecraft/server/EntityItem.java
@@ -5,6 +5,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 {
 
@@ -16,6 +17,7 @@
     private String g;
     private String h;
     public float a;
+    private int lastTick = MinecraftServer.currentTick; // CraftBukkit
 
     public EntityItem(World world, double d0, double d1, double d2) {
         super(world);
@@ -31,6 +33,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);
     }
 
@@ -55,9 +62,12 @@
             this.die();
         } else {
             super.m();
-            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;
@@ -96,12 +106,20 @@
                 this.motY *= -0.5D;
             }
 
+            /* Craftbukkit start - moved up
             if (this.age != -32768) {
                 ++this.age;
             }
+            // Craftbukkit end */
 
             this.ak();
             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();
             }
 
@@ -143,6 +161,7 @@
                     } else if (itemstack1.count + itemstack.count > itemstack1.getMaxStackSize()) {
                         return false;
                     } else {
+                        if (org.bukkit.craftbukkit.event.CraftEventFactory.callItemMergeEvent(this, entityitem).isCancelled()) return false; // CraftBukkit
                         itemstack1.count += itemstack.count;
                         entityitem.pickupDelay = Math.max(entityitem.pickupDelay, this.pickupDelay);
                         entityitem.age = Math.min(entityitem.age, this.age);
@@ -189,6 +208,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.ap();
             this.f = (int) ((float) this.f - f);
             if (this.f <= 0) {
@@ -238,7 +262,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();
         }
@@ -250,6 +285,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.h == null || 6000 - this.age <= 200 || this.h.equals(entityhuman.getName())) && entityhuman.inventory.pickup(itemstack)) {
                 if (itemstack.getItem() == Item.getItemOf(Blocks.LOG)) {
                     entityhuman.b((Statistic) AchievementList.g);