net/minecraft/world/level/block/a-r

This commit is contained in:
Owen1212055 2024-12-14 21:31:05 -05:00
parent 11b1877545
commit b16f6f533a
No known key found for this signature in database
GPG key ID: 2133292072886A30
177 changed files with 3259 additions and 3980 deletions

View file

@ -0,0 +1,14 @@
--- a/net/minecraft/world/level/block/AbstractCandleBlock.java
+++ b/net/minecraft/world/level/block/AbstractCandleBlock.java
@@ -44,6 +_,11 @@
@Override
protected void onProjectileHit(Level level, BlockState state, BlockHitResult hit, Projectile projectile) {
if (!level.isClientSide && projectile.isOnFire() && this.canBeLit(state)) {
+ // CraftBukkit start
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(level, hit.getBlockPos(), projectile).isCancelled()) {
+ return;
+ }
+ // CraftBukkit end
setLit(level, state, hit.getBlockPos(), true);
}
}

View file

@ -0,0 +1,11 @@
--- a/net/minecraft/world/level/block/AbstractCauldronBlock.java
+++ b/net/minecraft/world/level/block/AbstractCauldronBlock.java
@@ -58,7 +_,7 @@
ItemStack stack, BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hitResult
) {
CauldronInteraction cauldronInteraction = this.interactions.map().get(stack.getItem());
- return cauldronInteraction.interact(state, level, pos, player, hand, stack);
+ return cauldronInteraction.interact(state, level, pos, player, hand, stack, hitResult.getDirection()); // Paper - pass hit direction
}
@Override

View file

@ -1,11 +1,11 @@
--- a/net/minecraft/world/level/block/AnvilBlock.java --- a/net/minecraft/world/level/block/AnvilBlock.java
+++ b/net/minecraft/world/level/block/AnvilBlock.java +++ b/net/minecraft/world/level/block/AnvilBlock.java
@@ -62,8 +62,9 @@ @@ -62,8 +_,9 @@
@Override @Override
protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) {
if (!world.isClientSide) { if (!level.isClientSide) {
- player.openMenu(state.getMenuProvider(world, pos)); - player.openMenu(state.getMenuProvider(level, pos));
+ if (player.openMenu(state.getMenuProvider(world, pos)).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation + if (player.openMenu(state.getMenuProvider(level, pos)).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation
player.awardStat(Stats.INTERACT_WITH_ANVIL); player.awardStat(Stats.INTERACT_WITH_ANVIL);
+ } // Paper - Fix InventoryOpenEvent cancellation + } // Paper - Fix InventoryOpenEvent cancellation
} }

View file

@ -0,0 +1,19 @@
--- a/net/minecraft/world/level/block/BambooSaplingBlock.java
+++ b/net/minecraft/world/level/block/BambooSaplingBlock.java
@@ -43,7 +_,7 @@
@Override
protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) {
- if (random.nextInt(3) == 0 && level.isEmptyBlock(pos.above()) && level.getRawBrightness(pos.above(), 0) >= 9) {
+ if (random.nextFloat() < (level.spigotConfig.bambooModifier / (100.0f * 3)) && level.isEmptyBlock(pos.above()) && level.getRawBrightness(pos.above(), 0) >= 9) { // Spigot - SPIGOT-7159: Better modifier resolution
this.growBamboo(level, pos);
}
}
@@ -99,6 +_,6 @@
}
protected void growBamboo(Level level, BlockPos state) {
- level.setBlock(state.above(), Blocks.BAMBOO.defaultBlockState().setValue(BambooStalkBlock.LEAVES, BambooLeaves.SMALL), 3);
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(level, state, state.above(), Blocks.BAMBOO.defaultBlockState().setValue(BambooStalkBlock.LEAVES, BambooLeaves.SMALL), 3); // CraftBukkit - BlockSpreadEvent
}
}

View file

@ -0,0 +1,87 @@
--- a/net/minecraft/world/level/block/BambooStalkBlock.java
+++ b/net/minecraft/world/level/block/BambooStalkBlock.java
@@ -130,9 +_,9 @@
@Override
protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) {
if (state.getValue(STAGE) == 0) {
- if (random.nextInt(3) == 0 && level.isEmptyBlock(pos.above()) && level.getRawBrightness(pos.above(), 0) >= 9) {
+ if (random.nextFloat() < (level.spigotConfig.bambooModifier / (100.0f * 3)) && level.isEmptyBlock(pos.above()) && level.getRawBrightness(pos.above(), 0) >= 9) { // Spigot - SPIGOT-7159: Better modifier resolution
int i = this.getHeightBelowUpToMax(level, pos) + 1;
- if (i < 16) {
+ if (i < level.paperConfig().maxGrowthHeight.bamboo.max) { // Paper - Configurable cactus/bamboo/reed growth height
this.growBamboo(state, level, pos, random, i);
}
}
@@ -168,7 +_,7 @@
public boolean isValidBonemealTarget(LevelReader level, BlockPos pos, BlockState state) {
int heightAboveUpToMax = this.getHeightAboveUpToMax(level, pos);
int heightBelowUpToMax = this.getHeightBelowUpToMax(level, pos);
- return heightAboveUpToMax + heightBelowUpToMax + 1 < 16 && level.getBlockState(pos.above(heightAboveUpToMax)).getValue(STAGE) != 1;
+ return heightAboveUpToMax + heightBelowUpToMax + 1 < ((Level) level).paperConfig().maxGrowthHeight.bamboo.max && level.getBlockState(pos.above(heightAboveUpToMax)).getValue(STAGE) != 1; // Paper - Configurable cactus/bamboo/reed growth height
}
@Override
@@ -186,7 +_,7 @@
for (int i2 = 0; i2 < i1; i2++) {
BlockPos blockPos = pos.above(heightAboveUpToMax);
BlockState blockState = level.getBlockState(blockPos);
- if (i >= 16 || blockState.getValue(STAGE) == 1 || !level.isEmptyBlock(blockPos.above())) {
+ if (i >= level.paperConfig().maxGrowthHeight.bamboo.max || !blockState.is(Blocks.BAMBOO) || blockState.getValue(BambooStalkBlock.STAGE) == 1 || !level.isEmptyBlock(blockPos.above())) { // CraftBukkit - If the BlockSpreadEvent was cancelled, we have no bamboo here // Paper - Configurable cactus/bamboo/reed growth height
return;
}
@@ -206,29 +_,38 @@
BlockPos blockPos = pos.below(2);
BlockState blockState1 = level.getBlockState(blockPos);
BambooLeaves bambooLeaves = BambooLeaves.NONE;
+ boolean shouldUpdateOthers = false; // CraftBukkit
if (age >= 1) {
if (!blockState.is(Blocks.BAMBOO) || blockState.getValue(LEAVES) == BambooLeaves.NONE) {
bambooLeaves = BambooLeaves.SMALL;
} else if (blockState.is(Blocks.BAMBOO) && blockState.getValue(LEAVES) != BambooLeaves.NONE) {
bambooLeaves = BambooLeaves.LARGE;
if (blockState1.is(Blocks.BAMBOO)) {
- level.setBlock(pos.below(), blockState.setValue(LEAVES, BambooLeaves.SMALL), 3);
- level.setBlock(blockPos, blockState1.setValue(LEAVES, BambooLeaves.NONE), 3);
+ // CraftBukkit start - moved down
+ // world.setBlock(blockposition.below(), (IBlockData) iblockdata1.setValue(BlockBamboo.LEAVES, BlockPropertyBambooSize.SMALL), 3);
+ // world.setBlock(blockposition1, (IBlockData) iblockdata2.setValue(BlockBamboo.LEAVES, BlockPropertyBambooSize.NONE), 3);
+ shouldUpdateOthers = true;
+ // CraftBukkit end
}
}
}
int i = state.getValue(AGE) != 1 && !blockState1.is(Blocks.BAMBOO) ? 0 : 1;
- int i1 = (age < 11 || !(random.nextFloat() < 0.25F)) && age != 15 ? 0 : 1;
- level.setBlock(
- pos.above(), this.defaultBlockState().setValue(AGE, Integer.valueOf(i)).setValue(LEAVES, bambooLeaves).setValue(STAGE, Integer.valueOf(i1)), 3
- );
+ int i1 = (age < level.paperConfig().maxGrowthHeight.bamboo.min || random.nextFloat() >= 0.25F) && age != (level.paperConfig().maxGrowthHeight.bamboo.max - 1) ? 0 : 1; // Paper - Configurable cactus/bamboo/reed growth height
+ // CraftBukkit start
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(level, pos, pos.above(), this.defaultBlockState().setValue(net.minecraft.world.level.block.BambooStalkBlock.AGE, i).setValue(BambooStalkBlock.LEAVES, bambooLeaves).setValue(net.minecraft.world.level.block.BambooStalkBlock.STAGE, i1), 3)) {
+ if (shouldUpdateOthers) {
+ level.setBlock(pos.below(), blockState.setValue(BambooStalkBlock.LEAVES, BambooLeaves.SMALL), 3);
+ level.setBlock(blockPos, blockState1.setValue(BambooStalkBlock.LEAVES, BambooLeaves.NONE), 3);
+ }
+ }
+ // CraftBukkit end
}
protected int getHeightAboveUpToMax(BlockGetter level, BlockPos pos) {
int i = 0;
- while (i < 16 && level.getBlockState(pos.above(i + 1)).is(Blocks.BAMBOO)) {
+ while (i < ((Level) level).paperConfig().maxGrowthHeight.bamboo.max && level.getBlockState(pos.above(i + 1)).is(Blocks.BAMBOO)) { // Paper - Configurable cactus/bamboo/reed growth height
i++;
}
@@ -238,7 +_,7 @@
protected int getHeightBelowUpToMax(BlockGetter level, BlockPos pos) {
int i = 0;
- while (i < 16 && level.getBlockState(pos.below(i + 1)).is(Blocks.BAMBOO)) {
+ while (i < ((Level) level).paperConfig().maxGrowthHeight.bamboo.max && level.getBlockState(pos.below(i + 1)).is(Blocks.BAMBOO)) { // Paper - Configurable cactus/bamboo/reed growth height
i++;
}

View file

@ -1,12 +1,12 @@
--- a/net/minecraft/world/level/block/BarrelBlock.java --- a/net/minecraft/world/level/block/BarrelBlock.java
+++ b/net/minecraft/world/level/block/BarrelBlock.java +++ b/net/minecraft/world/level/block/BarrelBlock.java
@@ -41,8 +41,7 @@ @@ -41,8 +_,7 @@
@Override @Override
protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) {
- if (world instanceof ServerLevel serverLevel && world.getBlockEntity(pos) instanceof BarrelBlockEntity barrelBlockEntity) { - if (level instanceof ServerLevel serverLevel && level.getBlockEntity(pos) instanceof BarrelBlockEntity barrelBlockEntity) {
- player.openMenu(barrelBlockEntity); - player.openMenu(barrelBlockEntity);
+ if (world instanceof ServerLevel serverLevel && world.getBlockEntity(pos) instanceof BarrelBlockEntity barrelBlockEntity && player.openMenu(barrelBlockEntity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation + if (level instanceof ServerLevel serverLevel && level.getBlockEntity(pos) instanceof BarrelBlockEntity barrelBlockEntity && player.openMenu(barrelBlockEntity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation
player.awardStat(Stats.OPEN_BARREL); player.awardStat(Stats.OPEN_BARREL);
PiglinAi.angerNearbyPiglins(serverLevel, player, true); PiglinAi.angerNearbyPiglins(serverLevel, player, true);
} }

View file

@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/BaseFireBlock.java --- a/net/minecraft/world/level/block/BaseFireBlock.java
+++ b/net/minecraft/world/level/block/BaseFireBlock.java +++ b/net/minecraft/world/level/block/BaseFireBlock.java
@@ -12,6 +12,7 @@ @@ -12,6 +_,7 @@
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.context.BlockPlaceContext; import net.minecraft.world.item.context.BlockPlaceContext;
@ -8,22 +8,23 @@
import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockBehaviour; import net.minecraft.world.level.block.state.BlockBehaviour;
@@ -127,6 +128,7 @@ @@ -128,6 +_,8 @@
@Override @Override
protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { 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(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent + if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
+ 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.fireImmune()) { if (!entity.fireImmune()) {
if (entity.getRemainingFireTicks() < 0) { if (entity.getRemainingFireTicks() < 0) {
entity.setRemainingFireTicks(entity.getRemainingFireTicks() + 1); entity.setRemainingFireTicks(entity.getRemainingFireTicks() + 1);
@@ -137,7 +139,18 @@ @@ -137,7 +_,18 @@
} }
if (entity.getRemainingFireTicks() >= 0) { if (entity.getRemainingFireTicks() >= 0) {
- entity.igniteForSeconds(8.0F); - entity.igniteForSeconds(8.0F);
+ // CraftBukkit start + // CraftBukkit start
+ org.bukkit.event.entity.EntityCombustEvent event = new org.bukkit.event.entity.EntityCombustByBlockEvent(org.bukkit.craftbukkit.block.CraftBlock.at(world, pos), entity.getBukkitEntity(), 8.0F); + org.bukkit.event.entity.EntityCombustEvent event = new org.bukkit.event.entity.EntityCombustByBlockEvent(org.bukkit.craftbukkit.block.CraftBlock.at(level, pos), entity.getBukkitEntity(), 8.0F);
+ world.getCraftServer().getPluginManager().callEvent(event); + level.getCraftServer().getPluginManager().callEvent(event);
+ +
+ if (!event.isCancelled()) { + if (!event.isCancelled()) {
+ entity.igniteForSeconds(event.getDuration(), false); + entity.igniteForSeconds(event.getDuration(), false);
@ -36,41 +37,36 @@
} }
} }
@@ -146,26 +159,26 @@ @@ -146,24 +_,24 @@
} }
@Override @Override
- protected void onPlace(BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify) { - protected void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean isMoving) {
- if (!oldState.is(state.getBlock())) { + protected void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean isMoving, UseOnContext context) { // CraftBukkit - context
+ protected void onPlace(BlockState iblockdata, Level world, BlockPos blockposition, BlockState iblockdata1, boolean flag, UseOnContext context) { // CraftBukkit - context if (!oldState.is(state.getBlock())) {
+ if (!iblockdata1.is(iblockdata.getBlock())) { if (inPortalDimension(level)) {
if (BaseFireBlock.inPortalDimension(world)) { Optional<PortalShape> optional = PortalShape.findEmptyPortalShape(level, pos, Direction.Axis.X);
- Optional<PortalShape> optional = PortalShape.findEmptyPortalShape(world, pos, Direction.Axis.X);
+ Optional<PortalShape> optional = PortalShape.findEmptyPortalShape(world, blockposition, Direction.Axis.X);
if (optional.isPresent()) { if (optional.isPresent()) {
- ((PortalShape) optional.get()).createPortalBlocks(world); - optional.get().createPortalBlocks(level);
+ ((PortalShape) optional.get()).createPortalBlocks(world, (context == null) ? null : context.getPlayer()); // CraftBukkit - player + optional.get().createPortalBlocks(level, (context == null) ? null : context.getPlayer()); // CraftBukkit - player
return; return;
} }
} }
- if (!state.canSurvive(world, pos)) { if (!state.canSurvive(level, pos)) {
- world.removeBlock(pos, false); - level.removeBlock(pos, false);
+ if (!iblockdata.canSurvive(world, blockposition)) { + this.fireExtinguished(level, pos); // CraftBukkit - fuel block broke
+ this.fireExtinguished(world, blockposition); // CraftBukkit - fuel block broke
} }
} }
} }
private static boolean inPortalDimension(Level world) { private static boolean inPortalDimension(Level level) {
- return world.dimension() == Level.OVERWORLD || world.dimension() == Level.NETHER; - return level.dimension() == Level.OVERWORLD || level.dimension() == Level.NETHER;
+ return world.getTypeKey() == net.minecraft.world.level.dimension.LevelStem.OVERWORLD || world.getTypeKey() == net.minecraft.world.level.dimension.LevelStem.NETHER; // CraftBukkit - getTypeKey() + return level.getTypeKey() == net.minecraft.world.level.dimension.LevelStem.OVERWORLD || level.getTypeKey() == net.minecraft.world.level.dimension.LevelStem.NETHER; // CraftBukkit - getTypeKey()
} }
@Override @Override
@@ -213,4 +226,12 @@ @@ -208,4 +_,12 @@
} }
} }
} }

View file

@ -0,0 +1,45 @@
--- a/net/minecraft/world/level/block/BasePressurePlateBlock.java
+++ b/net/minecraft/world/level/block/BasePressurePlateBlock.java
@@ -81,6 +_,7 @@
@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.isClientSide) {
int signalForState = this.getSignalForState(state);
if (signalForState == 0) {
@@ -93,6 +_,19 @@
int signalStrength = this.getSignalStrength(level, pos);
boolean flag = currentSignal > 0;
boolean flag1 = signalStrength > 0;
+
+ // CraftBukkit start - Interact Pressure Plate
+ org.bukkit.World bworld = level.getWorld();
+ org.bukkit.plugin.PluginManager manager = level.getCraftServer().getPluginManager();
+
+ if (flag != flag1) {
+ org.bukkit.event.block.BlockRedstoneEvent eventRedstone = new org.bukkit.event.block.BlockRedstoneEvent(bworld.getBlockAt(pos.getX(), pos.getY(), pos.getZ()), currentSignal, signalStrength);
+ manager.callEvent(eventRedstone);
+
+ flag1 = eventRedstone.getNewCurrent() > 0;
+ signalStrength = eventRedstone.getNewCurrent();
+ }
+ // CraftBukkit end
if (currentSignal != signalStrength) {
BlockState blockState = this.setSignalForState(state, signalStrength);
level.setBlock(pos, blockState, 2);
@@ -145,7 +_,13 @@
}
protected static int getEntityCount(Level level, AABB box, Class<? extends Entity> entityClass) {
- return level.getEntitiesOfClass(entityClass, box, EntitySelector.NO_SPECTATORS.and(entity -> !entity.isIgnoringBlockTriggers())).size();
+ // CraftBukkit start
+ return BasePressurePlateBlock.getEntities(level, box, entityClass).size();
+ }
+
+ protected static <T extends Entity> java.util.List<T> getEntities(Level level, AABB box, Class<T> entityClass) {
+ return level.getEntitiesOfClass(entityClass, box, EntitySelector.NO_SPECTATORS.and(entity -> !entity.isIgnoringBlockTriggers()));
+ // CraftBukkit end
}
protected abstract int getSignalStrength(Level level, BlockPos pos);

View file

@ -0,0 +1,10 @@
--- a/net/minecraft/world/level/block/BaseRailBlock.java
+++ b/net/minecraft/world/level/block/BaseRailBlock.java
@@ -71,6 +_,7 @@
state = this.updateDir(level, pos, state, true);
if (this.isStraight) {
level.neighborChanged(state, pos, this, null, movedByPiston);
+ state = level.getBlockState(pos); // Paper - Fix some rails connecting improperly
}
return state;

View file

@ -1,12 +1,12 @@
--- a/net/minecraft/world/level/block/BeaconBlock.java --- a/net/minecraft/world/level/block/BeaconBlock.java
+++ b/net/minecraft/world/level/block/BeaconBlock.java +++ b/net/minecraft/world/level/block/BeaconBlock.java
@@ -46,8 +46,7 @@ @@ -46,8 +_,7 @@
@Override @Override
protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) {
- if (!world.isClientSide && world.getBlockEntity(pos) instanceof BeaconBlockEntity beaconBlockEntity) { - if (!level.isClientSide && level.getBlockEntity(pos) instanceof BeaconBlockEntity beaconBlockEntity) {
- player.openMenu(beaconBlockEntity); - player.openMenu(beaconBlockEntity);
+ if (!world.isClientSide && world.getBlockEntity(pos) instanceof BeaconBlockEntity beaconBlockEntity && player.openMenu(beaconBlockEntity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation + if (!level.isClientSide && level.getBlockEntity(pos) instanceof BeaconBlockEntity beaconBlockEntity && player.openMenu(beaconBlockEntity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation
player.awardStat(Stats.INTERACT_WITH_BEACON); player.awardStat(Stats.INTERACT_WITH_BEACON);
} }

View file

@ -1,21 +1,20 @@
--- a/net/minecraft/world/level/block/BedBlock.java --- a/net/minecraft/world/level/block/BedBlock.java
+++ b/net/minecraft/world/level/block/BedBlock.java +++ b/net/minecraft/world/level/block/BedBlock.java
@@ -95,7 +95,8 @@ @@ -92,7 +_,7 @@
} }
} }
- if (!BedBlock.canSetSpawn(world)) { - if (!canSetSpawn(level)) {
+ // CraftBukkit - moved world and biome check into EntityHuman + if (false && !canSetSpawn(level)) { // CraftBukkit - moved world and biome check into EntityHuman
+ if (false && !BedBlock.canSetSpawn(world)) { level.removeBlock(pos, false);
world.removeBlock(pos, false); BlockPos blockPos = pos.relative(state.getValue(FACING).getOpposite());
BlockPos blockposition1 = pos.relative(((Direction) state.getValue(BedBlock.FACING)).getOpposite()); if (level.getBlockState(blockPos).is(this)) {
@@ -103,22 +_,63 @@
@@ -108,25 +109,65 @@ level.explode(null, level.damageSources().badRespawnPointExplosion(center), null, center, 5.0F, true, Level.ExplosionInteraction.BLOCK);
world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d), (ExplosionDamageCalculator) null, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK);
return InteractionResult.SUCCESS_SERVER; return InteractionResult.SUCCESS_SERVER;
} else if ((Boolean) state.getValue(BedBlock.OCCUPIED)) { } else if (state.getValue(OCCUPIED)) {
+ if (!BedBlock.canSetSpawn(world)) return this.explodeBed(state, world, pos); // Paper - check explode first + if (!BedBlock.canSetSpawn(level)) return this.explodeBed(state, level, pos); // Paper - check explode first
if (!this.kickVillagerOutOfBed(world, pos)) { if (!this.kickVillagerOutOfBed(level, pos)) {
player.displayClientMessage(Component.translatable("block.minecraft.bed.occupied"), true); player.displayClientMessage(Component.translatable("block.minecraft.bed.occupied"), true);
} }
@ -25,10 +24,10 @@
+ BlockState finaliblockdata = state; + BlockState finaliblockdata = state;
+ BlockPos finalblockposition = pos; + BlockPos finalblockposition = pos;
+ // CraftBukkit end + // CraftBukkit end
player.startSleepInBed(pos).ifLeft((entityhuman_enumbedresult) -> { player.startSleepInBed(pos).ifLeft(bedSleepingProblem -> {
+ // Paper start - PlayerBedFailEnterEvent + // Paper start - PlayerBedFailEnterEvent
+ if (entityhuman_enumbedresult != null) { + if (bedSleepingProblem != null) {
+ io.papermc.paper.event.player.PlayerBedFailEnterEvent event = new io.papermc.paper.event.player.PlayerBedFailEnterEvent((org.bukkit.entity.Player) player.getBukkitEntity(), io.papermc.paper.event.player.PlayerBedFailEnterEvent.FailReason.values()[entityhuman_enumbedresult.ordinal()], org.bukkit.craftbukkit.block.CraftBlock.at(world, finalblockposition), !world.dimensionType().bedWorks(), io.papermc.paper.adventure.PaperAdventure.asAdventure(entityhuman_enumbedresult.getMessage())); + io.papermc.paper.event.player.PlayerBedFailEnterEvent event = new io.papermc.paper.event.player.PlayerBedFailEnterEvent((org.bukkit.entity.Player) player.getBukkitEntity(), io.papermc.paper.event.player.PlayerBedFailEnterEvent.FailReason.values()[bedSleepingProblem.ordinal()], org.bukkit.craftbukkit.block.CraftBlock.at(level, finalblockposition), !level.dimensionType().bedWorks(), io.papermc.paper.adventure.PaperAdventure.asAdventure(bedSleepingProblem.getMessage()));
+ if (!event.callEvent()) { + if (!event.callEvent()) {
+ return; + return;
+ } + }
@ -38,19 +37,18 @@
+ this.explodeBed(finaliblockdata, world, finalblockposition); + this.explodeBed(finaliblockdata, world, finalblockposition);
+ } else + } else
+ // CraftBukkit end + // CraftBukkit end
if (entityhuman_enumbedresult.getMessage() != null) { if (bedSleepingProblem.getMessage() != null) {
- player.displayClientMessage(entityhuman_enumbedresult.getMessage(), true); player.displayClientMessage(bedSleepingProblem.getMessage(), true);
+ final net.kyori.adventure.text.Component message = event.getMessage(); // Paper - PlayerBedFailEnterEvent + final net.kyori.adventure.text.Component message = event.getMessage(); // Paper - PlayerBedFailEnterEvent
+ if (message != null) player.displayClientMessage(io.papermc.paper.adventure.PaperAdventure.asVanilla(message), true); // Paper - PlayerBedFailEnterEvent + if (message != null) player.displayClientMessage(io.papermc.paper.adventure.PaperAdventure.asVanilla(message), true); // Paper - PlayerBedFailEnterEvent
} }
+ } // Paper - PlayerBedFailEnterEvent + } // Paper - PlayerBedFailEnterEvent
}); });
return InteractionResult.SUCCESS_SERVER; return InteractionResult.SUCCESS_SERVER;
+ } }
+ } }
+ } }
+
+ // CraftBukkit start + // CraftBukkit start
+ private InteractionResult explodeBed(BlockState iblockdata, Level world, BlockPos blockposition) { + private InteractionResult explodeBed(BlockState iblockdata, Level world, BlockPos blockposition) {
+ { + {
@ -65,28 +63,25 @@
+ +
+ Vec3 vec3d = blockposition.getCenter(); + Vec3 vec3d = blockposition.getCenter();
+ +
+ world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, blockState), (ExplosionDamageCalculator) null, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); // CraftBukkit - add state + world.explode(null, world.damageSources().badRespawnPointExplosion(vec3d, blockState), null, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); // CraftBukkit - add state
+ return InteractionResult.SUCCESS; + return InteractionResult.SUCCESS;
} + }
} + }
} + }
+ // CraftBukkit end + // CraftBukkit end
+
public static boolean canSetSpawn(Level world) { public static boolean canSetSpawn(Level level) {
- return world.dimensionType().bedWorks(); return level.dimensionType().bedWorks();
+ return world.dimensionType().bedWorks(); // Paper - actually check if the bed works
} }
@@ -311,6 +_,11 @@
private boolean kickVillagerOutOfBed(Level world, BlockPos pos) { if (!level.isClientSide) {
@@ -320,6 +361,11 @@ BlockPos blockPos = pos.relative(state.getValue(FACING));
BlockPos blockposition1 = pos.relative((Direction) state.getValue(BedBlock.FACING)); level.setBlock(blockPos, state.setValue(PART, BedPart.HEAD), 3);
world.setBlock(blockposition1, (BlockState) state.setValue(BedBlock.PART, BedPart.HEAD), 3);
+ // CraftBukkit start - SPIGOT-7315: Don't updated if we capture block states + // CraftBukkit start - SPIGOT-7315: Don't updated if we capture block states
+ if (world.captureBlockStates) { + if (level.captureBlockStates) {
+ return; + return;
+ } + }
+ // CraftBukkit end + // CraftBukkit end
world.blockUpdated(pos, Blocks.AIR); level.blockUpdated(pos, Blocks.AIR);
state.updateNeighbourShapes(world, pos, 3); state.updateNeighbourShapes(level, pos, 3);
} }

