From df0c5613b49cdc64de25854f2d42efa9d0752cd2 Mon Sep 17 00:00:00 2001 From: Clexus <528373858@qq.com> Date: Fri, 21 Aug 2026 22:46:51 +0800 Subject: [PATCH 1/3] Add EntityLandEvent --- .../paper/event/entity/EntityLandEvent.java | 61 +++++++++++++++++++ .../world/level/block/Block.java.patch | 10 +++ .../level/block/FarmlandBlock.java.patch | 5 +- .../world/level/block/HoneyBlock.java.patch | 10 +++ .../block/PointedDripstoneBlock.java.patch | 6 +- .../level/block/PowderSnowBlock.java.patch | 10 +++ .../world/level/block/SlimeBlock.java.patch | 12 ++++ .../level/block/TurtleEggBlock.java.patch | 10 +++ .../craftbukkit/event/CraftEventFactory.java | 13 ++++ 9 files changed, 135 insertions(+), 2 deletions(-) create mode 100644 paper-api/src/main/java/io/papermc/paper/event/entity/EntityLandEvent.java create mode 100644 paper-server/patches/sources/net/minecraft/world/level/block/SlimeBlock.java.patch diff --git a/paper-api/src/main/java/io/papermc/paper/event/entity/EntityLandEvent.java b/paper-api/src/main/java/io/papermc/paper/event/entity/EntityLandEvent.java new file mode 100644 index 000000000000..a86cc51b51c2 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/event/entity/EntityLandEvent.java @@ -0,0 +1,61 @@ +package io.papermc.paper.event.entity; + +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.entity.EntityEvent; +import org.jspecify.annotations.NullMarked; + +/** + * Called when an {@link Entity} lands on the block after falling. + * This event is called before {@link org.bukkit.event.entity.EntityDamageEvent}, {@link org.bukkit.event.entity.EntityChangeBlockEvent}, {@link org.bukkit.event.player.PlayerInteractEvent} + * and {@link org.bukkit.event.entity.EntityInteractEvent}. + */ +@NullMarked +public class EntityLandEvent extends EntityEvent implements Cancellable { + + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final Block block; + private boolean cancelled; + + public EntityLandEvent(final Entity entity, final Block block) { + super(entity); + this.block = block; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } + + /** + * Returns the block that the entity landed on. + * + * @return the block that the entity landed on + */ + public Block getBlock() { + return this.block; + } + + @Override + public boolean isCancelled() { + return this.cancelled; + } + + /** + * Sets whether to cancel the landing, cancelling this event will prevent + * the entity from taking fall damage and interact with the block. (ex: break turtle egg) + * + * @param cancel true if the event should be cancelled, false otherwise + */ + @Override + public void setCancelled(final boolean cancel) { + this.cancelled = cancel; + } +} diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/Block.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/Block.java.patch index b3fcedc0af12..b29d119ebc4d 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/Block.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/Block.java.patch @@ -170,6 +170,16 @@ } public void setPlacedBy(final Level level, final BlockPos pos, final BlockState state, final @Nullable LivingEntity by, final ItemStack itemStack) { +@@ -488,6 +_,9 @@ + } + + public void fallOn(final Level level, final BlockState state, final BlockPos pos, final Entity entity, final double fallDistance) { ++ if(!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityLandEvent(state, level, pos, entity, false)){ // Paper start - Add EntityLandEvent ++ return; ++ } // Paper end - Add EntityLandEvent + entity.causeFallDamage(fallDistance, 1.0F, entity.damageSources().fall()); + } + @@ -613,12 +_,20 @@ return this.builtInRegistryHolder; } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/FarmlandBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/FarmlandBlock.java.patch index e9491079cab5..0544dd24806c 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/FarmlandBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/FarmlandBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/FarmlandBlock.java +++ b/net/minecraft/world/level/block/FarmlandBlock.java -@@ -94,31 +_,59 @@ +@@ -94,31 +_,62 @@ @Override protected void randomTick(final BlockState state, final ServerLevel level, final BlockPos pos, final RandomSource random) { int moisture = state.getValue(MOISTURE); @@ -21,6 +21,9 @@ @Override public void fallOn(final Level level, final BlockState state, final BlockPos pos, final Entity entity, final double fallDistance) { ++ if(!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityLandEvent(state, level, pos, entity, true)){ // Paper start - Add EntityLandEvent ++ return; ++ } // Paper end - Add EntityLandEvent + 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.getRandom().nextFloat() < fallDistance - 0.5 diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/HoneyBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/HoneyBlock.java.patch index ca996ad35af6..d20d1e1564b2 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/HoneyBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/HoneyBlock.java.patch @@ -1,5 +1,15 @@ --- a/net/minecraft/world/level/block/HoneyBlock.java +++ b/net/minecraft/world/level/block/HoneyBlock.java +@@ -51,6 +_,9 @@ + + @Override + public void fallOn(final Level level, final BlockState state, final BlockPos pos, final Entity entity, final double fallDistance) { ++ if(!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityLandEvent(state, level, pos, entity, true)){ // Paper start - Add EntityLandEvent ++ return; ++ } // Paper end - Add EntityLandEvent + entity.playSound(SoundEvents.HONEY_BLOCK_SLIDE, 1.0F, 1.0F); + if (!level.isClientSide()) { + level.broadcastEntityEvent(entity, EntityEvent.HONEY_JUMP); @@ -70,6 +_,7 @@ final InsideBlockEffectApplier effectApplier, final boolean isPrecise diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/PointedDripstoneBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/PointedDripstoneBlock.java.patch index f06ade2e2409..a41fcc21ebdc 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/PointedDripstoneBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/PointedDripstoneBlock.java.patch @@ -1,8 +1,12 @@ --- a/net/minecraft/world/level/block/PointedDripstoneBlock.java +++ b/net/minecraft/world/level/block/PointedDripstoneBlock.java -@@ -63,7 +_,7 @@ +@@ -62,8 +_,11 @@ + @Override public void fallOn(final Level level, final BlockState state, final BlockPos pos, final Entity entity, final double fallDistance) { ++ if(!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityLandEvent(state, level, pos, entity, true)){ // Paper start - Add EntityLandEvent ++ return; ++ } // Paper end - Add EntityLandEvent if (state.getValue(TIP_DIRECTION) == Direction.UP && state.getValue(THICKNESS) == SpeleothemThickness.TIP) { - entity.causeFallDamage(fallDistance + 2.5, 2.0F, level.damageSources().stalagmite()); + entity.causeFallDamage(fallDistance + 2.5, 2.0F, level.damageSources().stalagmite().eventBlockDamager(level, pos)); // CraftBukkit diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/PowderSnowBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/PowderSnowBlock.java.patch index 95637c475007..0758a1ec72d8 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/PowderSnowBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/PowderSnowBlock.java.patch @@ -30,3 +30,13 @@ level.destroyBlock(position, false); } } +@@ -104,6 +_,9 @@ + + @Override + public void fallOn(final Level level, final BlockState state, final BlockPos pos, final Entity entity, final double fallDistance) { ++ if(!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityLandEvent(state, level, pos, entity, true)){ // Paper start - Add EntityLandEvent ++ return; ++ } // Paper end - Add EntityLandEvent + if (!(fallDistance < 4.0) && entity instanceof LivingEntity livingEntity) { + LivingEntity.Fallsounds entityFallsounds = livingEntity.getFallSounds(); + SoundEvent fallSound = fallDistance < 7.0 ? entityFallsounds.small() : entityFallsounds.big(); diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/SlimeBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/SlimeBlock.java.patch new file mode 100644 index 000000000000..d757794a9a9c --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/SlimeBlock.java.patch @@ -0,0 +1,12 @@ +--- a/net/minecraft/world/level/block/SlimeBlock.java ++++ b/net/minecraft/world/level/block/SlimeBlock.java +@@ -21,6 +_,9 @@ + + @Override + public void fallOn(final Level level, final BlockState state, final BlockPos pos, final Entity entity, final double fallDistance) { ++ if(!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityLandEvent(state, level, pos, entity, false)){ // Paper start - Add EntityLandEvent ++ return; ++ } // Paper end - Add EntityLandEvent + if (!entity.isSuppressingBounce()) { + entity.causeFallDamage(fallDistance, 0.0F, level.damageSources().fall()); + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/TurtleEggBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/TurtleEggBlock.java.patch index 49ba7862869d..e27431b6b1ae 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/TurtleEggBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/TurtleEggBlock.java.patch @@ -1,5 +1,15 @@ --- a/net/minecraft/world/level/block/TurtleEggBlock.java +++ b/net/minecraft/world/level/block/TurtleEggBlock.java +@@ -63,6 +_,9 @@ + + @Override + public void fallOn(final Level level, final BlockState state, final BlockPos pos, final Entity entity, final double fallDistance) { ++ if(!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityLandEvent(state, level, pos, entity, true)){ // Paper start - Add EntityLandEvent ++ return; ++ } // Paper end - Add EntityLandEvent + if (!(entity instanceof Zombie)) { + this.destroyEgg(level, state, pos, entity, 3); + } @@ -75,6 +_,19 @@ && level instanceof ServerLevel serverLevel && this.canDestroyEgg(serverLevel, entity) diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/paper-server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java index a5ea91906abe..c2ca6f1c39df 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -12,6 +12,7 @@ import io.papermc.paper.event.block.BlockLockCheckEvent; import io.papermc.paper.event.connection.PlayerConnectionValidateLoginEvent; import io.papermc.paper.event.entity.EntityIgniteEvent; +import io.papermc.paper.event.entity.EntityLandEvent; import io.papermc.paper.event.entity.ItemTransportingEntityValidateTargetEvent; import io.papermc.paper.event.player.PlayerBedFailEnterEvent; import io.papermc.paper.event.player.PlayerToggleEntityAgeLockEvent; @@ -69,6 +70,7 @@ import net.minecraft.world.level.Explosion; import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.SignBlockEntity; import net.minecraft.world.level.block.state.properties.NoteBlockInstrument; @@ -2425,4 +2427,15 @@ public static int callEntityIgniteEvent(Entity entity, int fuseTime) { } return event.getFuseTime(); } + + public static boolean callEntityLandEvent(net.minecraft.world.level.block.state.BlockState state, Level level, BlockPos pos, Entity entity, boolean isOverrideMethod) { + if (EntityLandEvent.getHandlerList().getRegisteredListeners().length == 0) { + return true; // No listeners, skip event creation + } + if(!isOverrideMethod && (state.is(Blocks.POINTED_DRIPSTONE) || state.is(Blocks.TURTLE_EGG) || state.is(Blocks.FARMLAND))){ + return true; // Event will be called in the class separately + } + EntityLandEvent event = new EntityLandEvent(entity.getBukkitEntity(), CraftBlock.at(level, pos)); + return event.callEvent(); + } } From db6a5fcf0b7a47819873d3aef29b98d531207a72 Mon Sep 17 00:00:00 2001 From: Clexus <528373858@qq.com> Date: Sun, 23 Aug 2026 11:08:23 +0800 Subject: [PATCH 2/3] Add fall distance support --- .../paper/event/entity/EntityLandEvent.java | 25 ++++++++++++++++++- .../world/level/block/Block.java.patch | 11 +++++--- .../level/block/FarmlandBlock.java.patch | 12 +++++---- .../world/level/block/HoneyBlock.java.patch | 14 ++++++++--- .../block/PointedDripstoneBlock.java.patch | 14 +++++++---- .../level/block/PowderSnowBlock.java.patch | 16 ++++++++---- .../world/level/block/SlimeBlock.java.patch | 12 ++++++--- .../level/block/TurtleEggBlock.java.patch | 13 +++++++--- .../craftbukkit/event/CraftEventFactory.java | 11 ++++---- 9 files changed, 93 insertions(+), 35 deletions(-) diff --git a/paper-api/src/main/java/io/papermc/paper/event/entity/EntityLandEvent.java b/paper-api/src/main/java/io/papermc/paper/event/entity/EntityLandEvent.java index a86cc51b51c2..be3a7514d823 100644 --- a/paper-api/src/main/java/io/papermc/paper/event/entity/EntityLandEvent.java +++ b/paper-api/src/main/java/io/papermc/paper/event/entity/EntityLandEvent.java @@ -19,10 +19,12 @@ public class EntityLandEvent extends EntityEvent implements Cancellable { private final Block block; private boolean cancelled; + private double fallDistance; - public EntityLandEvent(final Entity entity, final Block block) { + public EntityLandEvent(final Entity entity, final Block block, double fallDistance) { super(entity); this.block = block; + this.fallDistance = fallDistance; } @Override @@ -58,4 +60,25 @@ public boolean isCancelled() { public void setCancelled(final boolean cancel) { this.cancelled = cancel; } + + /** + * Gets the fall distance of the entity before landing. + * + * @return the fall distance + */ + public double getFallDistance() { + return fallDistance; + } + + /** + * Sets the fall distance of the entity before landing. + * Fall distance in the event is used to calculate fall damage and + * the chance of transforming {@link org.bukkit.Material#FARMLAND} to {@link org.bukkit.Material#DIRT} and + * the type of falling sound when the entity lands on {@link org.bukkit.Material#POWDER_SNOW}. + * + * @param fallDistance the fall distance + */ + public void setFallDistance(final double fallDistance) { + this.fallDistance = fallDistance; + } } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/Block.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/Block.java.patch index b29d119ebc4d..f1f027d73013 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/Block.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/Block.java.patch @@ -170,16 +170,19 @@ } public void setPlacedBy(final Level level, final BlockPos pos, final BlockState state, final @Nullable LivingEntity by, final ItemStack itemStack) { -@@ -488,6 +_,9 @@ +@@ -488,7 +_,11 @@ } public void fallOn(final Level level, final BlockState state, final BlockPos pos, final Entity entity, final double fallDistance) { -+ if(!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityLandEvent(state, level, pos, entity, false)){ // Paper start - Add EntityLandEvent +- entity.causeFallDamage(fallDistance, 1.0F, entity.damageSources().fall()); ++ double distance = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityLandEvent(state, level, pos, entity, fallDistance, false); // Paper start - Add EntityLandEvent ++ if(distance == -1){ + return; -+ } // Paper end - Add EntityLandEvent - entity.causeFallDamage(fallDistance, 1.0F, entity.damageSources().fall()); ++ } ++ entity.causeFallDamage(distance, 1.0F, entity.damageSources().fall()); // Paper end - Add EntityLandEvent } + public float getBounceRestitution() { @@ -613,12 +_,20 @@ return this.builtInRegistryHolder; } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/FarmlandBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/FarmlandBlock.java.patch index 0544dd24806c..8916aff1883f 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/FarmlandBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/FarmlandBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/FarmlandBlock.java +++ b/net/minecraft/world/level/block/FarmlandBlock.java -@@ -94,31 +_,62 @@ +@@ -94,31 +_,63 @@ @Override protected void randomTick(final BlockState state, final ServerLevel level, final BlockPos pos, final RandomSource random) { int moisture = state.getValue(MOISTURE); @@ -21,12 +21,14 @@ @Override public void fallOn(final Level level, final BlockState state, final BlockPos pos, final Entity entity, final double fallDistance) { -+ if(!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityLandEvent(state, level, pos, entity, true)){ // Paper start - Add EntityLandEvent ++ double distance = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityLandEvent(state, level, pos, entity, fallDistance, true); // Paper start - Add EntityLandEvent ++ if(distance == -1){ + return; -+ } // Paper end - Add EntityLandEvent -+ super.fallOn(level, state, pos, entity, fallDistance); // CraftBukkit - moved here as game rules / events shouldn't affect fall damage. ++ } ++ super.fallOn(level, state, pos, entity, distance); // CraftBukkit - moved here as game rules / events shouldn't affect fall damage. if (level instanceof ServerLevel serverLevel - && level.getRandom().nextFloat() < fallDistance - 0.5 +- && level.getRandom().nextFloat() < fallDistance - 0.5 ++ && level.getRandom().nextFloat() < distance - 0.5 // Paper end - Add EntityLandEvent && entity instanceof LivingEntity && (entity instanceof Player || serverLevel.getGameRules().get(GameRules.MOB_GRIEFING)) && entity.getBbWidth() * entity.getBbWidth() * entity.getBbHeight() > 0.512F) { diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/HoneyBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/HoneyBlock.java.patch index d20d1e1564b2..274de8a2d147 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/HoneyBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/HoneyBlock.java.patch @@ -1,15 +1,23 @@ --- a/net/minecraft/world/level/block/HoneyBlock.java +++ b/net/minecraft/world/level/block/HoneyBlock.java -@@ -51,6 +_,9 @@ +@@ -51,12 +_,16 @@ @Override public void fallOn(final Level level, final BlockState state, final BlockPos pos, final Entity entity, final double fallDistance) { -+ if(!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityLandEvent(state, level, pos, entity, true)){ // Paper start - Add EntityLandEvent ++ double distance = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityLandEvent(state, level, pos, entity, fallDistance, true); // Paper start - Add EntityLandEvent ++ if(distance == -1){ + return; -+ } // Paper end - Add EntityLandEvent ++ } entity.playSound(SoundEvents.HONEY_BLOCK_SLIDE, 1.0F, 1.0F); if (!level.isClientSide()) { level.broadcastEntityEvent(entity, EntityEvent.HONEY_JUMP); + } + +- if (entity.causeFallDamage(fallDistance, 0.2F, level.damageSources().fall())) { ++ if (entity.causeFallDamage(distance, 0.2F, level.damageSources().fall())) { // Paper end - Add EntityLandEvent + entity.playSound(this.soundType.getFallSound(), this.soundType.getVolume() * 0.5F, this.soundType.getPitch() * 0.75F); + } + } @@ -70,6 +_,7 @@ final InsideBlockEffectApplier effectApplier, final boolean isPrecise diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/PointedDripstoneBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/PointedDripstoneBlock.java.patch index a41fcc21ebdc..396148cbae7f 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/PointedDripstoneBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/PointedDripstoneBlock.java.patch @@ -1,18 +1,22 @@ --- a/net/minecraft/world/level/block/PointedDripstoneBlock.java +++ b/net/minecraft/world/level/block/PointedDripstoneBlock.java -@@ -62,8 +_,11 @@ +@@ -62,10 +_,14 @@ @Override public void fallOn(final Level level, final BlockState state, final BlockPos pos, final Entity entity, final double fallDistance) { -+ if(!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityLandEvent(state, level, pos, entity, true)){ // Paper start - Add EntityLandEvent ++ double distance = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityLandEvent(state, level, pos, entity, fallDistance, true); // Paper start - Add EntityLandEvent ++ if(distance == -1){ + return; -+ } // Paper end - Add EntityLandEvent ++ } if (state.getValue(TIP_DIRECTION) == Direction.UP && state.getValue(THICKNESS) == SpeleothemThickness.TIP) { - entity.causeFallDamage(fallDistance + 2.5, 2.0F, level.damageSources().stalagmite()); -+ entity.causeFallDamage(fallDistance + 2.5, 2.0F, level.damageSources().stalagmite().eventBlockDamager(level, pos)); // CraftBukkit ++ entity.causeFallDamage(distance + 2.5, 2.0F, level.damageSources().stalagmite().eventBlockDamager(level, pos)); // CraftBukkit } else { - super.fallOn(level, state, pos, entity, fallDistance); +- super.fallOn(level, state, pos, entity, fallDistance); ++ super.fallOn(level, state, pos, entity, distance); // Paper end - Add EntityLandEvent } + } + @@ -110,10 +_,11 @@ if (stalactiteTipPos != null) { if (fluidInfo.get().sourceState.is(Blocks.MUD) && fluid == Fluids.WATER) { diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/PowderSnowBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/PowderSnowBlock.java.patch index 0758a1ec72d8..572e17cf4982 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/PowderSnowBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/PowderSnowBlock.java.patch @@ -30,13 +30,19 @@ level.destroyBlock(position, false); } } -@@ -104,6 +_,9 @@ +@@ -104,9 +_,13 @@ @Override public void fallOn(final Level level, final BlockState state, final BlockPos pos, final Entity entity, final double fallDistance) { -+ if(!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityLandEvent(state, level, pos, entity, true)){ // Paper start - Add EntityLandEvent +- if (!(fallDistance < 4.0) && entity instanceof LivingEntity livingEntity) { ++ double distance = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityLandEvent(state, level, pos, entity, fallDistance, true); // Paper start - Add EntityLandEvent ++ if(distance == -1){ + return; -+ } // Paper end - Add EntityLandEvent - if (!(fallDistance < 4.0) && entity instanceof LivingEntity livingEntity) { ++ } ++ if (!(distance < 4.0) && entity instanceof LivingEntity livingEntity) { LivingEntity.Fallsounds entityFallsounds = livingEntity.getFallSounds(); - SoundEvent fallSound = fallDistance < 7.0 ? entityFallsounds.small() : entityFallsounds.big(); +- SoundEvent fallSound = fallDistance < 7.0 ? entityFallsounds.small() : entityFallsounds.big(); ++ SoundEvent fallSound = distance < 7.0 ? entityFallsounds.small() : entityFallsounds.big(); // Paper end - Add EntityLandEvent + entity.playSound(fallSound, 1.0F, 1.0F); + } + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/SlimeBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/SlimeBlock.java.patch index d757794a9a9c..0a8caaa58540 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/SlimeBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/SlimeBlock.java.patch @@ -1,12 +1,16 @@ --- a/net/minecraft/world/level/block/SlimeBlock.java +++ b/net/minecraft/world/level/block/SlimeBlock.java -@@ -21,6 +_,9 @@ +@@ -21,8 +_,12 @@ @Override public void fallOn(final Level level, final BlockState state, final BlockPos pos, final Entity entity, final double fallDistance) { -+ if(!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityLandEvent(state, level, pos, entity, false)){ // Paper start - Add EntityLandEvent ++ double distance = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityLandEvent(state, level, pos, entity, fallDistance, true); // Paper start - Add EntityLandEvent ++ if(distance == -1){ + return; -+ } // Paper end - Add EntityLandEvent ++ } if (!entity.isSuppressingBounce()) { - entity.causeFallDamage(fallDistance, 0.0F, level.damageSources().fall()); +- entity.causeFallDamage(fallDistance, 0.0F, level.damageSources().fall()); ++ entity.causeFallDamage(distance, 0.0F, level.damageSources().fall()); // Paper end - Add EntityLandEvent } + } + diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/TurtleEggBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/TurtleEggBlock.java.patch index e27431b6b1ae..3fee4fbc837c 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/TurtleEggBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/TurtleEggBlock.java.patch @@ -1,15 +1,22 @@ --- a/net/minecraft/world/level/block/TurtleEggBlock.java +++ b/net/minecraft/world/level/block/TurtleEggBlock.java -@@ -63,6 +_,9 @@ +@@ -63,11 +_,15 @@ @Override public void fallOn(final Level level, final BlockState state, final BlockPos pos, final Entity entity, final double fallDistance) { -+ if(!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityLandEvent(state, level, pos, entity, true)){ // Paper start - Add EntityLandEvent ++ double distance = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityLandEvent(state, level, pos, entity, fallDistance, true); // Paper start - Add EntityLandEvent ++ if(distance == -1){ + return; -+ } // Paper end - Add EntityLandEvent ++ } if (!(entity instanceof Zombie)) { this.destroyEgg(level, state, pos, entity, 3); } + +- super.fallOn(level, state, pos, entity, fallDistance); ++ super.fallOn(level, state, pos, entity, distance); // Paper end - Add EntityLandEvent + } + + private void destroyEgg(final Level level, final BlockState state, final BlockPos pos, final Entity entity, final int randomness) { @@ -75,6 +_,19 @@ && level instanceof ServerLevel serverLevel && this.canDestroyEgg(serverLevel, entity) diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/paper-server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java index c2ca6f1c39df..2cd6941456d1 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -2428,14 +2428,15 @@ public static int callEntityIgniteEvent(Entity entity, int fuseTime) { return event.getFuseTime(); } - public static boolean callEntityLandEvent(net.minecraft.world.level.block.state.BlockState state, Level level, BlockPos pos, Entity entity, boolean isOverrideMethod) { + public static double callEntityLandEvent(net.minecraft.world.level.block.state.BlockState state, Level level, BlockPos pos, Entity entity, double fallDistance, boolean isOverrideMethod) { if (EntityLandEvent.getHandlerList().getRegisteredListeners().length == 0) { - return true; // No listeners, skip event creation + return fallDistance; // No listeners, skip event creation } if(!isOverrideMethod && (state.is(Blocks.POINTED_DRIPSTONE) || state.is(Blocks.TURTLE_EGG) || state.is(Blocks.FARMLAND))){ - return true; // Event will be called in the class separately + return fallDistance; // Event will be called in the class separately } - EntityLandEvent event = new EntityLandEvent(entity.getBukkitEntity(), CraftBlock.at(level, pos)); - return event.callEvent(); + EntityLandEvent event = new EntityLandEvent(entity.getBukkitEntity(), CraftBlock.at(level, pos), fallDistance); + event.callEvent(); + return event.isCancelled() ? -1 : event.getFallDistance(); } } From b11adeea024274481f304bc2bc324d66ba2f36ca Mon Sep 17 00:00:00 2001 From: Clexus <528373858@qq.com> Date: Tue, 25 Aug 2026 09:30:31 +0800 Subject: [PATCH 3/3] Use new fallOn --- .../minecraft/world/level/block/Block.java.patch | 16 ++++++++++++---- .../world/level/block/FarmlandBlock.java.patch | 4 ++-- .../world/level/block/HayBlock.java.patch | 14 ++++++++++++++ .../world/level/block/HoneyBlock.java.patch | 2 +- .../level/block/PointedDripstoneBlock.java.patch | 4 ++-- .../world/level/block/PowderSnowBlock.java.patch | 2 +- .../world/level/block/SlimeBlock.java.patch | 2 +- .../world/level/block/TurtleEggBlock.java.patch | 4 ++-- .../craftbukkit/event/CraftEventFactory.java | 5 +---- 9 files changed, 36 insertions(+), 17 deletions(-) create mode 100644 paper-server/patches/sources/net/minecraft/world/level/block/HayBlock.java.patch diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/Block.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/Block.java.patch index f1f027d73013..0c2b6bb5c64f 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/Block.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/Block.java.patch @@ -170,19 +170,27 @@ } public void setPlacedBy(final Level level, final BlockPos pos, final BlockState state, final @Nullable LivingEntity by, final ItemStack itemStack) { -@@ -488,7 +_,11 @@ +@@ -488,8 +_,18 @@ } public void fallOn(final Level level, final BlockState state, final BlockPos pos, final Entity entity, final double fallDistance) { - entity.causeFallDamage(fallDistance, 1.0F, entity.damageSources().fall()); -+ double distance = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityLandEvent(state, level, pos, entity, fallDistance, false); // Paper start - Add EntityLandEvent +- } ++ fallOn(level, state, pos, entity, fallDistance, true); // Paper - Add EntityLandEvent ++ } ++ ++ // Paper start - Add EntityLandEvent ++ public void fallOn(final Level level, final BlockState state, final BlockPos pos, final Entity entity, final double fallDistance, boolean callEvent) { ++ double distance = callEvent ? org.bukkit.craftbukkit.event.CraftEventFactory.callEntityLandEvent(level, pos, entity, fallDistance) : fallDistance; + if(distance == -1){ + return; + } -+ entity.causeFallDamage(distance, 1.0F, entity.damageSources().fall()); // Paper end - Add EntityLandEvent - } ++ entity.causeFallDamage(distance, 1.0F, entity.damageSources().fall()); ++ } ++ // Paper end - Add EntityLandEvent public float getBounceRestitution() { + return this.bounceRestitution; @@ -613,12 +_,20 @@ return this.builtInRegistryHolder; } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/FarmlandBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/FarmlandBlock.java.patch index 8916aff1883f..5f7b60cde3f8 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/FarmlandBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/FarmlandBlock.java.patch @@ -21,11 +21,11 @@ @Override public void fallOn(final Level level, final BlockState state, final BlockPos pos, final Entity entity, final double fallDistance) { -+ double distance = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityLandEvent(state, level, pos, entity, fallDistance, true); // Paper start - Add EntityLandEvent ++ double distance = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityLandEvent(level, pos, entity, fallDistance); // Paper start - Add EntityLandEvent + if(distance == -1){ + return; + } -+ super.fallOn(level, state, pos, entity, distance); // CraftBukkit - moved here as game rules / events shouldn't affect fall damage. ++ super.fallOn(level, state, pos, entity, distance, false); // CraftBukkit - moved here as game rules / events shouldn't affect fall damage. if (level instanceof ServerLevel serverLevel - && level.getRandom().nextFloat() < fallDistance - 0.5 + && level.getRandom().nextFloat() < distance - 0.5 // Paper end - Add EntityLandEvent diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/HayBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/HayBlock.java.patch new file mode 100644 index 000000000000..b0dc5ccb98b5 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/HayBlock.java.patch @@ -0,0 +1,14 @@ +--- a/net/minecraft/world/level/block/HayBlock.java ++++ b/net/minecraft/world/level/block/HayBlock.java +@@ -23,6 +_,10 @@ + + @Override + public void fallOn(final Level level, final BlockState state, final BlockPos pos, final Entity entity, final double fallDistance) { +- entity.causeFallDamage(fallDistance, 0.2F, level.damageSources().fall()); ++ double distance = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityLandEvent(level, pos, entity, fallDistance); // Paper start - Add EntityLandEvent ++ if(distance == -1){ ++ return; ++ } ++ entity.causeFallDamage(distance, 0.2F, level.damageSources().fall()); // Paper end - Add EntityLandEvent + } + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/HoneyBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/HoneyBlock.java.patch index 274de8a2d147..46bfca68534e 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/HoneyBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/HoneyBlock.java.patch @@ -4,7 +4,7 @@ @Override public void fallOn(final Level level, final BlockState state, final BlockPos pos, final Entity entity, final double fallDistance) { -+ double distance = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityLandEvent(state, level, pos, entity, fallDistance, true); // Paper start - Add EntityLandEvent ++ double distance = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityLandEvent(level, pos, entity, fallDistance); // Paper start - Add EntityLandEvent + if(distance == -1){ + return; + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/PointedDripstoneBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/PointedDripstoneBlock.java.patch index 396148cbae7f..c23e86daa88e 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/PointedDripstoneBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/PointedDripstoneBlock.java.patch @@ -4,7 +4,7 @@ @Override public void fallOn(final Level level, final BlockState state, final BlockPos pos, final Entity entity, final double fallDistance) { -+ double distance = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityLandEvent(state, level, pos, entity, fallDistance, true); // Paper start - Add EntityLandEvent ++ double distance = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityLandEvent(level, pos, entity, fallDistance); // Paper start - Add EntityLandEvent + if(distance == -1){ + return; + } @@ -13,7 +13,7 @@ + entity.causeFallDamage(distance + 2.5, 2.0F, level.damageSources().stalagmite().eventBlockDamager(level, pos)); // CraftBukkit } else { - super.fallOn(level, state, pos, entity, fallDistance); -+ super.fallOn(level, state, pos, entity, distance); // Paper end - Add EntityLandEvent ++ super.fallOn(level, state, pos, entity, distance, false); // Paper end - Add EntityLandEvent } } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/PowderSnowBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/PowderSnowBlock.java.patch index 572e17cf4982..3b029d9e0984 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/PowderSnowBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/PowderSnowBlock.java.patch @@ -35,7 +35,7 @@ @Override public void fallOn(final Level level, final BlockState state, final BlockPos pos, final Entity entity, final double fallDistance) { - if (!(fallDistance < 4.0) && entity instanceof LivingEntity livingEntity) { -+ double distance = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityLandEvent(state, level, pos, entity, fallDistance, true); // Paper start - Add EntityLandEvent ++ double distance = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityLandEvent(level, pos, entity, fallDistance); // Paper start - Add EntityLandEvent + if(distance == -1){ + return; + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/SlimeBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/SlimeBlock.java.patch index 0a8caaa58540..364641b5f49c 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/SlimeBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/SlimeBlock.java.patch @@ -4,7 +4,7 @@ @Override public void fallOn(final Level level, final BlockState state, final BlockPos pos, final Entity entity, final double fallDistance) { -+ double distance = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityLandEvent(state, level, pos, entity, fallDistance, true); // Paper start - Add EntityLandEvent ++ double distance = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityLandEvent(level, pos, entity, fallDistance); // Paper start - Add EntityLandEvent + if(distance == -1){ + return; + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/TurtleEggBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/TurtleEggBlock.java.patch index 3fee4fbc837c..94b1f7b182bb 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/TurtleEggBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/TurtleEggBlock.java.patch @@ -4,7 +4,7 @@ @Override public void fallOn(final Level level, final BlockState state, final BlockPos pos, final Entity entity, final double fallDistance) { -+ double distance = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityLandEvent(state, level, pos, entity, fallDistance, true); // Paper start - Add EntityLandEvent ++ double distance = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityLandEvent(level, pos, entity, fallDistance); // Paper start - Add EntityLandEvent + if(distance == -1){ + return; + } @@ -13,7 +13,7 @@ } - super.fallOn(level, state, pos, entity, fallDistance); -+ super.fallOn(level, state, pos, entity, distance); // Paper end - Add EntityLandEvent ++ super.fallOn(level, state, pos, entity, distance, false); // Paper end - Add EntityLandEvent } private void destroyEgg(final Level level, final BlockState state, final BlockPos pos, final Entity entity, final int randomness) { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/paper-server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java index 2cd6941456d1..a59639ba752b 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -2428,13 +2428,10 @@ public static int callEntityIgniteEvent(Entity entity, int fuseTime) { return event.getFuseTime(); } - public static double callEntityLandEvent(net.minecraft.world.level.block.state.BlockState state, Level level, BlockPos pos, Entity entity, double fallDistance, boolean isOverrideMethod) { + public static double callEntityLandEvent(Level level, BlockPos pos, Entity entity, double fallDistance) { if (EntityLandEvent.getHandlerList().getRegisteredListeners().length == 0) { return fallDistance; // No listeners, skip event creation } - if(!isOverrideMethod && (state.is(Blocks.POINTED_DRIPSTONE) || state.is(Blocks.TURTLE_EGG) || state.is(Blocks.FARMLAND))){ - return fallDistance; // Event will be called in the class separately - } EntityLandEvent event = new EntityLandEvent(entity.getBukkitEntity(), CraftBlock.at(level, pos), fallDistance); event.callEvent(); return event.isCancelled() ? -1 : event.getFallDistance();