mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-27 15:00:13 +01:00
net/minecraft/world/level/block/a-r
This commit is contained in:
parent
11b1877545
commit
b16f6f533a
177 changed files with 3259 additions and 3980 deletions
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
|
@ -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
|
||||||
}
|
}
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
|
@ -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++;
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
|
@ -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 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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);
|
|
@ -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;
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
|
@ -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);
|
|
@ -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);
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
|
@ -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
|
|
@ -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);
|
|
@ -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
|
|
@ -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);
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
}
|
}
|
|
@ -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);
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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));
|
|
@ -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
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
);
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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
|
|
@ -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 {
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
}
|
|
@ -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()) {
|
|
@ -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
|
||||||
}
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
|
@ -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);
|
|
@ -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);
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
|
@ -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);
|
|
@ -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
|
|
@ -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();
|
|
@ -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();
|
|
@ -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
|
||||||
}
|
}
|
|
@ -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 {
|
|
@ -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 {
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
|
@ -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
|
|
@ -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
|
|
@ -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) {
|
|
@ -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
|
|
@ -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);
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
|
@ -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);
|
|
@ -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);
|
|
@ -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) {
|
|
@ -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 {
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
}
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
|
|
@ -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);
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
|
@ -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 {
|
|
@ -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
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
@ -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 {
|
|
@ -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
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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(
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
|
@ -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) {
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -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()) {
|
|
@ -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
Loading…
Reference in a new issue