View file

@ -0,0 +1,60 @@
--- a/net/minecraft/world/level/block/BeehiveBlock.java
+++ b/net/minecraft/world/level/block/BeehiveBlock.java
@@ -91,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
if (!level.isClientSide && te instanceof BeehiveBlockEntity beehiveBlockEntity) {
if (!EnchantmentHelper.hasTag(stack, EnchantmentTags.PREVENTS_BEE_SPAWNS_WHEN_MINING)) {
beehiveBlockEntity.emptyAllLivingFromHive(player, state, BeehiveBlockEntity.BeeReleaseStatus.EMERGENCY);
@@ -100,7 +_,7 @@
this.angerNearbyBees(level, pos);
}
- CriteriaTriggers.BEE_NEST_DESTROYED.trigger((ServerPlayer)player, state, stack, beehiveBlockEntity.getOccupantCount());
+ // CriteriaTriggers.BEE_NEST_DESTROYED.trigger((ServerPlayer)player, state, stack, beehiveBlockEntity.getOccupantCount()); // Paper - Trigger bee_nest_destroyed trigger in the correct place; moved until after items are dropped
}
}
@@ -122,14 +_,14 @@
for (Bee bee : entitiesOfClass) {
if (bee.getTarget() == null) {
Player player = Util.getRandom(entitiesOfClass1, level.random);
- bee.setTarget(player);
+ bee.setTarget(player, org.bukkit.event.entity.EntityTargetEvent.TargetReason.CLOSEST_PLAYER, true); // CraftBukkit
}
}
}
}
public static void dropHoneycomb(Level level, BlockPos pos) {
- popResource(level, pos, new ItemStack(Items.HONEYCOMB, 3));
+ popResource(level, pos, new ItemStack(Items.HONEYCOMB, 3)); // Paper - Add PlayerShearBlockEvent; conflict on change, item needs to be set below
}
@Override
@@ -141,8 +_,19 @@
if (honeyLevelValue >= 5) {
Item item = stack.getItem();
if (stack.is(Items.SHEARS)) {
+ // Paper start - Add PlayerShearBlockEvent
+ io.papermc.paper.event.block.PlayerShearBlockEvent event = new io.papermc.paper.event.block.PlayerShearBlockEvent((org.bukkit.entity.Player) player.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(stack), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand), new java.util.ArrayList<>());
+ event.getDrops().add(org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(new ItemStack(Items.HONEYCOMB, 3)));
+ if (!event.callEvent()) {
+ return InteractionResult.PASS;
+ }
+ // Paper end
level.playSound(player, player.getX(), player.getY(), player.getZ(), SoundEvents.BEEHIVE_SHEAR, SoundSource.BLOCKS, 1.0F, 1.0F);
- dropHoneycomb(level, pos);
+ // Paper start - Add PlayerShearBlockEvent
+ for (org.bukkit.inventory.ItemStack itemDrop : event.getDrops()) {
+ popResource(level, pos, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(itemDrop));
+ }
+ // Paper end - Add PlayerShearBlockEvent
stack.hurtAndBreak(1, player, LivingEntity.getSlotForHand(hand));
flag = true;
level.gameEvent(player, GameEvent.SHEAR, pos);

View file

@ -0,0 +1,14 @@
--- a/net/minecraft/world/level/block/BellBlock.java
+++ b/net/minecraft/world/level/block/BellBlock.java
@@ -142,6 +_,11 @@
direction = level.getBlockState(pos).getValue(FACING);
}
+ // CraftBukkit start
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBellRingEvent(level, pos, direction, entity)) {
+ return false;
+ }
+ // CraftBukkit end
((BellBlockEntity)blockEntity).onHit(direction);
level.playSound(null, pos, SoundEvents.BELL_BLOCK, SoundSource.BLOCKS, 2.0F, 1.0F);
level.gameEvent(entity, GameEvent.BLOCK_CHANGE, pos);

View file

@ -0,0 +1,88 @@
--- a/net/minecraft/world/level/block/BigDripleafBlock.java
+++ b/net/minecraft/world/level/block/BigDripleafBlock.java
@@ -136,7 +_,7 @@
@Override
protected void onProjectileHit(Level level, BlockState state, BlockHitResult hit, Projectile projectile) {
- this.setTiltAndScheduleTick(state, level, hit.getBlockPos(), Tilt.FULL, SoundEvents.BIG_DRIPLEAF_TILT_DOWN);
+ this.setTiltAndScheduleTick(state, level, hit.getBlockPos(), Tilt.FULL, SoundEvents.BIG_DRIPLEAF_TILT_DOWN, projectile); // CraftBukkit
}
@Override
@@ -199,9 +_,23 @@
@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.isClientSide) {
if (state.getValue(TILT) == Tilt.NONE && canEntityTilt(pos, entity) && !level.hasNeighborSignal(pos)) {
- this.setTiltAndScheduleTick(state, level, pos, Tilt.UNSTABLE, null);
+ // CraftBukkit start - tilt dripleaf
+ org.bukkit.event.Cancellable cancellable;
+ if (entity instanceof net.minecraft.world.entity.player.Player) {
+ cancellable = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent((net.minecraft.world.entity.player.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);
+ }
+
+ if (cancellable.isCancelled()) {
+ return;
+ }
+ this.setTiltAndScheduleTick(state, level, pos, Tilt.UNSTABLE, null, entity);
+ // CraftBukkit end
}
}
}
@@ -213,9 +_,9 @@
} else {
Tilt tilt = state.getValue(TILT);
if (tilt == Tilt.UNSTABLE) {
- this.setTiltAndScheduleTick(state, level, pos, Tilt.PARTIAL, SoundEvents.BIG_DRIPLEAF_TILT_DOWN);
+ this.setTiltAndScheduleTick(state, level, pos, Tilt.PARTIAL, SoundEvents.BIG_DRIPLEAF_TILT_DOWN, null); // CraftBukkit
} else if (tilt == Tilt.PARTIAL) {
- this.setTiltAndScheduleTick(state, level, pos, Tilt.FULL, SoundEvents.BIG_DRIPLEAF_TILT_DOWN);
+ this.setTiltAndScheduleTick(state, level, pos, Tilt.FULL, SoundEvents.BIG_DRIPLEAF_TILT_DOWN, null); // CraftBukkit
} else if (tilt == Tilt.FULL) {
resetTilt(state, level, pos);
}
@@ -238,8 +_,9 @@
return entity.onGround() && entity.position().y > pos.getY() + 0.6875F;
}
- private void setTiltAndScheduleTick(BlockState state, Level level, BlockPos pos, Tilt tilt, @Nullable SoundEvent sound) {
- setTilt(state, level, pos, tilt);
+ private void setTiltAndScheduleTick(BlockState state, Level level, BlockPos pos, Tilt tilt, @Nullable SoundEvent sound, @Nullable Entity entity) {
+ if (!BigDripleafBlock.setTilt(state, level, pos, tilt, entity)) return;
+ // CraftBukkit end
if (sound != null) {
playTiltSound(level, pos, sound);
}
@@ -251,18 +_,25 @@
}
private static void resetTilt(BlockState state, Level level, BlockPos pos) {
- setTilt(state, level, pos, Tilt.NONE);
+ setTilt(state, level, pos, Tilt.NONE, null); // CraftBukkit
if (state.getValue(TILT) != Tilt.NONE) {
playTiltSound(level, pos, SoundEvents.BIG_DRIPLEAF_TILT_UP);
}
}
- private static void setTilt(BlockState state, Level level, BlockPos pos, Tilt tilt) {
+ private static boolean setTilt(BlockState state, Level level, BlockPos pos, Tilt tilt, @Nullable Entity entity) { // CraftBukkit
+ if (entity != null) {
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, pos, state.setValue(BigDripleafBlock.TILT, tilt))) {
+ return false;
+ }
+ }
+ // CraftBukkit end
Tilt tilt1 = state.getValue(TILT);
level.setBlock(pos, state.setValue(TILT, tilt), 2);
if (tilt.causesVibration() && tilt != tilt1) {
level.gameEvent(null, GameEvent.BLOCK_CHANGE, pos);
}
+ return true; // CraftBukkit
}
@Override

View file

