Commits
md_5 authored 91cae6efbf0
78 78 | |
79 79 | |
80 80 | return this.h ? Items.AIR : this.item; |
81 81 | } |
82 82 | |
83 83 | - public EnumInteractionResult placeItem(ItemActionContext itemactioncontext) { |
84 84 | + public EnumInteractionResult placeItem(ItemActionContext itemactioncontext, EnumHand enumhand) { // CraftBukkit - add hand |
85 85 | EntityHuman entityhuman = itemactioncontext.getEntity(); |
86 86 | BlockPosition blockposition = itemactioncontext.getClickPosition(); |
87 87 | ShapeDetectorBlock shapedetectorblock = new ShapeDetectorBlock(itemactioncontext.getWorld(), blockposition, false); |
88 - | |
88 + | |
89 89 | if (entityhuman != null && !entityhuman.abilities.mayBuild && !this.b(itemactioncontext.getWorld().F(), shapedetectorblock)) { |
90 90 | return EnumInteractionResult.PASS; |
91 91 | } else { |
92 92 | + // CraftBukkit start - handle all block place event logic here |
93 + | + NBTTagCompound oldData = this.getTagClone(); |
93 94 | + int oldCount = this.getCount(); |
94 95 | + World world = itemactioncontext.getWorld(); |
95 96 | + |
96 97 | + if (!(this.getItem() instanceof ItemBucket)) { // if not bucket |
97 98 | + world.captureBlockStates = true; |
98 99 | + // special case bonemeal |
99 100 | + if (this.getItem() == Items.BONE_MEAL) { |
100 101 | + world.captureTreeGeneration = true; |
101 102 | + } |
102 103 | + } |
103 104 | Item item = this.getItem(); |
104 105 | EnumInteractionResult enuminteractionresult = item.a(itemactioncontext); |
106 + | + NBTTagCompound newData = this.getTagClone(); |
105 107 | + int newCount = this.getCount(); |
106 108 | + this.setCount(oldCount); |
109 + | + this.setTagClone(oldData); |
107 110 | + world.captureBlockStates = false; |
108 111 | + if (enuminteractionresult == EnumInteractionResult.SUCCESS && world.captureTreeGeneration && world.capturedBlockStates.size() > 0) { |
109 112 | + world.captureTreeGeneration = false; |
110 113 | + Location location = new Location(world.getWorld(), blockposition.getX(), blockposition.getY(), blockposition.getZ()); |
111 114 | + TreeType treeType = BlockSapling.treeType; |
112 115 | + BlockSapling.treeType = null; |
113 116 | + List<BlockState> blocks = (List<BlockState>) world.capturedBlockStates.clone(); |
114 117 | + world.capturedBlockStates.clear(); |
115 118 | + StructureGrowEvent structureEvent = null; |
116 119 | + if (treeType != null) { |
117 120 | + boolean isBonemeal = getItem() == Items.BONE_MEAL; |
118 121 | + structureEvent = new StructureGrowEvent(location, treeType, isBonemeal, (Player) entityhuman.getBukkitEntity(), blocks); |
119 122 | + org.bukkit.Bukkit.getPluginManager().callEvent(structureEvent); |
120 123 | + } |
121 124 | + |
122 125 | + BlockFertilizeEvent fertilizeEvent = new BlockFertilizeEvent(CraftBlock.at(world, blockposition), (Player) entityhuman.getBukkitEntity(), blocks); |
123 126 | + fertilizeEvent.setCancelled(structureEvent != null && structureEvent.isCancelled()); |
124 127 | + org.bukkit.Bukkit.getPluginManager().callEvent(fertilizeEvent); |
125 128 | + |
126 129 | + if (!fertilizeEvent.isCancelled()) { |
127 130 | + // Change the stack to its new contents if it hasn't been tampered with. |
128 - | + if (this.getCount() == oldCount) { |
131 + | + if (this.getCount() == oldCount && Objects.equals(this.tag, oldData)) { |
132 + | + this.setTag(newData); |
129 133 | + this.setCount(newCount); |
130 134 | + } |
131 135 | + for (BlockState blockstate : blocks) { |
132 136 | + blockstate.update(true); |
133 137 | + } |
134 138 | + } |
135 139 | + |
136 140 | + return enuminteractionresult; |
137 141 | + } |
138 142 | + world.captureTreeGeneration = false; |
157 161 | + blockstate.update(true, false); |
158 162 | + } |
159 163 | + |
160 164 | + // Brute force all possible updates |
161 165 | + BlockPosition placedPos = ((CraftBlock) placeEvent.getBlock()).getPosition(); |
162 166 | + for (EnumDirection dir : EnumDirection.values()) { |
163 167 | + ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutBlockChange(world, placedPos.shift(dir))); |
164 168 | + } |
165 169 | + } else { |
166 170 | + // Change the stack to its new contents if it hasn't been tampered with. |
167 - | + if (this.getCount() == oldCount) { |
171 + | + if (this.getCount() == oldCount && Objects.equals(this.tag, oldData)) { |
172 + | + this.setTag(newData); |
168 173 | + this.setCount(newCount); |
169 174 | + } |
170 175 | + |
171 176 | + for (Map.Entry<BlockPosition, TileEntity> e : world.capturedTileEntities.entrySet()) { |
172 177 | + world.setTileEntity(e.getKey(), e.getValue()); |
173 178 | + } |
174 179 | + |
175 180 | + for (BlockState blockstate : blocks) { |
176 181 | + int x = blockstate.getX(); |
177 182 | + int y = blockstate.getY(); |
222 227 | + |
223 228 | + entityhuman.b(StatisticList.ITEM_USED.b(item)); |
224 229 | + } |
225 230 | } |
226 231 | + world.capturedTileEntities.clear(); |
227 232 | + world.capturedBlockStates.clear(); |
228 233 | + // CraftBukkit end |
229 234 | |
230 235 | return enuminteractionresult; |
231 236 | } |
232 - | |
237 + | |
233 238 | nbttagcompound.setString("id", minecraftkey == null ? "minecraft:air" : minecraftkey.toString()); |
234 239 | nbttagcompound.setByte("Count", (byte) this.count); |
235 240 | if (this.tag != null) { |
236 241 | - nbttagcompound.set("tag", this.tag); |
237 242 | + nbttagcompound.set("tag", this.tag.clone()); // CraftBukkit - make defensive copy, data is going to another thread |
238 243 | } |
239 244 | |
240 245 | return nbttagcompound; |
241 - | |
246 + | |
242 247 | if (this.isDamaged(i, entityliving.getRandom(), entityliving instanceof EntityPlayer ? (EntityPlayer) entityliving : null)) { |
243 248 | entityliving.c(this); |
244 249 | Item item = this.getItem(); |
245 250 | + // CraftBukkit start - Check for item breaking |
246 251 | + if (this.count == 1 && entityliving instanceof EntityHuman) { |
247 252 | + org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerItemBreakEvent((EntityHuman) entityliving, this); |
248 253 | + } |
249 254 | + // CraftBukkit end |
250 255 | |
251 256 | this.subtract(1); |
252 257 | if (entityliving instanceof EntityHuman) { |
253 - | |
258 + | |
259 + | return this.tag; |
260 + | } |
261 + | |
262 + | + // CraftBukkit start |
263 + | + @Nullable |
264 + | + private NBTTagCompound getTagClone() { |
265 + | + return this.tag == null ? null : this.tag.clone(); |
266 + | + } |
267 + | + |
268 + | + private void setTagClone(@Nullable NBTTagCompound nbtttagcompound) { |
269 + | + this.setTag(nbtttagcompound == null ? null : nbtttagcompound.clone()); |
270 + | + } |
271 + | + // CraftBukkit end |
272 + | + |
273 + | public NBTTagCompound getOrCreateTag() { |
274 + | if (this.tag == null) { |
275 + | this.setTag(new NBTTagCompound()); |
276 + | |
254 277 | } |
255 278 | |
256 279 | public void setRepairCost(int i) { |
257 280 | + // CraftBukkit start - remove RepairCost tag when 0 (SPIGOT-3945) |
258 281 | + if (i == 0) { |
259 282 | + if (this.hasTag()) { |
260 283 | + this.tag.remove("RepairCost"); |
261 284 | + } |
262 285 | + return; |
263 286 | + } |
264 287 | + // CraftBukkit end |
265 288 | this.getOrCreateTag().setInt("RepairCost", i); |
266 289 | } |
267 290 | |
268 - | |
291 + | |
269 292 | nbttaglist.add((NBTBase) nbttagcompound); |
270 293 | } |
271 294 | |
272 295 | + // CraftBukkit start |
273 296 | + @Deprecated |
274 297 | + public void setItem(Item item) { |
275 298 | + this.item = item; |
276 299 | + } |
277 300 | + // CraftBukkit end |
278 301 | + |