Commits

DerFrZocker authored and md_5 committed 7c49f6279e1
SPIGOT-6895: Trees grown with applyBoneMeal() don't fire the StructureGrowthEvent
No tags

src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java

Modified
1 1 package org.bukkit.craftbukkit.block;
2 2
3 3 import com.google.common.base.Preconditions;
4 +import java.util.ArrayList;
4 5 import java.util.Collection;
5 6 import java.util.Collections;
6 7 import java.util.List;
8 +import java.util.Objects;
7 9 import java.util.stream.Collectors;
8 10 import net.minecraft.core.BlockPosition;
9 11 import net.minecraft.core.EnumDirection;
10 12 import net.minecraft.core.Holder;
11 13 import net.minecraft.core.IRegistry;
12 14 import net.minecraft.resources.ResourceKey;
13 15 import net.minecraft.server.level.WorldServer;
14 16 import net.minecraft.world.EnumHand;
15 17 import net.minecraft.world.EnumInteractionResult;
16 18 import net.minecraft.world.item.ItemBoneMeal;
17 19 import net.minecraft.world.item.Items;
18 20 import net.minecraft.world.item.context.ItemActionContext;
19 21 import net.minecraft.world.level.EnumSkyBlock;
20 22 import net.minecraft.world.level.GeneratorAccess;
21 23 import net.minecraft.world.level.RayTrace;
22 24 import net.minecraft.world.level.biome.BiomeBase;
23 25 import net.minecraft.world.level.block.BlockRedstoneWire;
26 +import net.minecraft.world.level.block.BlockSapling;
24 27 import net.minecraft.world.level.block.Blocks;
25 28 import net.minecraft.world.level.block.state.IBlockData;
26 29 import net.minecraft.world.phys.AxisAlignedBB;
27 30 import net.minecraft.world.phys.MovingObjectPosition;
28 31 import net.minecraft.world.phys.MovingObjectPositionBlock;
29 32 import net.minecraft.world.phys.Vec3D;
30 33 import net.minecraft.world.phys.shapes.VoxelShape;
31 34 import org.apache.commons.lang.Validate;
35 +import org.bukkit.Bukkit;
32 36 import org.bukkit.Chunk;
33 37 import org.bukkit.FluidCollisionMode;
34 38 import org.bukkit.Location;
35 39 import org.bukkit.Material;
36 40 import org.bukkit.Registry;
41 +import org.bukkit.TreeType;
37 42 import org.bukkit.World;
38 43 import org.bukkit.block.Biome;
39 44 import org.bukkit.block.Block;
40 45 import org.bukkit.block.BlockFace;
41 46 import org.bukkit.block.BlockState;
42 47 import org.bukkit.block.PistonMoveReaction;
43 48 import org.bukkit.block.data.BlockData;
44 49 import org.bukkit.craftbukkit.CraftFluidCollisionMode;
45 50 import org.bukkit.craftbukkit.CraftWorld;
46 51 import org.bukkit.craftbukkit.block.data.CraftBlockData;
47 52 import org.bukkit.craftbukkit.entity.CraftEntity;
48 53 import org.bukkit.craftbukkit.entity.CraftPlayer;
49 54 import org.bukkit.craftbukkit.inventory.CraftItemStack;
50 55 import org.bukkit.craftbukkit.util.CraftMagicNumbers;
51 56 import org.bukkit.craftbukkit.util.CraftNamespacedKey;
52 57 import org.bukkit.craftbukkit.util.CraftRayTraceResult;
53 58 import org.bukkit.craftbukkit.util.CraftVoxelShape;
54 59 import org.bukkit.entity.Entity;
55 60 import org.bukkit.entity.Player;
61 +import org.bukkit.event.block.BlockFertilizeEvent;
62 +import org.bukkit.event.world.StructureGrowEvent;
56 63 import org.bukkit.inventory.ItemStack;
57 64 import org.bukkit.metadata.MetadataValue;
58 65 import org.bukkit.plugin.Plugin;
59 66 import org.bukkit.util.BlockVector;
60 67 import org.bukkit.util.BoundingBox;
61 68 import org.bukkit.util.RayTraceResult;
62 69 import org.bukkit.util.Vector;
63 70
64 71 public class CraftBlock implements Block {
65 72 private final net.minecraft.world.level.GeneratorAccess world;
476 483 result = true;
477 484 }
478 485
479 486 // SPIGOT-6778: Directly call setBlock instead of setTypeAndData, so that the tile entiy is not removed and custom remove logic is run.
480 487 return world.setBlock(position, Blocks.AIR.defaultBlockState(), 3) && result;
481 488 }
482 489
483 490 @Override
484 491 public boolean applyBoneMeal(BlockFace face) {
485 492 EnumDirection direction = blockFaceToNotch(face);
486 - ItemActionContext context = new ItemActionContext(getCraftWorld().getHandle(), null, EnumHand.MAIN_HAND, Items.BONE_MEAL.getDefaultInstance(), new MovingObjectPositionBlock(Vec3D.ZERO, direction, getPosition(), false));
493 + BlockFertilizeEvent event = null;
494 + WorldServer world = getCraftWorld().getHandle();
495 + ItemActionContext context = new ItemActionContext(world, null, EnumHand.MAIN_HAND, Items.BONE_MEAL.getDefaultInstance(), new MovingObjectPositionBlock(Vec3D.ZERO, direction, getPosition(), false));
496 +
497 + // SPIGOT-6895: Call StructureGrowEvent and BlockFertilizeEvent
498 + world.captureTreeGeneration = true;
499 + EnumInteractionResult result = ItemBoneMeal.applyBonemeal(context);
500 + world.captureTreeGeneration = false;
501 +
502 + if (world.capturedBlockStates.size() > 0) {
503 + TreeType treeType = BlockSapling.treeType;
504 + BlockSapling.treeType = null;
505 + List<BlockState> blocks = new ArrayList<>(world.capturedBlockStates.values());
506 + world.capturedBlockStates.clear();
507 + StructureGrowEvent structureEvent = null;
508 +
509 + if (treeType != null) {
510 + structureEvent = new StructureGrowEvent(getLocation(), treeType, true, null, blocks);
511 + Bukkit.getPluginManager().callEvent(structureEvent);
512 + }
513 +
514 + event = new BlockFertilizeEvent(CraftBlock.at(world, getPosition()), null, blocks);
515 + event.setCancelled(structureEvent != null && structureEvent.isCancelled());
516 + Bukkit.getPluginManager().callEvent(event);
517 +
518 + if (!event.isCancelled()) {
519 + for (BlockState blockstate : blocks) {
520 + blockstate.update(true);
521 + }
522 + }
523 + }
487 524
488 - return ItemBoneMeal.applyBonemeal(context) == EnumInteractionResult.SUCCESS;
525 + return result == EnumInteractionResult.SUCCESS && (event == null || !event.isCancelled());
489 526 }
490 527
491 528 @Override
492 529 public Collection<ItemStack> getDrops() {
493 530 return getDrops(null);
494 531 }
495 532
496 533 @Override
497 534 public Collection<ItemStack> getDrops(ItemStack item) {
498 535 return getDrops(item, null);

Everything looks good. We'll let you know here if there's anything you should know about.

Add shortcut