@ -1,9 +1,9 @@
--- a/net/minecraft/world/level/block/BlastFurnaceBlock.java --- a/net/minecraft/world/level/block/BlastFurnaceBlock.java
+++ b/net/minecraft/world/level/block/BlastFurnaceBlock.java +++ b/net/minecraft/world/level/block/BlastFurnaceBlock.java
@@ -45,8 +45,7 @@ @@ -45,8 +_,7 @@
@Override @Override
protected void openContainer(Level world, BlockPos pos, Player player) { protected void openContainer(Level level, BlockPos pos, Player player) {
BlockEntity blockEntity = world.getBlockEntity(pos); BlockEntity blockEntity = level.getBlockEntity(pos);
- if (blockEntity instanceof BlastFurnaceBlockEntity) { - if (blockEntity instanceof BlastFurnaceBlockEntity) {
- player.openMenu((MenuProvider)blockEntity); - player.openMenu((MenuProvider)blockEntity);
+ if (blockEntity instanceof BlastFurnaceBlockEntity && player.openMenu((MenuProvider)blockEntity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation + if (blockEntity instanceof BlastFurnaceBlockEntity && player.openMenu((MenuProvider)blockEntity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation

View file

@ -1,6 +1,6 @@
--- a/net/minecraft/world/level/block/Block.java --- a/net/minecraft/world/level/block/Block.java
+++ b/net/minecraft/world/level/block/Block.java +++ b/net/minecraft/world/level/block/Block.java
@@ -88,6 +88,21 @@ @@ -90,6 +_,21 @@
public static final int UPDATE_LIMIT = 512; public static final int UPDATE_LIMIT = 512;
protected final StateDefinition<Block, BlockState> stateDefinition; protected final StateDefinition<Block, BlockState> stateDefinition;
private BlockState defaultBlockState; private BlockState defaultBlockState;
@ -22,8 +22,8 @@
@Nullable @Nullable
private Item item; private Item item;
private static final int CACHE_SIZE = 256; private static final int CACHE_SIZE = 256;
@@ -295,12 +310,38 @@ @@ -272,6 +_,27 @@
return state.getDrops(builder);
} }
+ // Paper start - Add BlockBreakBlockEvent + // Paper start - Add BlockBreakBlockEvent
@ -47,91 +47,92 @@
+ } + }
+ // Paper end - Add BlockBreakBlockEvent + // Paper end - Add BlockBreakBlockEvent
+ +
public static void dropResources(BlockState state, Level world, BlockPos pos, @Nullable BlockEntity blockEntity, @Nullable Entity entity, ItemStack tool) { public static void dropResources(BlockState state, Level level, BlockPos pos) {
if (level instanceof ServerLevel) {
getDrops(state, (ServerLevel)level, pos, null).forEach(itemStack -> popResource(level, pos, itemStack));
@@ -287,9 +_,14 @@
}
public static void dropResources(BlockState state, Level level, BlockPos pos, @Nullable BlockEntity blockEntity, @Nullable Entity entity, ItemStack tool) {
+ // Paper start - Properly handle xp dropping + // Paper start - Properly handle xp dropping
+ dropResources(state, world, pos, blockEntity, entity, tool, true); + dropResources(state, level, pos, blockEntity, entity, tool, true);
+ } + }
+ public static void dropResources(BlockState state, Level world, BlockPos pos, @Nullable BlockEntity blockEntity, @Nullable Entity entity, ItemStack tool, boolean dropExperience) { + public static void dropResources(BlockState state, Level level, BlockPos pos, @Nullable BlockEntity blockEntity, @Nullable Entity entity, ItemStack tool, boolean dropExperience) {
+ // Paper end - Properly handle xp dropping + // Paper end - Properly handle xp dropping
if (world instanceof ServerLevel) { if (level instanceof ServerLevel) {
Block.getDrops(state, (ServerLevel) world, pos, blockEntity, entity, tool).forEach((itemstack1) -> { getDrops(state, (ServerLevel)level, pos, blockEntity, entity, tool).forEach(itemStack -> popResource(level, pos, itemStack));
Block.popResource(world, pos, itemstack1); - state.spawnAfterBreak((ServerLevel)level, pos, tool, true);
}); + state.spawnAfterBreak((ServerLevel) level, pos, tool, dropExperience); // Paper - Properly handle xp dropping
- state.spawnAfterBreak((ServerLevel) world, pos, tool, true);
+ state.spawnAfterBreak((ServerLevel) world, pos, tool, dropExperience); // Paper - Properly handle xp dropping
} }
}
@@ -340,7 +381,13 @@
ItemEntity entityitem = (ItemEntity) itemEntitySupplier.get();
entityitem.setDefaultPickUpDelay();
- world.addFreshEntity(entityitem);
+ // CraftBukkit start
+ if (world.captureDrops != null) {
+ world.captureDrops.add(entityitem);
+ } else {
+ world.addFreshEntity(entityitem);
+ }
+ // CraftBukkit end
return;
}
}
@@ -348,8 +395,13 @@
} }
public void popExperience(ServerLevel world, BlockPos pos, int size) { @@ -320,13 +_,24 @@
if (level instanceof ServerLevel serverLevel && !stack.isEmpty() && serverLevel.getGameRules().getBoolean(GameRules.RULE_DOBLOCKDROPS)) {
ItemEntity itemEntity = itemEntitySupplier.get();
itemEntity.setDefaultPickUpDelay();
- level.addFreshEntity(itemEntity);
+ // CraftBukkit start
+ if (level.captureDrops != null) {
+ level.captureDrops.add(itemEntity);
+ } else {
+ level.addFreshEntity(itemEntity);
+ }
+ // CraftBukkit end
}
}
public void popExperience(ServerLevel level, BlockPos pos, int amount) {
+ // Paper start - add entity parameter + // Paper start - add entity parameter
+ popExperience(world, pos, size, null); + popExperience(level, pos, amount, null);
+ } + }
+ public void popExperience(ServerLevel world, BlockPos pos, int size, net.minecraft.world.entity.Entity entity) { + public void popExperience(ServerLevel level, BlockPos pos, int amount, net.minecraft.world.entity.Entity entity) {
+ // Paper end - add entity parameter + // Paper end - add entity paramete
if (world.getGameRules().getBoolean(GameRules.RULE_DOBLOCKDROPS)) { if (level.getGameRules().getBoolean(GameRules.RULE_DOBLOCKDROPS)) {
- ExperienceOrb.award(world, Vec3.atCenterOf(pos), size); - ExperienceOrb.award(level, Vec3.atCenterOf(pos), amount);
+ ExperienceOrb.award(world, Vec3.atCenterOf(pos), size, org.bukkit.entity.ExperienceOrb.SpawnReason.BLOCK_BREAK, entity); // Paper + ExperienceOrb.award(level, Vec3.atCenterOf(pos), amount, entity); // Paper
} }
} }
@@ -367,10 +419,18 @@
@@ -345,10 +_,18 @@
return this.defaultBlockState(); return this.defaultBlockState();
} }
+ @io.papermc.paper.annotation.DoNotUse @Deprecated // Paper - fix drops not preventing stats/food exhaustion + @io.papermc.paper.annotation.DoNotUse @Deprecated // Paper - fix drops not preventing stats/food exhaustion
public void playerDestroy(Level world, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool) { public void playerDestroy(Level level, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool) {
+ // Paper start - fix drops not preventing stats/food exhaustion + // Paper start - fix drops not preventing stats/food exhaustion
+ this.playerDestroy(world, player, pos, state, blockEntity, tool, true, true); + this.playerDestroy(level, player, pos, state, blockEntity, tool, true, true);
+ } + }
+ public void playerDestroy(Level world, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool, boolean includeDrops, boolean dropExp) { + public void playerDestroy(Level level, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool, boolean includeDrops, boolean dropExp) {
+ // Paper end - fix drops not preventing stats/food exhaustion + // Paper end - fix drops not preventing stats/food exhaustion
player.awardStat(Stats.BLOCK_MINED.get(this)); player.awardStat(Stats.BLOCK_MINED.get(this));
- player.causeFoodExhaustion(0.005F); - player.causeFoodExhaustion(0.005F);
- Block.dropResources(state, world, pos, blockEntity, player, tool); - dropResources(state, level, pos, blockEntity, player, tool);
+ player.causeFoodExhaustion(0.005F, org.bukkit.event.entity.EntityExhaustionEvent.ExhaustionReason.BLOCK_MINED); // CraftBukkit - EntityExhaustionEvent + player.causeFoodExhaustion(0.005F, org.bukkit.event.entity.EntityExhaustionEvent.ExhaustionReason.BLOCK_MINED); // CraftBukkit - EntityExhaustionEvent
+ if (includeDrops) { // Paper - fix drops not preventing stats/food exhaustion + if (includeDrops) { // Paper - fix drops not preventing stats/food exhaustion
+ Block.dropResources(state, world, pos, blockEntity, player, tool, dropExp); // Paper - Properly handle xp dropping + Block.dropResources(state, level, pos, blockEntity, player, tool, dropExp); // Paper - Properly handle xp dropping
+ } // Paper - fix drops not preventing stats/food exhaustion + } // Paper - fix drops not preventing stats/food exhaustion
} }
public void setPlacedBy(Level world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack itemStack) {} public void setPlacedBy(Level level, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack) {
@@ -490,15 +550,35 @@ @@ -469,12 +_,33 @@
return this.builtInRegistryHolder; return this.builtInRegistryHolder;
} }
- protected void tryDropExperience(ServerLevel world, BlockPos pos, ItemStack tool, IntProvider experience) { - protected void tryDropExperience(ServerLevel level, BlockPos pos, ItemStack heldItem, IntProvider amount) {
- int i = EnchantmentHelper.processBlockExperience(world, tool, experience.sample(world.getRandom())); + protected int tryDropExperience(ServerLevel level, BlockPos pos, ItemStack heldItem, IntProvider amount) { // CraftBukkit
+ // CraftBukkit start int i = EnchantmentHelper.processBlockExperience(level, heldItem, amount.sample(level.getRandom()));
+ protected int tryDropExperience(ServerLevel worldserver, BlockPos blockposition, ItemStack itemstack, IntProvider intprovider) {
+ int i = EnchantmentHelper.processBlockExperience(worldserver, itemstack, intprovider.sample(worldserver.getRandom()));
if (i > 0) { if (i > 0) {
- this.popExperience(world, pos, i); - this.popExperience(level, pos, i);
+ // this.popExperience(worldserver, blockposition, i); - }
- }
+ // CraftBukkit start
+ //this.popExperience(level, pos, i);
+ return i; + return i;
} + // Craftbukkit end
+ }
+ return 0; + return 0; // CraftBukkit
} + }
+ // CraftBukkit start
+ public int getExpDrop(BlockState iblockdata, ServerLevel worldserver, BlockPos blockposition, ItemStack itemstack, boolean flag) { + public int getExpDrop(BlockState iblockdata, ServerLevel worldserver, BlockPos blockposition, ItemStack itemstack, boolean flag) {
+ return 0; + return 0;
+ } + }
@ -148,7 +149,6 @@
+ return value; + return value;
+ } + }
+ // Spigot end + // Spigot end
+
private static record ShapePairKey(VoxelShape first, VoxelShape second) {
public boolean equals(Object object) { record ShapePairKey(VoxelShape first, VoxelShape second) {
@Override

View file

@ -1,12 +1,12 @@
--- a/net/minecraft/world/level/block/BrewingStandBlock.java --- a/net/minecraft/world/level/block/BrewingStandBlock.java
+++ b/net/minecraft/world/level/block/BrewingStandBlock.java +++ b/net/minecraft/world/level/block/BrewingStandBlock.java
@@ -68,8 +68,7 @@ @@ -68,8 +_,7 @@
@Override @Override
protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) {
- if (!world.isClientSide && world.getBlockEntity(pos) instanceof BrewingStandBlockEntity brewingStandBlockEntity) { - if (!level.isClientSide && level.getBlockEntity(pos) instanceof BrewingStandBlockEntity brewingStandBlockEntity) {
- player.openMenu(brewingStandBlockEntity); - player.openMenu(brewingStandBlockEntity);
+ if (!world.isClientSide && world.getBlockEntity(pos) instanceof BrewingStandBlockEntity brewingStandBlockEntity && player.openMenu(brewingStandBlockEntity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation + if (!level.isClientSide && level.getBlockEntity(pos) instanceof BrewingStandBlockEntity brewingStandBlockEntity && player.openMenu(brewingStandBlockEntity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation
player.awardStat(Stats.INTERACT_WITH_BREWINGSTAND); player.awardStat(Stats.INTERACT_WITH_BREWINGSTAND);
} }

View file

@ -1,10 +1,10 @@
--- a/net/minecraft/world/level/block/BubbleColumnBlock.java --- a/net/minecraft/world/level/block/BubbleColumnBlock.java
+++ b/net/minecraft/world/level/block/BubbleColumnBlock.java +++ b/net/minecraft/world/level/block/BubbleColumnBlock.java
@@ -48,6 +48,7 @@ @@ -48,6 +_,7 @@
@Override @Override
protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { 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(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent + if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
BlockState blockState = world.getBlockState(pos.above()); BlockState blockState = level.getBlockState(pos.above());
if (blockState.isAir()) { if (blockState.isAir()) {
entity.onAboveBubbleCol(state.getValue(DRAG_DOWN)); entity.onAboveBubbleCol(state.getValue(DRAG_DOWN));

View file

@ -1,17 +1,17 @@
--- a/net/minecraft/world/level/block/BuddingAmethystBlock.java --- a/net/minecraft/world/level/block/BuddingAmethystBlock.java
+++ b/net/minecraft/world/level/block/BuddingAmethystBlock.java +++ b/net/minecraft/world/level/block/BuddingAmethystBlock.java
@@ -45,7 +45,13 @@ @@ -44,7 +_,13 @@
if (block != null) { BlockState blockState1 = block.defaultBlockState()
BlockState iblockdata2 = (BlockState) ((BlockState) block.defaultBlockState().setValue(AmethystClusterBlock.FACING, enumdirection)).setValue(AmethystClusterBlock.WATERLOGGED, iblockdata1.getFluidState().getType() == Fluids.WATER); .setValue(AmethystClusterBlock.FACING, direction)
.setValue(AmethystClusterBlock.WATERLOGGED, Boolean.valueOf(blockState.getFluidState().getType() == Fluids.WATER));
- world.setBlockAndUpdate(blockposition1, iblockdata2); - level.setBlockAndUpdate(blockPos, blockState1);
+ // Paper start - Have Amethyst throw both spread and grow events + // Paper start - Have Amethyst throw both spread and grow events
+ if (block == Blocks.SMALL_AMETHYST_BUD) { + if (block == Blocks.SMALL_AMETHYST_BUD) {
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(world, pos, blockposition1, iblockdata2); // CraftBukkit + org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(level, pos, blockPos, blockState1); // CraftBukkit
+ } else { + } else {
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(world, blockposition1, iblockdata2); + org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, blockPos, blockState1);
+ } + }
+ // Paper end - Have Amethyst throw both spread and grow events + // Paper end - Have Amethyst throw both spread and grow events
} }
} }
}

View file

@ -0,0 +1,29 @@
--- a/net/minecraft/world/level/block/BushBlock.java
+++ b/net/minecraft/world/level/block/BushBlock.java
@@ -6,6 +_,7 @@
import net.minecraft.tags.BlockTags;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.BlockGetter;
+import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.ScheduledTickAccess;
import net.minecraft.world.level.block.state.BlockBehaviour;
@@ -35,9 +_,15 @@
BlockState neighborState,
RandomSource random
) {
- return !state.canSurvive(level, pos)
- ? Blocks.AIR.defaultBlockState()
- : super.updateShape(state, level, scheduledTickAccess, pos, direction, neighborPos, neighborState, random);
+ // CraftBukkit start
+ if (!state.canSurvive(level, pos)) {
+ // Suppress during worldgen
+ if (!(level instanceof net.minecraft.server.level.ServerLevel world1 && world1.hasPhysicsEvent) || !org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPhysicsEvent(world1, pos).isCancelled()) { // Paper
+ return Blocks.AIR.defaultBlockState();
+ }
+ }
+ return super.updateShape(state, level, scheduledTickAccess, pos, direction, neighborPos, neighborState, random);
+ // CraftBukkit end
}
@Override

View file

@ -0,0 +1,62 @@
--- a/net/minecraft/world/level/block/ButtonBlock.java
+++ b/net/minecraft/world/level/block/ButtonBlock.java
@@ -114,6 +_,19 @@
if (state.getValue(POWERED)) {
return InteractionResult.CONSUME;
} else {
+ // CraftBukkit start
+ boolean powered = state.getValue(ButtonBlock.POWERED);
+ org.bukkit.block.Block block = level.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ());
+ int old = (powered) ? 15 : 0;
+ int current = (!powered) ? 15 : 0;
+
+ org.bukkit.event.block.BlockRedstoneEvent eventRedstone = new org.bukkit.event.block.BlockRedstoneEvent(block, old, current);
+ level.getCraftServer().getPluginManager().callEvent(eventRedstone);
+
+ if ((eventRedstone.getNewCurrent() > 0) != (!powered)) {
+ return InteractionResult.SUCCESS;
+ }
+ // CraftBukkit end
this.press(state, level, pos, player);
return InteractionResult.SUCCESS;
}
@@ -179,6 +_,7 @@
@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.isClientSide && this.type.canButtonBeActivatedByArrows() && !state.getValue(POWERED)) {
this.checkPressed(state, level, pos);
}
@@ -190,7 +_,31 @@
: null;
boolean flag = abstractArrow != null;
boolean poweredValue = state.getValue(POWERED);
+ // CraftBukkit start - Call interact event when arrows turn on wooden buttons
+ if (poweredValue != flag && flag) {
+ org.bukkit.block.Block block = level.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ());
+ org.bukkit.event.entity.EntityInteractEvent event = new org.bukkit.event.entity.EntityInteractEvent(abstractArrow.getBukkitEntity(), block);
+ level.getCraftServer().getPluginManager().callEvent(event);
+
+ if (event.isCancelled()) {
+ return;
+ }
+ }
+ // CraftBukkit end
if (flag != poweredValue) {
+ // CraftBukkit start
+ boolean powered = poweredValue;
+ org.bukkit.block.Block block = level.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ());
+ int old = (powered) ? 15 : 0;
+ int current = (!powered) ? 15 : 0;
+
+ org.bukkit.event.block.BlockRedstoneEvent eventRedstone = new org.bukkit.event.block.BlockRedstoneEvent(block, old, current);
+ level.getCraftServer().getPluginManager().callEvent(eventRedstone);
+
+ if ((flag && eventRedstone.getNewCurrent() <= 0) || (!flag && eventRedstone.getNewCurrent() > 0)) {
+ return;
+ }
+ // CraftBukkit end
level.setBlock(pos, state.setValue(POWERED, Boolean.valueOf(flag)), 3);
this.updateNeighbours(state, level, pos);
this.playSound(null, level, pos, flag);

View file

@ -0,0 +1,12 @@
--- a/net/minecraft/world/level/block/CactusBlock.java
+++ b/net/minecraft/world/level/block/CactusBlock.java
@@ -113,7 +_,8 @@
@Override
protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) {
- entity.hurt(level.damageSources().cactus(), 1.0F);
+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
+ entity.hurt(level.damageSources().cactus().directBlock(level, pos), 1.0F); // CraftBukkit
}
@Override

View file

@ -1,25 +1,25 @@
--- a/net/minecraft/world/level/block/CakeBlock.java --- a/net/minecraft/world/level/block/CakeBlock.java
+++ b/net/minecraft/world/level/block/CakeBlock.java +++ b/net/minecraft/world/level/block/CakeBlock.java
@@ -66,6 +66,12 @@ @@ -67,6 +_,12 @@
if (block instanceof CandleBlock) { ) {
CandleBlock candleblock = (CandleBlock) block; Item item = stack.getItem();
if (stack.is(ItemTags.CANDLES) && state.getValue(BITES) == 0 && Block.byItem(item) instanceof CandleBlock candleBlock) {
+ // Paper start - call change block event + // Paper start - call change block event
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, pos, CandleCakeBlock.byCandle(candleblock))) { + if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, pos, CandleCakeBlock.byCandle(candleBlock))) {
+ player.containerMenu.sendAllDataToRemote(); // update inv because candle could decrease + player.containerMenu.sendAllDataToRemote(); // update inv because candle could decrease
+ return InteractionResult.TRY_WITH_EMPTY_HAND; + return InteractionResult.TRY_WITH_EMPTY_HAND;
+ } + }
+ // Paper end - call change block event + // Paper end - call change block event
stack.consume(1, player); stack.consume(1, player);
world.playSound((Player) null, pos, SoundEvents.CAKE_ADD_CANDLE, SoundSource.BLOCKS, 1.0F, 1.0F); level.playSound(null, pos, SoundEvents.CAKE_ADD_CANDLE, SoundSource.BLOCKS, 1.0F, 1.0F);
world.setBlockAndUpdate(pos, CandleCakeBlock.byCandle(candleblock)); level.setBlockAndUpdate(pos, CandleCakeBlock.byCandle(candleBlock));
@@ -97,10 +103,29 @@ @@ -97,9 +_,28 @@
if (!player.canEat(false)) { if (!player.canEat(false)) {
return InteractionResult.PASS; return InteractionResult.PASS;
} else { } else {
+ // Paper start - call change block event + // Paper start - call change block event
+ int i = state.getValue(CakeBlock.BITES); + int bitesValue = state.getValue(CakeBlock.BITES);
+ final BlockState newState = i < MAX_BITES ? state.setValue(CakeBlock.BITES, i + 1) : world.getFluidState(pos).createLegacyBlock(); + final BlockState newState = bitesValue < MAX_BITES ? state.setValue(CakeBlock.BITES, bitesValue + 1) : level.getFluidState(pos).createLegacyBlock();
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, pos, newState)) { + if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, pos, newState)) {
+ ((net.minecraft.server.level.ServerPlayer) player).getBukkitEntity().sendHealthUpdate(); + ((net.minecraft.server.level.ServerPlayer) player).getBukkitEntity().sendHealthUpdate();
+ return InteractionResult.PASS; // return a non-consume result to cake blocks don't drop their candles + return InteractionResult.PASS; // return a non-consume result to cake blocks don't drop their candles
@ -27,11 +27,11 @@
+ // Paper end - call change block event + // Paper end - call change block event
player.awardStat(Stats.EAT_CAKE_SLICE); player.awardStat(Stats.EAT_CAKE_SLICE);
- player.getFoodData().eat(2, 0.1F); - player.getFoodData().eat(2, 0.1F);
- int i = (Integer) state.getValue(CakeBlock.BITES); - int bitesValue = state.getValue(BITES);
+ // CraftBukkit start + // CraftBukkit start
+ // entityhuman.getFoodData().eat(2, 0.1F); + // entityhuman.getFoodData().eat(2, 0.1F);
+ int oldFoodLevel = player.getFoodData().foodLevel; + int oldFoodLevel = player.getFoodData().foodLevel;
+
+ org.bukkit.event.entity.FoodLevelChangeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callFoodLevelChangeEvent(player, 2 + oldFoodLevel); + org.bukkit.event.entity.FoodLevelChangeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callFoodLevelChangeEvent(player, 2 + oldFoodLevel);
+ +
+ if (!event.isCancelled()) { + if (!event.isCancelled()) {
@ -41,7 +41,6 @@
+ ((net.minecraft.server.level.ServerPlayer) player).getBukkitEntity().sendHealthUpdate(); + ((net.minecraft.server.level.ServerPlayer) player).getBukkitEntity().sendHealthUpdate();
+ // CraftBukkit end + // CraftBukkit end
+ // Paper - move up + // Paper - move up
+ level.gameEvent(player, GameEvent.EAT, pos);
world.gameEvent((Entity) player, (Holder) GameEvent.EAT, pos); if (bitesValue < 6) {
if (i < 6) { level.setBlock(pos, state.setValue(BITES, Integer.valueOf(bitesValue + 1)), 3);
world.setBlock(pos, (BlockState) state.setValue(CakeBlock.BITES, i + 1), 3);

View file

@ -0,0 +1,25 @@
--- a/net/minecraft/world/level/block/CampfireBlock.java
+++ b/net/minecraft/world/level/block/CampfireBlock.java
@@ -112,8 +_,9 @@
@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 (state.getValue(LIT) && entity instanceof LivingEntity) {
- entity.hurt(level.damageSources().campfire(), this.fireDamage);
+ entity.hurt(level.damageSources().campfire().directBlock(level, pos), (float) this.fireDamage); // CraftBukkit
}
super.entityInside(state, level, pos, entity);
@@ -242,6 +_,11 @@
&& projectile.mayInteract(serverLevel, blockPos)
&& !state.getValue(LIT)
&& !state.getValue(WATERLOGGED)) {
+ // CraftBukkit start
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(level, blockPos, projectile).isCancelled()) {
+ return;
+ }
+ // CraftBukkit end
level.setBlock(blockPos, state.setValue(BlockStateProperties.LIT, Boolean.valueOf(true)), 11);
}
}

View file

@ -1,11 +1,11 @@
--- a/net/minecraft/world/level/block/CartographyTableBlock.java --- a/net/minecraft/world/level/block/CartographyTableBlock.java
+++ b/net/minecraft/world/level/block/CartographyTableBlock.java +++ b/net/minecraft/world/level/block/CartographyTableBlock.java
@@ -32,8 +32,9 @@ @@ -32,8 +_,9 @@
@Override @Override
protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) {
if (!world.isClientSide) { if (!level.isClientSide) {
- player.openMenu(state.getMenuProvider(world, pos)); - player.openMenu(state.getMenuProvider(level, pos));
+ if (player.openMenu(state.getMenuProvider(world, pos)).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation + if (player.openMenu(state.getMenuProvider(level, pos)).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation
player.awardStat(Stats.INTERACT_WITH_CARTOGRAPHY_TABLE); player.awardStat(Stats.INTERACT_WITH_CARTOGRAPHY_TABLE);
+ } // Paper - Fix InventoryOpenEvent cancellation + } // Paper - Fix InventoryOpenEvent cancellation
} }

View file

@ -0,0 +1,18 @@
--- a/net/minecraft/world/level/block/CarvedPumpkinBlock.java
+++ b/net/minecraft/world/level/block/CarvedPumpkinBlock.java
@@ -79,9 +_,13 @@
}
private static void spawnGolemInWorld(Level level, BlockPattern.BlockPatternMatch patternMatch, Entity golem, BlockPos pos) {
- clearPatternBlocks(level, patternMatch);
+ // clearPatternBlocks(level, patternMatch); // CraftBukkit - moved down
golem.moveTo(pos.getX() + 0.5, pos.getY() + 0.05, pos.getZ() + 0.5, 0.0F, 0.0F);
- level.addFreshEntity(golem);
+ if (!level.addFreshEntity(golem, (golem.getType() == EntityType.SNOW_GOLEM) ? org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.BUILD_SNOWMAN : org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.BUILD_IRONGOLEM)) {
+ return;
+ }
+ clearPatternBlocks(level, patternMatch); // CraftBukkit - from above
+ // CraftBukkit end
for (ServerPlayer serverPlayer : level.getEntitiesOfClass(ServerPlayer.class, golem.getBoundingBox().inflate(5.0))) {
CriteriaTriggers.SUMMONED_ENTITY.trigger(serverPlayer, golem);

View file

@ -0,0 +1,46 @@
--- a/net/minecraft/world/level/block/CauldronBlock.java
+++ b/net/minecraft/world/level/block/CauldronBlock.java
@@ -40,9 +_,19 @@
public void handlePrecipitation(BlockState state, Level level, BlockPos pos, Biome.Precipitation precipitation) {
if (shouldHandlePrecipitation(level, precipitation)) {
if (precipitation == Biome.Precipitation.RAIN) {
+ // Paper start - Call CauldronLevelChangeEvent
+ if (!LayeredCauldronBlock.changeLevel(state, level, pos, Blocks.WATER_CAULDRON.defaultBlockState(), null, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL, false)) { // avoid duplicate game event
+ return;
+ }
+ // Paper end - Call CauldronLevelChangeEvent
level.setBlockAndUpdate(pos, Blocks.WATER_CAULDRON.defaultBlockState());
level.gameEvent(null, GameEvent.BLOCK_CHANGE, pos);
} else if (precipitation == Biome.Precipitation.SNOW) {
+ // Paper start - Call CauldronLevelChangeEvent
+ if (!LayeredCauldronBlock.changeLevel(state, level, pos, Blocks.POWDER_SNOW_CAULDRON.defaultBlockState(), null, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL, false)) { // avoid duplicate game event
+ return;
+ }
+ // Paper end - Call CauldronLevelChangeEvent
level.setBlockAndUpdate(pos, Blocks.POWDER_SNOW_CAULDRON.defaultBlockState());
level.gameEvent(null, GameEvent.BLOCK_CHANGE, pos);
}
@@ -58,13 +_,19 @@
protected void receiveStalactiteDrip(BlockState state, Level level, BlockPos pos, Fluid fluid) {
if (fluid == Fluids.WATER) {
BlockState blockState = Blocks.WATER_CAULDRON.defaultBlockState();
- level.setBlockAndUpdate(pos, blockState);
- level.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(blockState));
+ // Paper start - Call CauldronLevelChangeEvent; don't send level event or game event if cancelled
+ if (!LayeredCauldronBlock.changeLevel(state, level, pos, blockState, null, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL)) { // CraftBukkit
+ return;
+ }
+ // Paper end - Call CauldronLevelChangeEvent
level.levelEvent(1047, pos, 0);
} else if (fluid == Fluids.LAVA) {
BlockState blockState = Blocks.LAVA_CAULDRON.defaultBlockState();
- level.setBlockAndUpdate(pos, blockState);
- level.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(blockState));
+ // Paper start - Call CauldronLevelChangeEvent; don't send level event or game event if cancelled
+ if (!LayeredCauldronBlock.changeLevel(state, level, pos, blockState, null, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL)) { // CraftBukkit
+ return;
+ }
+ // Paper end - Call CauldronLevelChangeEvent
level.levelEvent(1046, pos, 0);
}
}

View file

@ -0,0 +1,27 @@
--- a/net/minecraft/world/level/block/CaveVines.java
+++ b/net/minecraft/world/level/block/CaveVines.java
@@ -23,7 +_,23 @@
static InteractionResult use(@Nullable Entity entity, BlockState state, Level level, BlockPos pos) {
if (state.getValue(BERRIES)) {
- Block.popResource(level, pos, new ItemStack(Items.GLOW_BERRIES, 1));
+ // CraftBukkit start
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, pos, (BlockState) state.setValue(CaveVines.BERRIES, false))) {
+ return InteractionResult.SUCCESS;
+ }
+
+ if (entity instanceof net.minecraft.world.entity.player.Player) {
+ org.bukkit.event.player.PlayerHarvestBlockEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerHarvestBlockEvent(level, pos, (net.minecraft.world.entity.player.Player) entity, net.minecraft.world.InteractionHand.MAIN_HAND, java.util.Collections.singletonList(new ItemStack(Items.GLOW_BERRIES, 1)));
+ 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()) {
+ Block.popResource(level, pos, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(itemStack));
+ }
+ } else {
+ Block.popResource(level, pos, new ItemStack(Items.GLOW_BERRIES, 1));
+ }
+ // CraftBukkit end
float f = Mth.randomBetween(level.random, 0.8F, 1.2F);
level.playSound(null, pos, SoundEvents.CAVE_VINES_PICK_BERRIES, SoundSource.BLOCKS, 1.0F, f);
BlockState blockState = state.setValue(BERRIES, Boolean.valueOf(false));

View file

@ -1,22 +1,23 @@
--- a/net/minecraft/world/level/block/CaveVinesBlock.java --- a/net/minecraft/world/level/block/CaveVinesBlock.java
+++ b/net/minecraft/world/level/block/CaveVinesBlock.java +++ b/net/minecraft/world/level/block/CaveVinesBlock.java
@@ -50,9 +50,18 @@ @@ -52,7 +_,7 @@
return to.setValue(BERRIES, from.getValue(BERRIES));
@Override
protected BlockState getGrowIntoState(BlockState state, RandomSource random) {
- return super.getGrowIntoState(state, random).setValue(BERRIES, Boolean.valueOf(random.nextFloat() < 0.11F));
+ return this.getGrowIntoState(state, random, null); // Paper - Fix Spigot growth modifiers
} }
+ // Paper start - Fix Spigot growth modifiers
@Override @Override
@@ -85,4 +_,11 @@
public void performBonemeal(ServerLevel level, RandomSource random, BlockPos pos, BlockState state) {
level.setBlock(pos, state.setValue(BERRIES, Boolean.valueOf(true)), 2);
}
+ // Paper start - Fix Spigot growth modifiers
+ @Override
+ protected BlockState getGrowIntoState(BlockState state, RandomSource random, @javax.annotation.Nullable Level level) { + protected BlockState getGrowIntoState(BlockState state, RandomSource random, @javax.annotation.Nullable Level level) {
+ final boolean value = random.nextFloat() < (level != null ? (0.11F * (level.spigotConfig.glowBerryModifier / 100.0F)) : 0.11F); + final boolean value = random.nextFloat() < (level != null ? (0.11F * (level.spigotConfig.glowBerryModifier / 100.0F)) : 0.11F);
+ return (BlockState) super.getGrowIntoState(state, random).setValue(CaveVinesBlock.BERRIES, value); + return (BlockState) super.getGrowIntoState(state, random).setValue(CaveVinesBlock.BERRIES, value);
+ } + }
+ // Paper end - Fix Spigot growth modifiers + // Paper end - Fix Spigot growth modifiers
+ }
+ @Override
protected BlockState getGrowIntoState(BlockState state, RandomSource random) {
- return super.getGrowIntoState(state, random).setValue(BERRIES, Boolean.valueOf(random.nextFloat() < 0.11F));
+ // Paper start - Fix Spigot growth modifiers
+ return this.getGrowIntoState(state, random, null);
}
@Override

View file

@ -1,10 +1,10 @@
--- a/net/minecraft/world/level/block/CeilingHangingSignBlock.java --- a/net/minecraft/world/level/block/CeilingHangingSignBlock.java
+++ b/net/minecraft/world/level/block/CeilingHangingSignBlock.java +++ b/net/minecraft/world/level/block/CeilingHangingSignBlock.java
@@ -159,6 +159,6 @@ @@ -184,6 +_,6 @@
@Nullable @Nullable
@Override @Override
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level world, BlockState state, BlockEntityType<T> type) { public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level level, BlockState state, BlockEntityType<T> blockEntityType) {
- return createTickerHelper(type, BlockEntityType.HANGING_SIGN, SignBlockEntity::tick); - return createTickerHelper(blockEntityType, BlockEntityType.HANGING_SIGN, SignBlockEntity::tick);
+ return null; // Craftbukkit - remove unnecessary sign ticking + return null; // Craftbukkit - remove unnecessary sign ticking
} }
} }

View file

@ -0,0 +1,11 @@
--- a/net/minecraft/world/level/block/ChangeOverTimeBlock.java
+++ b/net/minecraft/world/level/block/ChangeOverTimeBlock.java
@@ -16,7 +_,7 @@
default void changeOverTime(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) {
float f = 0.05688889F;
if (random.nextFloat() < 0.05688889F) {
- this.getNextState(state, level, pos, random).ifPresent(blockState -> level.setBlockAndUpdate(pos, blockState));
+ this.getNextState(state, level, pos, random).ifPresent(blockState -> org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(level, pos, blockState)); // CraftBukkit
}
}

View file

