From e9680a5afedcf05341b332870e0c542a17d78efa Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Sat, 14 Dec 2024 18:16:46 -0800 Subject: [PATCH] partial: net.minecraft.world.level.block --- .../world/level/block/SaplingBlock.java.patch | 54 ++++++++ .../level/block/ScaffoldingBlock.java.patch | 11 ++ .../world/level/block/SculkBlock.java.patch | 16 +++ .../level/block/SculkCatalystBlock.java.patch | 21 ++++ .../level/block/SculkSensorBlock.java.patch | 77 ++++++++++++ .../level/block/SculkShriekerBlock.java.patch | 28 +++++ .../level/block/SculkSpreader.java.patch | 55 ++++++++ .../level/block/SculkVeinBlock.java.patch | 31 +++++ .../level/block/ShulkerBoxBlock.java.patch | 34 ++--- .../world/level/block/SignBlock.java.patch | 49 ++++---- .../level/block/SmithingTableBlock.java.patch | 10 +- .../world/level/block/SmokerBlock.java.patch | 8 +- .../level/block/SnifferEggBlock.java.patch | 46 +++---- .../level/block/SnowLayerBlock.java.patch | 14 +++ .../world/level/block/SpawnerBlock.java.patch | 24 ++++ .../world/level/block/SpongeBlock.java.patch | 98 +++++++++++++++ .../block/SpreadingSnowyDirtBlock.java.patch | 25 ++++ .../world/level/block/StemBlock.java.patch | 38 ++++++ .../level/block/StonecutterBlock.java.patch | 10 +- .../level/block/SugarCaneBlock.java.patch | 20 +++ .../block/SweetBerryBushBlock.java.patch | 48 +++++++ .../world/level/block/TargetBlock.java.patch | 34 +++-- .../world/level/block/TntBlock.java.patch | 91 ++++++++++++++ .../level/block/TrapDoorBlock.java.patch | 44 +++++++ .../level/block/TripWireBlock.java.patch | 108 ++++++++++++++++ .../level/block/TripWireHookBlock.java.patch | 21 ++++ .../level/block/TurtleEggBlock.java.patch | 64 ++++++++++ .../world/level/block/VineBlock.java.patch | 68 ++++++++++ .../block/WallHangingSignBlock.java.patch | 6 +- .../level/block/WaterlilyBlock.java.patch | 17 +++ .../world/level/block/WebBlock.java.patch | 6 +- .../WeightedPressurePlateBlock.java.patch | 39 ++++++ .../level/block/WitherRoseBlock.java.patch | 16 +++ .../level/block/WitherSkullBlock.java.patch | 39 ++++++ .../world/level/block/SaplingBlock.java.patch | 117 ------------------ .../level/block/ScaffoldingBlock.java.patch | 11 -- .../world/level/block/SculkBlock.java.patch | 16 --- .../level/block/SculkCatalystBlock.java.patch | 21 ---- .../level/block/SculkSensorBlock.java.patch | 88 ------------- .../level/block/SculkShriekerBlock.java.patch | 30 ----- .../level/block/SculkSpreader.java.patch | 98 --------------- .../level/block/SculkVeinBlock.java.patch | 60 --------- .../level/block/SnowLayerBlock.java.patch | 14 --- .../world/level/block/SpawnerBlock.java.patch | 26 ---- .../world/level/block/SpongeBlock.java.patch | 114 ----------------- .../block/SpreadingSnowyDirtBlock.java.patch | 25 ---- .../world/level/block/StemBlock.java.patch | 47 ------- .../level/block/SugarCaneBlock.java.patch | 21 ---- .../block/SweetBerryBushBlock.java.patch | 62 ---------- .../world/level/block/TntBlock.java.patch | 102 --------------- .../level/block/TrapDoorBlock.java.patch | 51 -------- .../level/block/TripWireBlock.java.patch | 114 ----------------- .../level/block/TripWireHookBlock.java.patch | 34 ----- .../level/block/TurtleEggBlock.java.patch | 76 ------------ .../world/level/block/VineBlock.java.patch | 79 ------------ .../level/block/WaterlilyBlock.java.patch | 27 ---- .../WeightedPressurePlateBlock.java.patch | 49 -------- .../level/block/WitherRoseBlock.java.patch | 15 --- .../level/block/WitherSkullBlock.java.patch | 50 -------- 59 files changed, 1165 insertions(+), 1452 deletions(-) create mode 100644 paper-server/patches/sources/net/minecraft/world/level/block/SaplingBlock.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/level/block/ScaffoldingBlock.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/level/block/SculkBlock.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/level/block/SculkCatalystBlock.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/level/block/SculkSensorBlock.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/level/block/SculkShriekerBlock.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/level/block/SculkSpreader.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/level/block/SculkVeinBlock.java.patch rename paper-server/patches/{unapplied => sources}/net/minecraft/world/level/block/ShulkerBoxBlock.java.patch (67%) rename paper-server/patches/{unapplied => sources}/net/minecraft/world/level/block/SignBlock.java.patch (51%) rename paper-server/patches/{unapplied => sources}/net/minecraft/world/level/block/SmithingTableBlock.java.patch (64%) rename paper-server/patches/{unapplied => sources}/net/minecraft/world/level/block/SmokerBlock.java.patch (51%) rename paper-server/patches/{unapplied => sources}/net/minecraft/world/level/block/SnifferEggBlock.java.patch (55%) create mode 100644 paper-server/patches/sources/net/minecraft/world/level/block/SnowLayerBlock.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/level/block/SpawnerBlock.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/level/block/SpongeBlock.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/level/block/StemBlock.java.patch rename paper-server/patches/{unapplied => sources}/net/minecraft/world/level/block/StonecutterBlock.java.patch (63%) create mode 100644 paper-server/patches/sources/net/minecraft/world/level/block/SugarCaneBlock.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/level/block/SweetBerryBushBlock.java.patch rename paper-server/patches/{unapplied => sources}/net/minecraft/world/level/block/TargetBlock.java.patch (60%) create mode 100644 paper-server/patches/sources/net/minecraft/world/level/block/TntBlock.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/level/block/TrapDoorBlock.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/level/block/TripWireBlock.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/level/block/TripWireHookBlock.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/level/block/TurtleEggBlock.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/level/block/VineBlock.java.patch rename paper-server/patches/{unapplied => sources}/net/minecraft/world/level/block/WallHangingSignBlock.java.patch (60%) create mode 100644 paper-server/patches/sources/net/minecraft/world/level/block/WaterlilyBlock.java.patch rename paper-server/patches/{unapplied => sources}/net/minecraft/world/level/block/WebBlock.java.patch (77%) create mode 100644 paper-server/patches/sources/net/minecraft/world/level/block/WeightedPressurePlateBlock.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/level/block/WitherRoseBlock.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/level/block/WitherSkullBlock.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/level/block/SaplingBlock.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/level/block/ScaffoldingBlock.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/level/block/SculkBlock.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/level/block/SculkCatalystBlock.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/level/block/SculkSensorBlock.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/level/block/SculkShriekerBlock.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/level/block/SculkSpreader.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/level/block/SculkVeinBlock.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/level/block/SnowLayerBlock.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/level/block/SpawnerBlock.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/level/block/SpongeBlock.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/level/block/StemBlock.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/level/block/SugarCaneBlock.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/level/block/SweetBerryBushBlock.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/level/block/TntBlock.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/level/block/TrapDoorBlock.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/level/block/TripWireBlock.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/level/block/TripWireHookBlock.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/level/block/TurtleEggBlock.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/level/block/VineBlock.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/level/block/WaterlilyBlock.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/level/block/WeightedPressurePlateBlock.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/level/block/WitherRoseBlock.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/level/block/WitherSkullBlock.java.patch diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/SaplingBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/SaplingBlock.java.patch new file mode 100644 index 0000000000..9cb7276a2c --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/SaplingBlock.java.patch @@ -0,0 +1,54 @@ +--- a/net/minecraft/world/level/block/SaplingBlock.java ++++ b/net/minecraft/world/level/block/SaplingBlock.java +@@ -26,6 +_,7 @@ + protected static final float AABB_OFFSET = 6.0F; + protected static final VoxelShape SHAPE = Block.box(2.0, 0.0, 2.0, 14.0, 12.0, 14.0); + protected final TreeGrower treeGrower; ++ public static org.bukkit.TreeType treeType; // CraftBukkit + + @Override + public MapCodec codec() { +@@ -45,7 +_,7 @@ + + @Override + protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { +- if (level.getMaxLocalRawBrightness(pos.above()) >= 9 && random.nextInt(7) == 0) { ++ if (level.getMaxLocalRawBrightness(pos.above()) >= 9 && random.nextFloat() < (level.spigotConfig.saplingModifier / (100.0f * 7))) { // Spigot - SPIGOT-7159: Better modifier resolution + this.advanceTree(level, pos, state, random); + } + } +@@ -54,7 +_,33 @@ + if (state.getValue(STAGE) == 0) { + level.setBlock(pos, state.cycle(STAGE), 4); + } else { +- this.treeGrower.growTree(level, level.getChunkSource().getGenerator(), pos, state, random); ++ // CraftBukkit start ++ if (level.captureTreeGeneration) { ++ this.treeGrower.growTree(level, level.getChunkSource().getGenerator(), pos, state, random); ++ } else { ++ level.captureTreeGeneration = true; ++ this.treeGrower.growTree(level, level.getChunkSource().getGenerator(), pos, state, random); ++ level.captureTreeGeneration = false; ++ if (level.capturedBlockStates.size() > 0) { ++ org.bukkit.TreeType treeType = SaplingBlock.treeType; ++ SaplingBlock.treeType = null; ++ org.bukkit.Location location = org.bukkit.craftbukkit.util.CraftLocation.toBukkit(pos, level.getWorld()); ++ java.util.List blocks = new java.util.ArrayList<>(level.capturedBlockStates.values()); ++ level.capturedBlockStates.clear(); ++ org.bukkit.event.world.StructureGrowEvent event = null; ++ if (treeType != null) { ++ event = new org.bukkit.event.world.StructureGrowEvent(location, treeType, false, null, blocks); ++ org.bukkit.Bukkit.getPluginManager().callEvent(event); ++ } ++ if (event == null || !event.isCancelled()) { ++ for (org.bukkit.block.BlockState blockstate : blocks) { ++ org.bukkit.craftbukkit.block.CapturedBlockState.setBlockState(blockstate); ++ level.checkCapturedTreeStateForObserverNotify(pos, (org.bukkit.craftbukkit.block.CraftBlockState) blockstate); // Paper - notify observers even if grow failed ++ } ++ } ++ } ++ } ++ // CraftBukkit end + } + } + diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/ScaffoldingBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/ScaffoldingBlock.java.patch new file mode 100644 index 0000000000..8ad4e9b5f3 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/ScaffoldingBlock.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/level/block/ScaffoldingBlock.java ++++ b/net/minecraft/world/level/block/ScaffoldingBlock.java +@@ -119,7 +_,7 @@ + protected void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { + int distance = getDistance(level, pos); + BlockState blockState = state.setValue(DISTANCE, Integer.valueOf(distance)).setValue(BOTTOM, Boolean.valueOf(this.isBottom(level, pos, distance))); +- if (blockState.getValue(DISTANCE) == 7) { ++ if (blockState.getValue(DISTANCE) == 7&& !org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(level, pos, blockState.getFluidState().createLegacyBlock()).isCancelled()) { // CraftBukkit - BlockFadeEvent // Paper - fix wrong block state + if (state.getValue(DISTANCE) == 7) { + FallingBlockEntity.fall(level, pos, blockState); + } else { diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/SculkBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/SculkBlock.java.patch new file mode 100644 index 0000000000..681606e369 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/SculkBlock.java.patch @@ -0,0 +1,16 @@ +--- a/net/minecraft/world/level/block/SculkBlock.java ++++ b/net/minecraft/world/level/block/SculkBlock.java +@@ -37,8 +_,11 @@ + if (random.nextInt(growthSpawnCost) < charge) { + BlockPos blockPos = pos1.above(); + BlockState randomGrowthState = this.getRandomGrowthState(level, blockPos, random, spreader.isWorldGeneration()); +- level.setBlock(blockPos, randomGrowthState, 3); +- level.playSound(null, pos1, randomGrowthState.getSoundType().getPlaceSound(), SoundSource.BLOCKS, 1.0F, 1.0F); ++ // CraftBukkit start - Call BlockSpreadEvent ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(level, pos, blockPos, randomGrowthState, 3)) { ++ level.playSound(null, pos1, randomGrowthState.getSoundType().getPlaceSound(), SoundSource.BLOCKS, 1.0F, 1.0F); ++ } ++ // CraftBukkit end + } + + return Math.max(0, charge - growthSpawnCost); diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/SculkCatalystBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/SculkCatalystBlock.java.patch new file mode 100644 index 0000000000..5ba297feff --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/SculkCatalystBlock.java.patch @@ -0,0 +1,21 @@ +--- a/net/minecraft/world/level/block/SculkCatalystBlock.java ++++ b/net/minecraft/world/level/block/SculkCatalystBlock.java +@@ -61,8 +_,16 @@ + @Override + protected void spawnAfterBreak(BlockState state, ServerLevel level, BlockPos pos, ItemStack stack, boolean dropExperience) { + super.spawnAfterBreak(state, level, pos, stack, dropExperience); ++ // CraftBukkit start - Delegate to getExpDrop ++ } ++ ++ @Override ++ public int getExpDrop(BlockState state, ServerLevel level, BlockPos pos, ItemStack stack, boolean dropExperience) { + if (dropExperience) { +- this.tryDropExperience(level, pos, stack, this.xpRange); ++ return this.tryDropExperience(level, pos, stack, this.xpRange); + } +- } ++ ++ return 0; ++ // CraftBukkit end ++ } + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/SculkSensorBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/SculkSensorBlock.java.patch new file mode 100644 index 0000000000..900eb7905e --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/SculkSensorBlock.java.patch @@ -0,0 +1,77 @@ +--- a/net/minecraft/world/level/block/SculkSensorBlock.java ++++ b/net/minecraft/world/level/block/SculkSensorBlock.java +@@ -108,6 +_,18 @@ + && level.getBlockEntity(pos) instanceof SculkSensorBlockEntity sculkSensorBlockEntity + && level instanceof ServerLevel serverLevel + && sculkSensorBlockEntity.getVibrationUser().canReceiveVibration(serverLevel, pos, GameEvent.STEP, GameEvent.Context.of(state))) { ++ // CraftBukkit start ++ org.bukkit.event.Cancellable cancellable; ++ if (entity instanceof net.minecraft.world.entity.player.Player player) { ++ cancellable = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent(player, org.bukkit.event.block.Action.PHYSICAL, pos, null, null, null); ++ } else { ++ cancellable = new org.bukkit.event.entity.EntityInteractEvent(entity.getBukkitEntity(), level.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ())); ++ level.getCraftServer().getPluginManager().callEvent((org.bukkit.event.entity.EntityInteractEvent) cancellable); ++ } ++ if (cancellable.isCancelled()) { ++ return; ++ } ++ // CraftBukkit end + sculkSensorBlockEntity.getListener().forceScheduleVibration(serverLevel, GameEvent.STEP, GameEvent.Context.of(entity), entity.position()); + } + +@@ -200,10 +_,19 @@ + } + + public static boolean canActivate(BlockState state) { +- return getPhase(state) == SculkSensorPhase.INACTIVE; ++ return state.getBlock() instanceof SculkSensorBlock && getPhase(state) == SculkSensorPhase.INACTIVE; // Paper - Check for a valid type + } + + public static void deactivate(Level level, BlockPos pos, BlockState state) { ++ // CraftBukkit start ++ org.bukkit.event.block.BlockRedstoneEvent eventRedstone = new org.bukkit.event.block.BlockRedstoneEvent(org.bukkit.craftbukkit.block.CraftBlock.at(level, pos), state.getValue(SculkSensorBlock.POWER), 0); ++ level.getCraftServer().getPluginManager().callEvent(eventRedstone); ++ ++ if (eventRedstone.getNewCurrent() > 0) { ++ level.setBlock(pos, state.setValue(SculkSensorBlock.POWER, eventRedstone.getNewCurrent()), 3); ++ return; ++ } ++ // CraftBukkit end + level.setBlock(pos, state.setValue(PHASE, SculkSensorPhase.COOLDOWN).setValue(POWER, Integer.valueOf(0)), 3); + level.scheduleTick(pos, state.getBlock(), 10); + updateNeighbours(level, pos, state); +@@ -215,6 +_,15 @@ + } + + public void activate(@Nullable Entity entity, Level level, BlockPos pos, BlockState state, int power, int frequency) { ++ // CraftBukkit start ++ org.bukkit.event.block.BlockRedstoneEvent eventRedstone = new org.bukkit.event.block.BlockRedstoneEvent(org.bukkit.craftbukkit.block.CraftBlock.at(level, pos), state.getValue(SculkSensorBlock.POWER), power); ++ level.getCraftServer().getPluginManager().callEvent(eventRedstone); ++ ++ if (eventRedstone.getNewCurrent() <= 0) { ++ return; ++ } ++ power = eventRedstone.getNewCurrent(); ++ // CraftBukkit end + level.setBlock(pos, state.setValue(PHASE, SculkSensorPhase.ACTIVE).setValue(POWER, Integer.valueOf(power)), 3); + level.scheduleTick(pos, state.getBlock(), this.getActiveTicks()); + updateNeighbours(level, pos, state); +@@ -292,8 +_,16 @@ + @Override + protected void spawnAfterBreak(BlockState state, ServerLevel level, BlockPos pos, ItemStack stack, boolean dropExperience) { + super.spawnAfterBreak(state, level, pos, stack, dropExperience); ++ // CraftBukkit start - Delegate to getExpDrop ++ } ++ ++ @Override ++ public int getExpDrop(BlockState state, ServerLevel level, BlockPos pos, ItemStack stack, boolean dropExperience) { + if (dropExperience) { +- this.tryDropExperience(level, pos, stack, ConstantInt.of(5)); ++ return this.tryDropExperience(level, pos, stack, ConstantInt.of(5)); + } +- } ++ ++ return 0; ++ // CraftBukkit end ++ } + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/SculkShriekerBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/SculkShriekerBlock.java.patch new file mode 100644 index 0000000000..ff23c12bec --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/SculkShriekerBlock.java.patch @@ -0,0 +1,28 @@ +--- a/net/minecraft/world/level/block/SculkShriekerBlock.java ++++ b/net/minecraft/world/level/block/SculkShriekerBlock.java +@@ -66,6 +_,7 @@ + if (level instanceof ServerLevel serverLevel) { + ServerPlayer serverPlayer = SculkShriekerBlockEntity.tryGetPlayer(entity); + if (serverPlayer != null) { ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent(serverPlayer, org.bukkit.event.block.Action.PHYSICAL, pos, null, null, null).isCancelled()) return; // CraftBukkit + serverLevel.getBlockEntity(pos, BlockEntityType.SCULK_SHRIEKER).ifPresent(sculkShrieker -> sculkShrieker.tryShriek(serverLevel, serverPlayer)); + } + } +@@ -144,9 +_,16 @@ + @Override + protected void spawnAfterBreak(BlockState state, ServerLevel level, BlockPos pos, ItemStack stack, boolean dropExperience) { + super.spawnAfterBreak(state, level, pos, stack, dropExperience); ++ // CraftBukkit start - Delegate to getExpDrop ++ } ++ ++ @Override ++ public int getExpDrop(BlockState state, ServerLevel level, BlockPos pos, ItemStack stack, boolean dropExperience) { + if (dropExperience) { +- this.tryDropExperience(level, pos, stack, ConstantInt.of(5)); ++ return this.tryDropExperience(level, pos, stack, ConstantInt.of(5)); + } ++ return 0; ++ // CraftBukkit end + } + + @Nullable diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/SculkSpreader.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/SculkSpreader.java.patch new file mode 100644 index 0000000000..07f35283e7 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/SculkSpreader.java.patch @@ -0,0 +1,55 @@ +--- a/net/minecraft/world/level/block/SculkSpreader.java ++++ b/net/minecraft/world/level/block/SculkSpreader.java +@@ -25,6 +_,7 @@ + import net.minecraft.core.Vec3i; + import net.minecraft.nbt.CompoundTag; + import net.minecraft.nbt.NbtOps; ++import net.minecraft.nbt.Tag; + import net.minecraft.server.level.ServerLevel; + import net.minecraft.sounds.SoundEvents; + import net.minecraft.sounds.SoundSource; +@@ -50,6 +_,7 @@ + private final int additionalDecayRate; + private List cursors = new ArrayList<>(); + private static final Logger LOGGER = LogUtils.getLogger(); ++ public net.minecraft.world.level.Level level; // CraftBukkit + + public SculkSpreader( + boolean isWorldGeneration, TagKey replaceableBlocks, int growthSpawnCoat, int noGrowthRadius, int chargeDecayRate, int additionalDecayRate +@@ -114,7 +_,7 @@ + int min = Math.min(list.size(), 32); + + for (int i = 0; i < min; i++) { +- this.addCursor(list.get(i)); ++ this.addCursor(list.get(i), false); // Paper - don't fire event for block entity loading + } + } + } +@@ -130,13 +_,25 @@ + public void addCursors(BlockPos pos, int charge) { + while (charge > 0) { + int min = Math.min(charge, 1000); +- this.addCursor(new SculkSpreader.ChargeCursor(pos, min)); ++ this.addCursor(new SculkSpreader.ChargeCursor(pos, min), true); // Paper - allow firing event for other causes + charge -= min; + } + } + +- private void addCursor(SculkSpreader.ChargeCursor cursor) { ++ private void addCursor(SculkSpreader.ChargeCursor cursor, boolean fireEvent) { // Paper - add boolean to conditionally fire SculkBloomEvent + if (this.cursors.size() < 32) { ++ // CraftBukkit start ++ if (!this.isWorldGeneration() && fireEvent) { // CraftBukkit - SPIGOT-7475: Don't call event during world generation // Paper - add boolean to conditionally fire SculkBloomEvent ++ org.bukkit.craftbukkit.block.CraftBlock bukkitBlock = org.bukkit.craftbukkit.block.CraftBlock.at(this.level, cursor.pos); ++ org.bukkit.event.block.SculkBloomEvent event = new org.bukkit.event.block.SculkBloomEvent(bukkitBlock, cursor.getCharge()); ++ org.bukkit.Bukkit.getPluginManager().callEvent(event); ++ if (event.isCancelled()) { ++ return; ++ } ++ ++ cursor.charge = event.getCharge(); ++ } ++ // CraftBukkit end + this.cursors.add(cursor); + } + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/SculkVeinBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/SculkVeinBlock.java.patch new file mode 100644 index 0000000000..ae401d6908 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/SculkVeinBlock.java.patch @@ -0,0 +1,31 @@ +--- a/net/minecraft/world/level/block/SculkVeinBlock.java ++++ b/net/minecraft/world/level/block/SculkVeinBlock.java +@@ -90,14 +_,14 @@ + public int attemptUseCharge( + SculkSpreader.ChargeCursor cursor, LevelAccessor level, BlockPos pos, RandomSource random, SculkSpreader spreader, boolean shouldConvertBlocks + ) { +- if (shouldConvertBlocks && this.attemptPlaceSculk(spreader, level, cursor.getPos(), random)) { ++ if (shouldConvertBlocks && this.attemptPlaceSculk(spreader, level, cursor.getPos(), random, pos)) { // CraftBukkit - add source block + return cursor.getCharge() - 1; + } else { + return random.nextInt(spreader.chargeDecayRate()) == 0 ? Mth.floor(cursor.getCharge() * 0.5F) : cursor.getCharge(); + } + } + +- private boolean attemptPlaceSculk(SculkSpreader spreader, LevelAccessor level, BlockPos pos, RandomSource random) { ++ private boolean attemptPlaceSculk(SculkSpreader spreader, LevelAccessor level, BlockPos pos, RandomSource random, BlockPos sourceBlock) { // CraftBukkit + BlockState blockState = level.getBlockState(pos); + TagKey tagKey = spreader.replaceableBlocks(); + +@@ -108,6 +_,11 @@ + if (blockState1.is(tagKey)) { + BlockState blockState2 = Blocks.SCULK.defaultBlockState(); + level.setBlock(blockPos, blockState2, 3); ++ // CraftBukkit start - Call BlockSpreadEvent ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(level, sourceBlock, blockPos, blockState2, 3)) { ++ return false; ++ } ++ // CraftBukkit end + Block.pushEntitiesUp(blockState1, blockState2, level, blockPos); + level.playSound(null, blockPos, SoundEvents.SCULK_BLOCK_SPREAD, SoundSource.BLOCKS, 1.0F, 1.0F); + this.veinSpreader.spreadAll(blockState2, level, blockPos, spreader.isWorldGeneration()); diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/ShulkerBoxBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/ShulkerBoxBlock.java.patch similarity index 67% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/ShulkerBoxBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/ShulkerBoxBlock.java.patch index ef705416f0..ebbcb447db 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/ShulkerBoxBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/ShulkerBoxBlock.java.patch @@ -1,48 +1,48 @@ --- a/net/minecraft/world/level/block/ShulkerBoxBlock.java +++ b/net/minecraft/world/level/block/ShulkerBoxBlock.java -@@ -98,8 +98,8 @@ - protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { - if (world instanceof ServerLevel serverLevel - && world.getBlockEntity(pos) instanceof ShulkerBoxBlockEntity shulkerBoxBlockEntity -- && canOpen(state, world, pos, shulkerBoxBlockEntity)) { +@@ -100,8 +_,8 @@ + protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) { + if (level instanceof ServerLevel serverLevel + && level.getBlockEntity(pos) instanceof ShulkerBoxBlockEntity shulkerBoxBlockEntity +- && canOpen(state, level, pos, shulkerBoxBlockEntity)) { - player.openMenu(shulkerBoxBlockEntity); -+ && canOpen(state, world, pos, shulkerBoxBlockEntity) // Paper - Fix InventoryOpenEvent cancellation - expand if for belows check -+ && player.openMenu(shulkerBoxBlockEntity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation ++ && canOpen(state, level, pos, shulkerBoxBlockEntity) // Paper - Fix InventoryOpenEvent cancellation - expand if for belows check ++ && player.openMenu(shulkerBoxBlockEntity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation) { player.awardStat(Stats.OPEN_SHULKER_BOX); PiglinAi.angerNearbyPiglins(serverLevel, player, true); } -@@ -137,7 +137,7 @@ +@@ -139,7 +_,7 @@ itemEntity.setDefaultPickUpDelay(); - world.addFreshEntity(itemEntity); + level.addFreshEntity(itemEntity); } else { - shulkerBoxBlockEntity.unpackLootTable(player); + shulkerBoxBlockEntity.unpackLootTable(player, true); // Paper - force clear loot table so replenish data isn't persisted in the stack } } -@@ -147,7 +147,15 @@ +@@ -149,7 +_,15 @@ @Override - protected List getDrops(BlockState state, LootParams.Builder builder) { - BlockEntity blockEntity = builder.getOptionalParameter(LootContextParams.BLOCK_ENTITY); + protected List getDrops(BlockState state, LootParams.Builder params) { + BlockEntity blockEntity = params.getOptionalParameter(LootContextParams.BLOCK_ENTITY); + Runnable reAdd = null; // Paper if (blockEntity instanceof ShulkerBoxBlockEntity shulkerBoxBlockEntity) { + // Paper start - clear loot table if it was already used -+ if (shulkerBoxBlockEntity.lootableData().getLastFill() != -1 || !builder.getLevel().paperConfig().lootables.retainUnlootedShulkerBoxLootTableOnNonPlayerBreak) { ++ if (shulkerBoxBlockEntity.lootableData().getLastFill() != -1 || !params.getLevel().paperConfig().lootables.retainUnlootedShulkerBoxLootTableOnNonPlayerBreak) { + net.minecraft.resources.ResourceKey lootTableResourceKey = shulkerBoxBlockEntity.getLootTable(); + reAdd = () -> shulkerBoxBlockEntity.setLootTable(lootTableResourceKey); + shulkerBoxBlockEntity.setLootTable(null); + } + // Paper end - builder = builder.withDynamicDrop(CONTENTS, lootConsumer -> { + params = params.withDynamicDrop(CONTENTS, output -> { for (int i = 0; i < shulkerBoxBlockEntity.getContainerSize(); i++) { - lootConsumer.accept(shulkerBoxBlockEntity.getItem(i)); -@@ -155,7 +163,13 @@ + output.accept(shulkerBoxBlockEntity.getItem(i)); +@@ -157,7 +_,13 @@ }); } + // Paper start - re-set loot table if it was cleared + try { - return super.getDrops(state, builder); + return super.getDrops(state, params); + } finally { + if (reAdd != null) reAdd.run(); + } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/SignBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/SignBlock.java.patch similarity index 51% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/SignBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/SignBlock.java.patch index 5dac1e3a2d..36c68ab94b 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/SignBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/SignBlock.java.patch @@ -1,33 +1,31 @@ --- a/net/minecraft/world/level/block/SignBlock.java +++ b/net/minecraft/world/level/block/SignBlock.java -@@ -140,7 +140,7 @@ - } else if (flag1) { - return InteractionResult.SUCCESS_SERVER; - } else if (!this.otherPlayerIsEditingSign(player, tileentitysign) && player.mayBuild() && this.hasEditableText(player, tileentitysign, flag)) { -- this.openTextEdit(player, tileentitysign, flag); -+ this.openTextEdit(player, tileentitysign, flag, io.papermc.paper.event.player.PlayerOpenSignEvent.Cause.INTERACT); // Paper - Add PlayerOpenSignEvent +@@ -134,7 +_,7 @@ + } else if (!this.otherPlayerIsEditingSign(player, signBlockEntity) + && player.mayBuild() + && this.hasEditableText(player, signBlockEntity, isFacingFrontText)) { +- this.openTextEdit(player, signBlockEntity, isFacingFrontText); ++ this.openTextEdit(player, signBlockEntity, isFacingFrontText, io.papermc.paper.event.player.PlayerOpenSignEvent.Cause.INTERACT); // Paper - Add PlayerOpenSignEvent return InteractionResult.SUCCESS_SERVER; } else { return InteractionResult.PASS; -@@ -185,10 +185,36 @@ - return blockpropertywood; +@@ -176,7 +_,33 @@ + return woodType; } + @io.papermc.paper.annotation.DoNotUse @Deprecated // Paper - Add PlayerOpenSignEvent - public void openTextEdit(Player player, SignBlockEntity blockEntity, boolean front) { -- blockEntity.setAllowedPlayerEditor(player.getUUID()); -- player.openTextEdit(blockEntity, front); + public void openTextEdit(Player player, SignBlockEntity signEntity, boolean isFrontText) { + // Paper start - Add PlayerOpenSignEvent -+ this.openTextEdit(player, blockEntity, front, io.papermc.paper.event.player.PlayerOpenSignEvent.Cause.UNKNOWN); - } -+ public void openTextEdit(Player entityhuman, SignBlockEntity tileentitysign, boolean flag, io.papermc.paper.event.player.PlayerOpenSignEvent.Cause cause) { -+ org.bukkit.entity.Player bukkitPlayer = (org.bukkit.entity.Player) entityhuman.getBukkitEntity(); -+ org.bukkit.block.Block bukkitBlock = org.bukkit.craftbukkit.block.CraftBlock.at(tileentitysign.getLevel(), tileentitysign.getBlockPos()); ++ this.openTextEdit(player, signEntity, isFrontText, io.papermc.paper.event.player.PlayerOpenSignEvent.Cause.UNKNOWN); ++ } ++ public void openTextEdit(Player player, SignBlockEntity signEntity, boolean isFrontText, io.papermc.paper.event.player.PlayerOpenSignEvent.Cause cause) { ++ org.bukkit.entity.Player bukkitPlayer = (org.bukkit.entity.Player) player.getBukkitEntity(); ++ org.bukkit.block.Block bukkitBlock = org.bukkit.craftbukkit.block.CraftBlock.at(signEntity.getLevel(), signEntity.getBlockPos()); + org.bukkit.craftbukkit.block.CraftSign bukkitSign = (org.bukkit.craftbukkit.block.CraftSign) org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(bukkitBlock); + io.papermc.paper.event.player.PlayerOpenSignEvent event = new io.papermc.paper.event.player.PlayerOpenSignEvent( + bukkitPlayer, + bukkitSign, -+ flag ? org.bukkit.block.sign.Side.FRONT : org.bukkit.block.sign.Side.BACK, ++ isFrontText ? org.bukkit.block.sign.Side.FRONT : org.bukkit.block.sign.Side.BACK, + cause); + if (!event.callEvent()) return; + if (org.bukkit.event.player.PlayerSignOpenEvent.getHandlerList().getRegisteredListeners().length > 0) { @@ -37,22 +35,19 @@ + case INTERACT -> org.bukkit.event.player.PlayerSignOpenEvent.Cause.INTERACT; + case UNKNOWN -> org.bukkit.event.player.PlayerSignOpenEvent.Cause.UNKNOWN; + }; -+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerSignOpenEvent(entityhuman, tileentitysign, flag, legacyCause)) { ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerSignOpenEvent(player, signEntity, isFrontText, legacyCause)) { + // Paper end - Add PlayerOpenSignEvent + return; + } + } // Paper - Add PlayerOpenSignEvent -+ tileentitysign.setAllowedPlayerEditor(entityhuman.getUUID()); -+ entityhuman.openTextEdit(tileentitysign, flag); -+ } - - private boolean otherPlayerIsEditingSign(Player player, SignBlockEntity blockEntity) { - UUID uuid = blockEntity.getPlayerWhoMayEdit(); -@@ -199,6 +225,6 @@ + signEntity.setAllowedPlayerEditor(player.getUUID()); + player.openTextEdit(signEntity, isFrontText); + } +@@ -189,6 +_,6 @@ @Nullable @Override - public BlockEntityTicker getTicker(Level world, BlockState state, BlockEntityType type) { -- return createTickerHelper(type, BlockEntityType.SIGN, SignBlockEntity::tick); + public BlockEntityTicker getTicker(Level level, BlockState state, BlockEntityType blockEntityType) { +- return createTickerHelper(blockEntityType, BlockEntityType.SIGN, SignBlockEntity::tick); + return null; // Craftbukkit - remove unnecessary sign ticking } } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/SmithingTableBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/SmithingTableBlock.java.patch similarity index 64% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/SmithingTableBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/SmithingTableBlock.java.patch index e7724b2941..a2b4048bcb 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/SmithingTableBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/SmithingTableBlock.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/world/level/block/SmithingTableBlock.java +++ b/net/minecraft/world/level/block/SmithingTableBlock.java -@@ -38,8 +38,9 @@ +@@ -38,8 +_,9 @@ @Override - protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { - if (!world.isClientSide) { -- player.openMenu(state.getMenuProvider(world, pos)); -+ if (player.openMenu(state.getMenuProvider(world, pos)).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation + protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) { + if (!level.isClientSide) { +- player.openMenu(state.getMenuProvider(level, pos)); ++ if (player.openMenu(state.getMenuProvider(level, pos)).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation player.awardStat(Stats.INTERACT_WITH_SMITHING_TABLE); + } // Paper - Fix InventoryOpenEvent cancellation } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/SmokerBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/SmokerBlock.java.patch similarity index 51% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/SmokerBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/SmokerBlock.java.patch index 1d94e2a7cc..27b9bafcfd 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/SmokerBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/SmokerBlock.java.patch @@ -1,12 +1,12 @@ --- a/net/minecraft/world/level/block/SmokerBlock.java +++ b/net/minecraft/world/level/block/SmokerBlock.java -@@ -44,8 +44,7 @@ +@@ -44,8 +_,7 @@ @Override - protected void openContainer(Level world, BlockPos pos, Player player) { - BlockEntity blockEntity = world.getBlockEntity(pos); + protected void openContainer(Level level, BlockPos pos, Player player) { + BlockEntity blockEntity = level.getBlockEntity(pos); - if (blockEntity instanceof SmokerBlockEntity) { - player.openMenu((MenuProvider)blockEntity); -+ if (blockEntity instanceof SmokerBlockEntity && player.openMenu((MenuProvider)blockEntity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation ++ if (blockEntity instanceof SmokerBlockEntity smoker && player.openMenu(smoker).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation player.awardStat(Stats.INTERACT_WITH_SMOKER); } } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/SnifferEggBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/SnifferEggBlock.java.patch similarity index 55% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/SnifferEggBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/SnifferEggBlock.java.patch index ff63f628fe..aa5c5e2817 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/SnifferEggBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/SnifferEggBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/SnifferEggBlock.java +++ b/net/minecraft/world/level/block/SnifferEggBlock.java -@@ -61,12 +61,31 @@ +@@ -61,12 +_,31 @@ return this.getHatchLevel(state) == 2; } @@ -13,41 +13,41 @@ + // Paper end - Call BlockFadeEvent + @Override - public void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { + public void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { if (!this.isReadyToHatch(state)) { + // Paper start -+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(world, pos, state.setValue(HATCH, Integer.valueOf(this.getHatchLevel(state) + 1)), 2)) { -+ this.rescheduleTick(world, pos); ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, pos, state.setValue(HATCH, Integer.valueOf(this.getHatchLevel(state) + 1)), 2)) { ++ this.rescheduleTick(level, pos); + return; + } + // Paper end - world.playSound(null, pos, SoundEvents.SNIFFER_EGG_CRACK, SoundSource.BLOCKS, 0.7F, 0.9F + random.nextFloat() * 0.2F); -- world.setBlock(pos, state.setValue(HATCH, Integer.valueOf(this.getHatchLevel(state) + 1)), 2); + level.playSound(null, pos, SoundEvents.SNIFFER_EGG_CRACK, SoundSource.BLOCKS, 0.7F, 0.9F + random.nextFloat() * 0.2F); +- level.setBlock(pos, state.setValue(HATCH, Integer.valueOf(this.getHatchLevel(state) + 1)), 2); } else { + // Paper start - Call BlockFadeEvent -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world, pos, state.getFluidState().createLegacyBlock()).isCancelled()) { -+ this.rescheduleTick(world, pos); ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(level, pos, state.getFluidState().createLegacyBlock()).isCancelled()) { ++ this.rescheduleTick(level, pos); + return; + } + // Paper end - Call BlockFadeEvent - world.playSound(null, pos, SoundEvents.SNIFFER_EGG_HATCH, SoundSource.BLOCKS, 0.7F, 0.9F + random.nextFloat() * 0.2F); - world.destroyBlock(pos, false); - Sniffer sniffer = EntityType.SNIFFER.create(world, EntitySpawnReason.BREEDING); -@@ -74,7 +93,7 @@ - Vec3 vec3 = pos.getCenter(); + level.playSound(null, pos, SoundEvents.SNIFFER_EGG_HATCH, SoundSource.BLOCKS, 0.7F, 0.9F + random.nextFloat() * 0.2F); + level.destroyBlock(pos, false); + Sniffer sniffer = EntityType.SNIFFER.create(level, EntitySpawnReason.BREEDING); +@@ -74,7 +_,7 @@ + Vec3 center = pos.getCenter(); sniffer.setBaby(true); - sniffer.moveTo(vec3.x(), vec3.y(), vec3.z(), Mth.wrapDegrees(world.random.nextFloat() * 360.0F), 0.0F); -- world.addFreshEntity(sniffer); -+ world.addFreshEntity(sniffer, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.EGG); // Paper - use correct spawn reason + sniffer.moveTo(center.x(), center.y(), center.z(), Mth.wrapDegrees(level.random.nextFloat() * 360.0F), 0.0F); +- level.addFreshEntity(sniffer); ++ level.addFreshEntity(sniffer, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.EGG); // Paper - use correct spawn reason } } } -@@ -86,7 +105,7 @@ - world.levelEvent(3009, pos, 0); +@@ -86,7 +_,7 @@ + level.levelEvent(3009, pos, 0); } -- int i = bl ? 12000 : 24000; -+ int i = bl ? world.paperConfig().entities.sniffer.boostedHatchTime.or(BOOSTED_HATCH_TIME_TICKS) : world.paperConfig().entities.sniffer.hatchTime.or(REGULAR_HATCH_TIME_TICKS); // Paper - int j = i / 3; - world.gameEvent(GameEvent.BLOCK_PLACE, pos, GameEvent.Context.of(state)); - world.scheduleTick(pos, this, j + world.random.nextInt(300)); +- int i = flag ? 12000 : 24000; ++ int i = flag ? level.paperConfig().entities.sniffer.boostedHatchTime.or(BOOSTED_HATCH_TIME_TICKS) : level.paperConfig().entities.sniffer.hatchTime.or(REGULAR_HATCH_TIME_TICKS); // Paper + int i1 = i / 3; + level.gameEvent(GameEvent.BLOCK_PLACE, pos, GameEvent.Context.of(state)); + level.scheduleTick(pos, this, i1 + level.random.nextInt(300)); diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/SnowLayerBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/SnowLayerBlock.java.patch new file mode 100644 index 0000000000..37be3cda95 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/SnowLayerBlock.java.patch @@ -0,0 +1,14 @@ +--- a/net/minecraft/world/level/block/SnowLayerBlock.java ++++ b/net/minecraft/world/level/block/SnowLayerBlock.java +@@ -123,6 +_,11 @@ + @Override + protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { + if (level.getBrightness(LightLayer.BLOCK, pos) > 11) { ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(level, pos, Blocks.AIR.defaultBlockState()).isCancelled()) { ++ return; ++ } ++ // CraftBukkit end + dropResources(state, level, pos); + level.removeBlock(pos, false); + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/SpawnerBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/SpawnerBlock.java.patch new file mode 100644 index 0000000000..eebbd991a8 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/SpawnerBlock.java.patch @@ -0,0 +1,24 @@ +--- a/net/minecraft/world/level/block/SpawnerBlock.java ++++ b/net/minecraft/world/level/block/SpawnerBlock.java +@@ -46,11 +_,19 @@ + @Override + protected void spawnAfterBreak(BlockState state, ServerLevel level, BlockPos pos, ItemStack stack, boolean dropExperience) { + super.spawnAfterBreak(state, level, pos, stack, dropExperience); ++ // CraftBukkit start - Delegate to getExpDrop ++ } ++ ++ @Override ++ public int getExpDrop(BlockState state, ServerLevel level, BlockPos pos, ItemStack stack, boolean dropExperience) { + if (dropExperience) { + int i = 15 + level.random.nextInt(15) + level.random.nextInt(15); +- this.popExperience(level, pos, i); ++ // this.popExperience(level, pos, i); ++ return i; + } +- } ++ return 0; ++ // CraftBukkit end ++ } + + @Override + public void appendHoverText(ItemStack stack, Item.TooltipContext context, List tooltipComponents, TooltipFlag tooltipFlag) { diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/SpongeBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/SpongeBlock.java.patch new file mode 100644 index 0000000000..f39e9bfdf1 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/SpongeBlock.java.patch @@ -0,0 +1,98 @@ +--- a/net/minecraft/world/level/block/SpongeBlock.java ++++ b/net/minecraft/world/level/block/SpongeBlock.java +@@ -50,7 +_,8 @@ + } + + private boolean removeWaterBreadthFirstSearch(Level level, BlockPos pos) { +- return BlockPos.breadthFirstTraversal( ++ org.bukkit.craftbukkit.util.BlockStateListPopulator blockList = new org.bukkit.craftbukkit.util.BlockStateListPopulator(level); // CraftBukkit - Use BlockStateListPopulator ++ BlockPos.breadthFirstTraversal( + pos, + 6, + 65, +@@ -63,16 +_,18 @@ + if (blockPos.equals(pos)) { + return BlockPos.TraversalNodeStatus.ACCEPT; + } else { +- BlockState blockState = level.getBlockState(blockPos); +- FluidState fluidState = level.getFluidState(blockPos); ++ // CraftBukkit start ++ BlockState blockState = blockList.getBlockState(blockPos); ++ FluidState fluidState = blockList.getFluidState(blockPos); ++ // CraftBukkit end + if (!fluidState.is(FluidTags.WATER)) { + return BlockPos.TraversalNodeStatus.SKIP; + } else if (blockState.getBlock() instanceof BucketPickup bucketPickup +- && !bucketPickup.pickupBlock(null, level, blockPos, blockState).isEmpty()) { ++ && !bucketPickup.pickupBlock(null, blockList, blockPos, blockState).isEmpty()) { // CraftBukkit + return BlockPos.TraversalNodeStatus.ACCEPT; + } else { + if (blockState.getBlock() instanceof LiquidBlock) { +- level.setBlock(blockPos, Blocks.AIR.defaultBlockState(), 3); ++ blockList.setBlock(blockPos, Blocks.AIR.defaultBlockState(), 3); // CraftBukkit + } else { + if (!blockState.is(Blocks.KELP) + && !blockState.is(Blocks.KELP_PLANT) +@@ -81,16 +_,57 @@ + return BlockPos.TraversalNodeStatus.SKIP; + } + +- BlockEntity blockEntity = blockState.hasBlockEntity() ? level.getBlockEntity(blockPos) : null; +- dropResources(blockState, level, blockPos, blockEntity); +- level.setBlock(blockPos, Blocks.AIR.defaultBlockState(), 3); ++ // CraftBukkit start ++ // BlockEntity blockEntity = blockState.hasBlockEntity() ? level.getBlockEntity(blockPos) : null; ++ // dropResources(blockState, level, blockPos, blockEntity); ++ // level.setBlock(blockPos, Blocks.AIR.defaultBlockState(), 3); ++ blockList.setBlock(blockPos, Blocks.AIR.defaultBlockState(), 3); ++ // CraftBukkit end + } + + return BlockPos.TraversalNodeStatus.ACCEPT; + } + } + } +- ) +- > 1; ++ ); ++ // CraftBukkit start ++ java.util.List blocks = blockList.getList(); // Is a clone ++ if (!blocks.isEmpty()) { ++ final org.bukkit.block.Block bblock = level.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()); ++ ++ org.bukkit.event.block.SpongeAbsorbEvent event = new org.bukkit.event.block.SpongeAbsorbEvent(bblock, (java.util.List) (java.util.List) blocks); ++ level.getCraftServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) { ++ return false; ++ } ++ ++ for (org.bukkit.craftbukkit.block.CraftBlockState block : blocks) { ++ BlockPos blockposition1 = block.getPosition(); ++ BlockState iblockdata = level.getBlockState(blockposition1); ++ FluidState fluid = level.getFluidState(blockposition1); ++ ++ if (fluid.is(FluidTags.WATER)) { ++ if (iblockdata.getBlock() instanceof BucketPickup && !((BucketPickup) iblockdata.getBlock()).pickupBlock(null, blockList, blockposition1, iblockdata).isEmpty()) { ++ // NOP ++ } else if (iblockdata.getBlock() instanceof LiquidBlock) { ++ // NOP ++ } else if (iblockdata.is(Blocks.KELP) || iblockdata.is(Blocks.KELP_PLANT) || iblockdata.is(Blocks.SEAGRASS) || iblockdata.is(Blocks.TALL_SEAGRASS)) { ++ BlockEntity tileentity = iblockdata.hasBlockEntity() ? level.getBlockEntity(blockposition1) : null; ++ ++ // Paper start - Fix SpongeAbsortEvent handling ++ if (block.getHandle().isAir()) { ++ dropResources(iblockdata, level, blockposition1, tileentity); ++ } ++ // Paper end - Fix SpongeAbsortEvent handling ++ } ++ } ++ level.setBlock(blockposition1, block.getHandle(), block.getFlag()); ++ } ++ ++ return true; ++ } ++ return false; ++ // CraftBukkit end + } + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java.patch new file mode 100644 index 0000000000..0e8433bda8 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java.patch @@ -0,0 +1,25 @@ +--- a/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java ++++ b/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java +@@ -39,7 +_,13 @@ + + @Override + protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { ++ if (this instanceof GrassBlock && level.paperConfig().tickRates.grassSpread != 1 && (level.paperConfig().tickRates.grassSpread < 1 || (net.minecraft.server.MinecraftServer.currentTick + pos.hashCode()) % level.paperConfig().tickRates.grassSpread != 0)) { return; } // Paper - Configurable random tick rates for blocks + if (!canBeGrass(state, level, pos)) { ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(level, pos, Blocks.DIRT.defaultBlockState()).isCancelled()) { ++ return; ++ } ++ // CraftBukkit end + level.setBlockAndUpdate(pos, Blocks.DIRT.defaultBlockState()); + } else { + if (level.getMaxLocalRawBrightness(pos.above()) >= 9) { +@@ -48,7 +_,7 @@ + for (int i = 0; i < 4; i++) { + BlockPos blockPos = pos.offset(random.nextInt(3) - 1, random.nextInt(5) - 3, random.nextInt(3) - 1); + if (level.getBlockState(blockPos).is(Blocks.DIRT) && canPropagate(blockState, level, blockPos)) { +- level.setBlockAndUpdate(blockPos, blockState.setValue(SNOWY, Boolean.valueOf(isSnowySetting(level.getBlockState(blockPos.above()))))); ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(level, pos, blockPos, blockState.setValue(SNOWY, Boolean.valueOf(isSnowySetting(level.getBlockState(blockPos.above()))))); // CraftBukkit + } + } + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/StemBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/StemBlock.java.patch new file mode 100644 index 0000000000..3e1e7cca5a --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/StemBlock.java.patch @@ -0,0 +1,38 @@ +--- a/net/minecraft/world/level/block/StemBlock.java ++++ b/net/minecraft/world/level/block/StemBlock.java +@@ -80,11 +_,11 @@ + protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { + if (level.getRawBrightness(pos, 0) >= 9) { + float growthSpeed = CropBlock.getGrowthSpeed(this, level, pos); +- if (random.nextInt((int)(25.0F / growthSpeed) + 1) == 0) { ++ if (random.nextFloat() < ((this == Blocks.PUMPKIN_STEM ? level.spigotConfig.pumpkinModifier : level.spigotConfig.melonModifier) / (100.0f * (Math.floor((25.0F / growthSpeed) + 1))))) { // Spigot - SPIGOT-7159: Better modifier resolution + int ageValue = state.getValue(AGE); + if (ageValue < 7) { + state = state.setValue(AGE, Integer.valueOf(ageValue + 1)); +- level.setBlock(pos, state, 2); ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, pos, state, 2); // CraftBukkit + } else { + Direction randomDirection = Direction.Plane.HORIZONTAL.getRandomDirection(random); + BlockPos blockPos = pos.relative(randomDirection); +@@ -94,7 +_,11 @@ + Optional optional = registry.getOptional(this.fruit); + Optional optional1 = registry.getOptional(this.attachedStem); + if (optional.isPresent() && optional1.isPresent()) { +- level.setBlockAndUpdate(blockPos, optional.get().defaultBlockState()); ++ // CraftBukkit start ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, blockPos, optional.get().defaultBlockState())) { ++ return; ++ } ++ // CraftBukkit end + level.setBlockAndUpdate(pos, optional1.get().defaultBlockState().setValue(HorizontalDirectionalBlock.FACING, randomDirection)); + } + } +@@ -122,7 +_,7 @@ + public void performBonemeal(ServerLevel level, RandomSource random, BlockPos pos, BlockState state) { + int min = Math.min(7, state.getValue(AGE) + Mth.nextInt(level.random, 2, 5)); + BlockState blockState = state.setValue(AGE, Integer.valueOf(min)); +- level.setBlock(pos, blockState, 2); ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, pos, blockState, 2); // CraftBukkit + if (min == 7) { + blockState.randomTick(level, pos, level.random); + } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/StonecutterBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/StonecutterBlock.java.patch similarity index 63% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/StonecutterBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/StonecutterBlock.java.patch index 33e97daa48..cf39a9ca01 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/StonecutterBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/StonecutterBlock.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/world/level/block/StonecutterBlock.java +++ b/net/minecraft/world/level/block/StonecutterBlock.java -@@ -48,8 +48,9 @@ +@@ -48,8 +_,9 @@ @Override - protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { - if (!world.isClientSide) { -- player.openMenu(state.getMenuProvider(world, pos)); -+ if (player.openMenu(state.getMenuProvider(world, pos)).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation + protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) { + if (!level.isClientSide) { +- player.openMenu(state.getMenuProvider(level, pos)); ++ if (player.openMenu(state.getMenuProvider(level, pos)).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation player.awardStat(Stats.INTERACT_WITH_STONECUTTER); + } // Paper - Fix InventoryOpenEvent cancellation } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/SugarCaneBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/SugarCaneBlock.java.patch new file mode 100644 index 0000000000..009e5542fb --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/SugarCaneBlock.java.patch @@ -0,0 +1,20 @@ +--- a/net/minecraft/world/level/block/SugarCaneBlock.java ++++ b/net/minecraft/world/level/block/SugarCaneBlock.java +@@ -56,12 +_,13 @@ + i++; + } + +- if (i < 3) { ++ if (i < level.paperConfig().maxGrowthHeight.reeds) { // Paper - Configurable cactus/bamboo/reed growth height + int ageValue = state.getValue(AGE); +- if (ageValue == 15) { +- level.setBlockAndUpdate(pos.above(), this.defaultBlockState()); ++ int modifier = level.spigotConfig.caneModifier; // Spigot - SPIGOT-7159: Better modifier resolution ++ if (ageValue >= 15 || (modifier != 100 && random.nextFloat() < (modifier / (100.0f * 16)))) { // Spigot - SPIGOT-7159: Better modifier resolution ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, pos.above(), this.defaultBlockState()); // CraftBukkit + level.setBlock(pos, state.setValue(AGE, Integer.valueOf(0)), 4); +- } else { ++ } else if (modifier == 100 || random.nextFloat() < (modifier / (100.0f * 16))) { // Spigot - SPIGOT-7159: Better modifier resolution + level.setBlock(pos, state.setValue(AGE, Integer.valueOf(ageValue + 1)), 4); + } + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/SweetBerryBushBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/SweetBerryBushBlock.java.patch new file mode 100644 index 0000000000..8b96fa4a77 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/SweetBerryBushBlock.java.patch @@ -0,0 +1,48 @@ +--- a/net/minecraft/world/level/block/SweetBerryBushBlock.java ++++ b/net/minecraft/world/level/block/SweetBerryBushBlock.java +@@ -68,15 +_,17 @@ + @Override + protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { + int ageValue = state.getValue(AGE); +- if (ageValue < 3 && random.nextInt(5) == 0 && level.getRawBrightness(pos.above(), 0) >= 9) { ++ if (ageValue < 3 && random.nextFloat() < (level.spigotConfig.sweetBerryModifier / (100.0f * 5)) && level.getRawBrightness(pos.above(), 0) >= 9) { // Spigot - SPIGOT-7159: Better modifier resolution + BlockState blockState = state.setValue(AGE, Integer.valueOf(ageValue + 1)); +- level.setBlock(pos, blockState, 2); ++ // level.setBlock(pos, blockState, 2); ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, pos, blockState, 2)) return; // CraftBukkit + level.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(blockState)); + } + } + + @Override + protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) { ++ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent + if (entity instanceof LivingEntity && entity.getType() != EntityType.FOX && entity.getType() != EntityType.BEE) { + entity.makeStuckInBlock(state, new Vec3(0.8F, 0.75, 0.8F)); + if (level instanceof ServerLevel serverLevel && state.getValue(AGE) != 0) { +@@ -85,7 +_,7 @@ + double abs = Math.abs(vec3.x()); + double abs1 = Math.abs(vec3.z()); + if (abs >= 0.003F || abs1 >= 0.003F) { +- entity.hurtServer(serverLevel, level.damageSources().sweetBerryBush(), 1.0F); ++ entity.hurtServer(serverLevel, level.damageSources().sweetBerryBush().directBlock(level, pos), 1.0F); // CraftBukkit + } + } + } +@@ -109,7 +_,15 @@ + boolean flag = ageValue == 3; + if (ageValue > 1) { + int i = 1 + level.random.nextInt(2); +- popResource(level, pos, new ItemStack(Items.SWEET_BERRIES, i + (flag ? 1 : 0))); ++ // CraftBukkit start - useWithoutItem is always MAIN_HAND ++ org.bukkit.event.player.PlayerHarvestBlockEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerHarvestBlockEvent(level, pos, player, InteractionHand.MAIN_HAND, java.util.Collections.singletonList(new ItemStack(Items.SWEET_BERRIES, i + (flag ? 1 : 0)))); ++ if (event.isCancelled()) { ++ return InteractionResult.SUCCESS; // We need to return a success either way, because making it PASS or FAIL will result in a bug where cancelling while harvesting w/ block in hand places block ++ } ++ for (org.bukkit.inventory.ItemStack itemStack : event.getItemsHarvested()) { ++ popResource(level, pos, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(itemStack)); ++ } ++ // CraftBukkit end + level.playSound(null, pos, SoundEvents.SWEET_BERRY_BUSH_PICK_BERRIES, SoundSource.BLOCKS, 1.0F, 0.8F + level.random.nextFloat() * 0.4F); + BlockState blockState = state.setValue(AGE, Integer.valueOf(1)); + level.setBlock(pos, blockState, 2); diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/TargetBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/TargetBlock.java.patch similarity index 60% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/TargetBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/TargetBlock.java.patch index 5478fd0968..eeb2fc28bb 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/TargetBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/TargetBlock.java.patch @@ -1,9 +1,9 @@ --- a/net/minecraft/world/level/block/TargetBlock.java +++ b/net/minecraft/world/level/block/TargetBlock.java -@@ -42,6 +42,10 @@ +@@ -42,6 +_,10 @@ @Override - protected void onProjectileHit(Level world, BlockState state, BlockHitResult hit, Projectile projectile) { - int i = updateRedstoneOutput(world, state, hit, projectile); + protected void onProjectileHit(Level level, BlockState state, BlockHitResult hit, Projectile projectile) { + int i = updateRedstoneOutput(level, state, hit, projectile); + // Paper start - Add TargetHitEvent + } + private static void awardTargetHitCriteria(Projectile projectile, BlockHitResult hit, int i) { @@ -11,16 +11,15 @@ if (projectile.getOwner() instanceof ServerPlayer serverPlayer) { serverPlayer.awardStat(Stats.TARGET_HIT); CriteriaTriggers.TARGET_BLOCK_HIT.trigger(serverPlayer, projectile, hit.getLocation(), i); -@@ -51,10 +55,31 @@ - private static int updateRedstoneOutput(LevelAccessor world, BlockState state, BlockHitResult hitResult, Entity entity) { - int i = getRedstoneStrength(hitResult, hitResult.getLocation()); - int j = entity instanceof AbstractArrow ? 20 : 8; +@@ -51,9 +_,29 @@ + private static int updateRedstoneOutput(LevelAccessor level, BlockState state, BlockHitResult hit, Entity projectile) { + int redstoneStrength = getRedstoneStrength(hit, hit.getLocation()); + int i = projectile instanceof AbstractArrow ? 20 : 8; + // Paper start - Add TargetHitEvent + boolean shouldAward = false; -+ if (entity instanceof Projectile) { -+ final Projectile projectile = (Projectile) entity; -+ final org.bukkit.craftbukkit.block.CraftBlock craftBlock = org.bukkit.craftbukkit.block.CraftBlock.at(world, hitResult.getBlockPos()); -+ final org.bukkit.block.BlockFace blockFace = org.bukkit.craftbukkit.block.CraftBlock.notchToBlockFace(hitResult.getDirection()); ++ if (projectile instanceof Projectile) { ++ final org.bukkit.craftbukkit.block.CraftBlock craftBlock = org.bukkit.craftbukkit.block.CraftBlock.at(level, hit.getBlockPos()); ++ final org.bukkit.block.BlockFace blockFace = org.bukkit.craftbukkit.block.CraftBlock.notchToBlockFace(hit.getDirection()); + final io.papermc.paper.event.block.TargetHitEvent targetHitEvent = new io.papermc.paper.event.block.TargetHitEvent((org.bukkit.entity.Projectile) projectile.getBukkitEntity(), craftBlock, blockFace, i); + if (targetHitEvent.callEvent()) { + i = targetHitEvent.getSignalStrength(); @@ -30,16 +29,15 @@ + } + } + // Paper end - Add TargetHitEvent - if (!world.getBlockTicks().hasScheduledTick(hitResult.getBlockPos(), state.getBlock())) { - setOutputPower(world, state, i, hitResult.getBlockPos(), j); + if (!level.getBlockTicks().hasScheduledTick(hit.getBlockPos(), state.getBlock())) { + setOutputPower(level, state, redstoneStrength, hit.getBlockPos(), i); } - ++ + // Paper start - Award Hit Criteria after Block Update + if (shouldAward) { -+ awardTargetHitCriteria((Projectile) entity, hitResult, i); ++ awardTargetHitCriteria((Projectile) projectile, hit, i); + } + // Paper end - Award Hit Criteria after Block Update -+ - return i; - } + return redstoneStrength; + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/TntBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/TntBlock.java.patch new file mode 100644 index 0000000000..b03b95ae3c --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/TntBlock.java.patch @@ -0,0 +1,91 @@ +--- a/net/minecraft/world/level/block/TntBlock.java ++++ b/net/minecraft/world/level/block/TntBlock.java +@@ -45,7 +_,13 @@ + @Override + protected void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean isMoving) { + if (!oldState.is(state.getBlock())) { +- if (level.hasNeighborSignal(pos)) { ++ if (level.hasNeighborSignal(pos) && org.bukkit.craftbukkit.event.CraftEventFactory.callTNTPrimeEvent(level, pos, org.bukkit.event.block.TNTPrimeEvent.PrimeCause.REDSTONE, null, null)) { // CraftBukkit - TNTPrimeEvent ++ // Paper start - TNTPrimeEvent ++ org.bukkit.block.Block tntBlock = org.bukkit.craftbukkit.block.CraftBlock.at(level, pos); ++ if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.REDSTONE, null).callEvent()) { ++ return; ++ } ++ // Paper end - TNTPrimeEvent + explode(level, pos); + level.removeBlock(pos, false); + } +@@ -54,7 +_,13 @@ + + @Override + protected void neighborChanged(BlockState state, Level level, BlockPos pos, Block neighborBlock, @Nullable Orientation orientation, boolean movedByPiston) { +- if (level.hasNeighborSignal(pos)) { ++ if (level.hasNeighborSignal(pos) && org.bukkit.craftbukkit.event.CraftEventFactory.callTNTPrimeEvent(level, pos, org.bukkit.event.block.TNTPrimeEvent.PrimeCause.REDSTONE, null, null)) { // CraftBukkit - TNTPrimeEvent ++ // Paper start - TNTPrimeEvent ++ org.bukkit.block.Block tntBlock = org.bukkit.craftbukkit.block.CraftBlock.at(level, pos); ++ if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.REDSTONE, null).callEvent()) { ++ return; ++ } ++ // Paper end - TNTPrimeEvent + explode(level, pos); + level.removeBlock(pos, false); + } +@@ -62,7 +_,7 @@ + + @Override + public BlockState playerWillDestroy(Level level, BlockPos pos, BlockState state, Player player) { +- if (!level.isClientSide() && !player.isCreative() && state.getValue(UNSTABLE)) { ++ if (!level.isClientSide() && !player.isCreative() && state.getValue(UNSTABLE) && org.bukkit.craftbukkit.event.CraftEventFactory.callTNTPrimeEvent(level, pos, org.bukkit.event.block.TNTPrimeEvent.PrimeCause.BLOCK_BREAK, player, null)) { // CraftBukkit - TNTPrimeEvent + explode(level, pos); + } + +@@ -71,6 +_,13 @@ + + @Override + public void wasExploded(ServerLevel level, BlockPos pos, Explosion explosion) { ++ // Paper start - TNTPrimeEvent ++ org.bukkit.block.Block tntBlock = org.bukkit.craftbukkit.block.CraftBlock.at(level, pos); ++ org.bukkit.entity.Entity source = explosion.getDirectSourceEntity() != null ? explosion.getDirectSourceEntity().getBukkitEntity() : null; ++ if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.EXPLOSION, source).callEvent()) { ++ return; ++ } ++ // Paper end - TNTPrimeEvent + PrimedTnt primedTnt = new PrimedTnt(level, pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, explosion.getIndirectSourceEntity()); + int fuse = primedTnt.getFuse(); + primedTnt.setFuse((short)(level.random.nextInt(fuse / 4) + fuse / 8)); +@@ -97,6 +_,17 @@ + if (!stack.is(Items.FLINT_AND_STEEL) && !stack.is(Items.FIRE_CHARGE)) { + return super.useItemOn(stack, state, level, pos, player, hand, hitResult); + } else { ++ // CraftBukkit start - TNTPrimeEvent ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callTNTPrimeEvent(level, pos, org.bukkit.event.block.TNTPrimeEvent.PrimeCause.PLAYER, player, null)) { ++ return InteractionResult.CONSUME; ++ } ++ // CraftBukkit end ++ // Paper start - TNTPrimeEvent ++ org.bukkit.block.Block tntBlock = org.bukkit.craftbukkit.block.CraftBlock.at(level, pos); ++ if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.ITEM, player.getBukkitEntity()).callEvent()) { ++ return InteractionResult.FAIL; ++ } ++ // Paper end - TNTPrimeEvent + explode(level, pos, player); + level.setBlock(pos, Blocks.AIR.defaultBlockState(), 11); + Item item = stack.getItem(); +@@ -117,6 +_,17 @@ + BlockPos blockPos = hit.getBlockPos(); + Entity owner = projectile.getOwner(); + if (projectile.isOnFire() && projectile.mayInteract(serverLevel, blockPos)) { ++ // CraftBukkit start ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(projectile, blockPos, state.getFluidState().createLegacyBlock()) || !org.bukkit.craftbukkit.event.CraftEventFactory.callTNTPrimeEvent(level, blockPos, org.bukkit.event.block.TNTPrimeEvent.PrimeCause.PROJECTILE, projectile, null)) { // Paper - fix wrong block state ++ return; ++ } ++ // CraftBukkit end ++ // Paper start - TNTPrimeEvent ++ org.bukkit.block.Block tntBlock = org.bukkit.craftbukkit.block.CraftBlock.at(level, blockPos); ++ if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.PROJECTILE, projectile.getBukkitEntity()).callEvent()) { ++ return; ++ } ++ // Paper end - TNTPrimeEvent + explode(level, blockPos, owner instanceof LivingEntity ? (LivingEntity)owner : null); + level.removeBlock(blockPos, false); + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/TrapDoorBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/TrapDoorBlock.java.patch new file mode 100644 index 0000000000..dac679ac7e --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/TrapDoorBlock.java.patch @@ -0,0 +1,44 @@ +--- a/net/minecraft/world/level/block/TrapDoorBlock.java ++++ b/net/minecraft/world/level/block/TrapDoorBlock.java +@@ -146,7 +_,40 @@ + if (!level.isClientSide) { + boolean hasNeighborSignal = level.hasNeighborSignal(pos); + if (hasNeighborSignal != state.getValue(POWERED)) { +- if (state.getValue(OPEN) != hasNeighborSignal) { ++ // if (state.getValue(OPEN) != hasNeighborSignal) { ++ // CraftBukkit start ++ org.bukkit.World bworld = level.getWorld(); ++ org.bukkit.block.Block bblock = bworld.getBlockAt(pos.getX(), pos.getY(), pos.getZ()); ++ ++ int power = bblock.getBlockPower(); ++ int oldPower = state.getValue(TrapDoorBlock.OPEN) ? 15 : 0; ++ ++ if (oldPower == 0 ^ power == 0 || neighborBlock.defaultBlockState().isSignalSource()) { ++ org.bukkit.event.block.BlockRedstoneEvent eventRedstone = new org.bukkit.event.block.BlockRedstoneEvent(bblock, oldPower, power); ++ level.getCraftServer().getPluginManager().callEvent(eventRedstone); ++ hasNeighborSignal = eventRedstone.getNewCurrent() > 0; ++ } ++ // CraftBukkit end ++ // Paper start - break redstone on trapdoors early ++ boolean open = state.getValue(TrapDoorBlock.OPEN) != hasNeighborSignal; ++ // note: this must run before any state for this block/its neighborus are written to the world ++ // we allow the redstone event to fire so that plugins can block ++ if (hasNeighborSignal && open) { // if we are now powered and it caused the trap door to open ++ // in this case, first check for the redstone on top first ++ BlockPos abovePos = pos.above(); ++ BlockState above = level.getBlockState(abovePos); ++ if (above.getBlock() instanceof RedStoneWireBlock) { ++ level.setBlock(abovePos, Blocks.AIR.defaultBlockState(), Block.UPDATE_CLIENTS | Block.UPDATE_NEIGHBORS); ++ Block.popResource(level, abovePos, new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.REDSTONE)); ++ // now check that this didn't change our state ++ if (level.getBlockState(pos) != state) { ++ // our state was changed, so we cannot propagate this update ++ return; ++ } ++ } ++ } ++ if (open) { ++ // Paper end - break redstone on trapdoors early + state = state.setValue(OPEN, Boolean.valueOf(hasNeighborSignal)); + this.playSound(null, level, pos, hasNeighborSignal); + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/TripWireBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/TripWireBlock.java.patch new file mode 100644 index 0000000000..4be069ee99 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/TripWireBlock.java.patch @@ -0,0 +1,108 @@ +--- a/net/minecraft/world/level/block/TripWireBlock.java ++++ b/net/minecraft/world/level/block/TripWireBlock.java +@@ -72,6 +_,7 @@ + + @Override + public BlockState getStateForPlacement(BlockPlaceContext context) { ++ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return this.defaultBlockState(); // Paper - place tripwire without updating + BlockGetter level = context.getLevel(); + BlockPos clickedPos = context.getClickedPos(); + return this.defaultBlockState() +@@ -92,6 +_,7 @@ + BlockState neighborState, + RandomSource random + ) { ++ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return state; // Paper - prevent tripwire from updating + return direction.getAxis().isHorizontal() + ? state.setValue(PROPERTY_BY_DIRECTION.get(direction), Boolean.valueOf(this.shouldConnectTo(neighborState, direction))) + : super.updateShape(state, level, scheduledTickAccess, pos, direction, neighborPos, neighborState, random); +@@ -99,6 +_,7 @@ + + @Override + protected void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean isMoving) { ++ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return; // Paper - prevent adjacent tripwires from updating + if (!oldState.is(state.getBlock())) { + this.updateSource(level, pos, state); + } +@@ -106,6 +_,7 @@ + + @Override + protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving) { ++ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return; // Paper - prevent adjacent tripwires from updating + if (!isMoving && !state.is(newState.getBlock())) { + this.updateSource(level, pos, state.setValue(POWERED, Boolean.valueOf(true))); + } +@@ -113,6 +_,7 @@ + + @Override + public BlockState playerWillDestroy(Level level, BlockPos pos, BlockState state, Player player) { ++ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return state; // Paper - prevent disarming tripwires + if (!level.isClientSide && !player.getMainHandItem().isEmpty() && player.getMainHandItem().is(Items.SHEARS)) { + level.setBlock(pos, state.setValue(DISARMED, Boolean.valueOf(true)), 4); + level.gameEvent(player, GameEvent.SHEAR, pos); +@@ -122,6 +_,7 @@ + } + + private void updateSource(Level level, BlockPos pos, BlockState state) { ++ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return; // Paper - prevent adjacent tripwires from updating + for (Direction direction : new Direction[]{Direction.SOUTH, Direction.WEST}) { + for (int i = 1; i < 42; i++) { + BlockPos blockPos = pos.relative(direction, i); +@@ -147,6 +_,8 @@ + + @Override + protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) { ++ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return; // Paper - prevent tripwires from detecting collision ++ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent + if (!level.isClientSide) { + if (!state.getValue(POWERED)) { + this.checkPressed(level, pos, List.of(entity)); +@@ -156,6 +_,7 @@ + + @Override + protected void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { ++ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return; // Paper - prevent tripwire pressed check + if (level.getBlockState(pos).getValue(POWERED)) { + this.checkPressed(level, pos); + } +@@ -179,6 +_,40 @@ + } + } + } ++ ++ // CraftBukkit start - Call interact even when triggering connected tripwire ++ if (flag != poweredValue && poweredValue && blockState.getValue(TripWireBlock.ATTACHED)) { ++ org.bukkit.World bworld = level.getWorld(); ++ org.bukkit.plugin.PluginManager manager = level.getCraftServer().getPluginManager(); ++ org.bukkit.block.Block block = bworld.getBlockAt(pos.getX(), pos.getY(), pos.getZ()); ++ boolean allowed = false; ++ ++ // If all the events are cancelled block the tripwire trigger, else allow ++ for (Object object : entities) { ++ if (object != null) { ++ org.bukkit.event.Cancellable cancellable; ++ ++ if (object instanceof Player) { ++ cancellable = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent((Player) object, org.bukkit.event.block.Action.PHYSICAL, pos, null, null, null); ++ } else if (object instanceof Entity) { ++ cancellable = new org.bukkit.event.entity.EntityInteractEvent(((Entity) object).getBukkitEntity(), block); ++ manager.callEvent((org.bukkit.event.entity.EntityInteractEvent) cancellable); ++ } else { ++ continue; ++ } ++ ++ if (!cancellable.isCancelled()) { ++ allowed = true; ++ break; ++ } ++ } ++ } ++ ++ if (!allowed) { ++ return; ++ } ++ } ++ // CraftBukkit end + + if (flag != poweredValue) { + blockState = blockState.setValue(POWERED, Boolean.valueOf(flag)); diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/TripWireHookBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/TripWireHookBlock.java.patch new file mode 100644 index 0000000000..8a437b9c80 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/TripWireHookBlock.java.patch @@ -0,0 +1,21 @@ +--- a/net/minecraft/world/level/block/TripWireHookBlock.java ++++ b/net/minecraft/world/level/block/TripWireHookBlock.java +@@ -173,9 +_,18 @@ + notifyNeighbors(block, level, blockPosx, opposite); + emitState(level, blockPosx, flag2, flag3, flag, flag1); + } ++ // CraftBukkit start ++ org.bukkit.event.block.BlockRedstoneEvent eventRedstone = new org.bukkit.event.block.BlockRedstoneEvent(org.bukkit.craftbukkit.block.CraftBlock.at(level, pos), 15, 0); ++ level.getCraftServer().getPluginManager().callEvent(eventRedstone); ++ ++ if (eventRedstone.getNewCurrent() > 0) { ++ return; ++ } ++ // CraftBukkit end + + emitState(level, pos, flag2, flag3, flag, flag1); + if (!attaching) { ++ if (level.getBlockState(pos).getBlock() == Blocks.TRIPWIRE_HOOK) // Paper - Validate tripwire hook placement before update + level.setBlock(pos, blockState1.setValue(FACING, direction), 3); + if (shouldNotifyNeighbours) { + notifyNeighbors(block, level, pos, direction); diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/TurtleEggBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/TurtleEggBlock.java.patch new file mode 100644 index 0000000000..e7880ebb4f --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/TurtleEggBlock.java.patch @@ -0,0 +1,64 @@ +--- a/net/minecraft/world/level/block/TurtleEggBlock.java ++++ b/net/minecraft/world/level/block/TurtleEggBlock.java +@@ -74,6 +_,19 @@ + && level instanceof ServerLevel serverLevel + && this.canDestroyEgg(serverLevel, entity) + && level.random.nextInt(chance) == 0) { ++ // CraftBukkit start - Step on eggs ++ org.bukkit.event.Cancellable cancellable; ++ if (entity instanceof Player) { ++ cancellable = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent((Player) entity, org.bukkit.event.block.Action.PHYSICAL, pos, null, null, null); ++ } else { ++ cancellable = new org.bukkit.event.entity.EntityInteractEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)); ++ level.getCraftServer().getPluginManager().callEvent((org.bukkit.event.entity.EntityInteractEvent) cancellable); ++ } ++ ++ if (cancellable.isCancelled()) { ++ return; ++ } ++ // CraftBukkit end + this.decreaseEggs(serverLevel, pos, state); + } + } +@@ -95,10 +_,20 @@ + if (this.shouldUpdateHatchLevel(level) && onSand(level, pos)) { + int hatchValue = state.getValue(HATCH); + if (hatchValue < 2) { ++ // CraftBukkit start - Call BlockGrowEvent ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, pos, state.setValue(TurtleEggBlock.HATCH, hatchValue + 1), 2)) { ++ return; ++ } ++ // CraftBukkit end + level.playSound(null, pos, SoundEvents.TURTLE_EGG_CRACK, SoundSource.BLOCKS, 0.7F, 0.9F + random.nextFloat() * 0.2F); +- level.setBlock(pos, state.setValue(HATCH, Integer.valueOf(hatchValue + 1)), 2); ++ // level.setBlock(pos, state.setValue(HATCH, Integer.valueOf(hatchValue + 1)), 2); // CraftBukkit - handled above + level.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(state)); + } else { ++ // CraftBukkit start - Call BlockFadeEvent ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(level, pos, Blocks.AIR.defaultBlockState()).isCancelled()) { ++ return; ++ } ++ // CraftBukkit end + level.playSound(null, pos, SoundEvents.TURTLE_EGG_HATCH, SoundSource.BLOCKS, 0.7F, 0.9F + random.nextFloat() * 0.2F); + level.removeBlock(pos, false); + level.gameEvent(GameEvent.BLOCK_DESTROY, pos, GameEvent.Context.of(state)); +@@ -110,7 +_,7 @@ + turtle.setAge(-24000); + turtle.setHomePos(pos); + turtle.moveTo(pos.getX() + 0.3 + i * 0.2, pos.getY(), pos.getZ() + 0.3, 0.0F, 0.0F); +- level.addFreshEntity(turtle); ++ level.addFreshEntity(turtle, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.EGG); // CraftBukkit + } + } + } +@@ -138,8 +_,8 @@ + } + + @Override +- public void playerDestroy(Level level, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity te, ItemStack stack) { +- super.playerDestroy(level, player, pos, state, te, stack); ++ public void playerDestroy(Level level, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity te, ItemStack stack, boolean includeDrops, boolean dropExp) { // Paper - fix drops not preventing stats/food exhaustion ++ super.playerDestroy(level, player, pos, state, te, stack, includeDrops, dropExp); // Paper - fix drops not preventing stats/food exhaustion + this.decreaseEggs(level, pos, state); + } + diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/VineBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/VineBlock.java.patch new file mode 100644 index 0000000000..f5fb874107 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/VineBlock.java.patch @@ -0,0 +1,68 @@ +--- a/net/minecraft/world/level/block/VineBlock.java ++++ b/net/minecraft/world/level/block/VineBlock.java +@@ -191,7 +_,7 @@ + @Override + protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { + if (level.getGameRules().getBoolean(GameRules.RULE_DO_VINES_SPREAD)) { +- if (random.nextInt(4) == 0) { ++ if (random.nextFloat() < (level.spigotConfig.vineModifier / (100.0f * 4))) { // Spigot - SPIGOT-7159: Better modifier resolution + Direction random1 = Direction.getRandom(random); + BlockPos blockPos = pos.above(); + if (random1.getAxis().isHorizontal() && !state.getValue(getPropertyForFace(random1))) { +@@ -205,28 +_,31 @@ + boolean value1 = state.getValue(getPropertyForFace(counterClockWise)); + BlockPos blockPos2 = blockPos1.relative(clockWise); + BlockPos blockPos3 = blockPos1.relative(counterClockWise); ++ // CraftBukkit start - Call BlockSpreadEvent ++ BlockPos source = pos; + if (value && isAcceptableNeighbour(level, blockPos2, clockWise)) { +- level.setBlock(blockPos1, this.defaultBlockState().setValue(getPropertyForFace(clockWise), Boolean.valueOf(true)), 2); ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(level, source, blockPos1, this.defaultBlockState().setValue(getPropertyForFace(clockWise), Boolean.valueOf(true)), 2); + } else if (value1 && isAcceptableNeighbour(level, blockPos3, counterClockWise)) { +- level.setBlock(blockPos1, this.defaultBlockState().setValue(getPropertyForFace(counterClockWise), Boolean.valueOf(true)), 2); ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(level, source, blockPos1, this.defaultBlockState().setValue(getPropertyForFace(counterClockWise), Boolean.valueOf(true)), 2); + } else { + Direction opposite = random1.getOpposite(); + if (value && level.isEmptyBlock(blockPos2) && isAcceptableNeighbour(level, pos.relative(clockWise), opposite)) { +- level.setBlock(blockPos2, this.defaultBlockState().setValue(getPropertyForFace(opposite), Boolean.valueOf(true)), 2); ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(level, source, blockPos2, this.defaultBlockState().setValue(getPropertyForFace(opposite), Boolean.valueOf(true)), 2); + } else if (value1 && level.isEmptyBlock(blockPos3) && isAcceptableNeighbour(level, pos.relative(counterClockWise), opposite)) { +- level.setBlock(blockPos3, this.defaultBlockState().setValue(getPropertyForFace(opposite), Boolean.valueOf(true)), 2); ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(level, source, blockPos3, this.defaultBlockState().setValue(getPropertyForFace(opposite), Boolean.valueOf(true)), 2); + } else if (random.nextFloat() < 0.05 && isAcceptableNeighbour(level, blockPos1.above(), Direction.UP)) { +- level.setBlock(blockPos1, this.defaultBlockState().setValue(UP, Boolean.valueOf(true)), 2); ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(level, source, blockPos1, this.defaultBlockState().setValue(UP, Boolean.valueOf(true)), 2); + } ++ // CraftBukkit end + } + } else if (isAcceptableNeighbour(level, blockPos1, random1)) { +- level.setBlock(pos, state.setValue(getPropertyForFace(random1), Boolean.valueOf(true)), 2); ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, pos, (BlockState) state.setValue(VineBlock.getPropertyForFace(random1), true), 2); // CraftBukkit + } + } + } else { + if (random1 == Direction.UP && pos.getY() < level.getMaxY()) { + if (this.canSupportAtFace(level, pos, random1)) { +- level.setBlock(pos, state.setValue(UP, Boolean.valueOf(true)), 2); ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, pos, state.setValue(UP, Boolean.valueOf(true)), 2); // CraftBukkit + return; + } + +@@ -244,7 +_,7 @@ + } + + if (this.hasHorizontalConnection(blockState1)) { +- level.setBlock(blockPos, blockState1, 2); ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(level, pos, blockPos, blockState1, 2); // CraftBukkit + } + + return; +@@ -258,7 +_,7 @@ + BlockState blockState2 = blockState.isAir() ? this.defaultBlockState() : blockState; + BlockState blockState3 = this.copyRandomFaces(state, blockState2, random); + if (blockState2 != blockState3 && this.hasHorizontalConnection(blockState3)) { +- level.setBlock(blockPos1, blockState3, 2); ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(level, pos, blockPos1, blockState3, 2); // CraftBukkit + } + } + } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/WallHangingSignBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/WallHangingSignBlock.java.patch similarity index 60% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/WallHangingSignBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/WallHangingSignBlock.java.patch index 73be8c6267..0543306a35 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/WallHangingSignBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/WallHangingSignBlock.java.patch @@ -1,10 +1,10 @@ --- a/net/minecraft/world/level/block/WallHangingSignBlock.java +++ b/net/minecraft/world/level/block/WallHangingSignBlock.java -@@ -179,6 +179,6 @@ +@@ -187,6 +_,6 @@ @Nullable @Override - public BlockEntityTicker getTicker(Level world, BlockState state, BlockEntityType type) { -- return createTickerHelper(type, BlockEntityType.HANGING_SIGN, SignBlockEntity::tick); + public BlockEntityTicker getTicker(Level level, BlockState state, BlockEntityType blockEntityType) { +- return createTickerHelper(blockEntityType, BlockEntityType.HANGING_SIGN, SignBlockEntity::tick); + return null; // Craftbukkit - remove unnecessary sign ticking } } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/WaterlilyBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/WaterlilyBlock.java.patch new file mode 100644 index 0000000000..7176715848 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/WaterlilyBlock.java.patch @@ -0,0 +1,17 @@ +--- a/net/minecraft/world/level/block/WaterlilyBlock.java ++++ b/net/minecraft/world/level/block/WaterlilyBlock.java +@@ -29,8 +_,14 @@ + + @Override + protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) { ++ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent + super.entityInside(state, level, pos, entity); + if (level instanceof ServerLevel && entity instanceof AbstractBoat) { ++ // CraftBukkit start ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, pos, state.getFluidState().createLegacyBlock())) { // Paper - fix wrong block state ++ return; ++ } ++ // CraftBukkit end + level.destroyBlock(new BlockPos(pos), true, entity); + } + } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/WebBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/WebBlock.java.patch similarity index 77% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/WebBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/WebBlock.java.patch index 1204a1e128..e774bcdbb1 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/WebBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/WebBlock.java.patch @@ -1,10 +1,10 @@ --- a/net/minecraft/world/level/block/WebBlock.java +++ b/net/minecraft/world/level/block/WebBlock.java -@@ -24,6 +24,7 @@ +@@ -24,6 +_,7 @@ @Override - protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { -+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent + protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) { ++ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent Vec3 vec3 = new Vec3(0.25, 0.05F, 0.25); if (entity instanceof LivingEntity livingEntity && livingEntity.hasEffect(MobEffects.WEAVING)) { vec3 = new Vec3(0.5, 0.25, 0.5); diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/WeightedPressurePlateBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/WeightedPressurePlateBlock.java.patch new file mode 100644 index 0000000000..26787da952 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/WeightedPressurePlateBlock.java.patch @@ -0,0 +1,39 @@ +--- a/net/minecraft/world/level/block/WeightedPressurePlateBlock.java ++++ b/net/minecraft/world/level/block/WeightedPressurePlateBlock.java +@@ -6,6 +_,7 @@ + import net.minecraft.core.BlockPos; + import net.minecraft.util.Mth; + import net.minecraft.world.entity.Entity; ++import net.minecraft.world.entity.player.Player; + import net.minecraft.world.level.Level; + import net.minecraft.world.level.block.state.BlockBehaviour; + import net.minecraft.world.level.block.state.BlockState; +@@ -39,7 +_,27 @@ + + @Override + protected int getSignalStrength(Level level, BlockPos pos) { +- int min = Math.min(getEntityCount(level, TOUCH_AABB.move(pos), Entity.class), this.maxWeight); ++ // CraftBukkit start ++ // int min = Math.min(getEntityCount(level, TOUCH_AABB.move(pos), Entity.class), this.maxWeight); ++ int min = 0; ++ for (Entity entity : getEntities(level, WeightedPressurePlateBlock.TOUCH_AABB.move(pos), Entity.class)) { ++ org.bukkit.event.Cancellable cancellable; ++ ++ if (entity instanceof Player) { ++ cancellable = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent((Player) entity, org.bukkit.event.block.Action.PHYSICAL, pos, null, null, null); ++ } else { ++ cancellable = new org.bukkit.event.entity.EntityInteractEvent(entity.getBukkitEntity(), level.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ())); ++ level.getCraftServer().getPluginManager().callEvent((org.bukkit.event.entity.EntityInteractEvent) cancellable); ++ } ++ ++ // We only want to block turning the plate on if all events are cancelled ++ if (!cancellable.isCancelled()) { ++ min++; ++ } ++ } ++ ++ min = Math.min(min, this.maxWeight); ++ // CraftBukkit end + if (min > 0) { + float f = (float)Math.min(this.maxWeight, min) / this.maxWeight; + return Mth.ceil(f * 15.0F); diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/WitherRoseBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/WitherRoseBlock.java.patch new file mode 100644 index 0000000000..6a3cdd4e5a --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/WitherRoseBlock.java.patch @@ -0,0 +1,16 @@ +--- a/net/minecraft/world/level/block/WitherRoseBlock.java ++++ b/net/minecraft/world/level/block/WitherRoseBlock.java +@@ -63,11 +_,12 @@ + + @Override + protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) { ++ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent + if (level instanceof ServerLevel serverLevel + && level.getDifficulty() != Difficulty.PEACEFUL + && entity instanceof LivingEntity livingEntity + && !livingEntity.isInvulnerableTo(serverLevel, level.damageSources().wither())) { +- livingEntity.addEffect(this.getBeeInteractionEffect()); ++ livingEntity.addEffect(this.getBeeInteractionEffect(), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.WITHER_ROSE); // CraftBukkit + } + } + diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/WitherSkullBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/WitherSkullBlock.java.patch new file mode 100644 index 0000000000..63d29d1d8d --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/WitherSkullBlock.java.patch @@ -0,0 +1,39 @@ +--- a/net/minecraft/world/level/block/WitherSkullBlock.java ++++ b/net/minecraft/world/level/block/WitherSkullBlock.java +@@ -51,6 +_,7 @@ + } + + public static void checkSpawn(Level level, BlockPos pos, SkullBlockEntity blockEntity) { ++ if (level.captureBlockStates) return; // CraftBukkit + if (!level.isClientSide) { + BlockState blockState = blockEntity.getBlockState(); + boolean flag = blockState.is(Blocks.WITHER_SKELETON_SKULL) || blockState.is(Blocks.WITHER_SKELETON_WALL_SKULL); +@@ -59,7 +_,7 @@ + if (blockPatternMatch != null) { + WitherBoss witherBoss = EntityType.WITHER.create(level, EntitySpawnReason.TRIGGERED); + if (witherBoss != null) { +- CarvedPumpkinBlock.clearPatternBlocks(level, blockPatternMatch); ++ // CarvedPumpkinBlock.clearPatternBlocks(level, blockPatternMatch); // CraftBukkit - move down + BlockPos pos1 = blockPatternMatch.getBlock(1, 2, 0).getPos(); + witherBoss.moveTo( + pos1.getX() + 0.5, +@@ -70,12 +_,18 @@ + ); + witherBoss.yBodyRot = blockPatternMatch.getForwards().getAxis() == Direction.Axis.X ? 0.0F : 90.0F; + witherBoss.makeInvulnerable(); ++ // CraftBukkit start ++ if (!level.addFreshEntity(witherBoss, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.BUILD_WITHER)) { ++ return; ++ } ++ CarvedPumpkinBlock.clearPatternBlocks(level, blockPatternMatch); // CraftBukkit - from above ++ // CraftBukkit end + + for (ServerPlayer serverPlayer : level.getEntitiesOfClass(ServerPlayer.class, witherBoss.getBoundingBox().inflate(50.0))) { + CriteriaTriggers.SUMMONED_ENTITY.trigger(serverPlayer, witherBoss); + } + +- level.addFreshEntity(witherBoss); ++ // level.addFreshEntity(witherBoss); // CraftBukkit - moved up + CarvedPumpkinBlock.updatePatternBlocks(level, blockPatternMatch); + } + } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/SaplingBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/SaplingBlock.java.patch deleted file mode 100644 index dbd9b130a0..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/SaplingBlock.java.patch +++ /dev/null @@ -1,117 +0,0 @@ ---- a/net/minecraft/world/level/block/SaplingBlock.java -+++ b/net/minecraft/world/level/block/SaplingBlock.java -@@ -10,12 +10,19 @@ - import net.minecraft.world.level.LevelReader; - import net.minecraft.world.level.block.grower.TreeGrower; - import net.minecraft.world.level.block.state.BlockBehaviour; --import net.minecraft.world.level.block.state.BlockState; - import net.minecraft.world.level.block.state.StateDefinition; - import net.minecraft.world.level.block.state.properties.BlockStateProperties; - import net.minecraft.world.level.block.state.properties.IntegerProperty; - import net.minecraft.world.phys.shapes.CollisionContext; - import net.minecraft.world.phys.shapes.VoxelShape; -+// CraftBukkit start -+import org.bukkit.Location; -+import org.bukkit.TreeType; -+import org.bukkit.block.BlockState; -+import org.bukkit.craftbukkit.block.CapturedBlockState; -+import org.bukkit.craftbukkit.util.CraftLocation; -+import org.bukkit.event.world.StructureGrowEvent; -+// CraftBukkit end - - public class SaplingBlock extends BushBlock implements BonemealableBlock { - -@@ -28,6 +35,7 @@ - protected static final float AABB_OFFSET = 6.0F; - protected static final VoxelShape SHAPE = Block.box(2.0D, 0.0D, 2.0D, 14.0D, 12.0D, 14.0D); - protected final TreeGrower treeGrower; -+ public static TreeType treeType; // CraftBukkit - - @Override - public MapCodec codec() { -@@ -37,48 +45,74 @@ - protected SaplingBlock(TreeGrower generator, BlockBehaviour.Properties settings) { - super(settings); - this.treeGrower = generator; -- this.registerDefaultState((BlockState) ((BlockState) this.stateDefinition.any()).setValue(SaplingBlock.STAGE, 0)); -+ this.registerDefaultState((net.minecraft.world.level.block.state.BlockState) ((net.minecraft.world.level.block.state.BlockState) this.stateDefinition.any()).setValue(SaplingBlock.STAGE, 0)); - } - - @Override -- protected VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { -+ protected VoxelShape getShape(net.minecraft.world.level.block.state.BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { - return SaplingBlock.SHAPE; - } - - @Override -- protected void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { -- if (world.getMaxLocalRawBrightness(pos.above()) >= 9 && random.nextInt(7) == 0) { -+ protected void randomTick(net.minecraft.world.level.block.state.BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { -+ if (world.getMaxLocalRawBrightness(pos.above()) >= 9 && random.nextFloat() < (world.spigotConfig.saplingModifier / (100.0f * 7))) { // Spigot - SPIGOT-7159: Better modifier resolution - this.advanceTree(world, pos, state, random); - } - - } - -- public void advanceTree(ServerLevel world, BlockPos pos, BlockState state, RandomSource random) { -+ public void advanceTree(ServerLevel world, BlockPos pos, net.minecraft.world.level.block.state.BlockState state, RandomSource random) { - if ((Integer) state.getValue(SaplingBlock.STAGE) == 0) { -- world.setBlock(pos, (BlockState) state.cycle(SaplingBlock.STAGE), 4); -+ world.setBlock(pos, (net.minecraft.world.level.block.state.BlockState) state.cycle(SaplingBlock.STAGE), 4); - } else { -- this.treeGrower.growTree(world, world.getChunkSource().getGenerator(), pos, state, random); -+ // CraftBukkit start -+ if (world.captureTreeGeneration) { -+ this.treeGrower.growTree(world, world.getChunkSource().getGenerator(), pos, state, random); -+ } else { -+ world.captureTreeGeneration = true; -+ this.treeGrower.growTree(world, world.getChunkSource().getGenerator(), pos, state, random); -+ world.captureTreeGeneration = false; -+ if (world.capturedBlockStates.size() > 0) { -+ TreeType treeType = SaplingBlock.treeType; -+ SaplingBlock.treeType = null; -+ Location location = CraftLocation.toBukkit(pos, world.getWorld()); -+ java.util.List blocks = new java.util.ArrayList<>(world.capturedBlockStates.values()); -+ world.capturedBlockStates.clear(); -+ StructureGrowEvent event = null; -+ if (treeType != null) { -+ event = new StructureGrowEvent(location, treeType, false, null, blocks); -+ org.bukkit.Bukkit.getPluginManager().callEvent(event); -+ } -+ if (event == null || !event.isCancelled()) { -+ for (BlockState blockstate : blocks) { -+ CapturedBlockState.setBlockState(blockstate); -+ world.checkCapturedTreeStateForObserverNotify(pos, (org.bukkit.craftbukkit.block.CraftBlockState) blockstate); // Paper - notify observers even if grow failed -+ } -+ } -+ } -+ } -+ // CraftBukkit end - } - - } - - @Override -- public boolean isValidBonemealTarget(LevelReader world, BlockPos pos, BlockState state) { -+ public boolean isValidBonemealTarget(LevelReader world, BlockPos pos, net.minecraft.world.level.block.state.BlockState state) { - return true; - } - - @Override -- public boolean isBonemealSuccess(Level world, RandomSource random, BlockPos pos, BlockState state) { -+ public boolean isBonemealSuccess(Level world, RandomSource random, BlockPos pos, net.minecraft.world.level.block.state.BlockState state) { - return (double) world.random.nextFloat() < 0.45D; - } - - @Override -- public void performBonemeal(ServerLevel world, RandomSource random, BlockPos pos, BlockState state) { -+ public void performBonemeal(ServerLevel world, RandomSource random, BlockPos pos, net.minecraft.world.level.block.state.BlockState state) { - this.advanceTree(world, pos, state, random); - } - - @Override -- protected void createBlockStateDefinition(StateDefinition.Builder builder) { -+ protected void createBlockStateDefinition(StateDefinition.Builder builder) { - builder.add(SaplingBlock.STAGE); - } - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/ScaffoldingBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/ScaffoldingBlock.java.patch deleted file mode 100644 index d5960ee388..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/ScaffoldingBlock.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/net/minecraft/world/level/block/ScaffoldingBlock.java -+++ b/net/minecraft/world/level/block/ScaffoldingBlock.java -@@ -103,7 +103,7 @@ - int i = ScaffoldingBlock.getDistance(world, pos); - BlockState iblockdata1 = (BlockState) ((BlockState) state.setValue(ScaffoldingBlock.DISTANCE, i)).setValue(ScaffoldingBlock.BOTTOM, this.isBottom(world, pos, i)); - -- if ((Integer) iblockdata1.getValue(ScaffoldingBlock.DISTANCE) == 7) { -+ if ((Integer) iblockdata1.getValue(ScaffoldingBlock.DISTANCE) == 7 && !org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world, pos, iblockdata1.getFluidState().createLegacyBlock()).isCancelled()) { // CraftBukkit - BlockFadeEvent // Paper - fix wrong block state - if ((Integer) state.getValue(ScaffoldingBlock.DISTANCE) == 7) { - FallingBlockEntity.fall(world, pos, iblockdata1); - } else { diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/SculkBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/SculkBlock.java.patch deleted file mode 100644 index b7e23a6303..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/SculkBlock.java.patch +++ /dev/null @@ -1,16 +0,0 @@ ---- a/net/minecraft/world/level/block/SculkBlock.java -+++ b/net/minecraft/world/level/block/SculkBlock.java -@@ -43,8 +43,11 @@ - BlockPos blockposition2 = blockposition1.above(); - BlockState iblockdata = this.getRandomGrowthState(world, blockposition2, random, spreadManager.isWorldGeneration()); - -- world.setBlock(blockposition2, iblockdata, 3); -- world.playSound((Player) null, blockposition1, iblockdata.getSoundType().getPlaceSound(), SoundSource.BLOCKS, 1.0F, 1.0F); -+ // CraftBukkit start - Call BlockSpreadEvent -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(world, catalystPos, blockposition2, iblockdata, 3)) { -+ world.playSound((Player) null, blockposition1, iblockdata.getSoundType().getPlaceSound(), SoundSource.BLOCKS, 1.0F, 1.0F); -+ } -+ // CraftBukkit end - } - - return Math.max(0, i - j); diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/SculkCatalystBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/SculkCatalystBlock.java.patch deleted file mode 100644 index 12314e3c0c..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/SculkCatalystBlock.java.patch +++ /dev/null @@ -1,21 +0,0 @@ ---- a/net/minecraft/world/level/block/SculkCatalystBlock.java -+++ b/net/minecraft/world/level/block/SculkCatalystBlock.java -@@ -63,9 +63,16 @@ - @Override - protected void spawnAfterBreak(BlockState state, ServerLevel world, BlockPos pos, ItemStack tool, boolean dropExperience) { - super.spawnAfterBreak(state, world, pos, tool, dropExperience); -- if (dropExperience) { -- this.tryDropExperience(world, pos, tool, this.xpRange); -+ // CraftBukkit start - Delegate to getExpDrop -+ } -+ -+ @Override -+ public int getExpDrop(BlockState iblockdata, ServerLevel worldserver, BlockPos blockposition, ItemStack itemstack, boolean flag) { -+ if (flag) { -+ return this.tryDropExperience(worldserver, blockposition, itemstack, this.xpRange); - } - -+ return 0; -+ // CraftBukkit end - } - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/SculkSensorBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/SculkSensorBlock.java.patch deleted file mode 100644 index 8e63b99d10..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/SculkSensorBlock.java.patch +++ /dev/null @@ -1,88 +0,0 @@ ---- a/net/minecraft/world/level/block/SculkSensorBlock.java -+++ b/net/minecraft/world/level/block/SculkSensorBlock.java -@@ -43,6 +43,10 @@ - import net.minecraft.world.level.pathfinder.PathComputationType; - import net.minecraft.world.phys.shapes.CollisionContext; - import net.minecraft.world.phys.shapes.VoxelShape; -+// CraftBukkit start -+import org.bukkit.craftbukkit.block.CraftBlock; -+import org.bukkit.event.block.BlockRedstoneEvent; -+// CraftBukkit end - - public class SculkSensorBlock extends BaseEntityBlock implements SimpleWaterloggedBlock { - -@@ -104,6 +108,18 @@ - @Override - public void stepOn(Level world, BlockPos pos, BlockState state, Entity entity) { - if (!world.isClientSide() && SculkSensorBlock.canActivate(state) && entity.getType() != EntityType.WARDEN) { -+ // CraftBukkit start -+ org.bukkit.event.Cancellable cancellable; -+ if (entity instanceof Player) { -+ cancellable = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent((Player) entity, org.bukkit.event.block.Action.PHYSICAL, pos, null, null, null); -+ } else { -+ cancellable = new org.bukkit.event.entity.EntityInteractEvent(entity.getBukkitEntity(), world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ())); -+ world.getCraftServer().getPluginManager().callEvent((org.bukkit.event.entity.EntityInteractEvent) cancellable); -+ } -+ if (cancellable.isCancelled()) { -+ return; -+ } -+ // CraftBukkit end - BlockEntity tileentity = world.getBlockEntity(pos); - - if (tileentity instanceof SculkSensorBlockEntity) { -@@ -198,10 +214,19 @@ - } - - public static boolean canActivate(BlockState state) { -- return SculkSensorBlock.getPhase(state) == SculkSensorPhase.INACTIVE; -+ return state.getBlock() instanceof SculkSensorBlock && SculkSensorBlock.getPhase(state) == SculkSensorPhase.INACTIVE; // Paper - Check for a valid type - } - - public static void deactivate(Level world, BlockPos pos, BlockState state) { -+ // CraftBukkit start -+ BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(CraftBlock.at(world, pos), state.getValue(SculkSensorBlock.POWER), 0); -+ world.getCraftServer().getPluginManager().callEvent(eventRedstone); -+ -+ if (eventRedstone.getNewCurrent() > 0) { -+ world.setBlock(pos, state.setValue(SculkSensorBlock.POWER, eventRedstone.getNewCurrent()), 3); -+ return; -+ } -+ // CraftBukkit end - world.setBlock(pos, (BlockState) ((BlockState) state.setValue(SculkSensorBlock.PHASE, SculkSensorPhase.COOLDOWN)).setValue(SculkSensorBlock.POWER, 0), 3); - world.scheduleTick(pos, state.getBlock(), 10); - SculkSensorBlock.updateNeighbours(world, pos, state); -@@ -213,6 +238,15 @@ - } - - public void activate(@Nullable Entity sourceEntity, Level world, BlockPos pos, BlockState state, int power, int frequency) { -+ // CraftBukkit start -+ BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(CraftBlock.at(world, pos), state.getValue(SculkSensorBlock.POWER), power); -+ world.getCraftServer().getPluginManager().callEvent(eventRedstone); -+ -+ if (eventRedstone.getNewCurrent() <= 0) { -+ return; -+ } -+ power = eventRedstone.getNewCurrent(); -+ // CraftBukkit end - world.setBlock(pos, (BlockState) ((BlockState) state.setValue(SculkSensorBlock.PHASE, SculkSensorPhase.ACTIVE)).setValue(SculkSensorBlock.POWER, power), 3); - world.scheduleTick(pos, state.getBlock(), this.getActiveTicks()); - SculkSensorBlock.updateNeighbours(world, pos, state); -@@ -293,9 +327,16 @@ - @Override - protected void spawnAfterBreak(BlockState state, ServerLevel world, BlockPos pos, ItemStack tool, boolean dropExperience) { - super.spawnAfterBreak(state, world, pos, tool, dropExperience); -- if (dropExperience) { -- this.tryDropExperience(world, pos, tool, ConstantInt.of(5)); -+ // CraftBukkit start - Delegate to getExpDrop -+ } -+ -+ @Override -+ public int getExpDrop(BlockState iblockdata, ServerLevel worldserver, BlockPos blockposition, ItemStack itemstack, boolean flag) { -+ if (flag) { -+ return this.tryDropExperience(worldserver, blockposition, itemstack, ConstantInt.of(5)); - } - -+ return 0; -+ // CraftBukkit end - } - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/SculkShriekerBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/SculkShriekerBlock.java.patch deleted file mode 100644 index 8c254d2936..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/SculkShriekerBlock.java.patch +++ /dev/null @@ -1,30 +0,0 @@ ---- a/net/minecraft/world/level/block/SculkShriekerBlock.java -+++ b/net/minecraft/world/level/block/SculkShriekerBlock.java -@@ -63,6 +63,7 @@ - ServerPlayer entityplayer = SculkShriekerBlockEntity.tryGetPlayer(entity); - - if (entityplayer != null) { -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent(entityplayer, org.bukkit.event.block.Action.PHYSICAL, pos, null, null, null).isCancelled()) return; // CraftBukkit - worldserver.getBlockEntity(pos, BlockEntityType.SCULK_SHRIEKER).ifPresent((sculkshriekerblockentity) -> { - sculkshriekerblockentity.tryShriek(worldserver, entityplayer); - }); -@@ -140,10 +141,17 @@ - @Override - protected void spawnAfterBreak(BlockState state, ServerLevel world, BlockPos pos, ItemStack tool, boolean dropExperience) { - super.spawnAfterBreak(state, world, pos, tool, dropExperience); -- if (dropExperience) { -- this.tryDropExperience(world, pos, tool, ConstantInt.of(5)); -+ // CraftBukkit start - Delegate to getExpDrop -+ } -+ -+ @Override -+ public int getExpDrop(BlockState iblockdata, ServerLevel worldserver, BlockPos blockposition, ItemStack itemstack, boolean flag) { -+ if (flag) { -+ return this.tryDropExperience(worldserver, blockposition, itemstack, ConstantInt.of(5)); - } - -+ return 0; -+ // CraftBukkit end - } - - @Nullable diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/SculkSpreader.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/SculkSpreader.java.patch deleted file mode 100644 index a334f182c5..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/SculkSpreader.java.patch +++ /dev/null @@ -1,98 +0,0 @@ ---- a/net/minecraft/world/level/block/SculkSpreader.java -+++ b/net/minecraft/world/level/block/SculkSpreader.java -@@ -30,6 +30,7 @@ - import net.minecraft.core.Vec3i; - import net.minecraft.nbt.CompoundTag; - import net.minecraft.nbt.NbtOps; -+import net.minecraft.nbt.Tag; - import net.minecraft.server.level.ServerLevel; - import net.minecraft.sounds.SoundEvents; - import net.minecraft.sounds.SoundSource; -@@ -37,9 +38,14 @@ - import net.minecraft.tags.TagKey; - import net.minecraft.util.RandomSource; - import net.minecraft.world.entity.player.Player; -+import net.minecraft.world.level.Level; - import net.minecraft.world.level.LevelAccessor; - import net.minecraft.world.level.block.state.BlockState; - import org.slf4j.Logger; -+import org.bukkit.Bukkit; -+import org.bukkit.craftbukkit.block.CraftBlock; -+import org.bukkit.event.block.SculkBloomEvent; -+// CraftBukkit end - - public class SculkSpreader { - -@@ -57,6 +63,7 @@ - private final int additionalDecayRate; - private List cursors = new ArrayList(); - private static final Logger LOGGER = LogUtils.getLogger(); -+ public Level level; // CraftBukkit - - public SculkSpreader(boolean worldGen, TagKey replaceableTag, int extraBlockChance, int maxDistance, int spreadChance, int decayChance) { - this.isWorldGeneration = worldGen; -@@ -111,7 +118,7 @@ - public void load(CompoundTag nbt) { - if (nbt.contains("cursors", 9)) { - this.cursors.clear(); -- DataResult dataresult = SculkSpreader.ChargeCursor.CODEC.listOf().parse(new Dynamic(NbtOps.INSTANCE, nbt.getList("cursors", 10))); -+ DataResult> dataresult = SculkSpreader.ChargeCursor.CODEC.listOf().parse(new Dynamic<>(NbtOps.INSTANCE, nbt.getList("cursors", 10))); // CraftBukkit - decompile error - Logger logger = SculkSpreader.LOGGER; - - Objects.requireNonNull(logger); -@@ -119,14 +126,14 @@ - int i = Math.min(list.size(), 32); - - for (int j = 0; j < i; ++j) { -- this.addCursor((SculkSpreader.ChargeCursor) list.get(j)); -+ this.addCursor((SculkSpreader.ChargeCursor) list.get(j), false); // Paper - don't fire event for block entity loading - } - } - - } - - public void save(CompoundTag nbt) { -- DataResult dataresult = SculkSpreader.ChargeCursor.CODEC.listOf().encodeStart(NbtOps.INSTANCE, this.cursors); -+ DataResult dataresult = SculkSpreader.ChargeCursor.CODEC.listOf().encodeStart(NbtOps.INSTANCE, this.cursors); // CraftBukkit - decompile error - Logger logger = SculkSpreader.LOGGER; - - Objects.requireNonNull(logger); -@@ -139,14 +146,27 @@ - while (charge > 0) { - int j = Math.min(charge, 1000); - -- this.addCursor(new SculkSpreader.ChargeCursor(pos, j)); -+ this.addCursor(new SculkSpreader.ChargeCursor(pos, j), true); // Paper - allow firing event for other causes - charge -= j; - } - - } - -- private void addCursor(SculkSpreader.ChargeCursor cursor) { -+ private void addCursor(SculkSpreader.ChargeCursor cursor, boolean fireEvent) { // Paper - add boolean to conditionally fire SculkBloomEvent - if (this.cursors.size() < 32) { -+ // CraftBukkit start -+ if (!this.isWorldGeneration() && fireEvent) { // CraftBukkit - SPIGOT-7475: Don't call event during world generation // Paper - add boolean to conditionally fire SculkBloomEvent -+ CraftBlock bukkitBlock = CraftBlock.at(this.level, cursor.pos); -+ SculkBloomEvent event = new SculkBloomEvent(bukkitBlock, cursor.getCharge()); -+ Bukkit.getPluginManager().callEvent(event); -+ if (event.isCancelled()) { -+ return; -+ } -+ -+ cursor.charge = event.getCharge(); -+ } -+ // CraftBukkit end -+ - this.cursors.add(cursor); - } - } -@@ -244,7 +264,7 @@ - this.charge = charge; - this.decayDelay = decay; - this.updateDelay = update; -- this.facings = (Set) faces.orElse((Object) null); -+ this.facings = (Set) faces.orElse(null); // CraftBukkit - decompile error - } - - public ChargeCursor(BlockPos pos, int charge) { diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/SculkVeinBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/SculkVeinBlock.java.patch deleted file mode 100644 index 4d009bd7c1..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/SculkVeinBlock.java.patch +++ /dev/null @@ -1,60 +0,0 @@ ---- a/net/minecraft/world/level/block/SculkVeinBlock.java -+++ b/net/minecraft/world/level/block/SculkVeinBlock.java -@@ -101,28 +101,33 @@ - - @Override - public int attemptUseCharge(SculkSpreader.ChargeCursor cursor, LevelAccessor world, BlockPos catalystPos, RandomSource random, SculkSpreader spreadManager, boolean shouldConvertToBlock) { -- return shouldConvertToBlock && this.attemptPlaceSculk(spreadManager, world, cursor.getPos(), random) ? cursor.getCharge() - 1 : (random.nextInt(spreadManager.chargeDecayRate()) == 0 ? Mth.floor((float) cursor.getCharge() * 0.5F) : cursor.getCharge()); -+ // CraftBukkit - add source block -+ return shouldConvertToBlock && this.attemptPlaceSculk(spreadManager, world, cursor.getPos(), random, catalystPos) ? cursor.getCharge() - 1 : (random.nextInt(spreadManager.chargeDecayRate()) == 0 ? Mth.floor((float) cursor.getCharge() * 0.5F) : cursor.getCharge()); - } - -- private boolean attemptPlaceSculk(SculkSpreader spreadManager, LevelAccessor world, BlockPos pos, RandomSource random) { -- BlockState iblockdata = world.getBlockState(pos); -- TagKey tagkey = spreadManager.replaceableBlocks(); -- Iterator iterator = Direction.allShuffled(random).iterator(); -+ private boolean attemptPlaceSculk(SculkSpreader sculkspreader, LevelAccessor generatoraccess, BlockPos blockposition, RandomSource randomsource, BlockPos sourceBlock) { // CraftBukkit -+ BlockState iblockdata = generatoraccess.getBlockState(blockposition); -+ TagKey tagkey = sculkspreader.replaceableBlocks(); -+ Iterator iterator = Direction.allShuffled(randomsource).iterator(); - - while (iterator.hasNext()) { - Direction enumdirection = (Direction) iterator.next(); - - if (hasFace(iblockdata, enumdirection)) { -- BlockPos blockposition1 = pos.relative(enumdirection); -- BlockState iblockdata1 = world.getBlockState(blockposition1); -+ BlockPos blockposition1 = blockposition.relative(enumdirection); -+ BlockState iblockdata1 = generatoraccess.getBlockState(blockposition1); - - if (iblockdata1.is(tagkey)) { - BlockState iblockdata2 = Blocks.SCULK.defaultBlockState(); - -- world.setBlock(blockposition1, iblockdata2, 3); -- Block.pushEntitiesUp(iblockdata1, iblockdata2, world, blockposition1); -- world.playSound((Player) null, blockposition1, SoundEvents.SCULK_BLOCK_SPREAD, SoundSource.BLOCKS, 1.0F, 1.0F); -- this.veinSpreader.spreadAll(iblockdata2, world, blockposition1, spreadManager.isWorldGeneration()); -+ // CraftBukkit start - Call BlockSpreadEvent -+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(generatoraccess, sourceBlock, blockposition1, iblockdata2, 3)) { -+ return false; -+ } -+ // CraftBukkit end -+ Block.pushEntitiesUp(iblockdata1, iblockdata2, generatoraccess, blockposition1); -+ generatoraccess.playSound((Player) null, blockposition1, SoundEvents.SCULK_BLOCK_SPREAD, SoundSource.BLOCKS, 1.0F, 1.0F); -+ this.veinSpreader.spreadAll(iblockdata2, generatoraccess, blockposition1, sculkspreader.isWorldGeneration()); - Direction enumdirection1 = enumdirection.getOpposite(); - Direction[] aenumdirection = SculkVeinBlock.DIRECTIONS; - int i = aenumdirection.length; -@@ -132,10 +137,10 @@ - - if (enumdirection2 != enumdirection1) { - BlockPos blockposition2 = blockposition1.relative(enumdirection2); -- BlockState iblockdata3 = world.getBlockState(blockposition2); -+ BlockState iblockdata3 = generatoraccess.getBlockState(blockposition2); - - if (iblockdata3.is((Block) this)) { -- this.onDischarged(world, iblockdata3, blockposition2, random); -+ this.onDischarged(generatoraccess, iblockdata3, blockposition2, randomsource); - } - } - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/SnowLayerBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/SnowLayerBlock.java.patch deleted file mode 100644 index 5db7dbeea9..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/SnowLayerBlock.java.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- a/net/minecraft/world/level/block/SnowLayerBlock.java -+++ b/net/minecraft/world/level/block/SnowLayerBlock.java -@@ -99,6 +99,11 @@ - @Override - protected void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { - if (world.getBrightness(LightLayer.BLOCK, pos) > 11) { -+ // CraftBukkit start -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world, pos, Blocks.AIR.defaultBlockState()).isCancelled()) { -+ return; -+ } -+ // CraftBukkit end - dropResources(state, world, pos); - world.removeBlock(pos, false); - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/SpawnerBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/SpawnerBlock.java.patch deleted file mode 100644 index 8f4ea72cba..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/SpawnerBlock.java.patch +++ /dev/null @@ -1,26 +0,0 @@ ---- a/net/minecraft/world/level/block/SpawnerBlock.java -+++ b/net/minecraft/world/level/block/SpawnerBlock.java -@@ -45,12 +45,20 @@ - @Override - protected void spawnAfterBreak(BlockState state, ServerLevel world, BlockPos pos, ItemStack tool, boolean dropExperience) { - super.spawnAfterBreak(state, world, pos, tool, dropExperience); -- if (dropExperience) { -- int i = 15 + world.random.nextInt(15) + world.random.nextInt(15); -+ // CraftBukkit start - Delegate to getExpDrop -+ } - -- this.popExperience(world, pos, i); -+ @Override -+ public int getExpDrop(BlockState iblockdata, ServerLevel worldserver, BlockPos blockposition, ItemStack itemstack, boolean flag) { -+ if (flag) { -+ int i = 15 + worldserver.random.nextInt(15) + worldserver.random.nextInt(15); -+ -+ // this.popExperience(worldserver, blockposition, i); -+ return i; - } - -+ return 0; -+ // CraftBukkit end - } - - @Override diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/SpongeBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/SpongeBlock.java.patch deleted file mode 100644 index d0c197c400..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/SpongeBlock.java.patch +++ /dev/null @@ -1,114 +0,0 @@ ---- a/net/minecraft/world/level/block/SpongeBlock.java -+++ b/net/minecraft/world/level/block/SpongeBlock.java -@@ -15,6 +15,13 @@ - import net.minecraft.world.level.material.FluidState; - import net.minecraft.world.level.redstone.Orientation; - -+// CraftBukkit start -+import java.util.List; -+import org.bukkit.craftbukkit.block.CraftBlockState; -+import org.bukkit.craftbukkit.util.BlockStateListPopulator; -+import org.bukkit.event.block.SpongeAbsorbEvent; -+// CraftBukkit end -+ - public class SpongeBlock extends Block { - - public static final MapCodec CODEC = simpleCodec(SpongeBlock::new); -@@ -53,7 +60,8 @@ - } - - private boolean removeWaterBreadthFirstSearch(Level world, BlockPos pos) { -- return BlockPos.breadthFirstTraversal(pos, 6, 65, (blockposition1, consumer) -> { -+ BlockStateListPopulator blockList = new BlockStateListPopulator(world); // CraftBukkit - Use BlockStateListPopulator -+ BlockPos.breadthFirstTraversal(pos, 6, 65, (blockposition1, consumer) -> { - Direction[] aenumdirection = SpongeBlock.ALL_DIRECTIONS; - int i = aenumdirection.length; - -@@ -67,8 +75,10 @@ - if (blockposition1.equals(pos)) { - return BlockPos.TraversalNodeStatus.ACCEPT; - } else { -- BlockState iblockdata = world.getBlockState(blockposition1); -- FluidState fluid = world.getFluidState(blockposition1); -+ // CraftBukkit start -+ BlockState iblockdata = blockList.getBlockState(blockposition1); -+ FluidState fluid = blockList.getFluidState(blockposition1); -+ // CraftBukkit end - - if (!fluid.is(FluidTags.WATER)) { - return BlockPos.TraversalNodeStatus.SKIP; -@@ -78,27 +88,68 @@ - if (block instanceof BucketPickup) { - BucketPickup ifluidsource = (BucketPickup) block; - -- if (!ifluidsource.pickupBlock((Player) null, world, blockposition1, iblockdata).isEmpty()) { -+ if (!ifluidsource.pickupBlock((Player) null, blockList, blockposition1, iblockdata).isEmpty()) { // CraftBukkit - return BlockPos.TraversalNodeStatus.ACCEPT; - } - } - - if (iblockdata.getBlock() instanceof LiquidBlock) { -- world.setBlock(blockposition1, Blocks.AIR.defaultBlockState(), 3); -+ blockList.setBlock(blockposition1, Blocks.AIR.defaultBlockState(), 3); // CraftBukkit - } else { - if (!iblockdata.is(Blocks.KELP) && !iblockdata.is(Blocks.KELP_PLANT) && !iblockdata.is(Blocks.SEAGRASS) && !iblockdata.is(Blocks.TALL_SEAGRASS)) { - return BlockPos.TraversalNodeStatus.SKIP; - } - -- BlockEntity tileentity = iblockdata.hasBlockEntity() ? world.getBlockEntity(blockposition1) : null; -+ // CraftBukkit start -+ // TileEntity tileentity = iblockdata.hasBlockEntity() ? world.getBlockEntity(blockposition1) : null; - -- dropResources(iblockdata, world, blockposition1, tileentity); -- world.setBlock(blockposition1, Blocks.AIR.defaultBlockState(), 3); -+ // dropResources(iblockdata, world, blockposition1, tileentity); -+ blockList.setBlock(blockposition1, Blocks.AIR.defaultBlockState(), 3); -+ // CraftBukkit end - } - - return BlockPos.TraversalNodeStatus.ACCEPT; - } - } -- }) > 1; -+ }); -+ // CraftBukkit start -+ List blocks = blockList.getList(); // Is a clone -+ if (!blocks.isEmpty()) { -+ final org.bukkit.block.Block bblock = world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()); -+ -+ SpongeAbsorbEvent event = new SpongeAbsorbEvent(bblock, (List) (List) blocks); -+ world.getCraftServer().getPluginManager().callEvent(event); -+ -+ if (event.isCancelled()) { -+ return false; -+ } -+ -+ for (CraftBlockState block : blocks) { -+ BlockPos blockposition1 = block.getPosition(); -+ BlockState iblockdata = world.getBlockState(blockposition1); -+ FluidState fluid = world.getFluidState(blockposition1); -+ -+ if (fluid.is(FluidTags.WATER)) { -+ if (iblockdata.getBlock() instanceof BucketPickup && !((BucketPickup) iblockdata.getBlock()).pickupBlock((Player) null, blockList, blockposition1, iblockdata).isEmpty()) { -+ // NOP -+ } else if (iblockdata.getBlock() instanceof LiquidBlock) { -+ // NOP -+ } else if (iblockdata.is(Blocks.KELP) || iblockdata.is(Blocks.KELP_PLANT) || iblockdata.is(Blocks.SEAGRASS) || iblockdata.is(Blocks.TALL_SEAGRASS)) { -+ BlockEntity tileentity = iblockdata.hasBlockEntity() ? world.getBlockEntity(blockposition1) : null; -+ -+ // Paper start - Fix SpongeAbsortEvent handling -+ if (block.getHandle().isAir()) { -+ dropResources(iblockdata, world, blockposition1, tileentity); -+ } -+ // Paper end - Fix SpongeAbsortEvent handling -+ } -+ } -+ world.setBlock(blockposition1, block.getHandle(), block.getFlag()); -+ } -+ -+ return true; -+ } -+ return false; -+ // CraftBukkit end - } - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java.patch deleted file mode 100644 index 5777f59736..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java.patch +++ /dev/null @@ -1,25 +0,0 @@ ---- a/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java -+++ b/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java -@@ -43,7 +43,13 @@ - - @Override - protected void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { -+ if (this instanceof GrassBlock && world.paperConfig().tickRates.grassSpread != 1 && (world.paperConfig().tickRates.grassSpread < 1 || (net.minecraft.server.MinecraftServer.currentTick + pos.hashCode()) % world.paperConfig().tickRates.grassSpread != 0)) { return; } // Paper - Configurable random tick rates for blocks - if (!SpreadingSnowyDirtBlock.canBeGrass(state, world, pos)) { -+ // CraftBukkit start -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world, pos, Blocks.DIRT.defaultBlockState()).isCancelled()) { -+ return; -+ } -+ // CraftBukkit end - world.setBlockAndUpdate(pos, Blocks.DIRT.defaultBlockState()); - } else { - if (world.getMaxLocalRawBrightness(pos.above()) >= 9) { -@@ -53,7 +59,7 @@ - BlockPos blockposition1 = pos.offset(random.nextInt(3) - 1, random.nextInt(5) - 3, random.nextInt(3) - 1); - - if (world.getBlockState(blockposition1).is(Blocks.DIRT) && SpreadingSnowyDirtBlock.canPropagate(iblockdata1, world, blockposition1)) { -- world.setBlockAndUpdate(blockposition1, (BlockState) iblockdata1.setValue(SpreadingSnowyDirtBlock.SNOWY, isSnowySetting(world.getBlockState(blockposition1.above())))); -+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(world, pos, blockposition1, (BlockState) iblockdata1.setValue(SpreadingSnowyDirtBlock.SNOWY, isSnowySetting(world.getBlockState(blockposition1.above())))); // CraftBukkit - } - } - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/StemBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/StemBlock.java.patch deleted file mode 100644 index 625e104922..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/StemBlock.java.patch +++ /dev/null @@ -1,47 +0,0 @@ ---- a/net/minecraft/world/level/block/StemBlock.java -+++ b/net/minecraft/world/level/block/StemBlock.java -@@ -26,6 +26,7 @@ - import net.minecraft.world.level.block.state.properties.IntegerProperty; - import net.minecraft.world.phys.shapes.CollisionContext; - import net.minecraft.world.phys.shapes.VoxelShape; -+import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit - - public class StemBlock extends BushBlock implements BonemealableBlock { - -@@ -74,12 +75,12 @@ - if (world.getRawBrightness(pos, 0) >= 9) { - float f = CropBlock.getGrowthSpeed(this, world, pos); - -- if (random.nextInt((int) (25.0F / f) + 1) == 0) { -+ if (random.nextFloat() < ((this == Blocks.PUMPKIN_STEM ? world.spigotConfig.pumpkinModifier : world.spigotConfig.melonModifier) / (100.0f * (Math.floor((25.0F / f) + 1))))) { // Spigot - SPIGOT-7159: Better modifier resolution - int i = (Integer) state.getValue(StemBlock.AGE); - - if (i < 7) { - state = (BlockState) state.setValue(StemBlock.AGE, i + 1); -- world.setBlock(pos, state, 2); -+ CraftEventFactory.handleBlockGrowEvent(world, pos, state, 2); // CraftBukkit - } else { - Direction enumdirection = Direction.Plane.HORIZONTAL.getRandomDirection(random); - BlockPos blockposition1 = pos.relative(enumdirection); -@@ -91,7 +92,11 @@ - Optional optional1 = iregistry.getOptional(this.attachedStem); - - if (optional.isPresent() && optional1.isPresent()) { -- world.setBlockAndUpdate(blockposition1, ((Block) optional.get()).defaultBlockState()); -+ // CraftBukkit start -+ if (!CraftEventFactory.handleBlockGrowEvent(world, blockposition1, ((Block) optional.get()).defaultBlockState())) { -+ return; -+ } -+ // CraftBukkit end - world.setBlockAndUpdate(pos, (BlockState) ((Block) optional1.get()).defaultBlockState().setValue(HorizontalDirectionalBlock.FACING, enumdirection)); - } - } -@@ -121,7 +126,7 @@ - int i = Math.min(7, (Integer) state.getValue(StemBlock.AGE) + Mth.nextInt(world.random, 2, 5)); - BlockState iblockdata1 = (BlockState) state.setValue(StemBlock.AGE, i); - -- world.setBlock(pos, iblockdata1, 2); -+ CraftEventFactory.handleBlockGrowEvent(world, pos, iblockdata1, 2); // CraftBukkit - if (i == 7) { - iblockdata1.randomTick(world, pos, world.random); - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/SugarCaneBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/SugarCaneBlock.java.patch deleted file mode 100644 index 903b77b2e2..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/SugarCaneBlock.java.patch +++ /dev/null @@ -1,21 +0,0 @@ ---- a/net/minecraft/world/level/block/SugarCaneBlock.java -+++ b/net/minecraft/world/level/block/SugarCaneBlock.java -@@ -59,13 +59,14 @@ - ; - } - -- if (i < 3) { -+ if (i < world.paperConfig().maxGrowthHeight.reeds) { // Paper - Configurable cactus/bamboo/reed growth heigh - int j = (Integer) state.getValue(SugarCaneBlock.AGE); - -- if (j == 15) { -- world.setBlockAndUpdate(pos.above(), this.defaultBlockState()); -+ int modifier = world.spigotConfig.caneModifier; // Spigot - SPIGOT-7159: Better modifier resolution -+ if (j >= 15 || (modifier != 100 && random.nextFloat() < (modifier / (100.0f * 16)))) { // Spigot - SPIGOT-7159: Better modifier resolution -+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(world, pos.above(), this.defaultBlockState()); // CraftBukkit - world.setBlock(pos, (BlockState) state.setValue(SugarCaneBlock.AGE, 0), 4); -- } else { -+ } else if (modifier == 100 || random.nextFloat() < (modifier / (100.0f * 16))) { // Spigot - SPIGOT-7159: Better modifier resolution - world.setBlock(pos, (BlockState) state.setValue(SugarCaneBlock.AGE, j + 1), 4); - } - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/SweetBerryBushBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/SweetBerryBushBlock.java.patch deleted file mode 100644 index c0fadbe893..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/SweetBerryBushBlock.java.patch +++ /dev/null @@ -1,62 +0,0 @@ ---- a/net/minecraft/world/level/block/SweetBerryBushBlock.java -+++ b/net/minecraft/world/level/block/SweetBerryBushBlock.java -@@ -28,6 +28,12 @@ - import net.minecraft.world.phys.Vec3; - import net.minecraft.world.phys.shapes.CollisionContext; - import net.minecraft.world.phys.shapes.VoxelShape; -+// CraftBukkit start -+import java.util.Collections; -+import org.bukkit.craftbukkit.event.CraftEventFactory; -+import org.bukkit.craftbukkit.inventory.CraftItemStack; -+import org.bukkit.event.player.PlayerHarvestBlockEvent; -+// CraftBukkit end - - public class SweetBerryBushBlock extends BushBlock implements BonemealableBlock { - -@@ -67,10 +73,10 @@ - protected void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { - int i = (Integer) state.getValue(SweetBerryBushBlock.AGE); - -- if (i < 3 && random.nextInt(5) == 0 && world.getRawBrightness(pos.above(), 0) >= 9) { -+ if (i < 3 && random.nextFloat() < (world.spigotConfig.sweetBerryModifier / (100.0f * 5)) && world.getRawBrightness(pos.above(), 0) >= 9) { // Spigot - SPIGOT-7159: Better modifier resolution - BlockState iblockdata1 = (BlockState) state.setValue(SweetBerryBushBlock.AGE, i + 1); - -- world.setBlock(pos, iblockdata1, 2); -+ if (!CraftEventFactory.handleBlockGrowEvent(world, pos, iblockdata1, 2)) return; // CraftBukkit - world.gameEvent((Holder) GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(iblockdata1)); - } - -@@ -78,6 +84,7 @@ - - @Override - protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { -+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent - if (entity instanceof LivingEntity && entity.getType() != EntityType.FOX && entity.getType() != EntityType.BEE) { - entity.makeStuckInBlock(state, new Vec3(0.800000011920929D, 0.75D, 0.800000011920929D)); - if (world instanceof ServerLevel) { -@@ -91,7 +98,7 @@ - double d1 = Math.abs(vec3d.z()); - - if (d0 >= 0.003000000026077032D || d1 >= 0.003000000026077032D) { -- entity.hurtServer(worldserver, world.damageSources().sweetBerryBush(), 1.0F); -+ entity.hurtServer(worldserver, world.damageSources().sweetBerryBush().directBlock(world, pos), 1.0F); // CraftBukkit - } - } - -@@ -118,7 +125,15 @@ - if (i > 1) { - int j = 1 + world.random.nextInt(2); - -- popResource(world, pos, new ItemStack(Items.SWEET_BERRIES, j + (flag ? 1 : 0))); -+ // CraftBukkit start - useWithoutItem is always MAIN_HAND -+ PlayerHarvestBlockEvent event = CraftEventFactory.callPlayerHarvestBlockEvent(world, pos, player, InteractionHand.MAIN_HAND, Collections.singletonList(new ItemStack(Items.SWEET_BERRIES, j + (flag ? 1 : 0)))); -+ if (event.isCancelled()) { -+ return InteractionResult.SUCCESS; // We need to return a success either way, because making it PASS or FAIL will result in a bug where cancelling while harvesting w/ block in hand places block -+ } -+ for (org.bukkit.inventory.ItemStack itemStack : event.getItemsHarvested()) { -+ popResource(world, pos, CraftItemStack.asNMSCopy(itemStack)); -+ } -+ // CraftBukkit end - world.playSound((Player) null, pos, SoundEvents.SWEET_BERRY_BUSH_PICK_BERRIES, SoundSource.BLOCKS, 1.0F, 0.8F + world.random.nextFloat() * 0.4F); - BlockState iblockdata1 = (BlockState) state.setValue(SweetBerryBushBlock.AGE, 1); - diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/TntBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/TntBlock.java.patch deleted file mode 100644 index 42cf7a6881..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/TntBlock.java.patch +++ /dev/null @@ -1,102 +0,0 @@ ---- a/net/minecraft/world/level/block/TntBlock.java -+++ b/net/minecraft/world/level/block/TntBlock.java -@@ -28,6 +28,10 @@ - import net.minecraft.world.level.gameevent.GameEvent; - import net.minecraft.world.level.redstone.Orientation; - import net.minecraft.world.phys.BlockHitResult; -+// CraftBukkit start -+import org.bukkit.craftbukkit.event.CraftEventFactory; -+import org.bukkit.event.block.TNTPrimeEvent.PrimeCause; -+// CraftBukkit end - - public class TntBlock extends Block { - -@@ -47,7 +51,13 @@ - @Override - protected void onPlace(BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify) { - if (!oldState.is(state.getBlock())) { -- if (world.hasNeighborSignal(pos)) { -+ if (world.hasNeighborSignal(pos) && CraftEventFactory.callTNTPrimeEvent(world, pos, PrimeCause.REDSTONE, null, null)) { // CraftBukkit - TNTPrimeEvent -+ // Paper start - TNTPrimeEvent -+ org.bukkit.block.Block tntBlock = org.bukkit.craftbukkit.block.CraftBlock.at(world, pos); -+ if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.REDSTONE, null).callEvent()) { -+ return; -+ } -+ // Paper end - TNTPrimeEvent - TntBlock.explode(world, pos); - world.removeBlock(pos, false); - } -@@ -57,7 +67,13 @@ - - @Override - protected void neighborChanged(BlockState state, Level world, BlockPos pos, Block sourceBlock, @Nullable Orientation wireOrientation, boolean notify) { -- if (world.hasNeighborSignal(pos)) { -+ if (world.hasNeighborSignal(pos) && CraftEventFactory.callTNTPrimeEvent(world, pos, PrimeCause.REDSTONE, null, null)) { // CraftBukkit - TNTPrimeEvent -+ // Paper start - TNTPrimeEvent -+ org.bukkit.block.Block tntBlock = org.bukkit.craftbukkit.block.CraftBlock.at(world, pos); -+ if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.REDSTONE, null).callEvent()) { -+ return; -+ } -+ // Paper end - TNTPrimeEvent - TntBlock.explode(world, pos); - world.removeBlock(pos, false); - } -@@ -66,7 +82,7 @@ - - @Override - public BlockState playerWillDestroy(Level world, BlockPos pos, BlockState state, Player player) { -- if (!world.isClientSide() && !player.isCreative() && (Boolean) state.getValue(TntBlock.UNSTABLE)) { -+ if (!world.isClientSide() && !player.isCreative() && (Boolean) state.getValue(TntBlock.UNSTABLE) && CraftEventFactory.callTNTPrimeEvent(world, pos, PrimeCause.BLOCK_BREAK, player, null)) { // CraftBukkit - TNTPrimeEvent - TntBlock.explode(world, pos); - } - -@@ -75,6 +91,13 @@ - - @Override - public void wasExploded(ServerLevel world, BlockPos pos, Explosion explosion) { -+ // Paper start - TNTPrimeEvent -+ org.bukkit.block.Block tntBlock = org.bukkit.craftbukkit.block.CraftBlock.at(world, pos); -+ org.bukkit.entity.Entity source = explosion.getDirectSourceEntity() != null ? explosion.getDirectSourceEntity().getBukkitEntity() : null; -+ if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.EXPLOSION, source).callEvent()) { -+ return; -+ } -+ // Paper end - TNTPrimeEvent - PrimedTnt entitytntprimed = new PrimedTnt(world, (double) pos.getX() + 0.5D, (double) pos.getY(), (double) pos.getZ() + 0.5D, explosion.getIndirectSourceEntity()); - int i = entitytntprimed.getFuse(); - -@@ -101,6 +124,17 @@ - if (!stack.is(Items.FLINT_AND_STEEL) && !stack.is(Items.FIRE_CHARGE)) { - return super.useItemOn(stack, state, world, pos, player, hand, hit); - } else { -+ // CraftBukkit start - TNTPrimeEvent -+ if (!CraftEventFactory.callTNTPrimeEvent(world, pos, PrimeCause.PLAYER, player, null)) { -+ return InteractionResult.CONSUME; -+ } -+ // CraftBukkit end -+ // Paper start - TNTPrimeEvent -+ org.bukkit.block.Block tntBlock = org.bukkit.craftbukkit.block.CraftBlock.at(world, pos); -+ if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.ITEM, player.getBukkitEntity()).callEvent()) { -+ return InteractionResult.FAIL; -+ } -+ // Paper end - TNTPrimeEvent - TntBlock.explode(world, pos, player); - world.setBlock(pos, Blocks.AIR.defaultBlockState(), 11); - Item item = stack.getItem(); -@@ -123,6 +157,17 @@ - Entity entity = projectile.getOwner(); - - if (projectile.isOnFire() && projectile.mayInteract(worldserver, blockposition)) { -+ // CraftBukkit start -+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(projectile, blockposition, state.getFluidState().createLegacyBlock()) || !CraftEventFactory.callTNTPrimeEvent(world, blockposition, PrimeCause.PROJECTILE, projectile, null)) { // Paper - fix wrong block state -+ return; -+ } -+ // CraftBukkit end -+ // Paper start - TNTPrimeEvent -+ org.bukkit.block.Block tntBlock = org.bukkit.craftbukkit.block.CraftBlock.at(world, blockposition); -+ if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.PROJECTILE, projectile.getBukkitEntity()).callEvent()) { -+ return; -+ } -+ // Paper end - TNTPrimeEvent - TntBlock.explode(world, blockposition, entity instanceof LivingEntity ? (LivingEntity) entity : null); - world.removeBlock(blockposition, false); - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/TrapDoorBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/TrapDoorBlock.java.patch deleted file mode 100644 index 0f858bdcd3..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/TrapDoorBlock.java.patch +++ /dev/null @@ -1,51 +0,0 @@ ---- a/net/minecraft/world/level/block/TrapDoorBlock.java -+++ b/net/minecraft/world/level/block/TrapDoorBlock.java -@@ -37,6 +37,7 @@ - import net.minecraft.world.phys.BlockHitResult; - import net.minecraft.world.phys.shapes.CollisionContext; - import net.minecraft.world.phys.shapes.VoxelShape; -+import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit - - public class TrapDoorBlock extends HorizontalDirectionalBlock implements SimpleWaterloggedBlock { - -@@ -143,7 +144,39 @@ - boolean flag1 = world.hasNeighborSignal(pos); - - if (flag1 != (Boolean) state.getValue(TrapDoorBlock.POWERED)) { -- if ((Boolean) state.getValue(TrapDoorBlock.OPEN) != flag1) { -+ // CraftBukkit start -+ org.bukkit.World bworld = world.getWorld(); -+ org.bukkit.block.Block bblock = bworld.getBlockAt(pos.getX(), pos.getY(), pos.getZ()); -+ -+ int power = bblock.getBlockPower(); -+ int oldPower = (Boolean) state.getValue(TrapDoorBlock.OPEN) ? 15 : 0; -+ -+ if (oldPower == 0 ^ power == 0 || sourceBlock.defaultBlockState().isSignalSource()) { -+ BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(bblock, oldPower, power); -+ world.getCraftServer().getPluginManager().callEvent(eventRedstone); -+ flag1 = eventRedstone.getNewCurrent() > 0; -+ } -+ // CraftBukkit end -+ // Paper start - break redstone on trapdoors early -+ boolean open = (Boolean) state.getValue(TrapDoorBlock.OPEN) != flag1; -+ // note: this must run before any state for this block/its neighborus are written to the world -+ // we allow the redstone event to fire so that plugins can block -+ if (flag1 && open) { // if we are now powered and it caused the trap door to open -+ // in this case, first check for the redstone on top first -+ BlockPos abovePos = pos.above(); -+ BlockState above = world.getBlockState(abovePos); -+ if (above.getBlock() instanceof RedStoneWireBlock) { -+ world.setBlock(abovePos, Blocks.AIR.defaultBlockState(), Block.UPDATE_CLIENTS | Block.UPDATE_NEIGHBORS); -+ Block.popResource(world, abovePos, new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.REDSTONE)); -+ // now check that this didn't change our state -+ if (world.getBlockState(pos) != state) { -+ // our state was changed, so we cannot propagate this update -+ return; -+ } -+ } -+ } -+ if (open) { -+ // Paper end - break redstone on trapdoors early - state = (BlockState) state.setValue(TrapDoorBlock.OPEN, flag1); - this.playSound((Player) null, world, pos, flag1); - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/TripWireBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/TripWireBlock.java.patch deleted file mode 100644 index b081063a3f..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/TripWireBlock.java.patch +++ /dev/null @@ -1,114 +0,0 @@ ---- a/net/minecraft/world/level/block/TripWireBlock.java -+++ b/net/minecraft/world/level/block/TripWireBlock.java -@@ -28,6 +28,7 @@ - import net.minecraft.world.level.gameevent.GameEvent; - import net.minecraft.world.phys.shapes.CollisionContext; - import net.minecraft.world.phys.shapes.VoxelShape; -+import org.bukkit.event.entity.EntityInteractEvent; // CraftBukkit - - public class TripWireBlock extends Block { - -@@ -67,6 +68,7 @@ - - @Override - public BlockState getStateForPlacement(BlockPlaceContext ctx) { -+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return this.defaultBlockState(); // Paper - place tripwire without updating - Level world = ctx.getLevel(); - BlockPos blockposition = ctx.getClickedPos(); - -@@ -75,11 +77,13 @@ - - @Override - protected BlockState updateShape(BlockState state, LevelReader world, ScheduledTickAccess tickView, BlockPos pos, Direction direction, BlockPos neighborPos, BlockState neighborState, RandomSource random) { -+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return state; // Paper - prevent tripwire from updating - return direction.getAxis().isHorizontal() ? (BlockState) state.setValue((Property) TripWireBlock.PROPERTY_BY_DIRECTION.get(direction), this.shouldConnectTo(neighborState, direction)) : super.updateShape(state, world, tickView, pos, direction, neighborPos, neighborState, random); - } - - @Override - protected void onPlace(BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify) { -+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return; // Paper - prevent adjacent tripwires from updating - if (!oldState.is(state.getBlock())) { - this.updateSource(world, pos, state); - } -@@ -87,6 +91,7 @@ - - @Override - protected void onRemove(BlockState state, Level world, BlockPos pos, BlockState newState, boolean moved) { -+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return; // Paper - prevent adjacent tripwires from updating - if (!moved && !state.is(newState.getBlock())) { - this.updateSource(world, pos, (BlockState) state.setValue(TripWireBlock.POWERED, true)); - } -@@ -94,6 +99,7 @@ - - @Override - public BlockState playerWillDestroy(Level world, BlockPos pos, BlockState state, Player player) { -+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return state; // Paper - prevent disarming tripwires - if (!world.isClientSide && !player.getMainHandItem().isEmpty() && player.getMainHandItem().is(Items.SHEARS)) { - world.setBlock(pos, (BlockState) state.setValue(TripWireBlock.DISARMED, true), 4); - world.gameEvent((Entity) player, (Holder) GameEvent.SHEAR, pos); -@@ -103,6 +109,7 @@ - } - - private void updateSource(Level world, BlockPos pos, BlockState state) { -+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return; // Paper - prevent adjacent tripwires from updating - Direction[] aenumdirection = new Direction[]{Direction.SOUTH, Direction.WEST}; - int i = aenumdirection.length; - int j = 0; -@@ -140,6 +147,8 @@ - - @Override - protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { -+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return; // Paper - prevent tripwires from detecting collision -+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent - if (!world.isClientSide) { - if (!(Boolean) state.getValue(TripWireBlock.POWERED)) { - this.checkPressed(world, pos, List.of(entity)); -@@ -149,6 +158,7 @@ - - @Override - protected void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { -+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return; // Paper - prevent tripwire pressed check - if ((Boolean) world.getBlockState(pos).getValue(TripWireBlock.POWERED)) { - this.checkPressed(world, pos); - } -@@ -179,6 +189,40 @@ - } - } - -+ // CraftBukkit start - Call interact even when triggering connected tripwire -+ if (flag != flag1 && flag1 && (Boolean)iblockdata.getValue(TripWireBlock.ATTACHED)) { -+ org.bukkit.World bworld = world.getWorld(); -+ org.bukkit.plugin.PluginManager manager = world.getCraftServer().getPluginManager(); -+ org.bukkit.block.Block block = bworld.getBlockAt(pos.getX(), pos.getY(), pos.getZ()); -+ boolean allowed = false; -+ -+ // If all of the events are cancelled block the tripwire trigger, else allow -+ for (Object object : entities) { -+ if (object != null) { -+ org.bukkit.event.Cancellable cancellable; -+ -+ if (object instanceof Player) { -+ cancellable = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent((Player) object, org.bukkit.event.block.Action.PHYSICAL, pos, null, null, null); -+ } else if (object instanceof Entity) { -+ cancellable = new EntityInteractEvent(((Entity) object).getBukkitEntity(), block); -+ manager.callEvent((EntityInteractEvent) cancellable); -+ } else { -+ continue; -+ } -+ -+ if (!cancellable.isCancelled()) { -+ allowed = true; -+ break; -+ } -+ } -+ } -+ -+ if (!allowed) { -+ return; -+ } -+ } -+ // CraftBukkit end -+ - if (flag1 != flag) { - iblockdata = (BlockState) iblockdata.setValue(TripWireBlock.POWERED, flag1); - world.setBlock(pos, iblockdata, 3); diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/TripWireHookBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/TripWireHookBlock.java.patch deleted file mode 100644 index 85f745ec8f..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/TripWireHookBlock.java.patch +++ /dev/null @@ -1,34 +0,0 @@ ---- a/net/minecraft/world/level/block/TripWireHookBlock.java -+++ b/net/minecraft/world/level/block/TripWireHookBlock.java -@@ -31,6 +31,10 @@ - import net.minecraft.world.level.redstone.Orientation; - import net.minecraft.world.phys.shapes.CollisionContext; - import net.minecraft.world.phys.shapes.VoxelShape; -+// CraftBukkit start -+import org.bukkit.craftbukkit.block.CraftBlock; -+import org.bukkit.event.block.BlockRedstoneEvent; -+// CraftBukkit end - - public class TripWireHookBlock extends Block { - -@@ -174,10 +178,20 @@ - world.setBlock(blockposition1, (BlockState) iblockdata3.setValue(TripWireHookBlock.FACING, enumdirection1), 3); - TripWireHookBlock.notifyNeighbors(block, world, blockposition1, enumdirection1); - TripWireHookBlock.emitState(world, blockposition1, flag4, flag5, flag2, flag3); -+ } -+ -+ // CraftBukkit start -+ BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(CraftBlock.at(world, pos), 15, 0); -+ world.getCraftServer().getPluginManager().callEvent(eventRedstone); -+ -+ if (eventRedstone.getNewCurrent() > 0) { -+ return; - } -+ // CraftBukkit end - - TripWireHookBlock.emitState(world, pos, flag4, flag5, flag2, flag3); - if (!flag) { -+ if (world.getBlockState(pos).getBlock() == Blocks.TRIPWIRE_HOOK) // Paper - Validate tripwire hook placement before update - world.setBlock(pos, (BlockState) iblockdata3.setValue(TripWireHookBlock.FACING, enumdirection), 3); - if (flag1) { - TripWireHookBlock.notifyNeighbors(block, world, pos, enumdirection); diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/TurtleEggBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/TurtleEggBlock.java.patch deleted file mode 100644 index c27f68ac72..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/TurtleEggBlock.java.patch +++ /dev/null @@ -1,76 +0,0 @@ ---- a/net/minecraft/world/level/block/TurtleEggBlock.java -+++ b/net/minecraft/world/level/block/TurtleEggBlock.java -@@ -31,6 +31,11 @@ - import net.minecraft.world.level.gameevent.GameEvent; - import net.minecraft.world.phys.shapes.CollisionContext; - import net.minecraft.world.phys.shapes.VoxelShape; -+// CraftBukkit start -+import org.bukkit.event.entity.EntityInteractEvent; -+import org.bukkit.craftbukkit.block.CraftBlock; -+import org.bukkit.craftbukkit.event.CraftEventFactory; -+// CraftBukkit end - - public class TurtleEggBlock extends Block { - -@@ -74,6 +79,19 @@ - private void destroyEgg(Level world, BlockState state, BlockPos pos, Entity entity, int inverseChance) { - if (state.is(Blocks.TURTLE_EGG) && world instanceof ServerLevel worldserver) { - if (this.canDestroyEgg(worldserver, entity) && world.random.nextInt(inverseChance) == 0) { -+ // CraftBukkit start - Step on eggs -+ org.bukkit.event.Cancellable cancellable; -+ if (entity instanceof Player) { -+ cancellable = CraftEventFactory.callPlayerInteractEvent((Player) entity, org.bukkit.event.block.Action.PHYSICAL, pos, null, null, null); -+ } else { -+ cancellable = new EntityInteractEvent(entity.getBukkitEntity(), CraftBlock.at(worldserver, pos)); -+ worldserver.getCraftServer().getPluginManager().callEvent((EntityInteractEvent) cancellable); -+ } -+ -+ if (cancellable.isCancelled()) { -+ return; -+ } -+ // CraftBukkit end - this.decreaseEggs(worldserver, pos, state); - } - } -@@ -100,10 +118,20 @@ - int i = (Integer) state.getValue(TurtleEggBlock.HATCH); - - if (i < 2) { -+ // CraftBukkit start - Call BlockGrowEvent -+ if (!CraftEventFactory.handleBlockGrowEvent(world, pos, state.setValue(TurtleEggBlock.HATCH, i + 1), 2)) { -+ return; -+ } -+ // CraftBukkit end - world.playSound((Player) null, pos, SoundEvents.TURTLE_EGG_CRACK, SoundSource.BLOCKS, 0.7F, 0.9F + random.nextFloat() * 0.2F); -- world.setBlock(pos, (BlockState) state.setValue(TurtleEggBlock.HATCH, i + 1), 2); -+ // worldserver.setBlock(blockposition, (IBlockData) iblockdata.setValue(BlockTurtleEgg.HATCH, i + 1), 2); // CraftBukkit - handled above - world.gameEvent((Holder) GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(state)); - } else { -+ // CraftBukkit start - Call BlockFadeEvent -+ if (CraftEventFactory.callBlockFadeEvent(world, pos, Blocks.AIR.defaultBlockState()).isCancelled()) { -+ return; -+ } -+ // CraftBukkit end - world.playSound((Player) null, pos, SoundEvents.TURTLE_EGG_HATCH, SoundSource.BLOCKS, 0.7F, 0.9F + random.nextFloat() * 0.2F); - world.removeBlock(pos, false); - world.gameEvent((Holder) GameEvent.BLOCK_DESTROY, pos, GameEvent.Context.of(state)); -@@ -116,7 +144,7 @@ - entityturtle.setAge(-24000); - entityturtle.setHomePos(pos); - entityturtle.moveTo((double) pos.getX() + 0.3D + (double) j * 0.2D, (double) pos.getY(), (double) pos.getZ() + 0.3D, 0.0F, 0.0F); -- world.addFreshEntity(entityturtle); -+ world.addFreshEntity(entityturtle, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.EGG); // CraftBukkit - } - } - } -@@ -147,8 +175,8 @@ - } - - @Override -- public void playerDestroy(Level world, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool) { -- super.playerDestroy(world, player, pos, state, blockEntity, tool); -+ public void playerDestroy(Level world, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool, boolean includeDrops, boolean dropExp) { // Paper - fix drops not preventing stats/food exhaustion -+ super.playerDestroy(world, player, pos, state, blockEntity, tool, includeDrops, dropExp); // Paper - fix drops not preventing stats/food exhaustion - this.decreaseEggs(world, pos, state); - } - diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/VineBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/VineBlock.java.patch deleted file mode 100644 index 0403549dc8..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/VineBlock.java.patch +++ /dev/null @@ -1,79 +0,0 @@ ---- a/net/minecraft/world/level/block/VineBlock.java -+++ b/net/minecraft/world/level/block/VineBlock.java -@@ -24,6 +24,7 @@ - import net.minecraft.world.phys.shapes.CollisionContext; - import net.minecraft.world.phys.shapes.Shapes; - import net.minecraft.world.phys.shapes.VoxelShape; -+import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit - - public class VineBlock extends Block { - -@@ -184,7 +185,7 @@ - @Override - protected void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { - if (world.getGameRules().getBoolean(GameRules.RULE_DO_VINES_SPREAD)) { -- if (random.nextInt(4) == 0) { -+ if (random.nextFloat() < (world.spigotConfig.vineModifier / (100.0f * 4))) { // Spigot - SPIGOT-7159: Better modifier resolution - Direction enumdirection = Direction.getRandom(random); - BlockPos blockposition1 = pos.above(); - BlockPos blockposition2; -@@ -203,30 +204,34 @@ - BlockPos blockposition3 = blockposition2.relative(enumdirection1); - BlockPos blockposition4 = blockposition2.relative(enumdirection2); - -+ // CraftBukkit start - Call BlockSpreadEvent -+ BlockPos source = pos; -+ - if (flag && VineBlock.isAcceptableNeighbour(world, blockposition3, enumdirection1)) { -- world.setBlock(blockposition2, (BlockState) this.defaultBlockState().setValue(VineBlock.getPropertyForFace(enumdirection1), true), 2); -+ CraftEventFactory.handleBlockSpreadEvent(world, source, blockposition2, (BlockState) this.defaultBlockState().setValue(VineBlock.getPropertyForFace(enumdirection1), true), 2); - } else if (flag1 && VineBlock.isAcceptableNeighbour(world, blockposition4, enumdirection2)) { -- world.setBlock(blockposition2, (BlockState) this.defaultBlockState().setValue(VineBlock.getPropertyForFace(enumdirection2), true), 2); -+ CraftEventFactory.handleBlockSpreadEvent(world, source, blockposition2, (BlockState) this.defaultBlockState().setValue(VineBlock.getPropertyForFace(enumdirection2), true), 2); - } else { - Direction enumdirection3 = enumdirection.getOpposite(); - - if (flag && world.isEmptyBlock(blockposition3) && VineBlock.isAcceptableNeighbour(world, pos.relative(enumdirection1), enumdirection3)) { -- world.setBlock(blockposition3, (BlockState) this.defaultBlockState().setValue(VineBlock.getPropertyForFace(enumdirection3), true), 2); -+ CraftEventFactory.handleBlockSpreadEvent(world, source, blockposition3, (BlockState) this.defaultBlockState().setValue(VineBlock.getPropertyForFace(enumdirection3), true), 2); - } else if (flag1 && world.isEmptyBlock(blockposition4) && VineBlock.isAcceptableNeighbour(world, pos.relative(enumdirection2), enumdirection3)) { -- world.setBlock(blockposition4, (BlockState) this.defaultBlockState().setValue(VineBlock.getPropertyForFace(enumdirection3), true), 2); -+ CraftEventFactory.handleBlockSpreadEvent(world, source, blockposition4, (BlockState) this.defaultBlockState().setValue(VineBlock.getPropertyForFace(enumdirection3), true), 2); - } else if ((double) random.nextFloat() < 0.05D && VineBlock.isAcceptableNeighbour(world, blockposition2.above(), Direction.UP)) { -- world.setBlock(blockposition2, (BlockState) this.defaultBlockState().setValue(VineBlock.UP, true), 2); -+ CraftEventFactory.handleBlockSpreadEvent(world, source, blockposition2, (BlockState) this.defaultBlockState().setValue(VineBlock.UP, true), 2); - } -+ // CraftBukkit end - } - } else if (VineBlock.isAcceptableNeighbour(world, blockposition2, enumdirection)) { -- world.setBlock(pos, (BlockState) state.setValue(VineBlock.getPropertyForFace(enumdirection), true), 2); -+ CraftEventFactory.handleBlockGrowEvent(world, pos, (BlockState) state.setValue(VineBlock.getPropertyForFace(enumdirection), true), 2); // CraftBukkit - } - - } - } else { - if (enumdirection == Direction.UP && pos.getY() < world.getMaxY()) { - if (this.canSupportAtFace(world, pos, enumdirection)) { -- world.setBlock(pos, (BlockState) state.setValue(VineBlock.UP, true), 2); -+ CraftEventFactory.handleBlockGrowEvent(world, pos, (BlockState) state.setValue(VineBlock.UP, true), 2); // CraftBukkit - return; - } - -@@ -246,7 +251,7 @@ - } - - if (this.hasHorizontalConnection(iblockdata2)) { -- world.setBlock(blockposition1, iblockdata2, 2); -+ CraftEventFactory.handleBlockSpreadEvent(world, pos, blockposition1, iblockdata2, 2); // CraftBukkit - } - - return; -@@ -261,7 +266,7 @@ - BlockState iblockdata4 = this.copyRandomFaces(state, iblockdata3, random); - - if (iblockdata3 != iblockdata4 && this.hasHorizontalConnection(iblockdata4)) { -- world.setBlock(blockposition2, iblockdata4, 2); -+ CraftEventFactory.handleBlockSpreadEvent(world, pos, blockposition2, iblockdata4, 2); // CraftBukkit - } - } - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/WaterlilyBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/WaterlilyBlock.java.patch deleted file mode 100644 index 279e050da1..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/WaterlilyBlock.java.patch +++ /dev/null @@ -1,27 +0,0 @@ ---- a/net/minecraft/world/level/block/WaterlilyBlock.java -+++ b/net/minecraft/world/level/block/WaterlilyBlock.java -@@ -13,6 +13,9 @@ - import net.minecraft.world.level.material.Fluids; - import net.minecraft.world.phys.shapes.CollisionContext; - import net.minecraft.world.phys.shapes.VoxelShape; -+// CraftBukkit start -+import org.bukkit.craftbukkit.event.CraftEventFactory; -+// CraftBukkit end - - public class WaterlilyBlock extends BushBlock { - -@@ -30,8 +33,14 @@ - - @Override - protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { -+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent - super.entityInside(state, world, pos, entity); - if (world instanceof ServerLevel && entity instanceof AbstractBoat) { -+ // CraftBukkit start -+ if (!CraftEventFactory.callEntityChangeBlockEvent(entity, pos, state.getFluidState().createLegacyBlock())) { // Paper - fix wrong block state -+ return; -+ } -+ // CraftBukkit end - world.destroyBlock(new BlockPos(pos), true, entity); - } - diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/WeightedPressurePlateBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/WeightedPressurePlateBlock.java.patch deleted file mode 100644 index 67ce37fdf0..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/WeightedPressurePlateBlock.java.patch +++ /dev/null @@ -1,49 +0,0 @@ ---- a/net/minecraft/world/level/block/WeightedPressurePlateBlock.java -+++ b/net/minecraft/world/level/block/WeightedPressurePlateBlock.java -@@ -6,6 +6,7 @@ - import net.minecraft.core.BlockPos; - import net.minecraft.util.Mth; - import net.minecraft.world.entity.Entity; -+import net.minecraft.world.entity.player.Player; - import net.minecraft.world.level.Level; - import net.minecraft.world.level.block.state.BlockBehaviour; - import net.minecraft.world.level.block.state.BlockState; -@@ -13,6 +14,8 @@ - import net.minecraft.world.level.block.state.properties.BlockSetType; - import net.minecraft.world.level.block.state.properties.BlockStateProperties; - import net.minecraft.world.level.block.state.properties.IntegerProperty; -+import org.bukkit.event.entity.EntityInteractEvent; -+// CraftBukkit end - - public class WeightedPressurePlateBlock extends BasePressurePlateBlock { - -@@ -39,8 +42,28 @@ - - @Override - protected int getSignalStrength(Level world, BlockPos pos) { -- int i = Math.min(getEntityCount(world, WeightedPressurePlateBlock.TOUCH_AABB.move(pos), Entity.class), this.maxWeight); -+ // CraftBukkit start -+ // int i = Math.min(getEntityCount(world, BlockPressurePlateWeighted.TOUCH_AABB.move(blockposition), Entity.class), this.maxWeight); -+ int i = 0; -+ for (Entity entity : getEntities(world, WeightedPressurePlateBlock.TOUCH_AABB.move(pos), Entity.class)) { -+ org.bukkit.event.Cancellable cancellable; - -+ if (entity instanceof Player) { -+ cancellable = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent((Player) entity, org.bukkit.event.block.Action.PHYSICAL, pos, null, null, null); -+ } else { -+ cancellable = new EntityInteractEvent(entity.getBukkitEntity(), world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ())); -+ world.getCraftServer().getPluginManager().callEvent((EntityInteractEvent) cancellable); -+ } -+ -+ // We only want to block turning the plate on if all events are cancelled -+ if (!cancellable.isCancelled()) { -+ i++; -+ } -+ } -+ -+ i = Math.min(i, this.maxWeight); -+ // CraftBukkit end -+ - if (i > 0) { - float f = (float) Math.min(this.maxWeight, i) / (float) this.maxWeight; - diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/WitherRoseBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/WitherRoseBlock.java.patch deleted file mode 100644 index c456abf513..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/WitherRoseBlock.java.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- a/net/minecraft/world/level/block/WitherRoseBlock.java -+++ b/net/minecraft/world/level/block/WitherRoseBlock.java -@@ -63,10 +63,11 @@ - - @Override - protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { -+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent - if (world instanceof ServerLevel worldserver) { - if (world.getDifficulty() != Difficulty.PEACEFUL && entity instanceof LivingEntity entityliving) { - if (!entityliving.isInvulnerableTo(worldserver, world.damageSources().wither())) { -- entityliving.addEffect(this.getBeeInteractionEffect()); -+ entityliving.addEffect(this.getBeeInteractionEffect(), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.WITHER_ROSE); // CraftBukkit - } - } - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/WitherSkullBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/WitherSkullBlock.java.patch deleted file mode 100644 index e34748cc0e..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/WitherSkullBlock.java.patch +++ /dev/null @@ -1,50 +0,0 @@ ---- a/net/minecraft/world/level/block/WitherSkullBlock.java -+++ b/net/minecraft/world/level/block/WitherSkullBlock.java -@@ -26,6 +26,10 @@ - import net.minecraft.world.level.block.state.pattern.BlockPatternBuilder; - import net.minecraft.world.level.block.state.predicate.BlockStatePredicate; - -+// CraftBukkit start -+import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; -+// CraftBukkit end -+ - public class WitherSkullBlock extends SkullBlock { - - public static final MapCodec CODEC = simpleCodec(WitherSkullBlock::new); -@@ -58,6 +62,7 @@ - } - - public static void checkSpawn(Level world, BlockPos pos, SkullBlockEntity blockEntity) { -+ if (world.captureBlockStates) return; // CraftBukkit - if (!world.isClientSide) { - BlockState iblockdata = blockEntity.getBlockState(); - boolean flag = iblockdata.is(Blocks.WITHER_SKELETON_SKULL) || iblockdata.is(Blocks.WITHER_SKELETON_WALL_SKULL); -@@ -69,12 +74,18 @@ - WitherBoss entitywither = (WitherBoss) EntityType.WITHER.create(world, EntitySpawnReason.TRIGGERED); - - if (entitywither != null) { -- CarvedPumpkinBlock.clearPatternBlocks(world, shapedetector_shapedetectorcollection); -+ // BlockPumpkinCarved.clearPatternBlocks(world, shapedetector_shapedetectorcollection); // CraftBukkit - move down - BlockPos blockposition1 = shapedetector_shapedetectorcollection.getBlock(1, 2, 0).getPos(); - - entitywither.moveTo((double) blockposition1.getX() + 0.5D, (double) blockposition1.getY() + 0.55D, (double) blockposition1.getZ() + 0.5D, shapedetector_shapedetectorcollection.getForwards().getAxis() == Direction.Axis.X ? 0.0F : 90.0F, 0.0F); - entitywither.yBodyRot = shapedetector_shapedetectorcollection.getForwards().getAxis() == Direction.Axis.X ? 0.0F : 90.0F; - entitywither.makeInvulnerable(); -+ // CraftBukkit start -+ if (!world.addFreshEntity(entitywither, SpawnReason.BUILD_WITHER)) { -+ return; -+ } -+ CarvedPumpkinBlock.clearPatternBlocks(world, shapedetector_shapedetectorcollection); // CraftBukkit - from above -+ // CraftBukkit end - Iterator iterator = world.getEntitiesOfClass(ServerPlayer.class, entitywither.getBoundingBox().inflate(50.0D)).iterator(); - - while (iterator.hasNext()) { -@@ -83,7 +94,7 @@ - CriteriaTriggers.SUMMONED_ENTITY.trigger(entityplayer, (Entity) entitywither); - } - -- world.addFreshEntity(entitywither); -+ // world.addFreshEntity(entitywither); // CraftBukkit - moved up - CarvedPumpkinBlock.updatePatternBlocks(world, shapedetector_shapedetectorcollection); - } -