Commits
DerFrZocker authored and md_5 committed 7c49f6279e1
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 | |
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 | |
492 529 | public Collection<ItemStack> getDrops() { |
493 530 | return getDrops(null); |
494 531 | } |
495 532 | |
496 533 | |
497 534 | public Collection<ItemStack> getDrops(ItemStack item) { |
498 535 | return getDrops(item, null); |