@ -0,0 +1,79 @@
--- a/net/minecraft/world/level/block/ChestBlock.java
+++ b/net/minecraft/world/level/block/ChestBlock.java
@@ -120,6 +_,38 @@
}
};
+ // CraftBukkit start
+ public static class DoubleInventory implements MenuProvider {
+
+ private final ChestBlockEntity tileentitychest;
+ private final ChestBlockEntity tileentitychest1;
+ public final CompoundContainer inventorylargechest;
+
+ public DoubleInventory(ChestBlockEntity tileentitychest, ChestBlockEntity tileentitychest1, CompoundContainer inventorylargechest) {
+ this.tileentitychest = tileentitychest;
+ this.tileentitychest1 = tileentitychest1;
+ this.inventorylargechest = inventorylargechest;
+ }
+
+ @Nullable
+ @Override
+ public AbstractContainerMenu createMenu(int syncId, Inventory playerInventory, Player player) {
+ if (this.tileentitychest.canOpen(player) && this.tileentitychest1.canOpen(player)) {
+ this.tileentitychest.unpackLootTable(playerInventory.player);
+ this.tileentitychest1.unpackLootTable(playerInventory.player);
+ return ChestMenu.sixRows(syncId, playerInventory, this.inventorylargechest);
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public Component getDisplayName() {
+ return (Component) (this.tileentitychest.hasCustomName() ? this.tileentitychest.getDisplayName() : (this.tileentitychest1.hasCustomName() ? this.tileentitychest1.getDisplayName() : Component.translatable("container.chestDouble")));
+ }
+ };
+ // CraftBukkit end
+
@Override
public MapCodec<? extends ChestBlock> codec() {
return CODEC;
@@ -245,8 +_,7 @@
protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) {
if (level instanceof ServerLevel serverLevel) {
MenuProvider menuProvider = this.getMenuProvider(state, level, pos);
- if (menuProvider != null) {
- player.openMenu(menuProvider);
+ if (menuProvider != null && player.openMenu(menuProvider).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation
player.awardStat(this.getOpenChestStat());
PiglinAi.angerNearbyPiglins(serverLevel, player, true);
}
@@ -285,7 +_,14 @@
@Nullable
@Override
protected MenuProvider getMenuProvider(BlockState state, Level level, BlockPos pos) {
- return this.combine(state, level, pos, false).apply(MENU_PROVIDER_COMBINER).orElse(null);
+ // CraftBukkit start
+ return this.getMenuProvider(state, level, pos, false);
+ }
+
+ @Nullable
+ public MenuProvider getMenuProvider(BlockState state, Level level, BlockPos pos, boolean ignoreObstructions) {
+ return this.combine(state, level, pos, ignoreObstructions).apply(MENU_PROVIDER_COMBINER).orElse(null);
+ // CraftBukkit end
}
public static DoubleBlockCombiner.Combiner<ChestBlockEntity, Float2FloatFunction> opennessCombiner(final LidBlockEntity lid) {
@@ -328,6 +_,11 @@
}
private static boolean isCatSittingOnChest(LevelAccessor level, BlockPos pos) {
+ // Paper start - Option to disable chest cat detection
+ if (level.getMinecraftWorld().paperConfig().entities.behavior.disableChestCatDetection) {
+ return false;
+ }
+ // Paper end - Option to disable chest cat detection
List<Cat> entitiesOfClass = level.getEntitiesOfClass(
Cat.class, new AABB(pos.getX(), pos.getY() + 1, pos.getZ(), pos.getX() + 1, pos.getY() + 2, pos.getZ() + 1)
);

View file

@ -0,0 +1,24 @@
--- a/net/minecraft/world/level/block/ChorusFlowerBlock.java
+++ b/net/minecraft/world/level/block/ChorusFlowerBlock.java
@@ -96,8 +_,10 @@
}
if (flag && allNeighborsEmpty(level, blockPos, null) && level.isEmptyBlock(pos.above(2))) {
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(level, pos, blockPos, this.defaultBlockState().setValue(ChorusFlowerBlock.AGE, ageValue), 2)) { // CraftBukkit - add event
level.setBlock(pos, ChorusPlantBlock.getStateWithConnections(level, pos, this.plant.defaultBlockState()), 2);
this.placeGrownFlower(level, blockPos, ageValue);
+ } // CraftBukkit
} else if (ageValue < 4) {
int i = random.nextInt(4);
if (flag1) {
@@ -112,8 +_,10 @@
if (level.isEmptyBlock(blockPos1)
&& level.isEmptyBlock(blockPos1.below())
&& allNeighborsEmpty(level, blockPos1, randomDirection.getOpposite())) {
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(level, pos, blockPos1, this.defaultBlockState().setValue(ChorusFlowerBlock.AGE, ageValue + 1), 2)) { // CraftBukkit - add event
this.placeGrownFlower(level, blockPos1, ageValue + 1);
flag2 = true;
+ } // CraftBukkit
}
}

View file

@ -1,34 +1,34 @@
--- a/net/minecraft/world/level/block/ChorusPlantBlock.java --- a/net/minecraft/world/level/block/ChorusPlantBlock.java
+++ b/net/minecraft/world/level/block/ChorusPlantBlock.java +++ b/net/minecraft/world/level/block/ChorusPlantBlock.java
@@ -38,6 +38,7 @@ @@ -38,6 +_,7 @@
@Override @Override
public BlockState getStateForPlacement(BlockPlaceContext ctx) { public BlockState getStateForPlacement(BlockPlaceContext context) {
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableChorusPlantUpdates) return this.defaultBlockState(); // Paper - add option to disable block updates + if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableChorusPlantUpdates) return this.defaultBlockState(); // Paper - add option to disable block updates
return getStateWithConnections(ctx.getLevel(), ctx.getClickedPos(), this.defaultBlockState()); return getStateWithConnections(context.getLevel(), context.getClickedPos(), this.defaultBlockState());
} }
@@ -68,6 +69,7 @@ @@ -68,6 +_,7 @@
BlockState neighborState, BlockState neighborState,
RandomSource random RandomSource random
) { ) {
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableChorusPlantUpdates) return state; // Paper - add option to disable block updates + if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableChorusPlantUpdates) return state; // Paper - add option to disable block updates
if (!state.canSurvive(world, pos)) { if (!state.canSurvive(level, pos)) {
tickView.scheduleTick(pos, this, 1); scheduledTickAccess.scheduleTick(pos, this, 1);
return super.updateShape(state, world, tickView, pos, direction, neighborPos, neighborState, random); return super.updateShape(state, level, scheduledTickAccess, pos, direction, neighborPos, neighborState, random);
@@ -79,6 +81,7 @@ @@ -81,6 +_,7 @@
@Override @Override
protected void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { protected void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) {
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableChorusPlantUpdates) return; // Paper - add option to disable block updates + if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableChorusPlantUpdates) return; // Paper - add option to disable block updates
if (!state.canSurvive(world, pos)) { if (!state.canSurvive(level, pos)) {
world.destroyBlock(pos, true); level.destroyBlock(pos, true);
} }
@@ -86,6 +89,7 @@ @@ -88,6 +_,7 @@
@Override @Override
protected boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { protected boolean canSurvive(BlockState state, LevelReader level, BlockPos pos) {
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableChorusPlantUpdates) return true; // Paper - add option to disable block updates + if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableChorusPlantUpdates) return true; // Paper - add option to disable block updates
BlockState blockState = world.getBlockState(pos.below()); BlockState blockState = level.getBlockState(pos.below());
boolean bl = !world.getBlockState(pos.above()).isAir() && !blockState.isAir(); boolean flag = !level.getBlockState(pos.above()).isAir() && !blockState.isAir();

View file

@ -0,0 +1,24 @@
--- a/net/minecraft/world/level/block/CocoaBlock.java
+++ b/net/minecraft/world/level/block/CocoaBlock.java
@@ -64,10 +_,10 @@
@Override
protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) {
- if (level.random.nextInt(5) == 0) {
+ if (level.random.nextFloat() < (level.spigotConfig.cocoaModifier / (100.0f * 5))) { // Spigot - SPIGOT-7159: Better modifier resolution
int ageValue = state.getValue(AGE);
if (ageValue < 2) {
- level.setBlock(pos, state.setValue(AGE, Integer.valueOf(ageValue + 1)), 2);
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, pos, state.setValue(CocoaBlock.AGE, ageValue + 1), 2); // CraftBukkkit
}
}
}
@@ -141,7 +_,7 @@
@Override
public void performBonemeal(ServerLevel level, RandomSource random, BlockPos pos, BlockState state) {
- level.setBlock(pos, state.setValue(AGE, Integer.valueOf(state.getValue(AGE) + 1)), 2);
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, pos, state.setValue(CocoaBlock.AGE, state.getValue(CocoaBlock.AGE) + 1), 2); // CraftBukkit
}
@Override

View file

@ -0,0 +1,27 @@
--- a/net/minecraft/world/level/block/CommandBlock.java
+++ b/net/minecraft/world/level/block/CommandBlock.java
@@ -70,6 +_,15 @@
private void setPoweredAndUpdate(Level level, BlockPos pos, CommandBlockEntity blockEntity, boolean powered) {
boolean isPowered = blockEntity.isPowered();
+ // CraftBukkit start
+ org.bukkit.block.Block bukkitBlock = level.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ());
+ int old = isPowered ? 15 : 0;
+ int current = powered ? 15 : 0;
+
+ org.bukkit.event.block.BlockRedstoneEvent eventRedstone = new org.bukkit.event.block.BlockRedstoneEvent(bukkitBlock, old, current);
+ level.getCraftServer().getPluginManager().callEvent(eventRedstone);
+ powered = eventRedstone.getNewCurrent() > 0;
+ // CraftBukkit end
if (powered != isPowered) {
blockEntity.setPowered(powered);
if (powered) {
@@ -126,7 +_,7 @@
@Override
protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) {
BlockEntity blockEntity = level.getBlockEntity(pos);
- if (blockEntity instanceof CommandBlockEntity && player.canUseGameMasterBlocks()) {
+ if (blockEntity instanceof CommandBlockEntity && (player.canUseGameMasterBlocks() || (player.isCreative() && player.getBukkitEntity().hasPermission("minecraft.commandblock")))) { // Paper - command block permission
player.openCommandBlock((CommandBlockEntity)blockEntity);
return InteractionResult.SUCCESS;
} else {

View file

@ -0,0 +1,21 @@
--- a/net/minecraft/world/level/block/ComparatorBlock.java
+++ b/net/minecraft/world/level/block/ComparatorBlock.java
@@ -170,8 +_,18 @@
boolean shouldTurnOn = this.shouldTurnOn(level, pos, state);
boolean poweredValue = state.getValue(POWERED);
if (poweredValue && !shouldTurnOn) {
+ // CraftBukkit start
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, 15, 0).getNewCurrent() != 0) {
+ return;
+ }
+ // CraftBukkit end
level.setBlock(pos, state.setValue(POWERED, Boolean.valueOf(false)), 2);
} else if (!poweredValue && shouldTurnOn) {
+ // CraftBukkit start
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, 0, 15).getNewCurrent() != 15) {
+ return;
+ }
+ // CraftBukkit end
level.setBlock(pos, state.setValue(POWERED, Boolean.valueOf(true)), 2);
}

View file

@ -0,0 +1,148 @@
--- a/net/minecraft/world/level/block/ComposterBlock.java
+++ b/net/minecraft/world/level/block/ComposterBlock.java
@@ -243,6 +_,11 @@
if (levelValue < 8 && COMPOSTABLES.containsKey(stack.getItem())) {
if (levelValue < 7 && !level.isClientSide) {
BlockState blockState = addItem(player, state, level, pos, stack);
+ // Paper start - handle cancelled events
+ if (blockState == null) {
+ return InteractionResult.PASS;
+ }
+ // Paper end
level.levelEvent(1500, pos, state != blockState ? 1 : 0);
player.awardStat(Stats.ITEM_USED.get(stack.getItem()));
stack.consume(1, player);
@@ -268,7 +_,19 @@
public static BlockState insertItem(Entity entity, BlockState state, ServerLevel level, ItemStack stack, BlockPos pos) {
int levelValue = state.getValue(LEVEL);
if (levelValue < 7 && COMPOSTABLES.containsKey(stack.getItem())) {
- BlockState blockState = addItem(entity, state, level, pos, stack);
+ // CraftBukkit start
+ double rand = level.getRandom().nextDouble();
+ BlockState blockState = null; // Paper
+ if (false && (state == blockState || !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, pos, blockState))) { // Paper - move event call into addItem
+ return state;
+ }
+ blockState = ComposterBlock.addItem(entity, state, level, pos, stack, rand);
+ // Paper start - handle cancelled events
+ if (blockState == null) {
+ return state;
+ }
+ // Paper end
+ // CraftBukkit end
stack.shrink(1);
return blockState;
} else {
@@ -277,6 +_,14 @@
}
public static BlockState extractProduce(Entity entity, BlockState state, Level level, BlockPos pos) {
+ // CraftBukkit start
+ if (entity != null && !(entity instanceof Player)) {
+ BlockState iblockdata1 = ComposterBlock.empty(entity, state, org.bukkit.craftbukkit.util.DummyGeneratorAccess.INSTANCE, pos);
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, pos, iblockdata1)) {
+ return state;
+ }
+ }
+ // CraftBukkit end
if (!level.isClientSide) {
Vec3 vec3 = Vec3.atLowerCornerWithOffset(pos, 0.5, 1.01, 0.5).offsetRandom(level.random, 0.7F);
ItemEntity itemEntity = new ItemEntity(level, vec3.x(), vec3.y(), vec3.z(), new ItemStack(Items.BONE_MEAL));
@@ -296,14 +_,39 @@
return blockState;
}
+ @Nullable // Paper
static BlockState addItem(@Nullable Entity entity, BlockState state, LevelAccessor level, BlockPos pos, ItemStack stack) {
+ // CraftBukkit start
+ return ComposterBlock.addItem(entity, state, level, pos, stack, level.getRandom().nextDouble());
+ }
+ @Nullable // Paper - make it nullable
+ static BlockState addItem(@Nullable Entity entity, BlockState state, LevelAccessor level, BlockPos pos, ItemStack stack, double rand) {
int levelValue = state.getValue(LEVEL);
float _float = COMPOSTABLES.getFloat(stack.getItem());
- if ((levelValue != 0 || !(_float > 0.0F)) && !(level.getRandom().nextDouble() < _float)) {
+ // Paper start - Add CompostItemEvent and EntityCompostItemEvent
+ boolean willRaiseLevel = !((levelValue != 0 || _float <= 0.0F) && rand >= (double) _float);
+ final io.papermc.paper.event.block.CompostItemEvent event;
+ if (entity == null) {
+ event = new io.papermc.paper.event.block.CompostItemEvent(org.bukkit.craftbukkit.block.CraftBlock.at(level, pos), stack.getBukkitStack(), willRaiseLevel);
+ } else {
+ event = new io.papermc.paper.event.entity.EntityCompostItemEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos), stack.getBukkitStack(), willRaiseLevel);
+ }
+ if (!event.callEvent()) { // check for cancellation of entity event (non entity event can't be cancelled cause of hoppers)
+ return null;
+ }
+ willRaiseLevel = event.willRaiseLevel();
+
+ if (!willRaiseLevel) {
+ // Paper end - Add CompostItemEvent and EntityCompostItemEvent
return state;
} else {
int i = levelValue + 1;
BlockState blockState = state.setValue(LEVEL, Integer.valueOf(i));
+ // Paper start - move the EntityChangeBlockEvent here to avoid conflict later for the compost events
+ if (entity != null && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, pos, blockState)) {
+ return null;
+ }
+ // Paper end
level.setBlock(pos, blockState, 3);
level.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(entity, blockState));
if (i == 7) {
@@ -348,13 +_,14 @@
if (levelValue == 8) {
return new ComposterBlock.OutputContainer(state, level, pos, new ItemStack(Items.BONE_MEAL));
} else {
- return (WorldlyContainer)(levelValue < 7 ? new ComposterBlock.InputContainer(state, level, pos) : new ComposterBlock.EmptyContainer());
+ return (WorldlyContainer)(levelValue < 7 ? new ComposterBlock.InputContainer(state, level, pos) : new ComposterBlock.EmptyContainer(level, pos)); // CraftBukkit - empty generatoraccess, blockposition
}
}
public static class EmptyContainer extends SimpleContainer implements WorldlyContainer {
- public EmptyContainer() {
+ public EmptyContainer(LevelAccessor generatoraccess, BlockPos blockposition) { // CraftBukkit
super(0);
+ this.bukkitOwner = new org.bukkit.craftbukkit.inventory.CraftBlockInventoryHolder(generatoraccess, blockposition, this); // CraftBukkit
}
@Override
@@ -381,9 +_,11 @@
public InputContainer(BlockState state, LevelAccessor level, BlockPos pos) {
super(1);
+ this.bukkitOwner = new org.bukkit.craftbukkit.inventory.CraftBlockInventoryHolder(level, pos, this); // CraftBukkit
this.state = state;
this.level = level;
this.pos = pos;
+ this.bukkitOwner = new org.bukkit.craftbukkit.inventory.CraftBlockInventoryHolder(level, pos, this); // CraftBukkit
}
@Override
@@ -412,6 +_,11 @@
if (!item.isEmpty()) {
this.changed = true;
BlockState blockState = ComposterBlock.addItem(null, this.state, this.level, this.pos, item);
+ // Paper start - Add CompostItemEvent and EntityCompostItemEvent
+ if (blockState == null) {
+ return;
+ }
+ // Paper end - Add CompostItemEvent and EntityCompostItemEvent
this.level.levelEvent(1500, this.pos, blockState != this.state ? 1 : 0);
this.removeItemNoUpdate(0);
}
@@ -453,8 +_,15 @@
@Override
public void setChanged() {
+ // CraftBukkit start - allow putting items back (eg cancelled InventoryMoveItemEvent)
+ if (this.isEmpty()) {
ComposterBlock.empty(null, this.state, this.level, this.pos);
this.changed = true;
+ } else {
+ this.level.setBlock(this.pos, this.state, 3);
+ this.changed = false;
+ }
+ // CraftBukkit end
}
}
}

View file

@ -0,0 +1,66 @@
--- a/net/minecraft/world/level/block/ConcretePowderBlock.java
+++ b/net/minecraft/world/level/block/ConcretePowderBlock.java
@@ -38,7 +_,7 @@
@Override
public void onLand(Level level, BlockPos pos, BlockState state, BlockState replaceableState, FallingBlockEntity fallingBlock) {
if (shouldSolidify(level, pos, replaceableState)) {
- level.setBlock(pos, this.concrete.defaultBlockState(), 3);
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(level, pos, this.concrete.defaultBlockState(), 3); // CraftBukkit
}
}
@@ -47,7 +_,24 @@
BlockGetter level = context.getLevel();
BlockPos clickedPos = context.getClickedPos();
BlockState blockState = level.getBlockState(clickedPos);
- return shouldSolidify(level, clickedPos, blockState) ? this.concrete.defaultBlockState() : super.getStateForPlacement(context);
+ // CraftBukkit start
+ if (!ConcretePowderBlock.shouldSolidify(level, clickedPos, blockState)) {
+ return super.getStateForPlacement(context);
+ }
+
+ // TODO: An event factory call for methods like this
+ org.bukkit.craftbukkit.block.CraftBlockState craftBlockState = org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState((net.minecraft.world.level.LevelAccessor) level, clickedPos);
+ craftBlockState.setData(this.concrete.defaultBlockState());
+
+ org.bukkit.event.block.BlockFormEvent event = new org.bukkit.event.block.BlockFormEvent(craftBlockState.getBlock(), craftBlockState);
+ level.getServer().server.getPluginManager().callEvent(event);
+
+ if (!event.isCancelled()) {
+ return craftBlockState.getHandle();
+ }
+
+ return super.getStateForPlacement(context);
+ // CraftBukkit end
}
private static boolean shouldSolidify(BlockGetter level, BlockPos pos, BlockState state) {
@@ -88,9 +_,25 @@
BlockState neighborState,
RandomSource random
) {
- return touchesLiquid(level, pos)
- ? this.concrete.defaultBlockState()
- : super.updateShape(state, level, scheduledTickAccess, pos, direction, neighborPos, neighborState, random);
+ // CraftBukkit start
+ if (ConcretePowderBlock.touchesLiquid(level, pos)) {
+ // Suppress during worldgen
+ if (!(level instanceof Level world1)) {
+ return this.concrete.defaultBlockState();
+ }
+ org.bukkit.craftbukkit.block.CraftBlockState blockState = org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(world1, pos);
+ blockState.setData(this.concrete.defaultBlockState());
+
+ org.bukkit.event.block.BlockFormEvent event = new org.bukkit.event.block.BlockFormEvent(blockState.getBlock(), blockState);
+ world1.getCraftServer().getPluginManager().callEvent(event);
+
+ if (!event.isCancelled()) {
+ return blockState.getHandle();
+ }
+ }
+
+ return super.updateShape(state, level, scheduledTickAccess, pos, direction, neighborPos, neighborState, random);
+ // CraftBukkit end
}
@Override

View file

@ -1,14 +1,14 @@
--- a/net/minecraft/world/level/block/CoralBlock.java --- a/net/minecraft/world/level/block/CoralBlock.java
+++ b/net/minecraft/world/level/block/CoralBlock.java +++ b/net/minecraft/world/level/block/CoralBlock.java
@@ -40,6 +40,11 @@ @@ -37,6 +_,11 @@
@Override @Override
protected void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { protected void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) {
if (!this.scanForWater(world, pos)) { if (!this.scanForWater(level, pos)) {
+ // CraftBukkit start + // CraftBukkit start
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world, pos, this.deadBlock.defaultBlockState()).isCancelled()) { + if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(level, pos, this.deadBlock.defaultBlockState()).isCancelled()) {
+ return; + return;
+ } + }
+ // CraftBukkit end + // CraftBukkit end
world.setBlock(pos, this.deadBlock.defaultBlockState(), 2); level.setBlock(pos, this.deadBlock.defaultBlockState(), 2);
} }
}

View file

@ -1,14 +1,14 @@
--- a/net/minecraft/world/level/block/CoralFanBlock.java --- a/net/minecraft/world/level/block/CoralFanBlock.java
+++ b/net/minecraft/world/level/block/CoralFanBlock.java +++ b/net/minecraft/world/level/block/CoralFanBlock.java
@@ -41,6 +41,11 @@ @@ -38,6 +_,11 @@
@Override @Override
protected void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { protected void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) {
if (!scanForWater(state, world, pos)) { if (!scanForWater(state, level, pos)) {
+ // CraftBukkit start + // CraftBukkit start
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world, pos, this.deadBlock.defaultBlockState().setValue(CoralFanBlock.WATERLOGGED, false)).isCancelled()) { + if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(level, pos, this.deadBlock.defaultBlockState().setValue(CoralFanBlock.WATERLOGGED, false)).isCancelled()) {
+ return; + return;
+ } + }
+ // CraftBukkit end + // CraftBukkit end
world.setBlock(pos, (BlockState) this.deadBlock.defaultBlockState().setValue(CoralFanBlock.WATERLOGGED, false), 2); level.setBlock(pos, this.deadBlock.defaultBlockState().setValue(WATERLOGGED, Boolean.valueOf(false)), 2);
} }
}

View file

@ -1,14 +1,14 @@
--- a/net/minecraft/world/level/block/CoralPlantBlock.java --- a/net/minecraft/world/level/block/CoralPlantBlock.java
+++ b/net/minecraft/world/level/block/CoralPlantBlock.java +++ b/net/minecraft/world/level/block/CoralPlantBlock.java
@@ -46,6 +46,11 @@ @@ -43,6 +_,11 @@
@Override @Override
protected void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { protected void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) {
if (!scanForWater(state, world, pos)) { if (!scanForWater(state, level, pos)) {
+ // CraftBukkit start + // CraftBukkit start
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world, pos, this.deadBlock.defaultBlockState().setValue(CoralPlantBlock.WATERLOGGED, false)).isCancelled()) { + if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(level, pos, this.deadBlock.defaultBlockState().setValue(CoralPlantBlock.WATERLOGGED, false)).isCancelled()) {
+ return; + return;
+ } + }
+ // CraftBukkit end + // CraftBukkit end
world.setBlock(pos, (BlockState) this.deadBlock.defaultBlockState().setValue(CoralPlantBlock.WATERLOGGED, false), 2); level.setBlock(pos, this.deadBlock.defaultBlockState().setValue(WATERLOGGED, Boolean.valueOf(false)), 2);
} }
}

View file

@ -1,14 +1,14 @@
--- a/net/minecraft/world/level/block/CoralWallFanBlock.java --- a/net/minecraft/world/level/block/CoralWallFanBlock.java
+++ b/net/minecraft/world/level/block/CoralWallFanBlock.java +++ b/net/minecraft/world/level/block/CoralWallFanBlock.java
@@ -41,6 +41,11 @@ @@ -38,6 +_,11 @@
@Override @Override
protected void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { protected void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) {
if (!scanForWater(state, world, pos)) { if (!scanForWater(state, level, pos)) {
+ // CraftBukkit start + // CraftBukkit start
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world, pos, this.deadBlock.defaultBlockState().setValue(CoralWallFanBlock.WATERLOGGED, false).setValue(CoralWallFanBlock.FACING, state.getValue(CoralWallFanBlock.FACING))).isCancelled()) { + if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(level, pos, this.deadBlock.defaultBlockState().setValue(CoralWallFanBlock.WATERLOGGED, false).setValue(CoralWallFanBlock.FACING, state.getValue(CoralWallFanBlock.FACING))).isCancelled()) {
+ return; + return;
+ } + }
+ // CraftBukkit end + // CraftBukkit end
world.setBlock(pos, (BlockState) ((BlockState) this.deadBlock.defaultBlockState().setValue(CoralWallFanBlock.WATERLOGGED, false)).setValue(CoralWallFanBlock.FACING, (Direction) state.getValue(CoralWallFanBlock.FACING)), 2); level.setBlock(pos, this.deadBlock.defaultBlockState().setValue(WATERLOGGED, Boolean.valueOf(false)).setValue(FACING, state.getValue(FACING)), 2);
} }
}

View file

@ -0,0 +1,76 @@
--- a/net/minecraft/world/level/block/CrafterBlock.java
+++ b/net/minecraft/world/level/block/CrafterBlock.java
@@ -11,6 +_,7 @@
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.util.RandomSource;
+import net.minecraft.world.CompoundContainer;
import net.minecraft.world.Container;
import net.minecraft.world.Containers;
import net.minecraft.world.InteractionResult;
@@ -159,6 +_,13 @@
} else {
RecipeHolder<CraftingRecipe> recipeHolder = potentialResults.get();
ItemStack itemStack = recipeHolder.value().assemble(var11, level.registryAccess());
+ // CraftBukkit start
+ org.bukkit.event.block.CrafterCraftEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callCrafterCraftEvent(pos, level, crafterBlockEntity, itemStack, recipeHolder);
+ if (event.isCancelled()) {
+ return;
+ }
+ itemStack = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getResult());
+ // CraftBukkit end
if (itemStack.isEmpty()) {
level.levelEvent(1050, pos, 0);
} else {
@@ -193,7 +_,25 @@
Container containerAt = HopperBlockEntity.getContainerAt(level, pos.relative(direction));
ItemStack itemStack = stack.copy();
if (containerAt != null && (containerAt instanceof CrafterBlockEntity || stack.getCount() > containerAt.getMaxStackSize(stack))) {
+ // CraftBukkit start - InventoryMoveItemEvent
+ org.bukkit.craftbukkit.inventory.CraftItemStack oitemstack = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack);
+
+ org.bukkit.inventory.Inventory destinationInventory;
+ // Have to special case large chests as they work oddly
+ if (containerAt instanceof CompoundContainer) {
+ destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((CompoundContainer) containerAt);
+ } else {
+ destinationInventory = containerAt.getOwner().getInventory();
+ }
+
+ org.bukkit.event.inventory.InventoryMoveItemEvent event = new org.bukkit.event.inventory.InventoryMoveItemEvent(crafter.getOwner().getInventory(), oitemstack, destinationInventory, true);
+ level.getCraftServer().getPluginManager().callEvent(event);
+ itemStack = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getItem());
while (!itemStack.isEmpty()) {
+ if (event.isCancelled()) {
+ break;
+ }
+ // CraftBukkit end
ItemStack itemStack1 = itemStack.copyWithCount(1);
ItemStack itemStack2 = HopperBlockEntity.addItem(crafter, containerAt, itemStack1, direction.getOpposite());
if (!itemStack2.isEmpty()) {
@@ -203,7 +_,25 @@
itemStack.shrink(1);
}
} else if (containerAt != null) {
+ // CraftBukkit start - InventoryMoveItemEvent
+ org.bukkit.craftbukkit.inventory.CraftItemStack oitemstack = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack);
+
+ org.bukkit.inventory.Inventory destinationInventory;
+ // Have to special case large chests as they work oddly
+ if (containerAt instanceof CompoundContainer) {
+ destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((CompoundContainer) containerAt);
+ } else {
+ destinationInventory = containerAt.getOwner().getInventory();
+ }
+
+ org.bukkit.event.inventory.InventoryMoveItemEvent event = new org.bukkit.event.inventory.InventoryMoveItemEvent(crafter.getOwner().getInventory(), oitemstack, destinationInventory, true);
+ level.getCraftServer().getPluginManager().callEvent(event);
+ itemStack = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getItem());
while (!itemStack.isEmpty()) {
+ if (event.isCancelled()) {
+ break;
+ }
+ // CraftBukkit end
int count = itemStack.getCount();
itemStack = HopperBlockEntity.addItem(crafter, containerAt, itemStack, direction.getOpposite());
if (count == itemStack.getCount()) {

View file

@ -1,11 +1,10 @@
--- a/net/minecraft/world/level/block/CraftingTableBlock.java --- a/net/minecraft/world/level/block/CraftingTableBlock.java
+++ b/net/minecraft/world/level/block/CraftingTableBlock.java +++ b/net/minecraft/world/level/block/CraftingTableBlock.java
@@ -31,8 +31,9 @@ @@ -32,7 +_,9 @@
@Override protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) {
protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { if (!level.isClientSide) {
if (!world.isClientSide) { player.openMenu(state.getMenuProvider(level, pos));
- player.openMenu(state.getMenuProvider(world, pos)); + if (player.openMenu(state.getMenuProvider(level, pos)).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation
+ if (player.openMenu(state.getMenuProvider(world, pos)).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation
player.awardStat(Stats.INTERACT_WITH_CRAFTING_TABLE); player.awardStat(Stats.INTERACT_WITH_CRAFTING_TABLE);
+ } // Paper - Fix InventoryOpenEvent cancellation + } // Paper - Fix InventoryOpenEvent cancellation
} }

View file

@ -0,0 +1,49 @@
--- a/net/minecraft/world/level/block/CropBlock.java
+++ b/net/minecraft/world/level/block/CropBlock.java
@@ -88,8 +_,25 @@
int age = this.getAge(state);
if (age < this.getMaxAge()) {
float growthSpeed = getGrowthSpeed(this, level, pos);
- if (random.nextInt((int)(25.0F / growthSpeed) + 1) == 0) {
- level.setBlock(pos, this.getStateForAge(age + 1), 2);
+ // Spigot start
+ int modifier;
+ if (this == Blocks.BEETROOTS) {
+ modifier = level.spigotConfig.beetrootModifier;
+ } else if (this == Blocks.CARROTS) {
+ modifier = level.spigotConfig.carrotModifier;
+ } else if (this == Blocks.POTATOES) {
+ modifier = level.spigotConfig.potatoModifier;
+ // Paper start - Fix Spigot growth modifiers
+ } else if (this == Blocks.TORCHFLOWER_CROP) {
+ modifier = level.spigotConfig.torchFlowerModifier;
+ // Paper end - Fix Spigot growth modifiers
+ } else {
+ modifier = level.spigotConfig.wheatModifier;
+ }
+
+ if (random.nextFloat() < (modifier / (100.0f * (Math.floor((25.0F / growthSpeed) + 1))))) { // Spigot - SPIGOT-7159: Better modifier resolution
+ // Spigot end
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, pos, this.getStateForAge(age + 1), 2); // CraftBukkit
}
}
}
@@ -102,7 +_,7 @@
i = maxAge;
}
- level.setBlock(pos, this.getStateForAge(i), 2);
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, pos, this.getStateForAge(i), 2); // CraftBukkit
}
protected int getBonemealAgeIncrease(Level level) {
@@ -164,7 +_,8 @@
@Override
protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) {
- if (level instanceof ServerLevel serverLevel && entity instanceof Ravager && serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
+ 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 && entity instanceof Ravager && org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.AIR.defaultBlockState(), !serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit
serverLevel.destroyBlock(pos, true, entity);
}

View file

@ -0,0 +1,10 @@
--- a/net/minecraft/world/level/block/DaylightDetectorBlock.java
+++ b/net/minecraft/world/level/block/DaylightDetectorBlock.java
@@ -70,6 +_,7 @@
i = Mth.clamp(i, 0, 15);
if (state.getValue(POWER) != i) {
+ i = org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, state.getValue(DaylightDetectorBlock.POWER), i).getNewCurrent(); // CraftBukkit - Call BlockRedstoneEvent
level.setBlock(pos, state.setValue(POWER, Integer.valueOf(i)), 3);
}
}

View file

