13
0
geforkt von Mirrors/Paper

BlockDestroyEvent

Adds an event for when the server is going to destroy a current block,
potentially causing it to drop. This event can be cancelled to avoid
the block destruction, such as preventing signs from popping when
floating in the air.

This can replace many uses of BlockPhysicsEvent
Dieser Commit ist enthalten in:
Aikar 2019-02-06 00:20:33 -05:00
Ursprung 4c350ecbb5
Commit b71ceb5e0f

Datei anzeigen

@ -1,14 +1,17 @@
--- a/net/minecraft/world/level/Level.java --- a/net/minecraft/world/level/Level.java
+++ b/net/minecraft/world/level/Level.java +++ b/net/minecraft/world/level/Level.java
@@ -27,6 +27,7 @@ @@ -25,8 +25,10 @@
import net.minecraft.network.protocol.Packet;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
+import io.papermc.paper.util.MCUtil;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.FullChunkStatus; import net.minecraft.server.level.FullChunkStatus;
+import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent; import net.minecraft.sounds.SoundEvent;
import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource; import net.minecraft.sounds.SoundSource;
@@ -43,6 +44,7 @@ @@ -43,6 +45,7 @@
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.boss.EnderDragonPart; import net.minecraft.world.entity.boss.EnderDragonPart;
import net.minecraft.world.entity.boss.enderdragon.EnderDragon; import net.minecraft.world.entity.boss.enderdragon.EnderDragon;
@ -16,7 +19,7 @@
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.alchemy.PotionBrewing; import net.minecraft.world.item.alchemy.PotionBrewing;
@@ -57,12 +59,14 @@ @@ -57,12 +60,14 @@
import net.minecraft.world.level.block.entity.FuelValues; import net.minecraft.world.level.block.entity.FuelValues;
import net.minecraft.world.level.block.entity.TickingBlockEntity; import net.minecraft.world.level.block.entity.TickingBlockEntity;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
@ -31,7 +34,7 @@
import net.minecraft.world.level.entity.EntityTypeTest; import net.minecraft.world.level.entity.EntityTypeTest;
import net.minecraft.world.level.entity.LevelEntityGetter; import net.minecraft.world.level.entity.LevelEntityGetter;
import net.minecraft.world.level.gameevent.GameEvent; import net.minecraft.world.level.gameevent.GameEvent;
@@ -81,6 +85,25 @@ @@ -81,6 +86,25 @@
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import net.minecraft.world.scores.Scoreboard; import net.minecraft.world.scores.Scoreboard;
@ -57,7 +60,7 @@
public abstract class Level implements LevelAccessor, AutoCloseable { public abstract class Level implements LevelAccessor, AutoCloseable {
public static final Codec<ResourceKey<Level>> RESOURCE_KEY_CODEC = ResourceKey.codec(Registries.DIMENSION); public static final Codec<ResourceKey<Level>> RESOURCE_KEY_CODEC = ResourceKey.codec(Registries.DIMENSION);
@@ -94,7 +117,7 @@ @@ -94,7 +118,7 @@
public static final int TICKS_PER_DAY = 24000; public static final int TICKS_PER_DAY = 24000;
public static final int MAX_ENTITY_SPAWN_Y = 20000000; public static final int MAX_ENTITY_SPAWN_Y = 20000000;
public static final int MIN_ENTITY_SPAWN_Y = -20000000; public static final int MIN_ENTITY_SPAWN_Y = -20000000;
@ -66,7 +69,7 @@
protected final NeighborUpdater neighborUpdater; protected final NeighborUpdater neighborUpdater;
private final List<TickingBlockEntity> pendingBlockEntityTickers = Lists.newArrayList(); private final List<TickingBlockEntity> pendingBlockEntityTickers = Lists.newArrayList();
private boolean tickingBlockEntities; private boolean tickingBlockEntities;
@@ -121,23 +144,74 @@ @@ -121,23 +145,74 @@
private final DamageSources damageSources; private final DamageSources damageSources;
private long subTickCount; private long subTickCount;
@ -150,7 +153,7 @@
} }
}; };
} else { } else {
@@ -145,13 +219,90 @@ @@ -145,13 +220,90 @@
} }
this.thread = Thread.currentThread(); this.thread = Thread.currentThread();
@ -246,7 +249,7 @@
@Override @Override
public boolean isClientSide() { public boolean isClientSide() {
return this.isClientSide; return this.isClientSide;
@@ -163,6 +314,13 @@ @@ -163,6 +315,13 @@
return null; return null;
} }
@ -260,7 +263,7 @@
public boolean isInWorldBounds(BlockPos pos) { public boolean isInWorldBounds(BlockPos pos) {
return !this.isOutsideBuildHeight(pos) && Level.isInWorldBoundsHorizontal(pos); return !this.isOutsideBuildHeight(pos) && Level.isInWorldBoundsHorizontal(pos);
} }
@@ -179,18 +337,73 @@ @@ -179,18 +338,73 @@
return y < -20000000 || y >= 20000000; return y < -20000000 || y >= 20000000;
} }
@ -310,7 +313,7 @@
+ return chunk == null ? null : chunk.getFluidState(blockposition); + return chunk == null ? null : chunk.getFluidState(blockposition);
+ } + }
+ +
@Override + @Override
+ public final boolean hasChunkAt(BlockPos pos) { + public final boolean hasChunkAt(BlockPos pos) {
+ return getChunkIfLoaded(pos.getX() >> 4, pos.getZ() >> 4) != null; // Paper - Perf: Optimize Level.hasChunkAt(BlockPosition)Z + return getChunkIfLoaded(pos.getX() >> 4, pos.getZ() >> 4) != null; // Paper - Perf: Optimize Level.hasChunkAt(BlockPosition)Z
+ } + }
@ -331,13 +334,13 @@
+ return getWorldBorder().isWithinBounds(blockposition) ? getBlockStateIfLoaded(blockposition) : null; + return getWorldBorder().isWithinBounds(blockposition) ? getBlockStateIfLoaded(blockposition) : null;
+ } + }
+ +
+ @Override @Override
public ChunkAccess getChunk(int chunkX, int chunkZ, ChunkStatus leastStatus, boolean create) { public ChunkAccess getChunk(int chunkX, int chunkZ, ChunkStatus leastStatus, boolean create) {
+ // Paper end + // Paper end
ChunkAccess ichunkaccess = this.getChunkSource().getChunk(chunkX, chunkZ, leastStatus, create); ChunkAccess ichunkaccess = this.getChunkSource().getChunk(chunkX, chunkZ, leastStatus, create);
if (ichunkaccess == null && create) { if (ichunkaccess == null && create) {
@@ -207,6 +420,18 @@ @@ -207,6 +421,18 @@
@Override @Override
public boolean setBlock(BlockPos pos, BlockState state, int flags, int maxUpdateDepth) { public boolean setBlock(BlockPos pos, BlockState state, int flags, int maxUpdateDepth) {
@ -356,7 +359,7 @@
if (this.isOutsideBuildHeight(pos)) { if (this.isOutsideBuildHeight(pos)) {
return false; return false;
} else if (!this.isClientSide && this.isDebug()) { } else if (!this.isClientSide && this.isDebug()) {
@@ -214,45 +439,125 @@ @@ -214,44 +440,124 @@
} else { } else {
LevelChunk chunk = this.getChunkAt(pos); LevelChunk chunk = this.getChunkAt(pos);
Block block = state.getBlock(); Block block = state.getBlock();
@ -441,10 +444,10 @@
+ // CraftBukkit end + // CraftBukkit end
+ +
return true; return true;
} + }
} + }
} + }
+
+ // CraftBukkit start - Split off from above in order to directly send client and physic updates + // CraftBukkit start - Split off from above in order to directly send client and physic updates
+ public void notifyAndUpdatePhysics(BlockPos blockposition, LevelChunk chunk, BlockState oldBlock, BlockState newBlock, BlockState actualBlock, int i, int j) { + public void notifyAndUpdatePhysics(BlockPos blockposition, LevelChunk chunk, BlockState oldBlock, BlockState newBlock, BlockState actualBlock, int i, int j) {
+ BlockState iblockdata = newBlock; + BlockState iblockdata = newBlock;
@ -483,21 +486,49 @@
+ // CraftBukkit end + // CraftBukkit end
+ iblockdata.updateNeighbourShapes(this, blockposition, k, j - 1); + iblockdata.updateNeighbourShapes(this, blockposition, k, j - 1);
+ iblockdata.updateIndirectNeighbourShapes(this, blockposition, k, j - 1); + iblockdata.updateIndirectNeighbourShapes(this, blockposition, k, j - 1);
+ } }
+ +
+ // CraftBukkit start - SPIGOT-5710 + // CraftBukkit start - SPIGOT-5710
+ if (!this.preventPoiUpdated) { + if (!this.preventPoiUpdated) {
+ this.onBlockStateChange(blockposition, iblockdata1, iblockdata2); + this.onBlockStateChange(blockposition, iblockdata1, iblockdata2);
+ } + }
+ // CraftBukkit end + // CraftBukkit end
+ } }
+ } }
+ // CraftBukkit end + // CraftBukkit end
+
public void onBlockStateChange(BlockPos pos, BlockState oldBlock, BlockState newBlock) {} public void onBlockStateChange(BlockPos pos, BlockState oldBlock, BlockState newBlock) {}
@Override @@ -270,9 +576,26 @@
@@ -340,10 +645,18 @@ return false;
} else {
FluidState fluid = this.getFluidState(pos);
+ // Paper start - BlockDestroyEvent; while the above setAir method is named same and looks very similar
+ // they are NOT used with same intent and the above should not fire this event. The above method is more of a BlockSetToAirEvent,
+ // it doesn't imply destruction of a block that plays a sound effect / drops an item.
+ boolean playEffect = true;
+ BlockState effectType = iblockdata;
+ int xp = iblockdata.getBlock().getExpDrop(iblockdata, (ServerLevel) this, pos, ItemStack.EMPTY, true);
+ if (com.destroystokyo.paper.event.block.BlockDestroyEvent.getHandlerList().getRegisteredListeners().length > 0) {
+ com.destroystokyo.paper.event.block.BlockDestroyEvent event = new com.destroystokyo.paper.event.block.BlockDestroyEvent(org.bukkit.craftbukkit.block.CraftBlock.at(this, pos), fluid.createLegacyBlock().createCraftBlockData(), effectType.createCraftBlockData(), xp, drop);
+ if (!event.callEvent()) {
+ return false;
+ }
+ effectType = ((CraftBlockData) event.getEffectBlock()).getState();
+ playEffect = event.playEffect();
+ drop = event.willDrop();
+ xp = event.getExpToDrop();
+ }
+ // Paper end - BlockDestroyEvent
- if (!(iblockdata.getBlock() instanceof BaseFireBlock)) {
- this.levelEvent(2001, pos, Block.getId(iblockdata));
+ if (playEffect && !(effectType.getBlock() instanceof BaseFireBlock)) { // Paper - BlockDestroyEvent
+ this.levelEvent(2001, pos, Block.getId(effectType)); // Paper - BlockDestroyEvent
}
if (drop) {
@@ -340,10 +663,18 @@
@Override @Override
public BlockState getBlockState(BlockPos pos) { public BlockState getBlockState(BlockPos pos) {
@ -517,7 +548,7 @@
return chunk.getBlockState(pos); return chunk.getBlockState(pos);
} }
@@ -446,34 +759,53 @@ @@ -446,34 +777,53 @@
this.pendingBlockEntityTickers.clear(); this.pendingBlockEntityTickers.clear();
} }
@ -569,18 +600,18 @@
+ entity.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD); + entity.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD);
+ // Paper end - Prevent block entity and entity crashes + // Paper end - Prevent block entity and entity crashes
} }
+ } }
+ // Paper start - Option to prevent armor stands from doing entity lookups + // Paper start - Option to prevent armor stands from doing entity lookups
+ @Override + @Override
+ public boolean noCollision(@Nullable Entity entity, AABB box) { + public boolean noCollision(@Nullable Entity entity, AABB box) {
+ if (entity instanceof net.minecraft.world.entity.decoration.ArmorStand && !entity.level().paperConfig().entities.armorStands.doCollisionEntityLookups) return false; + if (entity instanceof net.minecraft.world.entity.decoration.ArmorStand && !entity.level().paperConfig().entities.armorStands.doCollisionEntityLookups) return false;
+ return LevelAccessor.super.noCollision(entity, box); + return LevelAccessor.super.noCollision(entity, box);
} + }
+ // Paper end - Option to prevent armor stands from doing entity lookups + // Paper end - Option to prevent armor stands from doing entity lookups
public boolean shouldTickDeath(Entity entity) { public boolean shouldTickDeath(Entity entity) {
return true; return true;
@@ -510,13 +842,29 @@ @@ -510,13 +860,29 @@
@Nullable @Nullable
@Override @Override
public BlockEntity getBlockEntity(BlockPos pos) { public BlockEntity getBlockEntity(BlockPos pos) {
@ -611,7 +642,7 @@
this.getChunkAt(blockposition).addAndRegisterBlockEntity(blockEntity); this.getChunkAt(blockposition).addAndRegisterBlockEntity(blockEntity);
} }
} }
@@ -643,7 +991,7 @@ @@ -643,7 +1009,7 @@
for (int k = 0; k < j; ++k) { for (int k = 0; k < j; ++k) {
EnderDragonPart entitycomplexpart = aentitycomplexpart[k]; EnderDragonPart entitycomplexpart = aentitycomplexpart[k];
@ -620,7 +651,7 @@
if (t0 != null && predicate.test(t0)) { if (t0 != null && predicate.test(t0)) {
result.add(t0); result.add(t0);
@@ -912,7 +1260,7 @@ @@ -912,7 +1278,7 @@
public static enum ExplosionInteraction implements StringRepresentable { public static enum ExplosionInteraction implements StringRepresentable {