@ -0,0 +1,14 @@
--- a/net/minecraft/world/level/block/DecoratedPotBlock.java
+++ b/net/minecraft/world/level/block/DecoratedPotBlock.java
@@ -237,6 +_,11 @@
protected void onProjectileHit(Level level, BlockState state, BlockHitResult hit, Projectile projectile) {
BlockPos blockPos = hit.getBlockPos();
if (level instanceof ServerLevel serverLevel && projectile.mayInteract(serverLevel, blockPos) && projectile.mayBreak(serverLevel)) {
+ // CraftBukkit start - call EntityChangeBlockEvent
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(projectile, blockPos, this.getFluidState(state).createLegacyBlock())) {
+ return;
+ }
+ // CraftBukkit end
level.setBlock(blockPos, state.setValue(CRACKED, Boolean.valueOf(true)), 4);
level.destroyBlock(blockPos, true, projectile);
}

View file

@ -0,0 +1,35 @@
--- a/net/minecraft/world/level/block/DetectorRailBlock.java
+++ b/net/minecraft/world/level/block/DetectorRailBlock.java
@@ -54,6 +_,7 @@
@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.isClientSide) {
if (!state.getValue(POWERED)) {
this.checkPressed(level, pos, state);
@@ -84,6 +_,7 @@
private void checkPressed(Level level, BlockPos pos, BlockState state) {
if (this.canSurvive(state, level, pos)) {
+ if (state.getBlock() != this) { return; } // Paper - Fix some rails connecting improperly
boolean poweredValue = state.getValue(POWERED);
boolean flag = false;
List<AbstractMinecart> interactingMinecartOfType = this.getInteractingMinecartOfType(level, pos, AbstractMinecart.class, entity -> true);
@@ -91,6 +_,16 @@
flag = true;
}
+ // CraftBukkit start
+ if (poweredValue != flag) {
+ org.bukkit.block.Block block = level.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ());
+
+ org.bukkit.event.block.BlockRedstoneEvent eventRedstone = new org.bukkit.event.block.BlockRedstoneEvent(block, flag ? 15 : 0, flag ? 15 : 0);
+ level.getCraftServer().getPluginManager().callEvent(eventRedstone);
+
+ flag = eventRedstone.getNewCurrent() > 0;
+ }
+ // CraftBukkit end
if (flag && !poweredValue) {
BlockState blockState = state.setValue(POWERED, Boolean.valueOf(true));
level.setBlock(pos, blockState, 3);

View file

@ -0,0 +1,21 @@
--- a/net/minecraft/world/level/block/DiodeBlock.java
+++ b/net/minecraft/world/level/block/DiodeBlock.java
@@ -56,8 +_,18 @@
boolean poweredValue = state.getValue(POWERED);
boolean shouldTurnOn = this.shouldTurnOn(level, pos, state);
if (poweredValue && !shouldTurnOn) {
+ // CraftBukkit start
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, 15, 0).getNewCurrent() != 0) {
+ return;
+ }
+ // CraftBukkit end
level.setBlock(pos, state.setValue(POWERED, Boolean.valueOf(false)), 2);
} else if (!poweredValue) {
+ // CraftBukkit start
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, 0, 15).getNewCurrent() != 15) {
+ return;
+ }
+ // CraftBukkit end
level.setBlock(pos, state.setValue(POWERED, Boolean.valueOf(true)), 2);
if (!shouldTurnOn) {
level.scheduleTick(pos, this, this.getDelay(state), TickPriority.VERY_HIGH);

View file

@ -1,14 +1,14 @@
--- a/net/minecraft/world/level/block/DirtPathBlock.java --- a/net/minecraft/world/level/block/DirtPathBlock.java
+++ b/net/minecraft/world/level/block/DirtPathBlock.java +++ b/net/minecraft/world/level/block/DirtPathBlock.java
@@ -51,6 +51,11 @@ @@ -60,6 +_,11 @@
@Override @Override
protected void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { protected void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) {
+ // CraftBukkit start - do not fade if the block is valid here + // CraftBukkit start - do not fade if the block is valid here
+ if (state.canSurvive(world, pos)) { + if (state.canSurvive(level, pos)) {
+ return; + return;
+ } + }
+ // CraftBukkit end + // CraftBukkit end
FarmBlock.turnToDirt((Entity) null, state, world, pos); FarmBlock.turnToDirt(null, state, level, pos);
} }

View file

@ -0,0 +1,47 @@
--- a/net/minecraft/world/level/block/DispenserBlock.java
+++ b/net/minecraft/world/level/block/DispenserBlock.java
@@ -50,6 +_,7 @@
private static final DefaultDispenseItemBehavior DEFAULT_BEHAVIOR = new DefaultDispenseItemBehavior();
public static final Map<Item, DispenseItemBehavior> DISPENSER_REGISTRY = new IdentityHashMap<>();
private static final int TRIGGER_DURATION = 4;
+ public static boolean eventFired = false; // CraftBukkit
@Override
public MapCodec<? extends DispenserBlock> codec() {
@@ -71,8 +_,7 @@
@Override
protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) {
- if (!level.isClientSide && level.getBlockEntity(pos) instanceof DispenserBlockEntity dispenserBlockEntity) {
- player.openMenu(dispenserBlockEntity);
+ if (!level.isClientSide && level.getBlockEntity(pos) instanceof DispenserBlockEntity dispenserBlockEntity && player.openMenu(dispenserBlockEntity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation
player.awardStat(dispenserBlockEntity instanceof DropperBlockEntity ? Stats.INSPECT_DROPPER : Stats.INSPECT_DISPENSER);
}
@@ -87,18 +_,26 @@
BlockSource blockSource = new BlockSource(level, pos, state, dispenserBlockEntity);
int randomSlot = dispenserBlockEntity.getRandomSlot(level.random);
if (randomSlot < 0) {
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFailedDispenseEvent(level, pos)) { // Paper - Add BlockFailedDispenseEvent
level.levelEvent(1001, pos, 0);
level.gameEvent(GameEvent.BLOCK_ACTIVATE, pos, GameEvent.Context.of(dispenserBlockEntity.getBlockState()));
+ } // Paper - Add BlockFailedDispenseEvent
} else {
ItemStack item = dispenserBlockEntity.getItem(randomSlot);
DispenseItemBehavior dispenseMethod = this.getDispenseMethod(level, item);
if (dispenseMethod != DispenseItemBehavior.NOOP) {
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockPreDispenseEvent(level, pos, item, randomSlot)) return; // Paper - Add BlockPreDispenseEvent
dispenserBlockEntity.setItem(randomSlot, dispenseMethod.dispense(blockSource, item));
}
}
}
}
+ // Paper start - Fix NPE with equippable and items without behavior
+ public static DispenseItemBehavior getDispenseBehavior(BlockSource pointer, ItemStack stack) {
+ return ((DispenserBlock) pointer.state().getBlock()).getDispenseMethod(pointer.level(), stack);
+ }
+ // Paper end - Fix NPE with equippable and items without behavior
protected DispenseItemBehavior getDispenseMethod(Level level, ItemStack item) {
if (!item.isItemEnabled(level.enabledFeatures())) {
return DEFAULT_BEHAVIOR;

View file

@ -0,0 +1,29 @@
--- a/net/minecraft/world/level/block/DoorBlock.java
+++ b/net/minecraft/world/level/block/DoorBlock.java
@@ -229,9 +_,23 @@
@Override
protected void neighborChanged(BlockState state, Level level, BlockPos pos, Block neighborBlock, @Nullable Orientation orientation, boolean movedByPiston) {
- boolean flag = level.hasNeighborSignal(pos)
- || level.hasNeighborSignal(pos.relative(state.getValue(HALF) == DoubleBlockHalf.LOWER ? Direction.UP : Direction.DOWN));
- if (!this.defaultBlockState().is(neighborBlock) && flag != state.getValue(POWERED)) {
+ // CraftBukkit start
+ BlockPos otherHalf = pos.relative(state.getValue(DoorBlock.HALF) == DoubleBlockHalf.LOWER ? Direction.UP : Direction.DOWN);
+ org.bukkit.World bworld = level.getWorld();
+ org.bukkit.block.Block bukkitBlock = bworld.getBlockAt(pos.getX(), pos.getY(), pos.getZ());
+ org.bukkit.block.Block blockTop = bworld.getBlockAt(otherHalf.getX(), otherHalf.getY(), otherHalf.getZ());
+
+ int power = bukkitBlock.getBlockPower();
+ int powerTop = blockTop.getBlockPower();
+ if (powerTop > power) power = powerTop;
+ int oldPower = (Boolean) state.getValue(DoorBlock.POWERED) ? 15 : 0;
+
+ if (oldPower == 0 ^ power == 0) {
+ org.bukkit.event.block.BlockRedstoneEvent eventRedstone = new org.bukkit.event.block.BlockRedstoneEvent(bukkitBlock, oldPower, power);
+ level.getCraftServer().getPluginManager().callEvent(eventRedstone);
+
+ boolean flag = eventRedstone.getNewCurrent() > 0;
+ // CraftBukkit end
if (flag != state.getValue(OPEN)) {
this.playSound(null, level, pos, flag);
level.gameEvent(null, flag ? GameEvent.BLOCK_OPEN : GameEvent.BLOCK_CLOSE, pos);

View file

@ -1,16 +1,16 @@
--- a/net/minecraft/world/level/block/DoubleBlockCombiner.java --- a/net/minecraft/world/level/block/DoubleBlockCombiner.java
+++ b/net/minecraft/world/level/block/DoubleBlockCombiner.java +++ b/net/minecraft/world/level/block/DoubleBlockCombiner.java
@@ -34,7 +34,12 @@ @@ -34,7 +_,12 @@
return new DoubleBlockCombiner.NeighborCombineResult.Single<>(blockEntity); return new DoubleBlockCombiner.NeighborCombineResult.Single<>(blockEntity);
} else { } else {
BlockPos blockPos = pos.relative(directionMapper.apply(state)); BlockPos blockPos = pos.relative(directionGetter.apply(state));
- BlockState blockState = world.getBlockState(blockPos); - BlockState blockState = level.getBlockState(blockPos);
+ // Paper start - Don't load Chunks from Hoppers and other things + // Paper start - Don't load Chunks from Hoppers and other things
+ BlockState blockState = world.getBlockStateIfLoaded(blockPos); + BlockState blockState = level.getBlockStateIfLoaded(blockPos);
+ if (blockState == null) { + if (blockState == null) {
+ return new DoubleBlockCombiner.NeighborCombineResult.Single<>(blockEntity); + return new DoubleBlockCombiner.NeighborCombineResult.Single<>(blockEntity);
+ } + }
+ // Paper end - Don't load Chunks from Hoppers and other things + // Paper end - Don't load Chunks from Hoppers and other things
if (blockState.is(state.getBlock())) { if (blockState.is(state.getBlock())) {
DoubleBlockCombiner.BlockType blockType2 = typeMapper.apply(blockState); DoubleBlockCombiner.BlockType blockType1 = doubleBlockTypeGetter.apply(blockState);
if (blockType2 != DoubleBlockCombiner.BlockType.SINGLE if (blockType1 != DoubleBlockCombiner.BlockType.SINGLE

View file

@ -0,0 +1,21 @@
--- a/net/minecraft/world/level/block/DoublePlantBlock.java
+++ b/net/minecraft/world/level/block/DoublePlantBlock.java
@@ -112,11 +_,16 @@
}
@Override
- public void playerDestroy(Level level, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity te, ItemStack stack) {
- super.playerDestroy(level, player, pos, Blocks.AIR.defaultBlockState(), 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, Blocks.AIR.defaultBlockState(), te, stack, includeDrops, dropExp); // Paper - fix drops not preventing stats/food exhaustion;
}
protected static void preventDropFromBottomPart(Level level, BlockPos pos, BlockState state, Player player) {
+ // CraftBukkit start
+ if (((net.minecraft.server.level.ServerLevel)level).hasPhysicsEvent && org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPhysicsEvent(level, pos).isCancelled()) { // Paper
+ return;
+ }
+ // CraftBukkit end
DoubleBlockHalf doubleBlockHalf = state.getValue(HALF);
if (doubleBlockHalf == DoubleBlockHalf.UPPER) {
BlockPos blockPos = pos.below();

View file

@ -0,0 +1,21 @@
--- a/net/minecraft/world/level/block/DragonEggBlock.java
+++ b/net/minecraft/world/level/block/DragonEggBlock.java
@@ -55,6 +_,18 @@
level.random.nextInt(16) - level.random.nextInt(16)
);
if (level.getBlockState(blockPos).isAir() && worldBorder.isWithinBounds(blockPos)) {
+ // CraftBukkit start
+ org.bukkit.block.Block from = level.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ());
+ org.bukkit.block.Block to = level.getWorld().getBlockAt(blockPos.getX(), blockPos.getY(), blockPos.getZ());
+ org.bukkit.event.block.BlockFromToEvent event = new org.bukkit.event.block.BlockFromToEvent(from, to);
+ org.bukkit.Bukkit.getPluginManager().callEvent(event);
+
+ if (event.isCancelled()) {
+ return;
+ }
+
+ blockPos = new BlockPos(event.getToBlock().getX(), event.getToBlock().getY(), event.getToBlock().getZ());
+ // CraftBukkit end
if (level.isClientSide) {
for (int i1 = 0; i1 < 128; i1++) {
double randomDouble = level.random.nextDouble();

View file

@ -1,11 +1,12 @@
--- a/net/minecraft/world/level/block/DropExperienceBlock.java --- a/net/minecraft/world/level/block/DropExperienceBlock.java
+++ b/net/minecraft/world/level/block/DropExperienceBlock.java +++ b/net/minecraft/world/level/block/DropExperienceBlock.java
@@ -31,9 +31,16 @@ @@ -31,8 +_,16 @@
@Override @Override
protected void spawnAfterBreak(BlockState state, ServerLevel world, BlockPos pos, ItemStack tool, boolean dropExperience) { protected void spawnAfterBreak(BlockState state, ServerLevel level, BlockPos pos, ItemStack stack, boolean dropExperience) {
super.spawnAfterBreak(state, world, pos, tool, dropExperience); super.spawnAfterBreak(state, level, pos, stack, dropExperience);
- if (dropExperience) { - if (dropExperience) {
- this.tryDropExperience(world, pos, tool, this.xpRange); - this.tryDropExperience(level, pos, stack, this.xpRange);
- }
+ // CraftBukkit start - Delegate to getExpDrop + // CraftBukkit start - Delegate to getExpDrop
+ } + }
+ +
@ -13,8 +14,8 @@
+ public int getExpDrop(BlockState iblockdata, ServerLevel worldserver, BlockPos blockposition, ItemStack itemstack, boolean flag) { + public int getExpDrop(BlockState iblockdata, ServerLevel worldserver, BlockPos blockposition, ItemStack itemstack, boolean flag) {
+ if (flag) { + if (flag) {
+ return this.tryDropExperience(worldserver, blockposition, itemstack, this.xpRange); + return this.tryDropExperience(worldserver, blockposition, itemstack, this.xpRange);
} + }
+
+ return 0; + return 0;
+ // CraftBukkit end + // CraftBukkit end
} }

View file

@ -0,0 +1,59 @@
--- a/net/minecraft/world/level/block/DropperBlock.java
+++ b/net/minecraft/world/level/block/DropperBlock.java
@@ -8,6 +_,7 @@
import net.minecraft.core.dispenser.DefaultDispenseItemBehavior;
import net.minecraft.core.dispenser.DispenseItemBehavior;
import net.minecraft.server.level.ServerLevel;
+import net.minecraft.world.CompoundContainer;
import net.minecraft.world.Container;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
@@ -23,7 +_,7 @@
public class DropperBlock extends DispenserBlock {
private static final Logger LOGGER = LogUtils.getLogger();
public static final MapCodec<DropperBlock> CODEC = simpleCodec(DropperBlock::new);
- private static final DispenseItemBehavior DISPENSE_BEHAVIOUR = new DefaultDispenseItemBehavior();
+ private static final DispenseItemBehavior DISPENSE_BEHAVIOUR = new DefaultDispenseItemBehavior(true); // CraftBukkit
@Override
public MapCodec<DropperBlock> codec() {
@@ -53,6 +_,7 @@
BlockSource blockSource = new BlockSource(level, pos, state, dispenserBlockEntity);
int randomSlot = dispenserBlockEntity.getRandomSlot(level.random);
if (randomSlot < 0) {
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFailedDispenseEvent(level, pos)) // Paper - Add BlockFailedDispenseEvent
level.levelEvent(1001, pos, 0);
} else {
ItemStack item = dispenserBlockEntity.getItem(randomSlot);
@@ -61,10 +_,29 @@
Container containerAt = HopperBlockEntity.getContainerAt(level, pos.relative(direction));
ItemStack itemStack;
if (containerAt == null) {
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockPreDispenseEvent(level, pos, item, randomSlot)) return; // Paper - Add BlockPreDispenseEvent
itemStack = DISPENSE_BEHAVIOUR.dispense(blockSource, item);
} else {
- itemStack = HopperBlockEntity.addItem(dispenserBlockEntity, containerAt, item.copyWithCount(1), direction.getOpposite());
- if (itemStack.isEmpty()) {
+ // CraftBukkit start - Fire event when pushing items into other inventories
+ org.bukkit.craftbukkit.inventory.CraftItemStack oitemstack = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(item.copyWithCount(1));
+
+ org.bukkit.inventory.Inventory destinationInventory;
+ // Have to special case large chests as they work oddly
+ if (containerAt instanceof CompoundContainer) {
+ destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((CompoundContainer) containerAt);
+ } else {
+ destinationInventory = containerAt.getOwner().getInventory();
+ }
+
+ org.bukkit.event.inventory.InventoryMoveItemEvent event = new org.bukkit.event.inventory.InventoryMoveItemEvent(containerAt.getOwner().getInventory(), oitemstack, destinationInventory, true);
+ level.getCraftServer().getPluginManager().callEvent(event);
+ if (event.isCancelled()) {
+ return;
+ }
+ itemStack = HopperBlockEntity.addItem(dispenserBlockEntity, containerAt, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getItem()), direction.getOpposite());
+ if (event.getItem().equals(oitemstack) && itemStack.isEmpty()) {
+ // CraftBukkit end
+
itemStack = item.copy();
itemStack.shrink(1);
} else {

View file

@ -0,0 +1,30 @@
--- a/net/minecraft/world/level/block/EndGatewayBlock.java
+++ b/net/minecraft/world/level/block/EndGatewayBlock.java
@@ -89,10 +_,15 @@
@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.canUsePortal(false)
&& !level.isClientSide
&& level.getBlockEntity(pos) instanceof TheEndGatewayBlockEntity theEndGatewayBlockEntity
&& !theEndGatewayBlockEntity.isCoolingDown()) {
+ // Paper start - call EntityPortalEnterEvent
+ org.bukkit.event.entity.EntityPortalEnterEvent event = new org.bukkit.event.entity.EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(level.getWorld(), pos.getX(), pos.getY(), pos.getZ()), org.bukkit.PortalType.END_GATEWAY); // Paper - add portal type
+ if (!event.callEvent()) return;
+ // Paper end - call EntityPortalEnterEvent
entity.setAsInsidePortal(this, pos);
TheEndGatewayBlockEntity.triggerCooldown(level, pos, state, theEndGatewayBlockEntity);
}
@@ -107,9 +_,9 @@
return null;
} else {
return entity instanceof ThrownEnderpearl
- ? new TeleportTransition(level, portalPosition, Vec3.ZERO, 0.0F, 0.0F, Set.of(), TeleportTransition.PLACE_PORTAL_TICKET)
+ ? new TeleportTransition(level, portalPosition, Vec3.ZERO, 0.0F, 0.0F, Set.of(), TeleportTransition.PLACE_PORTAL_TICKET, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.END_GATEWAY) // CraftBukkit
: new TeleportTransition(
- level, portalPosition, Vec3.ZERO, 0.0F, 0.0F, Relative.union(Relative.DELTA, Relative.ROTATION), TeleportTransition.PLACE_PORTAL_TICKET
+ level, portalPosition, Vec3.ZERO, 0.0F, 0.0F, Relative.union(Relative.DELTA, Relative.ROTATION), TeleportTransition.PLACE_PORTAL_TICKET, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.END_GATEWAY // CraftBukkit
);
}
} else {

View file

@ -0,0 +1,62 @@
--- a/net/minecraft/world/level/block/EndPortalBlock.java
+++ b/net/minecraft/world/level/block/EndPortalBlock.java
@@ -56,8 +_,15 @@
@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.canUsePortal(false)) {
+ // CraftBukkit start - Entity in portal
+ org.bukkit.event.entity.EntityPortalEnterEvent event = new org.bukkit.event.entity.EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(level.getWorld(), pos.getX(), pos.getY(), pos.getZ()), org.bukkit.PortalType.ENDER); // Paper - add portal type
+ level.getCraftServer().getPluginManager().callEvent(event);
+ if (event.isCancelled()) return; // Paper - make cancellable
+ // CraftBukkit end
if (!level.isClientSide && level.dimension() == Level.END && entity instanceof ServerPlayer serverPlayer && !serverPlayer.seenCredits) {
+ if (level.paperConfig().misc.disableEndCredits) {serverPlayer.seenCredits = true; return;} // Paper - Option to disable end credits
serverPlayer.showEndCredits();
} else {
entity.setAsInsidePortal(this, pos);
@@ -67,7 +_,7 @@
@Override
public TeleportTransition getPortalDestination(ServerLevel level, Entity entity, BlockPos pos) {
- ResourceKey<Level> resourceKey = level.dimension() == Level.END ? Level.OVERWORLD : Level.END;
+ ResourceKey<Level> resourceKey = level.getTypeKey() == net.minecraft.world.level.dimension.LevelStem.END ? Level.OVERWORLD : Level.END; // CraftBukkit - SPIGOT-6152: send back to main overworld in custom ends
ServerLevel level1 = level.getServer().getLevel(resourceKey);
if (level1 == null) {
return null;
@@ -78,7 +_,7 @@
float f;
Set<Relative> set;
if (flag) {
- EndPlatformFeature.createEndPlatform(level1, BlockPos.containing(bottomCenter).below(), true);
+ EndPlatformFeature.createEndPlatform(level1, BlockPos.containing(bottomCenter).below(), true, entity); // CraftBukkit
f = Direction.WEST.toYRot();
set = Relative.union(Relative.DELTA, Set.of(Relative.X_ROT));
if (entity instanceof ServerPlayer) {
@@ -88,15 +_,21 @@
f = 0.0F;
set = Relative.union(Relative.DELTA, Relative.ROTATION);
if (entity instanceof ServerPlayer serverPlayer) {
- return serverPlayer.findRespawnPositionAndUseSpawnBlock(false, TeleportTransition.DO_NOTHING);
+ return serverPlayer.findRespawnPositionAndUseSpawnBlock(false, TeleportTransition.DO_NOTHING, org.bukkit.event.player.PlayerRespawnEvent.RespawnReason.END_PORTAL); // CraftBukkit
}
bottomCenter = entity.adjustSpawnLocation(level1, blockPos).getBottomCenter();
}
- return new TeleportTransition(
- level1, bottomCenter, Vec3.ZERO, f, 0.0F, set, TeleportTransition.PLAY_PORTAL_SOUND.then(TeleportTransition.PLACE_PORTAL_TICKET)
- );
+ // CraftBukkit start
+ org.bukkit.craftbukkit.event.CraftPortalEvent event = entity.callPortalEvent(entity, org.bukkit.craftbukkit.util.CraftLocation.toBukkit(bottomCenter, level1.getWorld(), f, entity.getXRot()), org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.END_PORTAL, 0, 0);
+ if (event == null) {
+ return null;
+ }
+ org.bukkit.Location to = event.getTo();
+
+ return new TeleportTransition(((org.bukkit.craftbukkit.CraftWorld) to.getWorld()).getHandle(), org.bukkit.craftbukkit.util.CraftLocation.toVec3D(to), entity.getDeltaMovement(), to.getYaw(), to.getPitch(), set, TeleportTransition.PLAY_PORTAL_SOUND.then(TeleportTransition.PLACE_PORTAL_TICKET), org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.END_PORTAL);
+ // CraftBukkit end
}
}

View file

@ -0,0 +1,26 @@
--- a/net/minecraft/world/level/block/EnderChestBlock.java
+++ b/net/minecraft/world/level/block/EnderChestBlock.java
@@ -78,16 +_,15 @@
PlayerEnderChestContainer enderChestInventory = player.getEnderChestInventory();
if (enderChestInventory != null && level.getBlockEntity(pos) instanceof EnderChestBlockEntity enderChestBlockEntity) {
BlockPos blockPos = pos.above();
- if (level.getBlockState(blockPos).isRedstoneConductor(level, blockPos)) {
+ if (level.getBlockState(blockPos).isRedstoneConductor(level, blockPos)) { // Paper - diff on change; make sure that EnderChest#isBlocked uses the same logic
return InteractionResult.SUCCESS;
} else {
- if (level instanceof ServerLevel serverLevel) {
- enderChestInventory.setActiveChest(enderChestBlockEntity);
- player.openMenu(
- new SimpleMenuProvider(
- (containerId, playerInventory, player1) -> ChestMenu.threeRows(containerId, playerInventory, enderChestInventory), CONTAINER_TITLE
- )
- );
+ // Paper start - Fix InventoryOpenEvent cancellation - moved up;
+ enderChestInventory.setActiveChest(enderChestBlockEntity); // Needs to happen before ChestMenu.threeRows as it is required for opening animations
+ if (level instanceof ServerLevel serverLevel && player.openMenu(
+ new SimpleMenuProvider((i, inventory, playerx) -> ChestMenu.threeRows(i, inventory, enderChestInventory), CONTAINER_TITLE)
+ ).isPresent()) {
+ // Paper end - Fix InventoryOpenEvent cancellation - moved up;
player.awardStat(Stats.OPEN_ENDERCHEST);
PiglinAi.angerNearbyPiglins(serverLevel, player, true);
}

View file

@ -1,10 +1,10 @@
--- a/net/minecraft/world/level/block/EyeblossomBlock.java --- a/net/minecraft/world/level/block/EyeblossomBlock.java
+++ b/net/minecraft/world/level/block/EyeblossomBlock.java +++ b/net/minecraft/world/level/block/EyeblossomBlock.java
@@ -100,6 +100,7 @@ @@ -99,6 +_,7 @@
@Override @Override
protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { 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(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent + if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
if (!world.isClientSide() if (!level.isClientSide()
&& world.getDifficulty() != Difficulty.PEACEFUL && level.getDifficulty() != Difficulty.PEACEFUL
&& entity instanceof Bee bee && entity instanceof Bee bee

View file

@ -0,0 +1,93 @@
--- a/net/minecraft/world/level/block/FarmBlock.java
+++ b/net/minecraft/world/level/block/FarmBlock.java
@@ -95,31 +_,56 @@
@Override
protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) {
int moistureValue = state.getValue(MOISTURE);
+ if (moistureValue > 0 && level.paperConfig().tickRates.wetFarmland != 1 && (level.paperConfig().tickRates.wetFarmland < 1 || (net.minecraft.server.MinecraftServer.currentTick + pos.hashCode()) % level.paperConfig().tickRates.wetFarmland != 0)) { return; } // Paper - Configurable random tick rates for blocks
+ if (moistureValue == 0 && level.paperConfig().tickRates.dryFarmland != 1 && (level.paperConfig().tickRates.dryFarmland < 1 || (net.minecraft.server.MinecraftServer.currentTick + pos.hashCode()) % level.paperConfig().tickRates.dryFarmland != 0)) { return; } // Paper - Configurable random tick rates for blocks
if (!isNearWater(level, pos) && !level.isRainingAt(pos.above())) {
if (moistureValue > 0) {
- level.setBlock(pos, state.setValue(MOISTURE, Integer.valueOf(moistureValue - 1)), 2);
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleMoistureChangeEvent(level, pos, state.setValue(FarmBlock.MOISTURE, moistureValue - 1), 2); // CraftBukkit
} else if (!shouldMaintainFarmland(level, pos)) {
turnToDirt(null, state, level, pos);
}
} else if (moistureValue < 7) {
- level.setBlock(pos, state.setValue(MOISTURE, Integer.valueOf(7)), 2);
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleMoistureChangeEvent(level, pos, state.setValue(FarmBlock.MOISTURE, 7), 2); // CraftBukkit
}
}
@Override
public void fallOn(Level level, BlockState state, BlockPos pos, Entity entity, float fallDistance) {
+ super.fallOn(level, state, pos, entity, fallDistance); // CraftBukkit - moved here as game rules / events shouldn't affect fall damage.
if (level instanceof ServerLevel serverLevel
&& level.random.nextFloat() < fallDistance - 0.5F
&& entity instanceof LivingEntity
&& (entity instanceof Player || serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))
&& entity.getBbWidth() * entity.getBbWidth() * entity.getBbHeight() > 0.512F) {
+ // CraftBukkit start - Interact soil
+ 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);
+ }
+
+ if (cancellable.isCancelled()) {
+ return;
+ }
+
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.DIRT.defaultBlockState())) {
+ return;
+ }
+ // CraftBukkit end
turnToDirt(entity, state, level, pos);
}
- super.fallOn(level, state, pos, entity, fallDistance);
+ // super.fallOn(level, state, pos, entity, fallDistance); // CraftBukkit - moved up
}
public static void turnToDirt(@Nullable Entity entity, BlockState state, Level level, BlockPos pos) {
+ // CraftBukkit start
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(level, pos, Blocks.DIRT.defaultBlockState()).isCancelled()) {
+ return;
+ }
+ // CraftBukkit end
BlockState blockState = pushEntitiesUp(state, Blocks.DIRT.defaultBlockState(), level, pos);
level.setBlockAndUpdate(pos, blockState);
level.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(entity, blockState));
@@ -130,13 +_,27 @@
}
private static boolean isNearWater(LevelReader level, BlockPos pos) {
- for (BlockPos blockPos : BlockPos.betweenClosed(pos.offset(-4, 0, -4), pos.offset(4, 1, 4))) {
- if (level.getFluidState(blockPos).is(FluidTags.WATER)) {
- return true;
+ // Paper start - Perf: remove abstract block iteration
+ int xOff = pos.getX();
+ int yOff = pos.getY();
+ int zOff = pos.getZ();
+ for (int dz = -4; dz <= 4; ++dz) {
+ int z = dz + zOff;
+ for (int dx = -4; dx <= 4; ++dx) {
+ int x = xOff + dx;
+ for (int dy = 0; dy <= 1; ++dy) {
+ int y = dy + yOff;
+ net.minecraft.world.level.chunk.LevelChunk chunk = (net.minecraft.world.level.chunk.LevelChunk)level.getChunk(x >> 4, z >> 4);
+ net.minecraft.world.level.material.FluidState fluid = chunk.getBlockStateFinal(x, y, z).getFluidState();
+ if (fluid.is(FluidTags.WATER)) {
+ return true;
+ }
+ }
}
}
return false;
+ // Paper end - Perf: remove abstract block iteration
}
@Override

View file

@ -0,0 +1,20 @@
--- a/net/minecraft/world/level/block/FenceGateBlock.java
+++ b/net/minecraft/world/level/block/FenceGateBlock.java
@@ -213,6 +_,17 @@
protected void neighborChanged(BlockState state, Level level, BlockPos pos, Block neighborBlock, @Nullable Orientation orientation, boolean movedByPiston) {
if (!level.isClientSide) {
boolean hasNeighborSignal = level.hasNeighborSignal(pos);
+ // CraftBukkit start
+ boolean oldPowered = state.getValue(FenceGateBlock.POWERED);
+ if (oldPowered != hasNeighborSignal) {
+ int newPower = hasNeighborSignal ? 15 : 0;
+ int oldPower = oldPowered ? 15 : 0;
+ org.bukkit.block.Block bukkitBlock = org.bukkit.craftbukkit.block.CraftBlock.at(level, pos);
+ org.bukkit.event.block.BlockRedstoneEvent eventRedstone = new org.bukkit.event.block.BlockRedstoneEvent(bukkitBlock, oldPower, newPower);
+ level.getCraftServer().getPluginManager().callEvent(eventRedstone);
+ hasNeighborSignal = eventRedstone.getNewCurrent() > 0;
+ }
+ // CraftBukkit end
if (state.getValue(POWERED) != hasNeighborSignal) {
level.setBlock(pos, state.setValue(POWERED, Boolean.valueOf(hasNeighborSignal)).setValue(OPEN, Boolean.valueOf(hasNeighborSignal)), 2);
if (state.getValue(OPEN) != hasNeighborSignal) {

View file

@ -0,0 +1,169 @@
--- a/net/minecraft/world/level/block/FireBlock.java
+++ b/net/minecraft/world/level/block/FireBlock.java
@@ -14,6 +_,7 @@
import net.minecraft.tags.BiomeTags;
import net.minecraft.util.RandomSource;
import net.minecraft.world.item.context.BlockPlaceContext;
+import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.GameRules;
import net.minecraft.world.level.Level;
@@ -122,7 +_,25 @@
BlockState neighborState,
RandomSource random
) {
- return this.canSurvive(state, level, pos) ? this.getStateWithAge(level, pos, state.getValue(AGE)) : Blocks.AIR.defaultBlockState();
+ // CraftBukkit start
+ if (!(level instanceof ServerLevel)) return this.canSurvive(state, level, pos) ? (BlockState) this.getStateWithAge(level, pos, (Integer) state.getValue(FireBlock.AGE)) : Blocks.AIR.defaultBlockState(); // Paper - don't fire events in world generation
+ if (!this.canSurvive(state, level, pos)) {
+ // Suppress during worldgen
+ if (!(level instanceof Level world1)) {
+ return Blocks.AIR.defaultBlockState();
+ }
+ org.bukkit.craftbukkit.block.CraftBlockState blockState = org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(world1, pos);
+ blockState.setData(Blocks.AIR.defaultBlockState());
+
+ org.bukkit.event.block.BlockFadeEvent event = new org.bukkit.event.block.BlockFadeEvent(blockState.getBlock(), blockState);
+ world1.getCraftServer().getPluginManager().callEvent(event);
+
+ if (!event.isCancelled()) {
+ return blockState.getHandle();
+ }
+ }
+ return this.getStateWithAge(level, pos, (Integer) state.getValue(FireBlock.AGE)); // Paper - don't fire events in world generation; diff on change, see "don't fire events in world generation"
+ // CraftBukkit end
}
@Override
@@ -162,10 +_,10 @@
@Override
protected void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) {
- level.scheduleTick(pos, this, getFireTickDelay(level.random));
+ level.scheduleTick(pos, (Block) this, FireBlock.getFireTickDelay(level)); // Paper - Add fire-tick-delay option
if (level.getGameRules().getBoolean(GameRules.RULE_DOFIRETICK)) {
if (!state.canSurvive(level, pos)) {
- level.removeBlock(pos, false);
+ this.fireExtinguished(level, pos); // CraftBukkit - invalid place location
}
BlockState blockState = level.getBlockState(pos.below());
@@ -184,26 +_,28 @@
if (!this.isValidFireLocation(level, pos)) {
BlockPos blockPos = pos.below();
if (!level.getBlockState(blockPos).isFaceSturdy(level, blockPos, Direction.UP) || ageValue > 3) {
- level.removeBlock(pos, false);
+ this.fireExtinguished(level, pos); // CraftBukkit - extinguished by rain
}
return;
}
if (ageValue == 15 && random.nextInt(4) == 0 && !this.canBurn(level.getBlockState(pos.below()))) {
- level.removeBlock(pos, false);
+ this.fireExtinguished(level, pos); // CraftBukkit
return;
}
}
boolean isIncreasedFireBurnout = level.getBiome(pos).is(BiomeTags.INCREASED_FIRE_BURNOUT);
int i = isIncreasedFireBurnout ? -50 : 0;
- this.checkBurnOut(level, pos.east(), 300 + i, random, ageValue);
- this.checkBurnOut(level, pos.west(), 300 + i, random, ageValue);
- this.checkBurnOut(level, pos.below(), 250 + i, random, ageValue);
- this.checkBurnOut(level, pos.above(), 250 + i, random, ageValue);
- this.checkBurnOut(level, pos.north(), 300 + i, random, ageValue);
- this.checkBurnOut(level, pos.south(), 300 + i, random, ageValue);
+ // CraftBukkit start - add source blockposition to burn calls
+ this.checkBurnOut(level, pos.east(), 300 + i, random, ageValue, pos);
+ this.checkBurnOut(level, pos.west(), 300 + i, random, ageValue, pos);
+ this.checkBurnOut(level, pos.below(), 250 + i, random, ageValue, pos);
+ this.checkBurnOut(level, pos.above(), 250 + i, random, ageValue, pos);
+ this.checkBurnOut(level, pos.north(), 300 + i, random, ageValue, pos);
+ this.checkBurnOut(level, pos.south(), 300 + i, random, ageValue, pos);
+ // CraftBukkit end
BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos();
for (int i1 = -1; i1 <= 1; i1++) {
@@ -225,7 +_,15 @@
if (i5 > 0 && random.nextInt(i4) <= i5 && (!level.isRaining() || !this.isNearRain(level, mutableBlockPos))) {
int min1 = Math.min(15, ageValue + random.nextInt(5) / 4);
- level.setBlock(mutableBlockPos, this.getStateWithAge(level, mutableBlockPos, min1), 3);
+ // CraftBukkit start - Call to stop spread of fire
+ if (level.getBlockState(mutableBlockPos).getBlock() != Blocks.FIRE) {
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(level, mutableBlockPos, pos).isCancelled()) {
+ continue;
+ }
+
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(level, pos, mutableBlockPos, this.getStateWithAge(level, mutableBlockPos, min1), 3); // CraftBukkit
+ }
+ // CraftBukkit end
}
}
}
@@ -256,19 +_,42 @@
: this.igniteOdds.getInt(state.getBlock());
}
- private void checkBurnOut(Level level, BlockPos pos, int chance, RandomSource random, int age) {
+ private void checkBurnOut(Level level, BlockPos pos, int chance, RandomSource random, int age, BlockPos sourceposition) { // CraftBukkit add sourceposition
int burnOdds = this.getBurnOdds(level.getBlockState(pos));
if (random.nextInt(chance) < burnOdds) {
BlockState blockState = level.getBlockState(pos);
+
+ // CraftBukkit start
+ org.bukkit.block.Block theBlock = level.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ());
+ org.bukkit.block.Block sourceBlock = level.getWorld().getBlockAt(sourceposition.getX(), sourceposition.getY(), sourceposition.getZ());
+
+ org.bukkit.event.block.BlockBurnEvent event = new org.bukkit.event.block.BlockBurnEvent(theBlock, sourceBlock);
+ level.getCraftServer().getPluginManager().callEvent(event);
+
+ if (event.isCancelled()) {
+ return;
+ }
+
+ if (blockState.getBlock() instanceof TntBlock && !org.bukkit.craftbukkit.event.CraftEventFactory.callTNTPrimeEvent(level, pos, org.bukkit.event.block.TNTPrimeEvent.PrimeCause.FIRE, null, sourceposition)) {
+ return;
+ }
+ // CraftBukkit end
if (random.nextInt(age + 10) < 5 && !level.isRainingAt(pos)) {
int min = Math.min(age + random.nextInt(5) / 4, 15);
level.setBlock(pos, this.getStateWithAge(level, pos, min), 3);
} else {
- level.removeBlock(pos, false);
+ if(blockState.getBlock() != Blocks.TNT) level.removeBlock(pos, false); // Paper - TNTPrimeEvent; We might be cancelling it below, move the setAir down
}
Block block = blockState.getBlock();
if (block instanceof TntBlock) {
+ // 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.FIRE, null).callEvent()) {
+ return;
+ }
+ level.removeBlock(pos, false);
+ // Paper end - TNTPrimeEvent
TntBlock.explode(level, pos);
}
}
@@ -310,13 +_,14 @@
}
@Override
- protected void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean isMoving) {
- super.onPlace(state, level, pos, oldState, isMoving);
- level.scheduleTick(pos, this, getFireTickDelay(level.random));
+ protected void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean isMoving, UseOnContext context) {
+ super.onPlace(state, level, pos, oldState, isMoving, context);
+ // CraftBukkit end
+ level.scheduleTick(pos, this, FireBlock.getFireTickDelay(level)); // Paper - Add fire-tick-delay option
}
- private static int getFireTickDelay(RandomSource random) {
- return 30 + random.nextInt(10);
+ private static int getFireTickDelay(Level world) { // Paper - Add fire-tick-delay option
+ return world.paperConfig().environment.fireTickDelay + world.random.nextInt(10); // Paper - Add fire-tick-delay option
}
@Override

View file

@ -1,11 +1,11 @@
--- a/net/minecraft/world/level/block/FlowerPotBlock.java --- a/net/minecraft/world/level/block/FlowerPotBlock.java
+++ b/net/minecraft/world/level/block/FlowerPotBlock.java +++ b/net/minecraft/world/level/block/FlowerPotBlock.java
@@ -63,6 +63,18 @@ @@ -67,6 +_,18 @@
} else if (!this.isEmpty()) { } else if (!this.isEmpty()) {
return InteractionResult.CONSUME; return InteractionResult.CONSUME;
} else { } else {
+ // Paper start - Add PlayerFlowerPotManipulateEvent + // Paper start - Add PlayerFlowerPotManipulateEvent
+ org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(world, pos); + org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(level, pos);
+ org.bukkit.inventory.ItemStack placedStack = org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(stack); + org.bukkit.inventory.ItemStack placedStack = org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(stack);
+ +
+ io.papermc.paper.event.player.PlayerFlowerPotManipulateEvent event = new io.papermc.paper.event.player.PlayerFlowerPotManipulateEvent((org.bukkit.entity.Player) player.getBukkitEntity(), block, placedStack, true); + io.papermc.paper.event.player.PlayerFlowerPotManipulateEvent event = new io.papermc.paper.event.player.PlayerFlowerPotManipulateEvent((org.bukkit.entity.Player) player.getBukkitEntity(), block, placedStack, true);
@ -16,10 +16,10 @@
+ return InteractionResult.CONSUME; + return InteractionResult.CONSUME;
+ } + }
+ // Paper end - Add PlayerFlowerPotManipulateEvent + // Paper end - Add PlayerFlowerPotManipulateEvent
world.setBlock(pos, blockState, 3); level.setBlock(pos, blockState, 3);
world.gameEvent(player, GameEvent.BLOCK_CHANGE, pos); level.gameEvent(player, GameEvent.BLOCK_CHANGE, pos);
player.awardStat(Stats.POT_FLOWER); player.awardStat(Stats.POT_FLOWER);
@@ -77,6 +89,18 @@ @@ -81,6 +_,18 @@
return InteractionResult.CONSUME; return InteractionResult.CONSUME;
} else { } else {
ItemStack itemStack = new ItemStack(this.potted); ItemStack itemStack = new ItemStack(this.potted);

View file

@ -0,0 +1,31 @@
--- a/net/minecraft/world/level/block/FrogspawnBlock.java
+++ b/net/minecraft/world/level/block/FrogspawnBlock.java
@@ -89,6 +_,7 @@
@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.getType().equals(EntityType.FALLING_BLOCK)) {
this.destroyBlock(level, pos);
}
@@ -101,6 +_,11 @@
}
private void hatchFrogspawn(ServerLevel level, BlockPos pos, RandomSource random) {
+ // Paper start - Call BlockFadeEvent
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(level, pos, Blocks.AIR.defaultBlockState()).isCancelled()) {
+ return;
+ }
+ // Paper end - Call BlockFadeEven
this.destroyBlock(level, pos);
level.playSound(null, pos, SoundEvents.FROGSPAWN_HATCH, SoundSource.BLOCKS, 1.0F, 1.0F);
this.spawnTadpoles(level, pos, random);
@@ -121,7 +_,7 @@
int randomInt1 = random.nextInt(1, 361);
tadpole.moveTo(d, pos.getY() - 0.5, d1, randomInt1, 0.0F);
tadpole.setPersistenceRequired();
- level.addFreshEntity(tadpole);
+ level.addFreshEntity(tadpole, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.EGG); // Paper - use correct spawn reason
}
}
}

View file

@ -0,0 +1,24 @@
--- a/net/minecraft/world/level/block/FrostedIceBlock.java
+++ b/net/minecraft/world/level/block/FrostedIceBlock.java
@@ -42,6 +_,7 @@
@Override
protected void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) {
+ if (!level.paperConfig().environment.frostedIce.enabled) return; // Paper - Frosted ice options
if ((random.nextInt(3) == 0 || this.fewerNeigboursThan(level, pos, 4))
&& level.getMaxLocalRawBrightness(pos) > 11 - state.getValue(AGE) - state.getLightBlock()
&& this.slightlyMelt(state, level, pos)) {
@@ -51,11 +_,11 @@
mutableBlockPos.setWithOffset(pos, direction);
BlockState blockState = level.getBlockState(mutableBlockPos);
if (blockState.is(this) && !this.slightlyMelt(blockState, level, mutableBlockPos)) {
- level.scheduleTick(mutableBlockPos, this, Mth.nextInt(random, 20, 40));
+ level.scheduleTick(mutableBlockPos, this, Mth.nextInt(random, level.paperConfig().environment.frostedIce.delay.min, level.paperConfig().environment.frostedIce.delay.max)); // Paper - Frosted ice options
}
}
} else {
- level.scheduleTick(pos, this, Mth.nextInt(random, 20, 40));
+ level.scheduleTick(pos, this, Mth.nextInt(random, level.paperConfig().environment.frostedIce.delay.min, level.paperConfig().environment.frostedIce.delay.max)); // Paper - Frosted ice options
}
}

View file

@ -0,0 +1,21 @@
--- a/net/minecraft/world/level/block/FungusBlock.java
+++ b/net/minecraft/world/level/block/FungusBlock.java
@@ -72,6 +_,17 @@
@Override
public void performBonemeal(ServerLevel level, RandomSource random, BlockPos pos, BlockState state) {
- this.getFeature(level).ifPresent(holder -> holder.value().place(level, level.getChunkSource().getGenerator(), random, pos));
+ this.getFeature(level)
+ // CraftBukkit start
+ .map((value) -> {
+ if (this == Blocks.WARPED_FUNGUS) {
+ SaplingBlock.treeType = org.bukkit.TreeType.WARPED_FUNGUS;
+ } else if (this == Blocks.CRIMSON_FUNGUS) {
+ SaplingBlock.treeType = org.bukkit.TreeType.CRIMSON_FUNGUS;
+ }
+ return value;
+ })
+ .ifPresent(holder -> holder.value().place(level, level.getChunkSource().getGenerator(), random, pos));
+ // CraftBukkit end
}
}

View file

@ -1,9 +1,9 @@
--- a/net/minecraft/world/level/block/FurnaceBlock.java --- a/net/minecraft/world/level/block/FurnaceBlock.java
+++ b/net/minecraft/world/level/block/FurnaceBlock.java +++ b/net/minecraft/world/level/block/FurnaceBlock.java
@@ -45,8 +45,7 @@ @@ -45,8 +_,7 @@
@Override @Override
protected void openContainer(Level world, BlockPos pos, Player player) { protected void openContainer(Level level, BlockPos pos, Player player) {
BlockEntity blockEntity = world.getBlockEntity(pos); BlockEntity blockEntity = level.getBlockEntity(pos);
- if (blockEntity instanceof FurnaceBlockEntity) { - if (blockEntity instanceof FurnaceBlockEntity) {
- player.openMenu((MenuProvider)blockEntity); - player.openMenu((MenuProvider)blockEntity);
+ if (blockEntity instanceof FurnaceBlockEntity && player.openMenu((MenuProvider)blockEntity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation + if (blockEntity instanceof FurnaceBlockEntity && player.openMenu((MenuProvider)blockEntity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation

View file

@ -0,0 +1,12 @@
--- a/net/minecraft/world/level/block/GrindstoneBlock.java
+++ b/net/minecraft/world/level/block/GrindstoneBlock.java
@@ -151,8 +_,7 @@
@Override
protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) {
- if (!level.isClientSide) {
- player.openMenu(state.getMenuProvider(level, pos));
+ if (!level.isClientSide && player.openMenu(state.getMenuProvider(level, pos)).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation
player.awardStat(Stats.INTERACT_WITH_GRINDSTONE);
}

View file

@ -0,0 +1,36 @@
--- a/net/minecraft/world/level/block/GrowingPlantHeadBlock.java
+++ b/net/minecraft/world/level/block/GrowingPlantHeadBlock.java
@@ -44,14 +_,31 @@
@Override
protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) {
- if (state.getValue(AGE) < 25 && random.nextDouble() < this.growPerTickProbability) {
+ // Spigot start
+ int modifier;
+ if (this == Blocks.KELP) {
+ modifier = level.spigotConfig.kelpModifier;
+ } else if (this == Blocks.TWISTING_VINES) {
+ modifier = level.spigotConfig.twistingVinesModifier;
+ } else if (this == Blocks.WEEPING_VINES) {
+ modifier = level.spigotConfig.weepingVinesModifier;
+ } else {
+ modifier = level.spigotConfig.caveVinesModifier;
+ }
+ if ((Integer) state.getValue(GrowingPlantHeadBlock.AGE) < 25 && random.nextDouble() < ((modifier / 100.0D) * this.growPerTickProbability)) { // Spigot - SPIGOT-7159: Better modifier resolution
+ // Spigot end
BlockPos blockPos = pos.relative(this.growthDirection);
if (this.canGrowInto(level.getBlockState(blockPos))) {
- level.setBlockAndUpdate(blockPos, this.getGrowIntoState(state, level.random));
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(level, pos, blockPos, this.getGrowIntoState(state, level.random, level)); // CraftBukkit // Paper - Fix Spigot growth modifiers
}
}
}
+ // Paper start - Fix Spigot growth modifiers
+ protected BlockState getGrowIntoState(BlockState state, RandomSource random, @javax.annotation.Nullable Level level) {
+ return this.getGrowIntoState(state, random);
+ }
+ // Paper end - Fix Spigot growth modifiers
protected BlockState getGrowIntoState(BlockState state, RandomSource random) {
return state.cycle(AGE);
}

View file

@ -1,10 +1,10 @@
--- a/net/minecraft/world/level/block/HoneyBlock.java --- a/net/minecraft/world/level/block/HoneyBlock.java
+++ b/net/minecraft/world/level/block/HoneyBlock.java +++ b/net/minecraft/world/level/block/HoneyBlock.java
@@ -60,6 +60,7 @@ @@ -60,6 +_,7 @@
@Override @Override
protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { 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(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent + if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
if (this.isSlidingDown(pos, entity)) { if (this.isSlidingDown(pos, entity)) {
this.maybeDoSlideAchievement(entity, pos); this.maybeDoSlideAchievement(entity, pos);
this.doSlideMovement(entity); this.doSlideMovement(entity);

View file

@ -1,20 +1,20 @@
--- a/net/minecraft/world/level/block/HopperBlock.java --- a/net/minecraft/world/level/block/HopperBlock.java
+++ b/net/minecraft/world/level/block/HopperBlock.java +++ b/net/minecraft/world/level/block/HopperBlock.java
@@ -125,8 +125,7 @@ @@ -125,8 +_,7 @@
@Override @Override
protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) {
- if (!world.isClientSide && world.getBlockEntity(pos) instanceof HopperBlockEntity hopperBlockEntity) { - if (!level.isClientSide && level.getBlockEntity(pos) instanceof HopperBlockEntity hopperBlockEntity) {
- player.openMenu(hopperBlockEntity); - player.openMenu(hopperBlockEntity);
+ if (!world.isClientSide && world.getBlockEntity(pos) instanceof HopperBlockEntity hopperBlockEntity && player.openMenu(hopperBlockEntity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation + if (!level.isClientSide && level.getBlockEntity(pos) instanceof HopperBlockEntity hopperBlockEntity && player.openMenu(hopperBlockEntity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation
player.awardStat(Stats.INSPECT_HOPPER); player.awardStat(Stats.INSPECT_HOPPER);
} }
@@ -178,6 +177,7 @@ @@ -178,6 +_,7 @@
@Override @Override
protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { 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(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent + if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
BlockEntity blockEntity = world.getBlockEntity(pos); BlockEntity blockEntity = level.getBlockEntity(pos);
if (blockEntity instanceof HopperBlockEntity) { if (blockEntity instanceof HopperBlockEntity) {
HopperBlockEntity.entityInside(world, pos, state, entity, (HopperBlockEntity)blockEntity); HopperBlockEntity.entityInside(level, pos, state, entity, (HopperBlockEntity)blockEntity);

View file

@ -1,30 +1,30 @@
--- a/net/minecraft/world/level/block/HugeMushroomBlock.java --- a/net/minecraft/world/level/block/HugeMushroomBlock.java
+++ b/net/minecraft/world/level/block/HugeMushroomBlock.java +++ b/net/minecraft/world/level/block/HugeMushroomBlock.java
@@ -45,6 +45,7 @@ @@ -45,6 +_,7 @@
@Override @Override
public BlockState getStateForPlacement(BlockPlaceContext ctx) { public BlockState getStateForPlacement(BlockPlaceContext context) {
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableMushroomBlockUpdates) return this.defaultBlockState(); // Paper - add option to disable block updates + if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableMushroomBlockUpdates) return this.defaultBlockState(); // Paper - add option to disable block updates
BlockGetter blockGetter = ctx.getLevel(); BlockGetter level = context.getLevel();
BlockPos blockPos = ctx.getClickedPos(); BlockPos clickedPos = context.getClickedPos();
return this.defaultBlockState() return this.defaultBlockState()
@@ -67,6 +68,7 @@ @@ -67,6 +_,7 @@
BlockState neighborState, BlockState neighborState,
RandomSource random RandomSource random
) { ) {
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableMushroomBlockUpdates) return state; // Paper - add option to disable block updates + if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableMushroomBlockUpdates) return state; // Paper - add option to disable block updates
return neighborState.is(this) return neighborState.is(this)
? state.setValue(PROPERTY_BY_DIRECTION.get(direction), Boolean.valueOf(false)) ? state.setValue(PROPERTY_BY_DIRECTION.get(direction), Boolean.valueOf(false))
: super.updateShape(state, world, tickView, pos, direction, neighborPos, neighborState, random); : super.updateShape(state, level, scheduledTickAccess, pos, direction, neighborPos, neighborState, random);
@@ -74,6 +76,7 @@ @@ -74,6 +_,7 @@
@Override @Override
protected BlockState rotate(BlockState state, Rotation rotation) { protected BlockState rotate(BlockState state, Rotation rot) {
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableMushroomBlockUpdates) return state; // Paper - add option to disable block updates + if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableMushroomBlockUpdates) return state; // Paper - add option to disable block updates
return state.setValue(PROPERTY_BY_DIRECTION.get(rotation.rotate(Direction.NORTH)), state.getValue(NORTH)) return state.setValue(PROPERTY_BY_DIRECTION.get(rot.rotate(Direction.NORTH)), state.getValue(NORTH))
.setValue(PROPERTY_BY_DIRECTION.get(rotation.rotate(Direction.SOUTH)), state.getValue(SOUTH)) .setValue(PROPERTY_BY_DIRECTION.get(rot.rotate(Direction.SOUTH)), state.getValue(SOUTH))
.setValue(PROPERTY_BY_DIRECTION.get(rotation.rotate(Direction.EAST)), state.getValue(EAST)) .setValue(PROPERTY_BY_DIRECTION.get(rot.rotate(Direction.EAST)), state.getValue(EAST))
@@ -84,6 +87,7 @@ @@ -84,6 +_,7 @@
@Override @Override
protected BlockState mirror(BlockState state, Mirror mirror) { protected BlockState mirror(BlockState state, Mirror mirror) {

View file

@ -0,0 +1,30 @@
--- a/net/minecraft/world/level/block/IceBlock.java
+++ b/net/minecraft/world/level/block/IceBlock.java
@@ -32,8 +_,13 @@
}
@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
+ // Paper start - Improve Block#breakNaturally API
+ this.afterDestroy(level, pos, stack);
+ }
+ public void afterDestroy(Level level, BlockPos pos, ItemStack stack) {
+ // Paper end - Improve Block#breakNaturally API
if (!EnchantmentHelper.hasTag(stack, EnchantmentTags.PREVENTS_ICE_MELTING)) {
if (level.dimensionType().ultraWarm()) {
level.removeBlock(pos, false);
@@ -55,6 +_,11 @@
}
protected void melt(BlockState state, Level level, BlockPos pos) {
+ // CraftBukkit start
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(level, pos, level.dimensionType().ultraWarm() ? Blocks.AIR.defaultBlockState() : Blocks.WATER.defaultBlockState()).isCancelled()) {
+ return;
+ }
+ // CraftBukkit end
if (level.dimensionType().ultraWarm()) {
level.removeBlock(pos, false);
} else {

View file

@ -0,0 +1,11 @@
--- a/net/minecraft/world/level/block/InfestedBlock.java
+++ b/net/minecraft/world/level/block/InfestedBlock.java
@@ -52,7 +_,7 @@
Silverfish silverfish = EntityType.SILVERFISH.create(level, EntitySpawnReason.TRIGGERED);
if (silverfish != null) {
silverfish.moveTo(pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, 0.0F, 0.0F);
- level.addFreshEntity(silverfish);
+ level.addFreshEntity(silverfish, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SILVERFISH_BLOCK); // CraftBukkit - add SpawnReason
silverfish.spawnAnim();
}
}

View file

@ -1,10 +1,10 @@
--- a/net/minecraft/world/level/block/LavaCauldronBlock.java --- a/net/minecraft/world/level/block/LavaCauldronBlock.java
+++ b/net/minecraft/world/level/block/LavaCauldronBlock.java +++ b/net/minecraft/world/level/block/LavaCauldronBlock.java
@@ -32,6 +32,7 @@ @@ -32,6 +_,7 @@
@Override @Override
protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { 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(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent + if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
if (this.isEntityInsideContent(state, pos, entity)) { if (this.isEntityInsideContent(state, pos, entity)) {
entity.lavaHurt(); entity.lavaHurt();
} }

View file

@ -0,0 +1,109 @@
--- a/net/minecraft/world/level/block/LayeredCauldronBlock.java
+++ b/net/minecraft/world/level/block/LayeredCauldronBlock.java
@@ -61,35 +_,79 @@
@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 && entity.isOnFire() && this.isEntityInsideContent(state, pos, entity)) {
- entity.clearFire();
- if (entity.mayInteract(serverLevel, pos)) {
- this.handleEntityOnFireInside(state, level, pos);
+ // CraftBukkit start - moved down
+ // entity.clearFire();
+ if ((entity instanceof net.minecraft.world.entity.player.Player || serverLevel.getGameRules().getBoolean(net.minecraft.world.level.GameRules.RULE_MOBGRIEFING)) && entity.mayInteract(serverLevel, pos)) { // Paper - Fixes MC-248588
+ if (this.handleEntityOnFireInsideWithEvent(state, level, pos, entity)) { // Paper - fix powdered snow cauldron extinguishing entities
+ entity.clearFire();
+ }
+ // CraftBukkit end
}
}
}
- private void handleEntityOnFireInside(BlockState state, Level level, BlockPos pos) {
+ // CraftBukkit start
+ @io.papermc.paper.annotation.DoNotUse @Deprecated // Paper - fix powdered snow cauldron extinguishing entities; use #handleEntityOnFireInsideWithEvent
+ private boolean handleEntityOnFireInside(BlockState state, Level level, BlockPos pos, Entity entity) {
if (this.precipitationType == Biome.Precipitation.SNOW) {
- lowerFillLevel(Blocks.WATER_CAULDRON.defaultBlockState().setValue(LEVEL, state.getValue(LEVEL)), level, pos);
+ return LayeredCauldronBlock.lowerFillLevel((BlockState) Blocks.WATER_CAULDRON.defaultBlockState().setValue(LayeredCauldronBlock.LEVEL, (Integer) state.getValue(LayeredCauldronBlock.LEVEL)), level, pos, entity, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason.EXTINGUISH); // CraftBukkit
} else {
- lowerFillLevel(state, level, pos);
+ return LayeredCauldronBlock.lowerFillLevel(state, level, pos, entity, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason.EXTINGUISH); // CraftBukkit
}
}
public static void lowerFillLevel(BlockState state, Level level, BlockPos pos) {
- int i = state.getValue(LEVEL) - 1;
- BlockState blockState = i == 0 ? Blocks.CAULDRON.defaultBlockState() : state.setValue(LEVEL, Integer.valueOf(i));
- level.setBlockAndUpdate(pos, blockState);
- level.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(blockState));
- }
+ // CraftBukkit start
+ LayeredCauldronBlock.lowerFillLevel(state, level, pos, null, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason.UNKNOWN);
+ }
+ public static boolean lowerFillLevel(BlockState state, Level level, BlockPos BlockPos, Entity entity, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason reason) {
+ int i = (Integer) state.getValue(LayeredCauldronBlock.LEVEL) - 1;
+ BlockState iblockdata1 = i == 0 ? Blocks.CAULDRON.defaultBlockState() : (BlockState) state.setValue(LayeredCauldronBlock.LEVEL, i);
+
+ return LayeredCauldronBlock.changeLevel(state, level, BlockPos, iblockdata1, entity, reason);
+ }
+ // Paper start - fix powdered snow cauldron extinguishing entities
+ protected boolean handleEntityOnFireInsideWithEvent(BlockState state, Level world, BlockPos pos, Entity entity) {
+ if (this.precipitationType == Biome.Precipitation.SNOW) {
+ return LayeredCauldronBlock.lowerFillLevel((BlockState) Blocks.WATER_CAULDRON.defaultBlockState().setValue(LayeredCauldronBlock.LEVEL, (Integer) state.getValue(LayeredCauldronBlock.LEVEL)), world, pos, entity, CauldronLevelChangeEvent.ChangeReason.EXTINGUISH);
+ } else {
+ return LayeredCauldronBlock.lowerFillLevel(state, world, pos, entity, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason.EXTINGUISH);
+ }
+ }
+ // Paper end - fix powdered snow cauldron extinguishing entities
+
+ // CraftBukkit start
+ // Paper start - Call CauldronLevelChangeEvent
+ public static boolean changeLevel(BlockState iblockdata, Level world, BlockPos blockposition, BlockState newBlock, @javax.annotation.Nullable Entity entity, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason reason) { // Paper - entity is nullable
+ return changeLevel(iblockdata, world, blockposition, newBlock, entity, reason, true);
+ }
+
+ public static boolean changeLevel(BlockState iblockdata, Level world, BlockPos blockposition, BlockState newBlock, @javax.annotation.Nullable Entity entity, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason reason, boolean sendGameEvent) { // Paper - entity is nullable
+ // Paper end - Call CauldronLevelChangeEvent
+ org.bukkit.craftbukkit.block.CraftBlockState newState = org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(world, blockposition);
+ newState.setData(newBlock);
+
+ org.bukkit.event.block.CauldronLevelChangeEvent event = new org.bukkit.event.block.CauldronLevelChangeEvent(
+ world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()),
+ (entity == null) ? null : entity.getBukkitEntity(), reason, newState
+ );
+ world.getCraftServer().getPluginManager().callEvent(event);
+ if (event.isCancelled()) {
+ return false;
+ }
+ newState.update(true);
+ if (sendGameEvent) world.gameEvent(GameEvent.BLOCK_CHANGE, blockposition, GameEvent.Context.of(newBlock)); // Paper - Call CauldronLevelChangeEvent
+ return true;
+ }
+ // CraftBukkit end
@Override
public void handlePrecipitation(BlockState state, Level level, BlockPos pos, Biome.Precipitation precipitation) {
if (CauldronBlock.shouldHandlePrecipitation(level, precipitation) && state.getValue(LEVEL) != 3 && precipitation == this.precipitationType) {
BlockState blockState = state.cycle(LEVEL);
- level.setBlockAndUpdate(pos, blockState);
- level.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(blockState));
+ LayeredCauldronBlock.changeLevel(state, level, pos, blockState, null, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL); // CraftBukkit
}
}
@@ -107,8 +_,11 @@
protected void receiveStalactiteDrip(BlockState state, Level level, BlockPos pos, Fluid fluid) {
if (!this.isFull(state)) {
BlockState blockState = state.setValue(LEVEL, Integer.valueOf(state.getValue(LEVEL) + 1));
- level.setBlockAndUpdate(pos, blockState);
- level.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(blockState));
+ // CraftBukkit start
+ if (!LayeredCauldronBlock.changeLevel(state, level, pos, blockState, null, CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL)) {
+ return;
+ }
+ // CraftBukkit end
level.levelEvent(1047, pos, 0);
}
}

View file

@ -0,0 +1,17 @@
--- a/net/minecraft/world/level/block/LeavesBlock.java
+++ b/net/minecraft/world/level/block/LeavesBlock.java
@@ -63,6 +_,14 @@
@Override
protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) {
if (this.decaying(state)) {
+ // CraftBukkit start
+ org.bukkit.event.block.LeavesDecayEvent event = new org.bukkit.event.block.LeavesDecayEvent(level.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()));
+ level.getCraftServer().getPluginManager().callEvent(event);
+
+ if (event.isCancelled() || level.getBlockState(pos).getBlock() != this) {
+ return;
+ }
+ // CraftBukkit end
dropResources(state, level, pos);
level.removeBlock(pos, false);
}

View file

@ -0,0 +1,67 @@
--- a/net/minecraft/world/level/block/LecternBlock.java
+++ b/net/minecraft/world/level/block/LecternBlock.java
@@ -169,7 +_,24 @@
private static void placeBook(@Nullable LivingEntity entity, Level level, BlockPos pos, BlockState state, ItemStack stack) {
if (level.getBlockEntity(pos) instanceof LecternBlockEntity lecternBlockEntity) {
- lecternBlockEntity.setBook(stack.consumeAndReturn(1, entity));
+ // Paper start - Add PlayerInsertLecternBookEvent
+ ItemStack eventSourcedBookStack = null;
+ if (entity instanceof final net.minecraft.server.level.ServerPlayer serverPlayer) {
+ final io.papermc.paper.event.player.PlayerInsertLecternBookEvent event = new io.papermc.paper.event.player.PlayerInsertLecternBookEvent(
+ serverPlayer.getBukkitEntity(),
+ org.bukkit.craftbukkit.block.CraftBlock.at(level, pos),
+ org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(stack.copyWithCount(1))
+ );
+ if (!event.callEvent()) return;
+ eventSourcedBookStack = org.bukkit.craftbukkit.inventory.CraftItemStack.unwrap(event.getBook());
+ }
+ if (eventSourcedBookStack == null) {
+ eventSourcedBookStack = stack.consumeAndReturn(1, entity);
+ } else {
+ stack.consume(1, entity);
+ }
+ lecternBlockEntity.setBook(eventSourcedBookStack);
+ // Paper end - Add PlayerInsertLecternBookEvent
resetBookState(entity, level, pos, state, true);
level.playSound(null, pos, SoundEvents.BOOK_PUT, SoundSource.BLOCKS, 1.0F, 1.0F);
}
@@ -189,6 +_,16 @@
}
private static void changePowered(Level level, BlockPos pos, BlockState state, boolean powered) {
+ // Paper start - Call BlockRedstoneEvent properly
+ final int currentRedstoneLevel = state.getValue(LecternBlock.POWERED) ? 15 : 0, targetRedstoneLevel = powered ? 15 : 0;
+ if (currentRedstoneLevel != targetRedstoneLevel) {
+ final org.bukkit.event.block.BlockRedstoneEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, currentRedstoneLevel, targetRedstoneLevel);
+
+ if (event.getNewCurrent() != targetRedstoneLevel) {
+ return;
+ }
+ }
+ // Paper end - Call BlockRedstoneEvent properly
level.setBlock(pos, state.setValue(POWERED, Boolean.valueOf(powered)), 3);
updateBelow(level, pos, state);
}
@@ -218,9 +_,10 @@
}
private void popBook(BlockState state, Level level, BlockPos pos) {
- if (level.getBlockEntity(pos) instanceof LecternBlockEntity lecternBlockEntity) {
+ if (level.getBlockEntity(pos, false) instanceof LecternBlockEntity lecternBlockEntity) { // CraftBukkit - don't validate, type may be changed already
Direction direction = state.getValue(FACING);
ItemStack itemStack = lecternBlockEntity.getBook().copy();
+ if (itemStack.isEmpty()) return; // CraftBukkit - SPIGOT-5500
float f = 0.25F * direction.getStepX();
float f1 = 0.25F * direction.getStepZ();
ItemEntity itemEntity = new ItemEntity(level, pos.getX() + 0.5 + f, pos.getY() + 1, pos.getZ() + 0.5 + f1, itemStack);
@@ -296,8 +_,7 @@
private void openScreen(Level level, BlockPos pos, Player player) {
BlockEntity blockEntity = level.getBlockEntity(pos);
- if (blockEntity instanceof LecternBlockEntity) {
- player.openMenu((LecternBlockEntity)blockEntity);
+ if (blockEntity instanceof LecternBlockEntity lecternBlockEntity && player.openMenu(lecternBlockEntity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation
player.awardStat(Stats.INTERACT_WITH_LECTERN);
}
}

View file

@ -0,0 +1,22 @@
--- a/net/minecraft/world/level/block/LeverBlock.java
+++ b/net/minecraft/world/level/block/LeverBlock.java
@@ -100,6 +_,19 @@
makeParticle(blockState, level, pos, 1.0F);
}
} else {
+ // CraftBukkit start - Interact Lever
+ boolean powered = state.getValue(LeverBlock.POWERED); // Old powered state
+ org.bukkit.block.Block block = level.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ());
+ int old = (powered) ? 15 : 0;
+ int current = (!powered) ? 15 : 0;
+
+ org.bukkit.event.block.BlockRedstoneEvent eventRedstone = new org.bukkit.event.block.BlockRedstoneEvent(block, old, current);
+ level.getCraftServer().getPluginManager().callEvent(eventRedstone);
+
+ if ((eventRedstone.getNewCurrent() > 0) != (!powered)) {
+ return InteractionResult.SUCCESS;
+ }
+ // CraftBukkit end
this.pull(state, level, pos, null);
}

View file

@ -1,18 +1,16 @@
--- a/net/minecraft/world/level/block/LightBlock.java --- a/net/minecraft/world/level/block/LightBlock.java
+++ b/net/minecraft/world/level/block/LightBlock.java +++ b/net/minecraft/world/level/block/LightBlock.java
@@ -50,7 +50,15 @@ @@ -49,6 +_,13 @@
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
builder.add(LEVEL, WATERLOGGED); builder.add(LEVEL, WATERLOGGED);
} }
+ // Paper start - prevent unintended light block manipulation + // Paper start - prevent unintended light block manipulation
@Override + @Override
+ protected InteractionResult useItemOn(ItemStack stack, BlockState state, Level world, BlockPos pos, Player player, net.minecraft.world.InteractionHand hand, BlockHitResult hit) { + protected InteractionResult useItemOn(ItemStack stack, BlockState state, Level world, BlockPos pos, Player player, net.minecraft.world.InteractionHand hand, BlockHitResult hit) {
+ if (player.getItemInHand(hand).getItem() != Items.LIGHT || (world instanceof final net.minecraft.server.level.ServerLevel serverLevel && !player.mayInteract(serverLevel, pos)) || !player.mayUseItemAt(pos, hit.getDirection(), player.getItemInHand(hand))) { return net.minecraft.world.InteractionResult.PASS; } // Paper - Prevent unintended light block manipulation + if (player.getItemInHand(hand).getItem() != Items.LIGHT || (world instanceof final net.minecraft.server.level.ServerLevel serverLevel && !player.mayInteract(serverLevel, pos)) || !player.mayUseItemAt(pos, hit.getDirection(), player.getItemInHand(hand))) { return net.minecraft.world.InteractionResult.PASS; } // Paper - Prevent unintended light block manipulation
+ return super.useItemOn(stack, state, world, pos, player, hand, hit); + return super.useItemOn(stack, state, world, pos, player, hand, hit);
+ } + }
+ // Paper end - prevent unintended light block manipulation + // Paper end - prevent unintended light block manipulation
+
+ @Override @Override
protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) {
if (!world.isClientSide && player.canUseGameMasterBlocks()) {
world.setBlock(pos, state.cycle(LEVEL), 2);

View file

@ -0,0 +1,21 @@
--- a/net/minecraft/world/level/block/LightningRodBlock.java
+++ b/net/minecraft/world/level/block/LightningRodBlock.java
@@ -84,6 +_,18 @@
}
public void onLightningStrike(BlockState state, Level level, BlockPos pos) {
+ // CraftBukkit start
+ boolean powered = state.getValue(LightningRodBlock.POWERED);
+ int old = (powered) ? 15 : 0;
+ int current = (!powered) ? 15 : 0;
+
+ org.bukkit.event.block.BlockRedstoneEvent eventRedstone = new org.bukkit.event.block.BlockRedstoneEvent(org.bukkit.craftbukkit.block.CraftBlock.at(level, pos), old, current);
+ level.getCraftServer().getPluginManager().callEvent(eventRedstone);
+
+ if (eventRedstone.getNewCurrent() <= 0) {
+ return;
+ }
+ // CraftBukkit end
level.setBlock(pos, state.setValue(POWERED, Boolean.valueOf(true)), 3);
this.updateNeighbours(state, level, pos);
level.scheduleTick(pos, this, 8);

View file

@ -0,0 +1,67 @@
--- a/net/minecraft/world/level/block/LiquidBlock.java
+++ b/net/minecraft/world/level/block/LiquidBlock.java
@@ -135,9 +_,28 @@
@Override
protected void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean isMoving) {
if (this.shouldSpreadLiquid(level, pos, state)) {
- level.scheduleTick(pos, state.getFluidState().getType(), this.fluid.getTickDelay(level));
- }
- }
+ level.scheduleTick(pos, state.getFluidState().getType(), this.getFlowSpeed(level, pos)); // Paper - Configurable speed for water flowing over lava
+ }
+ }
+ // Paper start - Configurable speed for water flowing over lava
+ public int getFlowSpeed(Level world, BlockPos blockposition) {
+ if (net.minecraft.core.registries.BuiltInRegistries.FLUID.wrapAsHolder(this.fluid).is(FluidTags.WATER)) {
+ if (
+ isLava(world, blockposition.north(1)) ||
+ isLava(world, blockposition.south(1)) ||
+ isLava(world, blockposition.west(1)) ||
+ isLava(world, blockposition.east(1))
+ ) {
+ return world.paperConfig().environment.waterOverLavaFlowSpeed;
+ }
+ }
+ return this.fluid.getTickDelay(world);
+ }
+ private static boolean isLava(Level world, BlockPos blockPos) {
+ final FluidState fluidState = world.getFluidIfLoaded(blockPos);
+ return fluidState != null && fluidState.is(FluidTags.LAVA);
+ }
+ // Paper end - Configurable speed for water flowing over lava
@Override
protected BlockState updateShape(
@@ -160,7 +_,7 @@
@Override
protected void neighborChanged(BlockState state, Level level, BlockPos pos, Block neighborBlock, @Nullable Orientation orientation, boolean movedByPiston) {
if (this.shouldSpreadLiquid(level, pos, state)) {
- level.scheduleTick(pos, state.getFluidState().getType(), this.fluid.getTickDelay(level));
+ level.scheduleTick(pos, state.getFluidState().getType(), this.getFlowSpeed(level, pos)); // Paper - Configurable speed for water flowing over lava
}
}
@@ -173,13 +_,21 @@
if (level.getFluidState(blockPos).is(FluidTags.WATER)) {
Block block = level.getFluidState(pos).isSource() ? Blocks.OBSIDIAN : Blocks.COBBLESTONE;
level.setBlockAndUpdate(pos, block.defaultBlockState());
- this.fizz(level, pos);
+ // CraftBukkit start
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(level, pos, block.defaultBlockState())) {
+ this.fizz(level, pos);
+ }
+ // CraftBukkit end
return false;
}
if (isSoulSoil && level.getBlockState(blockPos).is(Blocks.BLUE_ICE)) {
level.setBlockAndUpdate(pos, Blocks.BASALT.defaultBlockState());
- this.fizz(level, pos);
+ // CraftBukkit start
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(level, pos, Blocks.BASALT.defaultBlockState())) {
+ this.fizz(level, pos);
+ }
+ // CraftBukkit end
return false;
}
}

View file

@ -0,0 +1,12 @@
--- a/net/minecraft/world/level/block/LoomBlock.java
+++ b/net/minecraft/world/level/block/LoomBlock.java
@@ -32,8 +_,7 @@
@Override
protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) {
- if (!level.isClientSide) {
- player.openMenu(state.getMenuProvider(level, pos));
+ if (!level.isClientSide && player.openMenu(state.getMenuProvider(level, pos)).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation
player.awardStat(Stats.INTERACT_WITH_LOOM);
}

View file

@ -0,0 +1,11 @@
--- a/net/minecraft/world/level/block/MagmaBlock.java
+++ b/net/minecraft/world/level/block/MagmaBlock.java
@@ -29,7 +_,7 @@
@Override
public void stepOn(Level level, BlockPos pos, BlockState state, Entity entity) {
if (!entity.isSteppingCarefully() && entity instanceof LivingEntity) {
- entity.hurt(level.damageSources().hotFloor(), 1.0F);
+ entity.hurt(level.damageSources().hotFloor().directBlock(level, pos), 1.0F); // CraftBukkit
}
super.stepOn(level, pos, state, entity);

View file

@ -1,11 +1,11 @@
--- a/net/minecraft/world/level/block/MangrovePropaguleBlock.java --- a/net/minecraft/world/level/block/MangrovePropaguleBlock.java
+++ b/net/minecraft/world/level/block/MangrovePropaguleBlock.java +++ b/net/minecraft/world/level/block/MangrovePropaguleBlock.java
@@ -123,7 +123,7 @@ @@ -123,7 +_,7 @@
@Override @Override
protected void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) {
if (!isHanging(state)) { if (!isHanging(state)) {
- if (random.nextInt(7) == 0) { - if (random.nextInt(7) == 0) {
+ if (random.nextFloat() < (world.spigotConfig.saplingModifier / (100.0F * 7))) { // Paper - Fix Spigot growth modifiers + if (random.nextFloat() < (level.spigotConfig.saplingModifier / (100.0F * 7))) { // Paper - Fix Spigot growth modifiers
this.advanceTree(world, pos, state, random); this.advanceTree(level, pos, state, random);
} }
} else { } else {

View file

@ -0,0 +1,42 @@
--- a/net/minecraft/world/level/block/MultifaceSpreader.java
+++ b/net/minecraft/world/level/block/MultifaceSpreader.java
@@ -154,14 +_,14 @@
level.getChunk(pos.pos()).markPosForPostprocessing(pos.pos());
}
- return level.setBlock(pos.pos(), stateForPlacement, 2);
+ return org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(level, pos.source(), pos.pos(), stateForPlacement, 2); // CraftBukkit
} else {
return false;
}
}
}
- public record SpreadPos(BlockPos pos, Direction face) {
+ public record SpreadPos(BlockPos pos, Direction face, BlockPos source) { // CraftBukkit
}
@FunctionalInterface
@@ -173,19 +_,19 @@
SAME_POSITION {
@Override
public MultifaceSpreader.SpreadPos getSpreadPos(BlockPos pos, Direction face, Direction spreadDirection) {
- return new MultifaceSpreader.SpreadPos(pos, face);
+ return new MultifaceSpreader.SpreadPos(pos, face, pos); // CraftBukkit
}
},
SAME_PLANE {
@Override
public MultifaceSpreader.SpreadPos getSpreadPos(BlockPos pos, Direction face, Direction spreadDirection) {
- return new MultifaceSpreader.SpreadPos(pos.relative(face), spreadDirection);
+ return new MultifaceSpreader.SpreadPos(pos.relative(face), spreadDirection, pos); // CraftBukkit
}
},
WRAP_AROUND {
@Override
public MultifaceSpreader.SpreadPos getSpreadPos(BlockPos pos, Direction face, Direction spreadDirection) {
- return new MultifaceSpreader.SpreadPos(pos.relative(face).relative(spreadDirection), face.getOpposite());
+ return new MultifaceSpreader.SpreadPos(pos.relative(face).relative(spreadDirection), face.getOpposite(), pos); // CraftBukkit
}
};

View file

@ -0,0 +1,36 @@
--- a/net/minecraft/world/level/block/MushroomBlock.java
+++ b/net/minecraft/world/level/block/MushroomBlock.java
@@ -47,7 +_,7 @@
@Override
protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) {
- if (random.nextInt(25) == 0) {
+ if (random.nextFloat() < (level.spigotConfig.mushroomModifier / (100.0f * 25))) { // Spigot - SPIGOT-7159: Better modifier resolution
int i = 5;
int i1 = 4;
@@ -60,6 +_,7 @@
}
BlockPos blockPos1 = pos.offset(random.nextInt(3) - 1, random.nextInt(2) - random.nextInt(2), random.nextInt(3) - 1);
+ final BlockPos sourcePos = pos; // Paper - Use correct source for mushroom block spread event
for (int i2 = 0; i2 < 4; i2++) {
if (level.isEmptyBlock(blockPos1) && state.canSurvive(level, blockPos1)) {
@@ -70,7 +_,7 @@
}
if (level.isEmptyBlock(blockPos1) && state.canSurvive(level, blockPos1)) {
- level.setBlock(blockPos1, state, 2);
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(level, sourcePos, blockPos1, state, 2); // CraftBukkit // Paper - Use correct source for mushroom block spread event
}
}
}
@@ -93,6 +_,7 @@
return false;
} else {
level.removeBlock(pos, false);
+ SaplingBlock.treeType = (this == Blocks.BROWN_MUSHROOM) ? org.bukkit.TreeType.BROWN_MUSHROOM : org.bukkit.TreeType.RED_MUSHROOM; // CraftBukkit
if (optional.get().value().place(level, level.getChunkSource().getGenerator(), random, pos)) {
return true;
} else {

View file

@ -0,0 +1,126 @@
--- a/net/minecraft/world/level/block/NetherPortalBlock.java
+++ b/net/minecraft/world/level/block/NetherPortalBlock.java
@@ -70,7 +_,7 @@
@Override
protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) {
- if (level.dimensionType().natural()
+ if (level.spigotConfig.enableZombiePigmenPortalSpawns && level.dimensionType().natural() // Spigot
&& level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING)
&& random.nextInt(2000) < level.getDifficulty().getId()) {
while (level.getBlockState(pos).is(this)) {
@@ -78,9 +_,13 @@
}
if (level.getBlockState(pos).isValidSpawn(level, pos, EntityType.ZOMBIFIED_PIGLIN)) {
- Entity entity = EntityType.ZOMBIFIED_PIGLIN.spawn(level, pos.above(), EntitySpawnReason.STRUCTURE);
+ Entity entity = EntityType.ZOMBIFIED_PIGLIN.spawn(level, pos.above(), EntitySpawnReason.STRUCTURE, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NETHER_PORTAL); // CraftBukkit - set spawn reason to NETHER_PORTAL
if (entity != null) {
entity.setPortalCooldown();
+ // Paper start - Add option to nerf pigmen from nether portals
+ entity.fromNetherPortal = true;
+ if (level.paperConfig().entities.behavior.nerfPigmenFromNetherPortals) ((net.minecraft.world.entity.Mob) entity).aware = false;
+ // Paper end - Add option to nerf pigmen from nether portals
Entity vehicle = entity.getVehicle();
if (vehicle != null) {
vehicle.setPortalCooldown();
@@ -111,7 +_,13 @@
@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.canUsePortal(false)) {
+ // CraftBukkit start - Entity in portal
+ org.bukkit.event.entity.EntityPortalEnterEvent event = new org.bukkit.event.entity.EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(level.getWorld(), pos.getX(), pos.getY(), pos.getZ()), org.bukkit.PortalType.NETHER); // Paper - add portal type
+ level.getCraftServer().getPluginManager().callEvent(event);
+ if (event.isCancelled()) return; // Paper - make cancellable
+ // CraftBukkit end
entity.setAsInsidePortal(this, pos);
}
}
@@ -134,22 +_,46 @@
@Nullable
@Override
public TeleportTransition getPortalDestination(ServerLevel level, Entity entity, BlockPos pos) {
- ResourceKey<Level> resourceKey = level.dimension() == Level.NETHER ? Level.OVERWORLD : Level.NETHER;
+ // CraftBukkit start
+ ResourceKey<Level> resourceKey = level.getTypeKey() == net.minecraft.world.level.dimension.LevelStem.NETHER ? Level.OVERWORLD : Level.NETHER;
ServerLevel level1 = level.getServer().getLevel(resourceKey);
+ // Paper start - Add EntityPortalReadyEvent
+ io.papermc.paper.event.entity.EntityPortalReadyEvent portalReadyEvent = new io.papermc.paper.event.entity.EntityPortalReadyEvent(entity.getBukkitEntity(), level1 == null ? null : level1.getWorld(), org.bukkit.PortalType.NETHER);
+ if (!portalReadyEvent.callEvent()) {
+ entity.portalProcess = null;
+ return null;
+ }
+ level1 = portalReadyEvent.getTargetWorld() == null ? null : ((org.bukkit.craftbukkit.CraftWorld) portalReadyEvent.getTargetWorld()).getHandle();
+ // Paper end - Add EntityPortalReadyEvent
if (level1 == null) {
return null;
} else {
- boolean flag = level1.dimension() == Level.NETHER;
+ boolean flag = level1.getTypeKey() == net.minecraft.world.level.dimension.LevelStem.NETHER; // CraftBukkit
WorldBorder worldBorder = level1.getWorldBorder();
double teleportationScale = DimensionType.getTeleportationScale(level.dimensionType(), level1.dimensionType());
BlockPos blockPos = worldBorder.clampToBounds(entity.getX() * teleportationScale, entity.getY(), entity.getZ() * teleportationScale);
+ // Paper start - Configurable portal search radius
+ int portalSearchRadius = level1.paperConfig().environment.portalSearchRadius;
+ if (entity.level().paperConfig().environment.portalSearchVanillaDimensionScaling && flag) { // flag = is going to nether
+ portalSearchRadius = (int) (portalSearchRadius / level1.dimensionType().coordinateScale());
+ }
+ // Paper end - Configurable portal search radius
+ // CraftBukkit start
+ org.bukkit.craftbukkit.event.CraftPortalEvent event = entity.callPortalEvent(entity, org.bukkit.craftbukkit.util.CraftLocation.toBukkit(blockPos, level1.getWorld()), org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.NETHER_PORTAL, portalSearchRadius, level1.paperConfig().environment.portalCreateRadius); // Paper - use custom portal search radius
+ if (event == null) {
+ return null;
+ }
+ level1 = ((org.bukkit.craftbukkit.CraftWorld) event.getTo().getWorld()).getHandle();
+ worldBorder = level1.getWorldBorder();
+ blockPos = worldBorder.clampToBounds(event.getTo().getX(), event.getTo().getY(), event.getTo().getZ());
+ // CraftBukkit end
return this.getExitPortal(level1, entity, pos, blockPos, flag, worldBorder);
}
}
@Nullable
- private TeleportTransition getExitPortal(ServerLevel level, Entity entity, BlockPos pos, BlockPos exitPos, boolean isNether, WorldBorder worldBorder) {
- Optional<BlockPos> optional = level.getPortalForcer().findClosestPortalPosition(exitPos, isNether, worldBorder);
+ private TeleportTransition getExitPortal(ServerLevel level, Entity entity, BlockPos pos, BlockPos exitPos, boolean isNether, WorldBorder worldBorder, int searchRadius, boolean canCreatePortal, int createRadius) { // CraftBukkit
+ Optional<BlockPos> optional = level.getPortalForcer().findClosestPortalPosition(exitPos, worldBorder, searchRadius); // Craftbukkit
BlockUtil.FoundRectangle largestRectangleAround;
TeleportTransition.PostTeleportTransition postTeleportTransition;
if (optional.isPresent()) {
@@ -164,17 +_,22 @@
blockPos1 -> level.getBlockState(blockPos1) == blockState
);
postTeleportTransition = TeleportTransition.PLAY_PORTAL_SOUND.then(entity1 -> entity1.placePortalTicket(blockPos));
- } else {
+ } else if (canCreatePortal) { // CraftBukkit
Direction.Axis axis = entity.level().getBlockState(pos).getOptionalValue(AXIS).orElse(Direction.Axis.X);
- Optional<BlockUtil.FoundRectangle> optional1 = level.getPortalForcer().createPortal(exitPos, axis);
+ Optional<BlockUtil.FoundRectangle> optional1 = level.getPortalForcer().createPortal(exitPos, axis, entity, createRadius); // CraftBukkit
if (optional1.isEmpty()) {
- LOGGER.error("Unable to create a portal, likely target out of worldborder");
+ // LOGGER.error("Unable to create a portal, likely target out of worldborder"); // CraftBukkit
return null;
}
largestRectangleAround = optional1.get();
postTeleportTransition = TeleportTransition.PLAY_PORTAL_SOUND.then(TeleportTransition.PLACE_PORTAL_TICKET);
}
+ // CraftBukkit start
+ else {
+ return null;
+ }
+ // CraftBukkit end
return getDimensionTransitionFromExit(entity, pos, largestRectangleAround, level, postTeleportTransition);
}
@@ -220,7 +_,7 @@
boolean flag = axis1 == Direction.Axis.X;
Vec3 vec3 = new Vec3(blockPos.getX() + (flag ? d2 : d4), blockPos.getY() + d3, blockPos.getZ() + (flag ? d4 : d2));
Vec3 vec31 = PortalShape.findCollisionFreePosition(vec3, level, entity, dimensions);
- return new TeleportTransition(level, vec31, Vec3.ZERO, i, 0.0F, Relative.union(Relative.DELTA, Relative.ROTATION), postTeleportTransition);
+ return new TeleportTransition(level, vec31, Vec3.ZERO, i, 0.0F, Relative.union(Relative.DELTA, Relative.ROTATION), postTeleportTransition, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.NETHER_PORTAL); // CraftBukkit
}
@Override

View file

@ -0,0 +1,14 @@
--- a/net/minecraft/world/level/block/NetherWartBlock.java
+++ b/net/minecraft/world/level/block/NetherWartBlock.java
@@ -55,9 +_,9 @@
@Override
protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) {
int ageValue = state.getValue(AGE);
- if (ageValue < 3 && random.nextInt(10) == 0) {
+ if (ageValue < 3 && random.nextFloat() < (level.spigotConfig.wartModifier / (100.0f * 10))) { // Spigot - SPIGOT-7159: Better modifier resolution
state = state.setValue(AGE, Integer.valueOf(ageValue + 1));
- level.setBlock(pos, state, 2);
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, pos, state, 2); // CraftBukkit
}
}

View file

@ -0,0 +1,78 @@
--- a/net/minecraft/world/level/block/NoteBlock.java
+++ b/net/minecraft/world/level/block/NoteBlock.java
@@ -70,6 +_,7 @@
@Override
public BlockState getStateForPlacement(BlockPlaceContext context) {
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableNoteblockUpdates) return this.defaultBlockState(); // Paper - place without considering instrument
return this.setInstrument(context.getLevel(), context.getClickedPos(), this.defaultBlockState());
}
@@ -84,6 +_,7 @@
BlockState neighborState,
RandomSource random
) {
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableNoteblockUpdates) return state; // Paper - prevent noteblock instrument from updating
boolean flag = direction.getAxis() == Direction.Axis.Y;
return flag
? this.setInstrument(level, pos, state)
@@ -92,10 +_,12 @@
@Override
protected void neighborChanged(BlockState state, Level level, BlockPos pos, Block neighborBlock, @Nullable Orientation orientation, boolean movedByPiston) {
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableNoteblockUpdates) return; // Paper - prevent noteblock powered-state from updating
boolean hasNeighborSignal = level.hasNeighborSignal(pos);
if (hasNeighborSignal != state.getValue(POWERED)) {
if (hasNeighborSignal) {
this.playNote(null, state, level, pos);
+ state = level.getBlockState(pos); // CraftBukkit - SPIGOT-5617: update in case changed in event
}
level.setBlock(pos, state.setValue(POWERED, Boolean.valueOf(hasNeighborSignal)), 3);
@@ -104,6 +_,13 @@
private void playNote(@Nullable Entity entity, BlockState state, Level level, BlockPos pos) {
if (state.getValue(INSTRUMENT).worksAboveNoteBlock() || level.getBlockState(pos.above()).isAir()) {
+ // CraftBukkit start
+ // org.bukkit.event.block.NotePlayEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callNotePlayEvent(world, pos, state.getValue(NoteBlock.INSTRUMENT), state.getValue(NoteBlock.NOTE));
+ // if (event.isCancelled()) {
+ // return;
+ // }
+ // CraftBukkit end
+ // Paper - move NotePlayEvent call to fix instrument/note changes; TODO any way to cancel the game event?
level.blockEvent(pos, this, 0, 0);
level.gameEvent(entity, GameEvent.NOTE_BLOCK_PLAY, pos);
}
@@ -121,7 +_,7 @@
@Override
protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) {
if (!level.isClientSide) {
- state = state.cycle(NOTE);
+ if (!io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableNoteblockUpdates) state = state.cycle(NoteBlock.NOTE); // Paper - prevent noteblock note from updating
level.setBlock(pos, state, 3);
this.playNote(player, state, level, pos);
player.awardStat(Stats.TUNE_NOTEBLOCK);
@@ -145,9 +_,13 @@
@Override
protected boolean triggerEvent(BlockState state, Level level, BlockPos pos, int id, int param) {
NoteBlockInstrument noteBlockInstrument = state.getValue(INSTRUMENT);
+ // Paper start - move NotePlayEvent call to fix instrument/note changes
+ org.bukkit.event.block.NotePlayEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callNotePlayEvent(level, pos, noteBlockInstrument, state.getValue(NOTE));
+ if (event.isCancelled()) return false;
+ // Paper end - move NotePlayEvent call to fix instrument/note changes
float pitchFromNote;
if (noteBlockInstrument.isTunable()) {
- int noteValue = state.getValue(NOTE);
+ int noteValue = event.getNote().getId(); // Paper - move NotePlayEvent call to fix instrument/note changes
pitchFromNote = getPitchFromNote(noteValue);
level.addParticle(ParticleTypes.NOTE, pos.getX() + 0.5, pos.getY() + 1.2, pos.getZ() + 0.5, noteValue / 24.0, 0.0, 0.0);
} else {
@@ -163,7 +_,7 @@
holder = Holder.direct(SoundEvent.createVariableRangeEvent(customSoundId));
} else {
- holder = noteBlockInstrument.getSoundEvent();
+ holder = org.bukkit.craftbukkit.block.data.CraftBlockData.toNMS(event.getInstrument(), NoteBlockInstrument.class).getSoundEvent(); // Paper - move NotePlayEvent call to fix instrument/note changes
}
level.playSeededSound(

View file

@ -1,14 +1,14 @@
--- a/net/minecraft/world/level/block/NyliumBlock.java --- a/net/minecraft/world/level/block/NyliumBlock.java
+++ b/net/minecraft/world/level/block/NyliumBlock.java +++ b/net/minecraft/world/level/block/NyliumBlock.java
@@ -41,6 +41,11 @@ @@ -39,6 +_,11 @@
@Override @Override
protected void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) {
if (!NyliumBlock.canBeNylium(state, world, pos)) { if (!canBeNylium(state, level, pos)) {
+ // CraftBukkit start + // CraftBukkit start
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world, pos, Blocks.NETHERRACK.defaultBlockState()).isCancelled()) { + if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(level, pos, Blocks.NETHERRACK.defaultBlockState()).isCancelled()) {
+ return; + return;
+ } + }
+ // CraftBukkit end + // CraftBukkit end
world.setBlockAndUpdate(pos, Blocks.NETHERRACK.defaultBlockState()); level.setBlockAndUpdate(pos, Blocks.NETHERRACK.defaultBlockState());
} }
}

View file

@ -0,0 +1,21 @@
--- a/net/minecraft/world/level/block/ObserverBlock.java
+++ b/net/minecraft/world/level/block/ObserverBlock.java
@@ -50,8 +_,18 @@
@Override
protected void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) {
if (state.getValue(POWERED)) {
+ // CraftBukkit start
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, 15, 0).getNewCurrent() != 0) {
+ return;
+ }
+ // CraftBukkit end
level.setBlock(pos, state.setValue(POWERED, Boolean.valueOf(false)), 2);
} else {
+ // CraftBukkit start
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, 0, 15).getNewCurrent() != 15) {
+ return;
+ }
+ // CraftBukkit end
level.setBlock(pos, state.setValue(POWERED, Boolean.valueOf(true)), 2);
level.scheduleTick(pos, this, 2);
}

View file

@ -0,0 +1,20 @@
--- a/net/minecraft/world/level/block/PitcherCropBlock.java
+++ b/net/minecraft/world/level/block/PitcherCropBlock.java
@@ -131,7 +_,7 @@
@Override
public void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) {
float growthSpeed = CropBlock.getGrowthSpeed(this, level, pos);
- boolean flag = random.nextInt((int)(25.0F / growthSpeed) + 1) == 0;
+ boolean flag = random.nextFloat() < (level.spigotConfig.pitcherPlantModifier / (100.0F * (Math.floor(25.0F / growthSpeed) + 1))); // Paper - Fix Spigot growth modifiers
if (flag) {
this.grow(level, state, pos, 1);
}
@@ -141,7 +_,7 @@
int min = Math.min(state.getValue(AGE) + ageIncrement, 4);
if (this.canGrow(level, pos, state, min)) {
BlockState blockState = state.setValue(AGE, Integer.valueOf(min));
- level.setBlock(pos, blockState, 2);
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, pos, blockState, 2)) return; // Paper
if (isDouble(min)) {
level.setBlock(pos.above(), blockState.setValue(HALF, DoubleBlockHalf.UPPER), 3);
}

View file

@ -0,0 +1,68 @@
--- a/net/minecraft/world/level/block/PointedDripstoneBlock.java
+++ b/net/minecraft/world/level/block/PointedDripstoneBlock.java
@@ -147,6 +_,11 @@
&& projectile.mayBreak(serverLevel)
&& projectile instanceof ThrownTrident
&& projectile.getDeltaMovement().length() > 0.6) {
+ // CraftBukkit start
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(projectile, blockPos, state.getFluidState().createLegacyBlock())) { // Paper - fix wrong block state
+ return;
+ }
+ // CraftBukkit end
level.destroyBlock(blockPos, true);
}
}
@@ -155,7 +_,7 @@
@Override
public void fallOn(Level level, BlockState state, BlockPos pos, Entity entity, float fallDistance) {
if (state.getValue(TIP_DIRECTION) == Direction.UP && state.getValue(THICKNESS) == DripstoneThickness.TIP) {
- entity.causeFallDamage(fallDistance + 2.0F, 2.0F, level.damageSources().stalagmite());
+ entity.causeFallDamage(fallDistance + 2.0F, 2.0F, level.damageSources().stalagmite().directBlock(level, pos)); // CraftBukkit
} else {
super.fallOn(level, state, pos, entity, fallDistance);
}
@@ -213,10 +_,12 @@
if (blockPos != null) {
if (fluidAboveStalactite.get().sourceState.is(Blocks.MUD) && fluid == Fluids.WATER) {
BlockState blockState = Blocks.CLAY.defaultBlockState();
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(level, fluidAboveStalactite.get().pos, blockState)) { // Paper - Call BlockFormEvent
level.setBlockAndUpdate(fluidAboveStalactite.get().pos, blockState);
Block.pushEntitiesUp(fluidAboveStalactite.get().sourceState, blockState, level, fluidAboveStalactite.get().pos);
level.gameEvent(GameEvent.BLOCK_CHANGE, fluidAboveStalactite.get().pos, GameEvent.Context.of(blockState));
level.levelEvent(1504, blockPos, 0);
+ } // Paper - Call BlockFormEvent
} else {
BlockPos blockPos1 = findFillableCauldronBelowStalactiteTip(level, blockPos, fluid);
if (blockPos1 != null) {
@@ -380,17 +_,17 @@
if (isUnmergedTipWithDirection(blockState, direction.getOpposite())) {
createMergedTips(blockState, server, blockPos);
} else if (blockState.isAir() || blockState.is(Blocks.WATER)) {
- createDripstone(server, blockPos, direction, DripstoneThickness.TIP);
+ createDripstone(server, blockPos, direction, DripstoneThickness.TIP, pos); // CraftBukkit;
}
}
- private static void createDripstone(LevelAccessor level, BlockPos pos, Direction direction, DripstoneThickness thickness) {
+ private static void createDripstone(LevelAccessor level, BlockPos pos, Direction direction, DripstoneThickness thickness, BlockPos source) { // CraftBukkit
BlockState blockState = Blocks.POINTED_DRIPSTONE
.defaultBlockState()
.setValue(TIP_DIRECTION, direction)
.setValue(THICKNESS, thickness)
.setValue(WATERLOGGED, Boolean.valueOf(level.getFluidState(pos).getType() == Fluids.WATER));
- level.setBlock(pos, blockState, 3);
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(level, source, pos, blockState, 3); // CraftBukkit
}
private static void createMergedTips(BlockState state, LevelAccessor level, BlockPos pos) {
@@ -404,8 +_,8 @@
blockPos = pos.below();
}
- createDripstone(level, blockPos1, Direction.DOWN, DripstoneThickness.TIP_MERGE);
- createDripstone(level, blockPos, Direction.UP, DripstoneThickness.TIP_MERGE);
+ createDripstone(level, blockPos1, Direction.DOWN, DripstoneThickness.TIP_MERGE, pos); // CraftBukkit
+ createDripstone(level, blockPos, Direction.UP, DripstoneThickness.TIP_MERGE, pos); // CraftBukkit
}
public static void spawnDripParticle(Level level, BlockPos pos, BlockState state) {

View file

@ -0,0 +1,25 @@
--- a/net/minecraft/world/level/block/PowderSnowBlock.java
+++ b/net/minecraft/world/level/block/PowderSnowBlock.java
@@ -58,6 +_,7 @@
@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.getInBlockState().is(this)) {
entity.makeStuckInBlock(state, new Vec3(0.9F, 1.5, 0.9F));
if (level.isClientSide) {
@@ -80,8 +_,13 @@
entity.setIsInPowderSnow(true);
if (level instanceof ServerLevel serverLevel) {
if (entity.isOnFire()
- && (serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) || entity instanceof Player)
+ // CraftBukkit - move down
&& entity.mayInteract(serverLevel, pos)) {
+ // CraftBukkit start
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.AIR.defaultBlockState(), !(serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) || entity instanceof Player))) {
+ return;
+ }
+ // CraftBukkit end
level.destroyBlock(pos, false);
}

View file

@ -0,0 +1,16 @@
--- a/net/minecraft/world/level/block/PoweredRailBlock.java
+++ b/net/minecraft/world/level/block/PoweredRailBlock.java
@@ -133,6 +_,13 @@
|| this.findPoweredRailSignal(level, pos, state, true, 0)
|| this.findPoweredRailSignal(level, pos, state, false, 0);
if (flag != poweredValue) {
+ // CraftBukkit start
+ int power = flag ? 15 : 0;
+ int newPower = org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, power, 15 - power).getNewCurrent();
+ if (newPower == power) {
+ return;
+ }
+ // CraftBukkit end
level.setBlock(pos, state.setValue(POWERED, Boolean.valueOf(flag)), 3);
level.updateNeighborsAt(pos.below(), this);
if (state.getValue(SHAPE).isSlope()) {

View file

@ -0,0 +1,43 @@
--- a/net/minecraft/world/level/block/PressurePlateBlock.java
+++ b/net/minecraft/world/level/block/PressurePlateBlock.java
@@ -5,6 +_,7 @@
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
+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;
@@ -46,7 +_,31 @@
case EVERYTHING -> Entity.class;
case MOBS -> LivingEntity.class;
};
- return getEntityCount(level, TOUCH_AABB.move(pos), clazz) > 0 ? 15 : 0;
+ // CraftBukkit start - Call interact event when turning on a pressure plate
+ for (Entity entity : getEntities(level, PressurePlateBlock.TOUCH_AABB.move(pos), clazz)) {
+ if (this.getSignalForState(level.getBlockState(pos)) == 0) {
+ org.bukkit.World bworld = level.getWorld();
+ org.bukkit.plugin.PluginManager manager = level.getCraftServer().getPluginManager();
+ 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(), bworld.getBlockAt(pos.getX(), pos.getY(), pos.getZ()));
+ manager.callEvent((org.bukkit.event.entity.EntityInteractEvent) cancellable);
+ }
+
+ // We only want to block turning the plate on if all events are cancelled
+ if (cancellable.isCancelled()) {
+ continue;
+ }
+ }
+
+ return 15;
+ }
+
+ return 0;
+ // CraftBukkit end
}
@Override

Some files were not shown because too many files have changed in this diff Show more